StyleValueList is a list of StyleValues of the same type, for use in
properties like `margin` which accept a variable number of arguments.
I had originally hoped to simply swap the old ValueListStyleValue from
being a list of ComponentValues to one of StyleValues, but I can see now
that I will need to have both for a little while, so renamed the old
is_value_list() to is_component_value_list() temporarily.
I had accidentally parsed it in `parse_builtin_or_dynamic_value()`
instead of `parse_length()` before, which was confusing, so now it's
parsed along with other Lengths.
Whether it should be a Length is up for debate, and has been tripping me
up a few times, but a lot of code expects it to be one. For now, an
'auto' Length value (or any other value which overloads `is_auto()`)
also claims to be a `ValueID::Auto` identifier.
A '0' token can be interpreted both as a Number, and as a Length. This
is problematic as in our CSS parser, we often call parse_css_value()
first, to figure out what something is, and then assign it. So we do not
know in advance whether we want a Length or not. Previously, it always
got parsed as a Length, and then every place that expected a
NumericStyleValue had to also check for a Length(0), which is easy to
forget to do.
In particular, this was causing issues with the `flex` property parsing.
To solve this, we now always parse 0 as a NumericStyleValue, and NSVs of
0 pretend to be a Length(0px) when asked. In two places, we were casting
to a LengthStyleValue* based on is_length(), which no longer works, so
those have been adjusted to use `StyleValue::to_length()` instead. They
also now check for `is_numeric()` first, to avoid the extra conversion
to a Length and back.
Possibly this opens up new issues elsewhere. In my testing it seems
fine, but until we can get CSS test suites running, it's hard to know
for certain.
Previously, the loops would stop before reaching EOF, meaning that the
values that should have been set to EOF were left with their 0 initial
values. Now, we initialize to EOFs instead. The if/else inside the loops
always ran the else branch so I have removed the if branches.
Change all the places that were including the deprecated parser, to
include the new one instead, and then delete the old parser code.
`ParentNode::query_selector[_all]()` now treat their input as a
comma-separated list of selectors, instead of just one, and return
elements that match any of the selectors in that list. This is according
to these specs:
- querySelector/querySelectorAll:
https://dom.spec.whatwg.org/#ref-for-dom-parentnode-queryselector%E2%91%A0
- selector matching algorithm:
https://www.w3.org/TR/selectors-4/#match-against-tree
These mostly match the API in `DeprecatedCSSParser.h`. The exception is
that `parse_selector()` returns a `SelectorList` instead of just one
`Selector`. The only uses of that are in
`ParentNode::query_selector[_all]()` which should be matching against a
list, according to the spec.
`parse_html_length()` is an odd case. It's used for `width="200"` cases
in HTML, so is not really CSS related, but does produce a StyleValue.
The values allowed in `width/height` in HTML vary per element, but they
are a lot more restricted than in CSS, so it's slightly inappropriate to
use the CSS parser for them, even though it's convenient.
We also ignore a few functions:
- `parse_line_width()`
- `parse_line_style()`
- `parse_color()`
These are all only used in `StyleResolver`, when it is given a property
value as a String. That won't happen once the old parser is removed.
`parse_as_foo()` implies that the Parser's internal data is used,
whereas `parse_a_foo()` implies that the passed-in data is used.
Also, made all the `parse_a_foo()` methods private, as they are only
required within the Parser, and this makes the API clearer to outsiders.
The `parse_a(s)_foo()` naming is a little awkward, but it comes from
section 5.3 of the spec, so seemed worth keeping:
https://www.w3.org/TR/css-syntax-3/#parser-entry-points
Previous multi-value properties use a ValueListStyleValue, which then
gets parsed into its sub-properties in the StyleResolver. However, that
is not ideal, especially as it exposes StyleResolver to the inner
workings of the Parser and Tokenizer, which it should not need to know
about.
The way `box-shadow` was implemented as a StyleValue subclass means that
the parsing can happen inside the Parser instead, which seems like a
better solution. Converting the other complicated cases (background,
font, list-style) is on my todo list for later.
This lets us get the Length and Color values directly, without having to
create a StyleValue object and then throw it away again, when parsing
the box-shadow property in the next commit.
This is three small, related changes:
1. Element::has_attribute() now returns true if the attribute exists but
has no value. (eg, `<div foo />` -> `has_attribute("foo")`)
2. SelectorEngine::matches_attribute() now makes sure there is a first
segment before comparing it, fixing a crash.
3. CSS::Parser now converts attribute names in attribute selectors to
lowercase, to match the expectations of the rest of the system.
Converting to lowercase is not always correct, depending on language,
but since we only currently support HTML, and that expects them to be
case-insensitive, it is fine for now.
Parsing this pattern from CSS tokens turns out to be slightly crazy, but
thankfully well documented in the spec.
The spec lists the cases in order of simple -> complicated, but this
would cause problems in code, since `<n-dimension> <signed-.integer>`
would never by reached, as `<n-dimension>` comes before. Instead, I
have grouped them by their first token.
Also renamed the NthChildPattern class to ANPlusBPattern, to match spec
terminology.
The spec does not directly tell us how to parse selectors, so there are
likely some bugs here, but I've used the spec language where possible.
This is very much based on the previous selector parsing code.
Any parse error inside a selector makes the entire SelectorList
invalid, so nothing is returned.
- CompoundSelector -> *deleted*
- ComplexSelector -> CompoundSelector
- Relation -> Combinator
Our Selector is really a ComplexSelector, but only the Parser and
SelectorEngine need to know that, so keeping it named Selector makes it
more understandable for users.
Our CompoundSelector is really a CompoundSelectorAndCombinator.
Combining the two makes sense in our codebase, but the accurate name is
so long that I think it makes the code less readable.
Renamed some Combinators to also match the spec terminology:
- AdjacentSibling -> NextSibling
- GeneralSibling -> SubsequentSibling
The previous names are somewhat ambiguous, so hopefully this is clearer.
This was a hack copied over from the old parser, but it was causing
problems with flex-grow, and probably other properties that accept
numbers. Removing it does not seem to break anything, so lets' remove
it! :^)
Also added css-import.html, which tests the 3 syntax variations on
`@import` statements. Note that the optional media-query parameter to
`@import` is not handled yet.
We immediately use this in CSSStyleDeclaration to fix that "background"
in element.style did not return true.
This is the mechanism used in css3test.com for detecting support of
features.
This adds support for box-shadows to the DeprecatedCSSParser. When it
encounters a box-shadow property, the following syntaxes can get parsed:
- box-shadow: <offset_x> <offset_y> <color>
- box-shadow: <offset_x> <offset_y> <blur_radius> <color>
There is other possible data following the property, but those aren't
supported for now.
This patch spreads box-shadows around:
- The Values important to box-shadows are stored in a BoxShadowData
struct
- StyleProperties knows how to construct such a struct from a
BoxShadowStyleValue and a Node knows how to ask for it
- CalculatedValues contain BoxShadowData and expose them
This patch finally adds the actual calculation that goes into calc()
expressions. When the resolution of a Length that is a calculated value
the parsed CalculatedStyleValue gets traversed and appropriate values
get calculated.
This is a bit hackish, but this way the existance of the calc()
becomes transparent to the user who just wants a Length and doesn't
care where it came from.
This patch adds the parsing of previously tokenized calc() expressions
into the CSS-Parser. The tokens are processed into a complete
CalculatedStyleValue.
This detects and resolves these in the text-decoration property, in any
order:
- text-decoration-color
- text-decoration-line
- text-decoration-style
Only the solid underline renders, but all three sub-properties are
assigned correctly.
The font property now resolves into its various parts:
- font-family
- font-weight
- font-size
- font-style
- line-height
The font-variant and font-stretch parts are left unparsed since LibWeb
doesn't know how to render those.
Added `fonts.html` as a test for various forms of `font` declarations,
based on the examples in the spec.
This resolves the three sub-properties, appearing in any order:
- list-style-image
- list-style-position
- list-style-type
Added `list-style-position` values to support this, though they are not
yet used in rendering.