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.
Remove 11 heavy includes from Document.h that were only needed for
pointer/reference types (already forward-declared in Forward.h), and
extract the nested ViewportClient interface to a standalone header.
This reduces Document.h's recompilation cascade from ~1228 files to
~717 files (42% reduction). Headers like BrowsingContext.h that were
previously transitively included see even larger improvements (from
~1228 down to ~73 dependents).
This code that used `charset` created a second `environment_encoding`
variable which shadowed the outer one, making it a no-op. Now we
actually use its value.
Do not load fallback favicons from /favicon.ico for auxiliary browsing
contexts (popup windows). This matches the behavior observed in Chrome
and Firefox, and avoids unnecessary network requests that can interfere
with Content Security Policy violation reporting.
This fixes the javascript-url-navigation-evaluated-to-string-inherits-
csp.html Web Platform Test, which was failing because favicon CSP
violations were being reported before the actual test violation.
The report_timing lambda was capturing `this` and reading
m_fetch_controller when invoked. This is fragile because
m_fetch_controller could be overwritten by a subsequent preload
before the first preload's callbacks run.
Use a FetchControllerHolder to bind the controller to each specific
fetch. The holder is captured by the lambda and populated after
fetch() returns, ensuring callbacks always use the correct controller.
Previously, the `preload`, `preconnect` and `dns-prefetch` keywords
took precedence over the others. When these keywords were present
the default fetch processing steps would not occur even when a relevant
keyword such as `stylesheet` or `icon` was present.
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.
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.
HTMLLinkElement is the final user of Resource/ResourceClient (used for
preloads and icons). This ports these link types to use fetch according
to the spec.
Preloads were particularly goofy because they would be stored in the
ResourceLoader's ad-hoc cache. But this cache was never consulted for
organic loads, thus were never used. There is more work to be done to
use these preloads within fetch, but for now they at least are stored
in fetch's HTTP cache for re-use.
We don't typically put spec links for methods in both the .h and .cpp
(we just put them in the .cpp).
Let's also generally organize the methods in spec-order, which for
HTMLLinkElement generally goes: init fetch -> fetch -> process data.
Makes it a bit easier to scroll through the spec and the code at the
same time.
Commit 77f6edaf71 tried to map the promise
returned from the ImageCodecPlugin to the same promise type used for SVG
decoding. However, `map` drops the existing resolution callbacks on the
floor.
Instead, let's keep the ImageCodecPlugin promise alone, and resolve the
returned promise explicitly.
Some websites do not specify the MIME type of style sheets, instead
using as= or just leaving it empty.
Both Chromium and Firefox do load them regardless, so let's do it too.
Fixes external CSS being blocked on https://beatsaver.com/, where they
have a `style-src` directive set to `'self' 'nonce-[value]'`
Relates to #5643, but does not make the website load.
Instead, porting over all users to use the newly created
Origin::create_opaque factory function. This also requires porting
over some users of Origin to avoid default construction.
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.
The basic idea is that style sheets can block script execution under
some circumstances. With this commit, we now handle the simplest cases
where a parser-inserted link element gets to download its style sheet
before script execution continues.
This improves performance on Speedometer 3 where JavaScript APIs that
depend on layout results (like Element.scrollIntoView()) would get
called too early (before the relevant CSS was downloaded), and so we'd
perform premature layout work. This work then had to be redone after
downloading the CSS anyway, wasting time.
Note that our Text/input/link-re-enable-crash.html test had to be
tweaked after these changes, since it relied on the old, incorrect,
behavior where scripts would run before downloading CSS.
The spec is unclear about when exactly we should parse the style sheet.
Previously we'd do so before calling this algorithm, which was
error-prone, as seen by the bug fixed by the previous commit. The spec
for step 1 of "create a CSS style sheet" says:
1. Create a new CSS style sheet object and set its properties as
specified.
The definitions linked are UA-defined enough that it seems reasonable to
put the parsing here. That simplifies the user code a little and makes
it harder to mess up. It does raise the question of what to do if
parsing fails. I've matched our previous behaviour by just logging and
returning in that case.
While I'm modifying this method, I've also converted the bool params to
enums so they're a little clearer to read.
Before this change, we assigned the style sheet's location *after* its
content rules were parsed and added to it. This meant any `@import`s
would try to fetch their style sheet before they knew the URL they
should fetch it relative to.
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.
We were handling removing the style sheet from the shadow root, but not
appending to it. Fixing this also revealed a bug that a removed link
element would always try to remove from the document's list, as the
root is no longer the shadow root it's in. The fix is to use the passed
in old root to remove the style sheet from.
Fixes the cookie banner on https://nos.nl/
Note that "becomes browsing-context connected" is defined as:
> When the insertion steps are invoked with it as the argument and it is
> now browsing-context connected.
This fixes an issue where WPT editing tests would clone the entire DOM
thousands of times and re-fetch all the linked CSS files once per clone.
This commit implements the main "render blocking" behavior for link
elements, drastically reducing the amount of FOUC (flash of unstyled
content) we subject our users to.
The document will now block rendering until linked style sheets
referenced by parser-created link elements have loaded (or failed).
Note that we don't yet extend the blocking period until "critical
subresources" such as imported style sheets have been downloaded
as well.
This is required to store Content Security Policies, as their
Directives are implemented as subclasses with overridden virtual
functions. Thus, they cannot be stored as generic Directive classes, as
it'll lose the ability to call overridden functions when they are
copied.
We only need a Page for file:// urls. At some point we probably
needed it for other kinds of requests, but the current functionality
doesn't need to store the Page pointer on the ResourceLoader.
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.
There are essentially 3 URL parsing AOs defined by the spec:
1. Parse a URL
2. Encoding parse a URL
3. Encoding parse a URL and serialize the result
Further, these are replicated between the Document and the ESO.
This patch defines these methods in accordance with the spec and updates
existing users to invoke the correct method. In places where the correct
method is ambiguous, we use the encoding parser to preserve existing ad-
hoc behavior.