LibWeb/CSS: Store CSSStyleSheet location as a URL

We already have a URL when we construct these, and we want a URL later,
so avoid serializing and re-parsing it.
This commit is contained in:
Sam Atkins 2025-04-08 13:18:56 +01:00 committed by Tim Ledbetter
commit da1ff1ba40
Notes: github-actions[bot] 2025-04-09 17:48:14 +00:00
7 changed files with 20 additions and 12 deletions

View file

@ -37,13 +37,13 @@ WebIDL::ExceptionOr<GC::Ref<CSSStyleSheet>> CSSStyleSheet::construct_impl(JS::Re
// 2. Set sheets location to the base URL of the associated Document for the current principal global object. // 2. Set sheets location to the base URL of the associated Document for the current principal global object.
auto associated_document = as<HTML::Window>(HTML::current_principal_global_object()).document(); auto associated_document = as<HTML::Window>(HTML::current_principal_global_object()).document();
sheet->set_location(associated_document->base_url().to_string()); sheet->set_location(associated_document->base_url());
// 3. Set sheets stylesheet base URL to the baseURL attribute value from options. // 3. Set sheets stylesheet base URL to the baseURL attribute value from options.
if (options.has_value() && options->base_url.has_value()) { if (options.has_value() && options->base_url.has_value()) {
Optional<URL::URL> sheet_location_url; Optional<URL::URL> sheet_location_url;
if (sheet->location().has_value()) if (sheet->location().has_value())
sheet_location_url = URL::Parser::basic_parse(sheet->location().release_value()); sheet_location_url = sheet->location().release_value();
// AD-HOC: This isn't explicitly mentioned in the specification, but multiple modern browsers do this. // AD-HOC: This isn't explicitly mentioned in the specification, but multiple modern browsers do this.
Optional<URL::URL> url = sheet->location().has_value() ? sheet_location_url->complete_url(options->base_url.value()) : URL::Parser::basic_parse(options->base_url.value()); Optional<URL::URL> url = sheet->location().has_value() ? sheet_location_url->complete_url(options->base_url.value()) : URL::Parser::basic_parse(options->base_url.value());
@ -100,7 +100,7 @@ CSSStyleSheet::CSSStyleSheet(JS::Realm& realm, CSSRuleList& rules, MediaList& me
, m_rules(&rules) , m_rules(&rules)
{ {
if (location.has_value()) if (location.has_value())
set_location(location->to_string()); set_location(move(location));
for (auto& rule : *m_rules) for (auto& rule : *m_rules)
rule->set_parent_style_sheet(this); rule->set_parent_style_sheet(this);

View file

@ -27,6 +27,13 @@ void StyleSheet::visit_edges(Cell::Visitor& visitor)
visitor.visit(m_media); visitor.visit(m_media);
} }
Optional<String> StyleSheet::href() const
{
if (m_location.has_value())
return m_location->to_string();
return {};
}
void StyleSheet::set_owner_node(DOM::Element* element) void StyleSheet::set_owner_node(DOM::Element* element)
{ {
m_owner_node = element; m_owner_node = element;

View file

@ -13,6 +13,7 @@
namespace Web::CSS { namespace Web::CSS {
// https://drafts.csswg.org/cssom-1/#the-stylesheet-interface
class StyleSheet : public Bindings::PlatformObject { class StyleSheet : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(StyleSheet, Bindings::PlatformObject); WEB_PLATFORM_OBJECT(StyleSheet, Bindings::PlatformObject);
@ -24,10 +25,10 @@ public:
DOM::Element* owner_node() { return m_owner_node; } DOM::Element* owner_node() { return m_owner_node; }
void set_owner_node(DOM::Element*); void set_owner_node(DOM::Element*);
Optional<String> href() const { return m_location; } Optional<String> href() const;
Optional<String> location() const { return m_location; } Optional<URL::URL> location() const { return m_location; }
void set_location(Optional<String> location) { m_location = move(location); } void set_location(Optional<URL::URL> location) { m_location = move(location); }
String title() const { return m_title; } String title() const { return m_title; }
Optional<String> title_for_bindings() const; Optional<String> title_for_bindings() const;
@ -67,7 +68,7 @@ private:
GC::Ptr<DOM::Element> m_owner_node; GC::Ptr<DOM::Element> m_owner_node;
GC::Ptr<CSSStyleSheet> m_parent_style_sheet; GC::Ptr<CSSStyleSheet> m_parent_style_sheet;
Optional<String> m_location; Optional<URL::URL> m_location;
String m_title; String m_title;
String m_type_string; String m_type_string;

View file

@ -60,7 +60,7 @@ void StyleSheetList::add_a_css_style_sheet(CSS::CSSStyleSheet& sheet)
} }
// https://www.w3.org/TR/cssom/#create-a-css-style-sheet // https://www.w3.org/TR/cssom/#create-a-css-style-sheet
void StyleSheetList::create_a_css_style_sheet(String type, DOM::Element* owner_node, String media, String title, bool alternate, bool origin_clean, Optional<String> location, CSS::CSSStyleSheet* parent_style_sheet, CSS::CSSRule* owner_rule, CSS::CSSStyleSheet& sheet) void StyleSheetList::create_a_css_style_sheet(String type, DOM::Element* owner_node, String media, String title, bool alternate, bool origin_clean, Optional<URL::URL> location, CSS::CSSStyleSheet* parent_style_sheet, CSS::CSSRule* owner_rule, CSS::CSSStyleSheet& sheet)
{ {
// 1. Create a new CSS style sheet object and set its properties as specified. // 1. Create a new CSS style sheet object and set its properties as specified.
// FIXME: We receive `sheet` from the caller already. This is weird. // FIXME: We receive `sheet` from the caller already. This is weird.

View file

@ -5879,7 +5879,7 @@ void Document::for_each_active_css_style_sheet(Function<void(CSS::CSSStyleSheet&
static Optional<CSS::CSSStyleSheet&> find_style_sheet_with_url(String const& url, CSS::CSSStyleSheet& style_sheet) static Optional<CSS::CSSStyleSheet&> find_style_sheet_with_url(String const& url, CSS::CSSStyleSheet& style_sheet)
{ {
if (style_sheet.location() == url) if (style_sheet.href() == url)
return style_sheet; return style_sheet;
for (auto& import_rule : style_sheet.import_rules()) { for (auto& import_rule : style_sheet.import_rules()) {

View file

@ -492,7 +492,7 @@ void HTMLLinkElement::process_stylesheet_resource(bool success, Fetch::Infrastru
if (m_loaded_style_sheet) { if (m_loaded_style_sheet) {
Optional<String> location; Optional<String> location;
if (!response.url_list().is_empty()) if (!response.url_list().is_empty())
location = response.url_list().first().to_string(); location = response.url_list().first();
document_or_shadow_root_style_sheets().create_a_css_style_sheet( document_or_shadow_root_style_sheets().create_a_css_style_sheet(
"text/css"_string, "text/css"_string,

View file

@ -834,8 +834,8 @@ static void gather_style_sheets(Vector<Web::CSS::StyleSheetIdentifier>& results,
} }
if (valid) { if (valid) {
if (auto location = sheet.location(); location.has_value()) if (auto sheet_url = sheet.href(); sheet_url.has_value())
identifier.url = location.release_value(); identifier.url = sheet_url.release_value();
identifier.rule_count = sheet.rules().length(); identifier.rule_count = sheet.rules().length();
results.append(move(identifier)); results.append(move(identifier));