Commit graph

364 commits

Author SHA1 Message Date
Sam Atkins
761d29d647 LibWeb: Make CSS ParsingContext::m_url not Optional
This always has a value, so let's make that clearer.
2022-04-29 00:07:31 +02:00
Sam Atkins
ce5914230f LibWeb: Actually use BorderRadiusShorthandStyleValue
Somehow we were never actually using this before, but parsing the
property as a StyleValueList instead.
2022-04-18 21:30:51 +02:00
Sam Atkins
00782d9a59 LibWeb: Disallow trailing commas in transform function arguments 2022-04-18 14:16:28 +02:00
Sam Atkins
b3a6044fd8 LibWeb: Disallow non-whitespace tokens after "none" in transform
Before this, a declaration like `transform: none yellow 20;` would be
parsed as `transform: none;`. Now it's correctly rejected as invalid.
2022-04-18 14:16:28 +02:00
Sam Atkins
a52f6fb5b0 LibWeb: Use TransformFunctionMetadata when parsing their arguments
Now, the parser will reject a transform function if:
- There are too many arguments.
- There are too few arguments.
- An argument is the wrong type.
2022-04-18 14:16:28 +02:00
Sam Atkins
61ad39b110 LibWeb: Use generated TransformFunction enum and functions 2022-04-18 14:16:28 +02:00
Sam Atkins
7c91fda088 LibWeb: Allow multiple text-decoration-lines
The spec grammar for `text-decoration-line` is:

`none | [ underline || overline || line-through || blink ]`

Which means that it's either `none`, or any combination of the other
values. This patch makes that parse for `text-decoration-line` and
`text-decoration`, stores the results as a Vector, and adjusts
`paint_text_decoration()` to run as a loop over all the values that are
provided.

As noted, storing a Vector of values is a bit wasteful, as they could be
stored as flags in a single `u8`. But I was getting too confused trying
to do that in a nice way.
2022-04-14 21:54:10 +02:00
Sam Atkins
431a9938a8 LibWeb: Rename StyleRule -> Rule
This name is what's used in the spec, and is a little less confusing.
2022-04-12 23:03:46 +02:00
Sam Atkins
cf24dc2e0c LibWeb: Break friendship between CSS StyleRule and Parser
As before, this requires deviating from the spec slightly to create the
StyleRule fully-formed instead of creating it empty and then modifying
its internals.
2022-04-12 23:03:46 +02:00
Sam Atkins
d67e817d8e LibWeb: Break friendship between CSS Function and Parser
Again, this means deviating from the spec by creating a complete
Function in one go instead of creating it empty and then poking at its
internals.
2022-04-12 23:03:46 +02:00
Sam Atkins
128d08ecef LibWeb: Empend instead of Appending DeclarationOrAtRules 2022-04-12 23:03:46 +02:00
Sam Atkins
269810b954 LibWeb: Break friendship between CSS Declaration and Parser
This means deviating slightly from the spec in order to construct a
fully-initialized Declaration instead of creating an empty one and then
poking at its internals.

DeclarationOrAtRule should probably use a Variant, but for now, making
its Declaration member optional is quick and easy.
2022-04-12 23:03:46 +02:00
Sam Atkins
69496f4afd LibWeb: Make Declaration.m_name a FlyString 2022-04-12 23:03:46 +02:00
Sam Atkins
f235da27d9 LibWeb: Break friendship between CSS Block and Parser
This means deviating a little from the spec, so that we create a
complete Block in one go instead of creating an empty one and then
poking at its internals.
2022-04-12 23:03:46 +02:00
Sam Atkins
3e49036edf LibWeb: Move/rename StyleBlockRule to Parser::Block 2022-04-12 23:03:46 +02:00
Sam Atkins
e0b2ebcc7b LibWeb: Move/rename StyleFunctionRule to Parser::Function 2022-04-12 23:03:46 +02:00
Sam Atkins
c449cabae3 LibWeb: Move CSS Parser into new Web::CSS::Parser namespace
The goal here is to move the parser-internal classes into this namespace
so they can have more convenient names without causing collisions. The
Parser itself won't collide, and would be more convenient to just
remain `CSS::Parser`, but having a namespace and a class with the same
name makes C++ unhappy.
2022-04-12 23:03:46 +02:00
Simon Wanner
539adf5b9c LibWeb: Support WOFF in font-face 2022-04-09 23:48:18 +02:00
Sam Atkins
12b8570ce3 LibWeb: Understand the format() part of a @font-face's src
This is used to skip downloading fonts in formats that we don't support.
Currently we only support TTF as far as I am aware.

