Both Chromium and Gecko delay the document's load event for CSS image
resource requests (background-image, mask-image, etc). We now start
fetching CSS image resources as soon as their stylesheet is associated
with a document, rather than deferring until layout. This is done by
collecting ImageStyleValues during stylesheet parsing and initiating
their fetches when the stylesheet is added to the document.
Fixes#3448
Previously, `<link rel=stylesheet>` would delay the load event until its
style sheet loaded, but not care about its subresources. `<style>`
would not delay the load event at all. Instead, each `@import` would
delay the load event.
Now, both `<style>` and `<link>` delay the load event until their style
sheet and its critical subresources have loaded or failed. This means
that CSSImportRules no longer need to delay the load event themselves,
because they do so implicitly as a critical subresource of their parent
style sheet.
This doesn't directly affect behavior, but means that any other critical
style resources we add will automatically delay the load event.
One wrinkle here is that the spec for the `<link>` element requires that
we wait for the style sheet's critical subresources *before* we create
a CSSStyleSheet, which means we don't yet know what those are.
https://html.spec.whatwg.org/multipage/semantics.html#fetching-and-processing-a-resource-from-a-link-element:critical-subresources
For now we simply ignore this, as we did before. That means we continue
to not delay the `<link>`'s load event.
Previously, we fired the load event immediately, without waiting for
anything. This was good for not timing out, but bad for anything that
wanted to wait for the load to complete.
CSSStyleSheet now maintains a list of critical subresources, and waits
for all of them to complete before it then tells its owner that it is
ready. "Complete" here means the network request completed with or
without an error. This is done by having those subresources (just
`@import` for now) notify their style sheet when they complete. This
then propagates up as an `@import` tells its style sheet, which then
would tell its parent `@import` if it had one.
There are other subresources we should wait for (specifically fonts and
background images) but this commit just adds `@import` as a first step.
Specifically, we create and assign a layer if its import conditions
currently apply.
With this change, every case in the `layer-import.html` test actually
functions correctly, apart from our lack of proper `load` event
support. (Tested by hacking in a 100ms wait after the `await Promise()`
statement.)
...instead of returning the one from its associated style sheet.
This reverts 848a250b29 where I made
`CSSImportRule.media` nullable.
CSSImportRule may not have an associated style sheet, because of not
matching a supports condition, or just failing to load the URL.
Regardless of whether we do or not, the expected (non-spec) behaviour
is that we should return a MediaList always, which matches the media
queries specified on the `@import` rule.
Having the dumping code in a separate Dump.cpp meant that it was often
overlooked when the rules gained new features, and also limits dumping
to publicly-accessible information.
The recent commits 28ba610f32 and
70c4ed261f adjusted some include
directives to avoid excessive recompilation when changing some header
files. This has broken compilation with clang-cl on Windows without
getting noticed before the PRs were merged.
An upcoming commit will migrate the contents of Headers.h/cpp to LibHTTP
for use outside of LibWeb. These CORS and MIME helpers depend on other
LibWeb facilities, however, so they cannot be moved.
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/
Previously these were only stored on the root style sheet and were
accessed by imported stylesheets via their owner rule.
Propagating these to imported style sheets allows us to more easily know
when they change for said imported style sheets.
Before this change, we were going through the chain of base classes for
each IDL interface object and having them set the prototype to their
prototype.
Instead of doing that, reorder things so that we set the right prototype
immediately in Foo::initialize(), and then don't bother in all the base
class overrides.
This knocks off a ~1% profile item on Speedometer 3.
See the spec issue in the comments for details. There are situations
where we will need to call this but don't have a CSSStyleSheet to pass
in, but we always have a Document, so use that where possible.
These actually always return a value, despite the `CSSStyleSheet*`
return type. So, make that clearer by returning `GC::Ref<CSSStyleSheet>`
instead. This also means we can remove some ad-hoc error-checking code.
The regression in the "conditional-CSSGroupingRule" test is we now fail
the "inserting an `@import`" subtests differently and the subtests
aren't independent. Specifically, we don't yet implement the checks in
`CSSRuleList::insert_a_css_rule()` that reject certain rules from being
inserted. Previously we didn't insert the `@import` rule because we
failed to parse its relative URL. Now we parse it correctly, we end up
inserting it.
When `CSSRuleList::remove_a_css_rule()` is called, the removed rule has
its parent style sheet set to null. We shouldn't try to fetch an import
in this case.
It's possible to parse an `@import` rule that isn't attached to a
document. We only actually need it to have one when fetching the linked
style sheet, and that should only happen when the CSSImportRule is
attached to a document. So, we can just accept a null pointer when
constructing it.
We relied on that Document to get the Realm, so pass that in as a
separate parameter.
To prepare for introducing a CSS::URL type, we need to qualify any use
of LibURL as `::URL::foo` instead of `URL::foo` so the compiler doesn't
get confused.
Many of these uses will be replaced, but I don't want to mix this in
with what will likely already be a large change.
This is not really a context, but more of a set of parameters for
creating a Parser. So, treat it as such: Rename it to ParsingParams,
and store its values and methods directly in the Parser instead of
keeping the ParsingContext around.
This has a nice side-effect of not including DOM/Document.h everywhere
that needs a Parser.
Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:
* JS::NonnullGCPtr -> GC::Ref
* JS::GCPtr -> GC::Ptr
* JS::HeapFunction -> GC::Function
* JS::CellImpl -> GC::Cell
* JS::Handle -> GC::Root
The main motivation behind this is to remove JS specifics of the Realm
from the implementation of the Heap.
As a side effect of this change, this is a bit nicer to read than the
previous approach, and in my opinion, also makes it a little more clear
that this method is specific to a JavaScript Realm.