Previously, attempting to get the computed value for a
grid-template-rows or grid-template-columns property would cause a crash
if the element had no associated paintable.
Function is defined as `round(<rounding-strategy>?, A, B?)`
With this change resolved type is `typeof(resolve(A))`, instead of
`typeof(A)`.
For example `round(up, 20%, 1px)` with 200px percentage basis is now
correctly resolved in 40px instead of 40%.
Progress on https://www.notion.so/ landing page.
Logging a parse error when the attribute is not present, is not useful,
but does fill the debug log with errors that hide any real parsing
errors. This patch introduces an early-out in this situation to prevent
this spam.
The following spec algorithms had changed since we implemented them:
- "parse a sizes attribute"
- "update the source set"
- "create a source set"
This commit brings them up to date, as well as adding some additional
logging when parsing the sizes attribute fails in some way.
This change takes all existing WebIDL files in the repo that had
definition lines without four leading spaces, and fixes them so they
have four leading spaces.
Instead of throwing all pseudo-element rules in one bucket, let's have
one bucket per pseudo-element.
This means we only run ::before rules for ::before pseudo-elements,
only ::after rules for ::after, etc.
Average style update time on https://tailwindcss.com/ 250ms -> 215ms.
Once we know the final value of the `content` property for a
pseudo-element, we can bail early if the value is `none` or `normal`
(note that `normal` only applies to ::before and ::after).
In those cases, no pseudo-element will be generated, so everything
that follows in StyleComputer would be wasted work.
This noticeably improves performance on many pages, such as
https://tailwindcss.com/ where style updates go from 360ms -> 250ms.
This makes the way we've implemented the CSS `revert` keyword a lot less
expensive.
Until now, we were making a deep copy of all property values at the
start of each cascade origin. (Those are the values that `revert` would
bring us back to if encountered.)
With this patch, the revert property set becomes a shallow copy, and we
only clone the property set if the cascade ends up writing something.
This knocks a 5% profile item down to 1.3% on https://tailwindcss.com
Skia is more permissive when it comes to font loading, compared to our
own OpenType implementation, which it has superseded, parsing an invalid
TTF does not result in an error but rather produces a font that is
incorrectly displayed. This change updates the FontLoader to address
this behavior and to stop attempting to parse a font as a last resort
when format detection has failed.
Fixes regression on x.com when text is not displayed introduced in
a9d5a99568
If grid-template-rows or grid-template-columns queried for a box that is
not a grid container, the result should be computed value instead of
null.
Fixes crashing in inspector.
Instead of only bucketing these by class name, let's also bucket by
tag name and ID.
Reduces the number of selectors evaluated on https://tailwindcss.com/
from 2.9% to 1.9%.
By filtering first, we end up allocating much less vector space
most of the time.
This is mostly helpful in pathological cases where there's a huge number
of rules present, but most of them get rejected early.
That's awkward, but getComputedStyle needs to return used track values
for gridTemplateColumns and gridTemplateRows properties. This change
implements it by saving style values with used values into layout state,
so it could be assigned to paintables during LayoutState::commit() and
later accessed by style_value_for_property().
I haven't seen it used in the wild, but WPT grid tests extensively use
it. For example this change helps to go from 0/10 to 8/10 on this test:
https://wpt.live/css/css-grid/layout-algorithm/grid-fit-content-percentage.html
Before this change, the ancestor filter would only reject rules that
required a certain set of descendant strings (class, ID or tag name)
to be present in the current element's ancestor chain.
An immediate child is also a descendant, so we can include this
relationship in the ancestor filter as well.
This substantially improves the efficiency of the ancestor filter on
websites using Tailwind CSS.
For example, https://tailwindcss.com/ itself goes from full style
updates taking ~1400ms to ~350ms. Still *way* too long, but a huge
improvement nonetheless.
By bucketing these seletors by class or ID, we can avoid running them
in more cases.
Before, we were only avoiding them if the context element wasn't a div.
Now we avoid them for any element that doesn't have that specific class
or ID.
This reduces the number of selectors ran on https://vercel.com by a bit
more, from 1.90% to 1.65%.
These are just roundabout ways of writing .foo, so we can still put them
in the rules-by-class bucket and skip running them when the element
doesn't have that class.
Note that :is(.foo .bar) is also bucketed as a class rule, since the
context element must have the `bar` class for the selector to match.
This is a massive speedup on https://vercel.com/ as it cuts the number
of selectors we actually evaluate from 7.0% to 1.9%.
You can now build with STYLE_INVALIDATION_DEBUG and get a debug stream
of reasons why style invalidations are happening and where.
I've rewritten this code many times, so instead of throwing it away once
again, I figured we should at least have it behind a flag.
Before this change, we were cascading custom properties for each layer,
and then replacing any previously cascaded properties for the element
with only the set from this latest layer.
The patch fixes the issue by making each pass of the custom property
cascade add to the same set, and then finally assigning that set of
properties to the element.
This API is a relic from the time when it was important for objects to
have easy access to the Window, and to know it was the global object.
We now have more spec-related concepts like relevant_global_object and
current_global_object to pull the Window out of thin air.
Before this change, we were only checking for actual glyph containment
in a font if unicode ranges were specified. However that is not
sufficient for emoji support, where we want to continue searching for
a font until one containing emojis is found.
I didn't want to add another set of boilerplatey tree-walking methods,
so here's a general-purpose one. :^)
`for_each_effective_rule()` walks the tree of effective style rules, and
runs the callback on each one, in either pre- or postorder. The
previous `for_each_effective_style/keyframes_rule()` methods of
`CSSStyleSheet` are then reimplemented in terms of
`for_each_effective_rule()`, and we can get rid of their equivalents
elsewhere.
Depending on usage, `@layer` has two forms, with two different CSSOM
types. One simply lists layer names and the other defines a layer with
its contained rules.
This change should move us forward toward emoji support, as we are no
longer limited by our own OpenType implementation, which was failing
to parse the TrueType Collection format used to store emoji fonts
(at least on macOS).
Currently we rely on parser returning an error if encoded data cannot be
parsed into a valid WOFF or WOFF2 font, which is not going to be true
after switching to Skia that sometimes does not fail even if a data does
not represent a valid font.
This will be used by the inspector, for showing style sheet contents.
Identifying a specific style sheet is a bit tricky. Depending on where
it came from, a style sheet may have a URL, it might be associated with
a DOM element, both, or neither. This varied information is wrapped in
a new StyleSheetIdentifier struct.
This is to enable the inspector to show this source.
There's a fairly hefty FIXME here because duplicating the source text is
a significant waste of memory. But I don't want to get too sidetracked.
This is only used for CSS style sheets. One case wants it as a String,
and the others don't care, but will in future also want to have the
source as a String.
According to https://www.w3.org/TR/css-grid-2/#placement-shorthands
when setting the 'grid-row' and 'grid-column' shorthand property to a
single <custom-ident> value, both 'grid-row-start'/'grid-column-start'
and 'grid-row-end'/'grid-column-end' should be set to that
<custom_ident>.