The parts of a `src` are in a fixed order, unusually, which makes the
parsing more nesty instead of loopy.
2022-04-07 21:20:14 +02:00
Sam Atkins
dbb0b68175 LibWeb: Disallow global CSS keywords in @font-face font-family 2022-04-07 21:20:14 +02:00
Sam Atkins
dbbd6d3508 LibWeb: Parse @font-face unicode-range descriptor 2022-04-07 21:20:14 +02:00
Sam Atkins
ef7d80ced2 LibWeb: Parse <urange> as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)

This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
2022-04-07 21:20:14 +02:00
Sam Atkins
802ccc210f LibWeb: Expose Declaration's internals with getters
This is more in line with our style of not accessing `m_foo` fields
directly.
2022-04-07 21:20:14 +02:00
Sam Atkins
611a209756 LibWeb: Rename StyleDeclarationRule -> Declaration
This is the term used in the CSS specs.
2022-04-07 21:20:14 +02:00
Sam Atkins
8b538b1578 LibWeb: Rename StyleComponentValueRule -> ComponentValue
"Component value" is the term used in the spec, and it doesn't conflict
 with any other types, so let's use the shorter name. :^)

Also, this doesn't need to be friends with the Parser any more.
2022-04-07 21:20:14 +02:00
Idan Horowitz
086969277e Everywhere: Run clang-format 2022-04-01 21:24:45 +01:00
Sam Atkins
cd199d9d06 LibWeb: Implement and use parse_a_style_blocks_contents() 2022-03-30 18:43:07 +02:00
Sam Atkins
6a0adbefc7 LibWeb: Tidy up StyleRule API
Constantly accessing private `m_foo` fields feels uncomfortable and
doesn't fit well with our code style.
2022-03-30 18:43:07 +02:00
Sam Atkins
75db8b1f86 LibWeb: Spec-comment consume_a_function() 2022-03-30 18:43:07 +02:00
Sam Atkins
512d1df1c4 LibWeb: Spec-comment consume_a_simple_block() 2022-03-30 18:43:07 +02:00
Sam Atkins
5a23965e93 LibWeb: Comment discrepancy from spec in consume_a_declaration()
We're calling this in a way that is incorrect, and so the algorithm's
assumption that the next token is an `<ident-token>` is wrong, and we
have to handle that failing. Ideally we would just stop calling this
incorrectly, but until then, let's actually document what is happening.
2022-03-30 18:43:07 +02:00
Sam Atkins
999cc51512 LibWeb: Spec-comment consume_a_component_value() 2022-03-30 18:43:07 +02:00
Sam Atkins
be86d19529 LIbWeb: Spec-comment consume_a_list_of_declarations() 2022-03-30 18:43:07 +02:00
Sam Atkins
e72f42bea1 LibWeb: Spec-comment consume_a_qualified_rule() 2022-03-30 18:43:07 +02:00
Sam Atkins
fe86718035 LibWeb: Spec-comment consume_an_at_rule() 2022-03-30 18:43:07 +02:00
Sam Atkins
d77de5ccec LibWeb: Spec-comment consume_a_list_of_rules() 2022-03-30 18:43:07 +02:00
Sam Atkins
a4f8056828 LibWeb: Spec-comment parse_a_comma_separated_list_of_component_values
The code had to change a bit to match. Previously, we appended an empty
sub-list immediately, but now we append it at the end. The difference
is that if there are no tokens, we now correctly return an empty
list-of-lists, instead of a list containing an empty list.
2022-03-30 18:43:07 +02:00
Sam Atkins
6ec92f5527 LibWeb: Spec-comment parse_a_list_of_component_values() 2022-03-30 18:43:07 +02:00
Sam Atkins
34b3c09462 LibWeb: Spec-comment parse_a_component_value() 2022-03-30 18:43:07 +02:00
Sam Atkins
bcf4254331 LibWeb: Spec-comment parse_a_list_of_declarations()
The `parse_as_list_of_declarations()` public method is unused and will
not be used by any user code so has been removed.
2022-03-30 18:43:07 +02:00
Sam Atkins
2aac9f9258 LibWeb: Bring parse_a_declaration() to spec and add comments
User code now calls `parse_as_supports_condition()` which actually does
the conversion to a StyleProperty.
2022-03-30 18:43:07 +02:00
Sam Atkins
239c36a19e LibWeb: Spec-comment parse_a_rule()
We now correctly call convert_to_rule() outside of this function.

