LibWeb: Support loading alternative style sheets

Alternative style sheets are now fetched and are applied to the
document if they are explicitly enabled by removing the disabled
attribute.
This commit is contained in:
Tim Ledbetter 2024-04-16 21:02:50 +01:00 committed by Andreas Kling
parent 25f8c26624
commit 4a3497e9cd
7 changed files with 52 additions and 8 deletions

View file

@ -0,0 +1,6 @@
<!DOCTYPE html>
<link rel="match" href="reference/alternative-style-sheets-ref.html" />
<link title="preferred" rel="stylesheet" href="data:text/css,html { background: green }">
<!-- These alternative style sheets shouldn't be applied -->
<link title="alternative" rel="alternate stylesheet" href="data:text/css,html { background: red !important }">
<link id="no-title" rel="alternate stylesheet" href="data:text/css,html { background: blue !important }">

View file

@ -0,0 +1,6 @@
<!DOCTYPE html>
<style>
html {
background-color: green;
}
</style>

View file

@ -0,0 +1,3 @@
background color initial value: rgba(0, 0, 0, 0)
background color after preferred style sheet enabled: rgb(255, 0, 0)
background color after alternate style sheet enabled: rgb(0, 128, 0)

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<script src="include.js"></script>
<link title="preferred" disabled rel="stylesheet" href="data:text/css,html { background: rgb(255, 0, 0) }">
<link title="alternative" disabled rel="alternate stylesheet" href="data:text/css,html { background: rgb(0, 128, 0) !important }">
<script>
asyncTest(done => {
const documentStyle = getComputedStyle(document.documentElement);
println(`background color initial value: ${documentStyle.backgroundColor}`);
const primaryLink = document.querySelector("link[title=preferred]");
const alternativeLink = document.querySelector("link[title=alternative]");
primaryLink.onload = () => {
println(`background color after preferred style sheet enabled: ${documentStyle.backgroundColor}`);
alternativeLink.disabled = false;
};
alternativeLink.onload = () => {
println(`background color after alternate style sheet enabled: ${documentStyle.backgroundColor}`);
done();
};
primaryLink.disabled = false;
});
</script>

View file

@ -4806,12 +4806,15 @@ WebIDL::ExceptionOr<void> Document::set_adopted_style_sheets(JS::Value new_value
void Document::for_each_css_style_sheet(Function<void(CSS::CSSStyleSheet&)>&& callback) const
{
for (auto& style_sheet : m_style_sheets->sheets())
callback(*style_sheet);
for (auto& style_sheet : m_style_sheets->sheets()) {
if (!(style_sheet->is_alternate() && style_sheet->disabled()))
callback(*style_sheet);
}
if (m_adopted_style_sheets) {
m_adopted_style_sheets->for_each<CSS::CSSStyleSheet>([&](auto& style_sheet) {
callback(style_sheet);
if (!(style_sheet.is_alternate() && style_sheet.disabled()))
callback(style_sheet);
});
}
}

View file

@ -50,8 +50,7 @@ void HTMLLinkElement::inserted()
{
HTMLElement::inserted();
// FIXME: Handle alternate stylesheets properly
if (m_relationship & Relationship::Stylesheet && !(m_relationship & Relationship::Alternate)) {
if (m_relationship & Relationship::Stylesheet) {
// https://html.spec.whatwg.org/multipage/links.html#link-type-stylesheet:fetch-and-process-the-linked-resource
// The appropriate times to fetch and process this type of link are:
// - When the external resource link is created on a link element that is already browsing-context connected.
@ -110,8 +109,12 @@ void HTMLLinkElement::attribute_changed(FlyString const& name, Optional<String>
}
}
// FIXME: Handle alternate stylesheets properly
if (m_relationship & Relationship::Stylesheet && !(m_relationship & Relationship::Alternate)) {
// https://html.spec.whatwg.org/multipage/semantics.html#the-link-element:explicitly-enabled
// Whenever the disabled attribute is removed, set the link element's explicitly enabled attribute to true.
if (!value.has_value() && name == HTML::AttributeNames::disabled)
m_explicitly_enabled = true;
if (m_relationship & Relationship::Stylesheet) {
if (name == HTML::AttributeNames::disabled && m_loaded_style_sheet)
document_or_shadow_root_style_sheets().remove_a_css_style_sheet(*m_loaded_style_sheet);
@ -374,7 +377,7 @@ void HTMLLinkElement::process_stylesheet_resource(bool success, Fetch::Infrastru
this,
attribute(HTML::AttributeNames::media).value_or({}),
in_a_document_tree() ? attribute(HTML::AttributeNames::title).value_or({}) : String {},
false,
m_relationship & Relationship::Alternate && !m_explicitly_enabled,
true,
{},
nullptr,

View file

@ -133,6 +133,8 @@ private:
Optional<DOM::DocumentLoadEventDelayer> m_document_load_event_delayer;
unsigned m_relationship { 0 };
// https://html.spec.whatwg.org/multipage/semantics.html#explicitly-enabled
bool m_explicitly_enabled { false };
};
}