Move PropertyNameAndID, custom property data, registered custom
properties, and Typed OM associated property names to Utf16FlyString.
This removes the FlyString storage boundary from CSS property-name
handling and lets CSSStyleProperties keep the name it receives from
CSSOM instead of converting it back to UTF-8.
Add a parser entry point that preserves authored CSS declarations for
DevTools. The Rules panel needs the original property names, shorthand
values, invalid declarations, custom properties, and !important flags
rather than only the expanded computed representation.
Parse arbitrary substitution function arguments as spans into the
existing component value list. This avoids copying each argument into a
new vector for var(), attr(), env(), if(), and inherit() parsing.
Expose a span-returning declaration-value parser that shares the same
walker as the existing vector-returning API, so the argument parser does
not duplicate declaration-value grammar logic. Substitution output still
uses owned vectors, and the unresolved Typed OM reifier now consumes
spans too.
Parse subgrid track listings for grid-template rows and columns,
including fixed and auto-fill name-repeat line-name lists. Preserve
the subgrid keyword through computed values and shorthand serialization,
and make interpolation discrete instead of routing subgrid lists through
the explicit track interpolation path.
Import WPT coverage for subgrid grid-template parsing and computed
values, and add text coverage for discrete subgrid track-list animation.
safe and unsafe are <overflow-position> modifiers per css-align-3
and must accompany an alignment value. Reject them as standalone
keywords for align-items, align-self, justify-items and
justify-self.
The check only applies when these properties are parsed as
longhands; their use inside the place-items and place-self
shorthands goes through a separate code path and is unaffected.
`@scope (a) to (b) {}` applies its contained style rules to elements
that have `a` as a parent, and do not have `a b` as a parent. Both the
`a` and `b` selector lists are optional.
Because it's situational whether a `@scope` will apply to a given
element, we store the ancestor scope on the `MatchingRule`, similar to
`@container`, and then determine during matching whether all the parent
`@scope`s match or not.
The rules for how selectors inside `@scope` are adjusted and interpreted
are a bit confusing. Unlike for other at-rules, nested style rules
inside `@scope` do not get a leading `&` added during parsing. To
support this, `adapt_nested_relative_selector_list()` now takes a flag
for whether its parent is a `@scope` or not.
`@scope` can also contain nested declarations without itself being
nested inside a style rule.
When determining their selectors, nested declarations rules adopt the
`@scope`'s scoping root if it has one, or otherwise fall back to the
parent element of the `<style>` element (not implemented here,) or the
`:root`. These are required to have zero specificity, so we wrap the
selector in `:where()`.
e.g., `@container (width >= 300px) {}` and similar.
During style computation, flag any elements whose style depends on a
size container. Then re-evaluate their style after the initial layout
has been computed and size containers have a size. This may take
multiple passes, as these may have further descendants that depend on
their size, etc. We limit this to 8 passes currently.
SizeFeature itself is very similar to MediaFeature, but queries the
container element instead. There are only 6 size features specified, so
they're hard-coded instead of generated from JSON.
Also add a counter test for the narrower restyle path.
`<media-feature>` and the upcoming `<size-feature>` from `@container`,
share the same syntax and almost all of their behaviour. To avoid a lot
of duplication, pull as much as possible into a FeatureQuery template
class that they will both inherit from.
MediaFeatureValue is renamed FeatureValue as it's also shared by both.
No behaviour change.
Keep consumed response body bytes in Core::ImmutableBytes instead of
requiring a ByteBuffer. This lets responses that already arrived as
file-backed immutable data keep that representation through body
consumption, while streamed responses can still adopt their
accumulated ByteBuffer without another copy.
Update the body consumers that only inspect bytes to read from
immutable byte views. Font loading still copies at its existing
ownership boundary, where the off-thread preparation path takes a
ByteBuffer.
This changes the shape of the parsed value when we don't have a fallback
color for a `<url>` value from having no second value in the
`StyleValueList` to having an `EmptyOptionalStyleValue`.
In the future we should switch to using a better file format for this,
i.e. one that supports directly pasting CSS grammar production blocks
(https://drafts.csswg.org/css-values-4/#css-grammar-production-block)
and has support for inline comments, but we use JSON for now for
simplicity's sake.
Add an abstract image style value for image-set() and parse both the
standard and -webkit-prefixed spellings through the existing <image>
value path. The parser accepts URL and string image candidates,
optional resolution descriptors, and type() filters.
Track attr-taint through substituted component values so image-set()
candidates using attr()-derived URL-producing tokens are rejected when
resolved for URL-using properties.
Update the relevant WPT baselines now that image-set() parsing is
supported in additional value contexts.
Previously we would generate the calculation context based on the
current value parsing context. The main problem with this was that
contexts were defined per property by default and had to be overriden
per component value using "special" contexts, which was easy to forget.
We now generate the calculation context per component value in the
relevant `parse_foo_value` methods.
The new failures in `typed_arithmetic.html` are because we no longer
treat percentages as resolving to their property-level type when
computing what the resolved type of a calculation is i.e. when we are
parsing the `<number>` portion of `line-height` we treat percentages as
raw percentages, not lengths. This brings us in line with WebKit but no
longer with Chrome and WPT, I am not sure what the correct behavior is.
This brings a couple of advantages:
- Previously we relied on the caller validating the parsed value was in
bounds after the fact - this was usually fine but there are a couple
of places that it was forgotten (see the tests added in this commit),
requiring the bounds to be passed as arguments makes us consider the
desired range more explicitly.
- In a future commit we will use the passed bounds as the clamping
bounds for computed values, removing the need for the existing
`ValueParsingContext` based method we have at the moment.
- Generating code is easier with this approach
This allows us to avoid the ugly hack in
`property_accepted_type_ranges()`.
This also updates the `ValueType` to be `opacity-value` rather than
`opacity` to match the spec.
These are only used at used value time (since we store as `StyleValue`s
before) by which time we resolve all percentages except for layout
relative length percentages.
Apart from making the code a bit easier to follow, we'll need to
distinguish between the two in order to insert a pseudo-element
combinator in front of pseudo-elements (including the single-colon
legacy ones).
next_is_pseudo_element() is its own function because it'll be needed in
a couple of other places, again to support pseudo-element combinators.
This simplifies handling (particularly around absolutization and
interpolation) and allows us to support calculated flex values (which
will come in a later commit).
This introduces two new top-level `ValueParsingContext`s,
`OnScreenCanvasContextFontValue` and `CanvasContextGenericValue`, while
these are handled the same for now, there is a distinction is whether or
not they allow tree counting functions (which will come in a later
commit)
The main limitation here are that none of the container-query features
are parsed in a meaningful way; they all become `<general-enclosed>`.
Parsing for them will be added as they are implemented.
When parsing declarations within a nested grouping rule, we don't store
these directly, but within a "nested declarations rule", in most cases
this is `CSSNestedDeclarations`, but this isn't always the case e.g.
`@function` rules and others (e.g. @media) within them should instead
use `CSSFunctionDeclarations`
Some at-rules (i.e. `@function`) require us to support custom
descriptors (e.g. `--foo`).
We do this by adding `DescriptorID::Custom` and using a new
`DescriptorNameAndID` class in a bunch of places where we previously
just used `DescriptorID`
We no longer try to resolve calculated values at parse time which means
we support relative lengths.
We now clamp negative values rather than rejecting them at parse time.
Parsing has been inlined into `parse_ratio_value` and `parse_ratio` has
been removed since `parse_ratio_value` was the only caller
See previous commit for details
We now support parsing of `display-p3-linear` (although it just falls
back to using Oklab since Skia doesn't support it)
Previously we had two implementations for parsing
`<color-interpolation-method>`, one for gradients and one for
`color-mix()` - this commit adds another which will unify the existing
ones in following commits.
This implementation has a couple of advantages over the existing ones:
- It is simpler in that it uses global CSS enums and their helper
functions
- It is spec compliant (unlike the `color-mix()` one which allows
arbitrary idents)
- It parses as a `StyleValue` which will be required once we support
`<custom-color-space>` since that can be an `ident()` which isn't
resolvable at parse time