As before, I've renamed `parse_as_rule()` -> `parse_as_css_rule()` to
match the free function that calls it.
2022-03-30 18:43:07 +02:00
Sam Atkins
12a787ef8a LibWeb: Use parse_a_list_of_rules() for @media and @supports
From the spec:
> "Parse a list of rules" is intended for the content of at-rules such
> as @media. It differs from "Parse a stylesheet" in the handling of
> <CDO-token> and <CDC-token>.
- https://www.w3.org/TR/css-syntax-3/#ref-for-parse-a-list-of-rules
2022-03-30 18:43:07 +02:00
Sam Atkins
7a225a380c LibWeb: Bring parse_a_list_of_rules() to spec
This is not actually used by anything currently, but it should be used
for `@media` and other at-rules.

Removed the public parse_as_list_of_rules() because public functions
should be things that outside classes actually need to use.
2022-03-30 18:43:07 +02:00
Sam Atkins
85d8c652e9 LibWeb: Implement and use "parse a CSS stylesheet" algorithm
`parse_a_stylesheet()` should not do any conversion on its rules. This
change corrects that. There are other places where we get this wrong,
but one thing at a time. :^)
2022-03-30 18:43:07 +02:00
Sam Atkins
fc3d51c59e LibWeb: Use an enum class for the "top-level flag" 2022-03-30 18:43:07 +02:00
Sam Atkins
87b125dcb9 LibWeb: Spec-comment parse_a_stylesheet()
Also introduce a `location` parameter when parsing a CSSStyleSheet. This
is not provided by anyone yet.
2022-03-30 18:43:07 +02:00
Sam Atkins
05bd0ca3ee LibWeb: Rename parse_css() -> parse_css_stylesheet() 2022-03-30 18:43:07 +02:00
Simon Wanner
6437f5da36 LibWeb: Add basic support for the attr() CSS function
CSS Values and Units Module Level 5 defines attr as:
  `attr(<q-name> <attr-type>?, <declaration-value>?)`

This implementation does not contain support for the type argument,
effectively supporting `attr(<q-name>, <declaration-value>?)`
2022-03-30 03:18:14 +02:00
Daniel Glazman
91e1383b85 LibWeb: Implement attribute selector case identifier 2022-03-29 18:53:20 +02:00
Andreas Kling
427beb97b5 LibWeb: Streamline how inline CSS style declarations are constructed
When parsing the "style" attribute on elements, we'd previously ask the
CSS parser for a PropertyOwningCSSStyleDeclaration. Then we'd create a
new ElementCSSInlineStyleDeclaration and transfer the properties from
the first object to the second object.

