In level 2 of the web animations spec, times are no longer always
measures in milliseconds, they can also be percents when dealing with
progress-based (i.e. scroll-based) timelines.
We don't actually support percent times yet but this change will make it
easier to implement when we do.
Web Animations Level 2 disallows setting some `AnimationEffect` timing
values (start delay, end delay, iteration duration) directly and instead
allows authors to set the specified values which are then normalized
into the actual used values taking into account the type of the
associated timeline (i.e. progress- vs time-based)
This method did two things:
1) on the base class (`AnimationTimeline`) it was a setter for
`m_current_time` and;
2) on the child classes (e.g. `DocumentTimeline`) it updated the
timeline's current time given a document timestamp
It makes more sense for theses to be distinct methods
Font computation and loading is distinct enough from style computation
that it makes more sense to have this in it's own class.
This will be useful later when we move the font loading process to
`ComputedProperties` in order to respect animated values.
From the spec:
> The owning element of a transition refers to the element or
pseudo-element to which the transition-property property was applied
that generated the animation.
https://drafts.csswg.org/css-transitions-2/#owning-element
Previously we only stored the element.
This works by generating random values using XorShift128PlusRNG at
compute time and then caching them on the document using the relevant
random-caching-key
There are a couple of remaining RFC 9111 methods in LibWeb's Fetch, but
these are currently directly tied to the way we store GC-allocated HTTP
response objects. So de-coupling that is left as a future exercise.
The spec declares these as a byte sequence, which we then implemented as
a ByteBuffer. This has become pretty awkward to deal with, as evidenced
by the plethora of `MUST(ByteBuffer::copy(...))` and `.bytes()` calls
everywhere inside Fetch. We would then treat the bytes as a string
anyways by wrapping them in StringView everywhere.
We now store these as a ByteString. This is more comfortable to deal
with, and we no longer need to continually copy underlying storage (as
ByteString is ref-counted).
This work is largely preparatory for an upcoming HTTP header refactor.
This flag defaults to false for new Documents, such as the one created
here for use by template elements' contents. Without setting it to
true, nothing inside a template can have a declarative shadow dom.
As noted, this appears to be a spec issue. I am not convinced that this
is the correct fix, but it is simple and does solve the issue without
any apparent regressions.
The implementation here is a ad-hoc, but there's no clear spec for
exactly how to handle "critical subresources" blocking rendering.
For now, this is overly conservative but fixes ugly FOUC on some
websites like https://hey.com/
Before this change, we've been maintaining various StyleComputer caches
at the document level.
This made sense for old-school documents without shadow trees, since
all the style information was document-wide anyway. However, documents
with many shadow trees ended up suffering since any time you mutated
a style sheet inside a shadow tree, *all* style caches for the entire
document would get invalidated.
This was particularly expensive on Reddit, which has tons of shadow
trees with their own style elements. Every time we'd create one of their
custom elements, we'd invalidate the document-level "rule cache" and
have to rebuild it, taking about ~60ms each time (ouch).
This commit introduces a new object called StyleScope.
Every Document and ShadowRoot has its own StyleScope. Rule caches etc
are moved from StyleComputer to StyleScope.
Rule cache invalidation now happens at StyleScope level. As an example,
rule cache rebuilds now take ~1ms on Reddit instead of ~60ms.
This is largely a mechanical change, moving things around, but there's
one key detail to be aware of: due to the :host selector, which works
across the shadow DOM boundary and reaches from inside a shadow tree out
into the light tree, there are various places where we have to check
both the shadow tree's StyleScope *and* the document-level StyleScope
in order to get all rules that may apply.
Prevents observably calling Trusted Types, which can run arbitrary JS,
cause crashes due to use of MUST and allow arbitrary JS to modify
internal elements.
We were doing this manually within `Document::update_layout()` and
`CSSStyleProperties::get_direct_property()` but we should do it for all
callers of `Document::update_style()`
Otherwise the layout tree will still contain the top layer element(s).
Fixes Steam Events & Announcements `<dialog>` modal visually not fully
disappearing upon removal.
Adds pinch event handling that adjusts the VisualViewport scale and
offset. VisualViewport's (offset, scale) is then used to construct a
transformation matrix which is applied before display list execution.
Previously we would always use the window's viewport which was incorrect
if we were within an iframe.
This is likely applicable to all uses of
`Length::ResolutionContext::for_window`.
The overlay shown for the node hovered in the inspector is painted as
part of the normal tree traversal of all paintables. This works well in
most cases, but falls short in specific scenarios:
* If the hovered node or one of its ancestors establishes a stacking
context and there is another element that establishes a stacking
context close by or overlapping it, the overlay and especially the
tooltip can become partially hidden behind the second element. Ditto
for elements that act as if they established a stacking context.
* If the hovered node or one of its ancestors involves clipping, the
clip is applied to the overlay and espicially the tooltip. This can
cause them to be partially invisible.
* Similarly, if the hovered node or one of its ancestors has a defined
mask, the mask is applied to the overlay, often making it mostly
invisible.
* No overlays are shown for SVG nodes because they are painted
differently from HTML documents.
Some of these problems may be fixable with the current system. But some
seem like they fundamentally cannot work fully when the overlays are
painted as part of the regular tree traversal.
Instead we pull out painting the overlay as a separate pass executed
after the tree traversal. This way we ensure that the overlays are
always painted last and therefore on top of everything else. This also
makes sure that the overlays are unaffected by clips and masks. And
since overlay painting is independent from painting the actual elements,
it just works as well.
However we need to be careful, because we still need to apply some of
the steps of the tree traversal to get the correct result. Namely we
need to apply scroll offsets and transforms. To do so, we collect all
ancestors of the hovered node and apply those as if we were in the
normal tree traversal.