MediaQueryList will now remember if a state change occurred when
evaluating its match state. This memory can then be used by the document
later on when it's updating all queries, to ensure that we don't forget
to fire at least one change event.
This also required plumbing the system visibility state to initial
about:blank documents, since otherwise they would be stuck in "hidden"
state indefinitely and never evaluate their media queries.
Instead of checking all elements in a document for containment in
`:has()` invalidation set, we could narrow this down to ancestors and
ancestor siblings, like we already do for subject `:has()` invalidation.
This change brings great improvement on GitHub that has selectors with
non-subject `:has()` and sibling combinators (e.g., `.a:has(.b) ~ .c`)
which prior to this change meant style invalidation for whole document.
The spec wants these keywords to appear in a particular order when
serialized, so let's just put them in that order during parsing.
This also fixes a bug where we didn't reject `font-variant-east-asian`
that contains `normal` alongside another value.
Also, rather than always parsing them as a StyleValueList, parse single
values on their own, and then support that in the to_font_variant_foo()
methods.
Without this, we'd happily parse `font-variant-caps: small-caps potato`
as just `small-caps` and ignore the fact that unused tokens were left
over.
This fix gets us some WPT subtest passes, and removes the need for a
bespoke parsing function for font-variant-caps.
Without this, getting a property's value from `element.style.foo` would
fail if `foo` is a shorthand property which has a longhand that is also
a shorthand. For example, `border` expands to `border-width` which
expands to `border-top-width`.
This is because we used `property()` to get a longhand's value, but this
returns nothing if the property is a shorthand.
This commit solves that by moving most of get_property_value() into a
separate method that returns a StyleProperty instead of a String, and
which calls itself recursively for shorthands. Also move the manual
shorthand construction out of ResolvedCSSStyleDeclaration so that all
CSSStyleDeclarations can use it.
This is a weird behaviour specific to `font` - it can reset some
properties that it never actually sets. As such, it didn't seem worth
adding this concept to the code generator, but just manually stuffing
the ShorthandStyleValue with them during parsing.
This allows us to inspect its properties. To avoid wasted work, we only
compute and cache the properties if the originating element was, or is,
displaying as a list item.
This commit changes the strategy for updating inherited styles. Instead
of marking all potentially affected nodes during style invalidation, the
decision is now made on-the-fly during style recalculation. Child nodes
will only have their inherited styles recalculated if their parent's
properties have changed.
On Discord this allows to 1000x reduce number of nodes with recalculated
inherited style.
This was an old hack intended to make percentage sizes on flex items
before we had implemented the appropriate special behavior of definite
sizes in flex layout.
Removing it makes flex layout less magical and should not change
behavior in any observable way.
The spec tells us to treat `auto` as `fit-content` when determining
flex item cross sizes, so let's just do *that* instead of awkwardly
doing an uncacheable nested layout of the item.
This was the only instance of `LayoutState` nesting outside of intrinsic
sizing, so removing it is an important step towards simplifying layout.
Turns out it was a lot easier than expected.
We've long claimed to support this, but then silently ignored string
values, until 4cb2063577 which would
not-so-silently crash instead. (Oops)
So, actually pass the string value along and use it in the list marker.
As part of this, rename our `list-style-type` enum to
`counter-style-name-keyword`. This is an awkward name, attempting to be
spec-based. (The spec says `<counter-style>`, which is either a
`<counter-style-name>` or a function, and the `<counter-style-name>` is
a `<custom-ident>` that also has a few predefined values. So this is the
best I could come up with.)
Unfortunately only one WPT test for this passes - the others fail
because we produce a different layout when text is in `::before` than
when it's in `::marker`, and similar issues.
`invalidate_style()` already tries to avoid scheduling invalidation for
`:has()` by checking result of `may_have_has_selectors()`, but it might
still result in unnecessary work because `may_have_has_selectors()`
does not force building of rules cache. This change adds
`have_has_selectors()` that forces building of rules cache and is
invoked in `update_style()` to double-check whether we actually need to
process scheduled `:has()` invalidations.
This allows to skip ~100000 ancestor traversals on this WPT test:
https://wpt.live/html/select/options-length-too-large.html
We were previously assuming that dictionary members were always
required when being returned.
This is a bit of a weird case, because unlike _input_ dictionaries
which the spec marks as required, 'result' dictionaries do not seem to
be marked in spec IDL as required. This is still fine from the POV that
the spec is written as it states that we should only be putting the
values into the dictionary if the value exists.
We could do this through some metaprogramming constexpr type checks.
For example, if the type in our C++ representation was not an
Optional, we can skip the has_value check.
Instead of doing that, change the IDL of the result dictionaries to
annotate these members so that the IDL generator knows this
information up front. While all current cases have every single
member returned or not returned, it is conceivable that the spec
could have a situation that one member is always returned (and
should get marked as required), while the others are optionally
returned. Therefore, this new GenerateAsRequired attribute is
applied for each individual member.
We don't yet support a proxy configuration, but we can still validate
the capability received from the WebDriver client. We should also fail
to create a WebDriver session if a proxy configuration is present.
We currently define our custom WebDriver capabilities with a dictionary
of the form:
"serenity:ladybird": {
"headless": true
}
This patch flattens the configuration, such that each Ladybird option
will be its own capability. This matches how Firefox configures their
own options with geckodriver. So we now have:
"ladybird:headless": true
Moves pseudo class matching helpers into Element methods, so they don't
have to be duplicated between SelectorEngine and function that checks if
element is included in invalidation set.