This patch teaches the parser to make ElementCSSInlineStyleDeclaration
objects directly.
2022-03-29 16:35:46 +02:00
Sam Atkins
6672c19c93 LibWeb: Parse @font-face rules
This is very limited for now, only caring about `font-family` and `src`.
2022-03-28 22:25:25 +02:00
Sam Atkins
1dcde57922 LibWeb: Bring "parse a list of declarations" closer to spec
The work to create a PropertyOwningCSSStyleDeclaration is now moved to
convert_to_style_declaration() instead.
2022-03-28 22:25:25 +02:00
Sam Atkins
da1a819858 LibWeb: Rename parse_css_declaration() -> parse_css_style_attribute() 2022-03-28 22:25:25 +02:00
Andreas Kling
fda25f9505 LibWeb: Move HTML dimension value parsing from CSS to HTML namespace
These are part of HTML, not CSS, so let's not confuse things.
2022-03-26 17:31:01 +01:00
Andreas Kling
434970f022 LibWeb: Remove the totally ad-hoc parse_html_length()
All clients of this API have been migrated to HTML dimension value
parsing instead.
2022-03-26 17:31:01 +01:00
Andreas Kling
28c929e85c LibWeb: Add parser for the HTML "non-zero dimensions value" microsyntax 2022-03-26 17:31:01 +01:00
Andreas Kling
075bdfdef8 LibWeb: Add a parser for the HTML "dimension value" microsyntax 2022-03-26 17:31:01 +01:00
Sam Atkins
c914e732d2 LibWeb+Base: Fix An+B of foo parsing
When I wrote the An+B parser, it was guaranteed to have no
non-whitespace tokens after it. This is no longer true with the `of
foo` syntax, so this patch corrects the logic when there is no `+B`
segment.

This makes this case shown on Twitter work correctly. :^)
https://twitter.com/simevidas/status/1506657566012678151
2022-03-24 18:08:45 +01:00
Sam Atkins
03daa4653f LibWeb: Parse and compute text-shadow property 2022-03-24 18:08:34 +01:00
Sam Atkins
f078bb8294 LibWeb: Implement disallowing inset when parsing shadows
`text-shadow` does not support this, so this way we can still use the
same parsing code.

It's OK that we still assign a ShadowPlacement value to the
ShadowStyleValue, since it will just get ignored when painting
text-shadows, but if it appears in the property value then that is a
syntax error.
2022-03-24 18:08:34 +01:00
Sam Atkins
1094654adc LbWeb: Rename BoxShadowFoo => ShadowFoo
The `text-shadow` property is almost identical to `box-shadow`:
> Values are interpreted as for box-shadow [CSS-BACKGROUNDS-3].
> (But note that the inset keyword are not allowed.)

