The values of attribute selectors are now compared case insensitively
by default if the attribute's document is not a HTML document, or the
element is not in the HTML namespace.
We previously had 4 single-instance StyleValues for these keywords.
CSS-Typed-OM expects them keywords to be exposed as CSSKeywordValue, so
it's simpler to treat them the same. The single-instance behaviour is
kept by having StyleValue::create() use a cached instance for each of
these.
For a long time, we've used two terms, inconsistently:
- "Identifier" is a spec term, but refers to a sequence of alphanumeric
characters, which may or may not be a keyword. (Keywords are a
subset of all identifiers.)
- "ValueID" is entirely non-spec, and is directly called a "keyword" in
the CSS specs.
So to avoid confusion as much as possible, let's align with the spec
terminology. I've attempted to change variable names as well, but
obviously we use Keywords in a lot of places in LibWeb and so I may
have missed some.
One exception is that I've not renamed "valid-identifiers" in
Properties.json... I'd like to combine that and the "valid-types" array
together eventually, so there's no benefit to doing an extra rename
now.
Being constrained by this macro is going to make it more difficult to
refactor our StyleValue types to match the Typed-OM spec, so let's
reintroduce the boilerplate for now.
No functional changes.
The `start` and `end` value set the text alignment based on the computed
value of `direction`. The default value of `text-align` is now `start`
instead of `left`.
Right now, we deviate from the CSSOM spec regarding our
CSSStyleDeclaration classes, so this is not as close to the spec as I'd
like. But it works, which means we'll be able to test pseudo-element
styling a lot more easily. :^)
As noted, this is hacky because the parser wasn't written to allow
parsing an individual component of a selector. (Fox example, the
convenient-sounding `parse_pseudo_simple_selector()` assumes the first
colon has already been consumed...) So until that changes, this parses
the input as an entire selector-list, and then throws it away if it's
not a single pseudo-element selector.
It's only temporary though, I promise. 😅
Instead of carrying the display list for a mask in each command that
might potentially be affected by "background-clip: text", this change
introduces a new AddMask command that is applied once for all
background layers within one box.
The new AddMask command includes a rectangle for the mask destination
that is translated by the corresponding scroll offset.
Fixes https://github.com/LadybirdBrowser/ladybird/issues/857
This change fixes layering violation by moving to_px() calls to happen
before display list recording. Also it should make display list
recording a bit faster by resolving background properties beforehand.
For the SVG <use> element, we want to support loading HTML documents
that have a SVG element inside of it pointed to by the URL fragment.
In this situation we would need to fetch and parse the entire document
in SharedImageRequest (so that we can still cache the SVGs). Rename
SharedImageRequest to SharedResourceRequest to make the class a little
more generic for future usecases.
Previously, calling `setProperty` or `removeProperty` from JS on a
CSSStyleDeclaration returned from `getComputedStyle()` would return
null. We now return a NoModificationAllowedError instead, which aligns
our implementation with the specification.
Not every value in a StyleProperties will be non-null by the time we
perform `revert`, so let's make a specialized function for reverting a
property instead of using the path that requires the value to be
non-null.
This shrinks each instance of PercentageOr by 8 bytes and avoids virtual
dispatch when resolving calc() values. It's a win-win!
Many data structures shrink as a result. An example is ComputedValues
which goes from 3376 bytes to 3024 bytes per instance.
We were saving to source declarations for *every* property, even though
we only ever looked it up for animation-name.
This patch gets rid of the per-property source pointer and we now keep
a single pointer to the animation-name source only.
This shrinks StyleProperties from 6512 bytes to 4368 bytes per instance.
Pseudo-elements' style is only computed while building the layout tree.
This meant that previously, they would not have their style recomputed
in some cases. (Such as when :hover is applied to an ancestor.)
Now, when recomputing an element's style, we also return a full
invalidation if one or more pseudo-elements would exist either before or
after style recomputation.
This heuristic produces some false positives, but no false negatives.
Because pseudo-elements' style is computed during layout building, any
computation done here is then thrown away. So this approach minimises
the amount of wasted style computation. Plus it's simple, until we have
data on what approach would be faster.
This fixes the Acid2 nose becoming blue when the .nose div is hovered.
These have a few rules that we didn't follow in most cases:
- CSS-wide keywords are not allowed. (inherit, initial, etc)
- `default` is not allowed.
- The above and any other disallowed identifiers must be tested
case-insensitively.
This introduces a `parse_custom_ident_value()` method, which takes a
list of disallowed identifier names, and handles the above rules.
This removes some ambiguity about what the return value should be if
the index is out of range.
Previously, we would sometimes return a JS null, and other times a JS
undefined.
It will also let us fold together the checks for whether an index is a
supported property index, followed by getting the value just afterwards.
This is `counter(name, style?)` or `counters(name, link, style?)`. The
difference being, `counter()` matches only the nearest level (eg, "1"),
and `counters()` combines all the levels in the tree (eg, "3.4.1").
These control the state of CSS counters.
Parsing code for `reversed(counter-name)` is implemented, but disabled
for now until we are able to resolve values for those.
The new method is Parser::parse_all_as_single_none_value(), which has a
few advantages:
1. There's no need for user code to manually create a StyleValue.
2. It consumes tokens so that doesn't have to be done manually.
3. Whitespace before or after the `none` is consumed correctly.
It does mean we create and then discard a `none` StyleValue in a couple
of places, namely parsing for `grid-*` properties. We may or may not
want to migrate those to returning the IdentifierStyleValue instead.
This represents each element's set of CSS counters.
https://drafts.csswg.org/css-lists-3/#css-counters-set
Counters are resolved while building the tree. Most elements will not
have any counters to keep track of, so as an optimization, we don't
create a CountersSet object until the element actually needs one.
In order to properly support counters on pseudo-elements, the
CountersSet needs to go somewhere else. However, my experiments with
placing it on the Layout::Node kept hitting a wall. For now, this is
fairly simple at least.