So, let's use the same data structures and parsing code for both. :^)
2022-03-24 18:08:34 +01:00
Sam Atkins
004f69b535 LibWeb: Restore :is() and :where() selector parsing
This was a casualty in a recent merge-conflict resolution. Oops!
2022-03-23 15:46:48 -04:00
Andreas Kling
5118a4c1e7 LibWeb: Parse CSS "font-variant" as part of "font"
This allows us to parse CSS "font" values that contain e.g "small-caps"
or "normal", as used on Acid3.
2022-03-23 14:54:21 +01:00
Sam Atkins
c0d3f1a5e4 LibWeb: Use CSS::Number for CalculatedStyleValue numbers 2022-03-22 15:47:36 +01:00
Sam Atkins
fe372cd073 LibWeb: Use CSS::Number for Token numeric values 2022-03-22 15:47:36 +01:00
Sam Atkins
0795b9f7bb LibWeb: Use floats instead of doubles for CSS numbers
Using doubles isn't necessary, and they make things slightly bigger and
slower, so let's use floats instead.
2022-03-22 15:47:36 +01:00
Sam Atkins
404a7cb63a LibGfx+LibWeb: Use floats not doubles to create HSL colors
There's really no reason to use doubles here, except at the time I
wanted to use doubles everywhere in CSS. I now realize that is
excessive, so everything can be floats instead.
2022-03-22 15:47:36 +01:00
Sam Atkins
75ec960495 LibWeb: Initialize PseudoClass/PseudoElement selectors in one go
There was no real benefit to creating the SimpleSelector early and then
modifying it, and doing so made this code harder to follow than it
needs to be.
2022-03-22 15:47:36 +01:00
Sam Atkins
c0db19f63c LibWeb: Use a Variant for SimpleSelector's contents
This reduces SimpleSelector's size from 112 bytes to 80 bytes. :^)
2022-03-22 15:47:36 +01:00
Simon Wanner
dc94879b83 LibWeb: Support transform: translate(...) by percentage 2022-03-22 02:06:21 +01:00
Simon Wanner
63055ff5ad LibWeb: Parse the CSS transform-origin property
This is almost a PositionStyleValue, but it's serialized differently,
so let's use a StyleValueList with 2 length-percentage values.
2022-03-22 02:06:21 +01:00
Andreas Kling
1206dd2215 LibWeb: Make parse_html_length() accept floating point numbers
This makes stuff like <img width="12.5"> work. This code is not great,
so I've left a FIXME about improving it.
2022-03-21 15:58:21 +01:00
Hendiadyoin1
fff12847d5 LibWeb: Pull out larger parsing parts from Parser::parse_simple_selector
This lowers its cognitive complexity from 271 to under 100.
The new `parse_pseudo_simple_selector` still has a complexity of 114.
2022-03-21 12:49:00 +01:00
Hendiadyoin1
397d8b4aca LibWeb: Use a switch-statement on the delimiter for MatchType selection
... in Parser::parse_simple_selector
2022-03-21 12:49:00 +01:00
Hendiadyoin1
19cca57f8a LibWeb: Condense Delim checks in Parser::parse_simple_selector
This also removes some else-after-returns and adds some const qualifiers
2022-03-21 12:49:00 +01:00
Hendiadyoin1
3f8347718c LibWeb: Use a u32 for a delim tokens value
The spec says:
> <delim-token> has a value composed of a single code point.

So using StringView is a bit overkill.
This also allows us to use switch statements in the future.
2022-03-21 12:49:00 +01:00
Sam Atkins
d60b3be29a LibWeb: Implement the :focus-within selector
This matches if it has focus, or any nodes inside it do.
2022-03-20 17:35:31 +00:00
Andreas Kling
bdd42c9b0e LibWeb: Add basic support for :lang() CSS selector
This doesn't have parsing support for multiple languages in the same
selector. Support for language subcodes is not great either. But it
does do the basics.
2022-03-20 13:36:45 +01:00
Simon Wanner
c4f46893f6 LibWeb: Add parsing support for the remaining transform functions 2022-03-18 18:51:42 +01:00
Sam Atkins
174a25db5b LibWeb: Combine identical relative/regular selector parsing functions 2022-03-18 11:34:02 +01:00
Sam Atkins
5b0187477b LibWeb: Implement :nth-[last-]child(n of foo) syntax
In Selectors level 4, `:nth-child()` and `:nth-last-child()` can both
optionally take a selector-list argument. This selector-list acts as a
filter, so that only elements matching the list are counted. For
example, this means that the following are equivalent:

```css
:nth-child(2n+1 of p) {}
p:nth-of-type(2n+1) {}
```
2022-03-18 11:34:02 +01:00
Sam Atkins
993653317c LibWeb: Implement the :where() selector
This is identical to :is() except for specificity, so we can use the
same code paths. :^)
2022-03-18 11:34:02 +01:00
Sam Atkins
c148ed50bb LibWeb: Implement the :is() selector
This lets us finally get rid of a FIXME in the default style sheet. :^)
2022-03-18 11:34:02 +01:00
Sam Atkins
5319e2ba8e LibWeb: Parse forgiving selector-lists
`<forgiving-selector-list>` and `<forgiving-relative-selector-list>` are
the same as regular selector-lists, except that an invalid selector
does not make the whole list invalid. The former is used by the `:is()`
pseudo-class.

For example:

```css
/* This entire selector-list is invalid */
.foo, .bar, !?invalid { }

/* This is valid, but the "!?invalid" selector is removed */
:is(.foo, .bar, !?invalid) { }
```

Also as part of this, I've removed the `parse_a_selector(TokenStream)`
and `parse_a_relative_selector(TokenStream)` methods as they don't add
anything useful.
2022-03-18 11:34:02 +01:00
Lenny Maiorani
c37820b898 Libraries: Use default constructors/destructors in LibWeb
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cother-other-default-operation-rules

"The compiler is more likely to get the default semantics right and
you cannot implement these functions better than the compiler."
2022-03-17 17:23:49 +00:00
Simon Wanner
1ed5e79478 LibWeb: Fix resolving relative URLs in style sheets
Relative URLs in style sheets should be resolved relative to the
style sheet they're in instead of the document.
2022-03-14 22:22:53 +01:00
Sam Atkins
1c18bb13a2 LibWeb: Move pseudo-element-from-string code into Selector 2022-03-10 17:30:09 +01:00
Sam Atkins
56a36da44e LibWeb: Only try parsing valid types of media-feature values
This resolves the ambiguity between whether a single number is a number
or a ratio. :^)

Also removed the "no more tokens" checks from
deea129b8c - that logic was completely
wrong, since there are always tokens after a value in the `(123 < foo <
456)` syntax.
2022-03-09 23:06:30 +01:00
Sam Atkins
fd47460141 LibWeb: Use ValueID for media-query identifiers 2022-03-09 23:06:30 +01:00
Sam Atkins
0371d33132 LibWeb+Meta: Stop discrete media-features from parsing as ranges
Only "range" type media-features are allowed to appear in range syntax,
or have a `min-/max-` prefix.
2022-03-09 23:06:30 +01:00
Sam Atkins
12561327d6 LibWeb: Use MediaFeatureIDs instead of Strings :^) 2022-03-09 23:06:30 +01:00
Sam Atkins
deea129b8c LibWeb: Add Ratio type to MediaFeatureValue
As noted, the Parser can't handle the `<number>` syntax for this - it
gets parsed instead by the `<number>` branch. We can't actually resolve
the ambiguity without making the Parser aware of what type each
media-feature is, but I will get to that soon. :^)
2022-03-07 13:42:25 +01:00
Sam Atkins
5f93f1c161 LibWeb: Introduce and parse CSS Ratio type
This is only used by media-queries, so for now we can skip
adding/parsing a StyleValue for these.
2022-03-07 13:42:25 +01:00
Karol Kosek
0f7156ed81 LibWeb: Parse CSS text-decoration-thickness property 2022-03-06 22:04:41 +01:00
Sam Atkins
a57128467a LibWeb: Implement :nth-of-type and :nth-last-of-type selectors :^) 2022-02-26 15:30:24 +01:00
Sam Atkins
817cd13d59 LibWeb: Implement the ::marker pseudo-element
This matches the marker boxes of list-items.
2022-02-25 19:35:34 +01:00
Sam Atkins
caef4ec157 LibWeb: Move PseudoElement enum up a level
This in preparation for changing how we store these, plus it's unwieldy
having to type CSS::Selector::SimpleSelector::PseudoElement.
2022-02-25 19:35:34 +01:00
Sam Atkins
adaab23149 LibWeb: Parse the content property
For now, we only understand `none`, `normal`, `<image>` and `<string>`.
The various other functions and identifiers can be added later.

We can *almost* use a StyleValueList for this, except it's divided into
two parts - the content, and the optional "alt text". So, I've added a
new StyleValue for it.
2022-02-25 19:35:34 +01:00
Sam Atkins
fd2ef43cb4 LibWeb: Implement <resolution> as a media feature type
This is the only dimension type besides `<length>` that is used in any
media queries in levels 4 or 5 right now. Others can be included
if/when they're needed.
2022-02-24 08:04:25 +01:00