mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-02 22:30:31 +00:00
LibWeb: Keep track of each CSSStyleSheet's CSSImportRules
This will be used to gather up a list of all loaded style sheets for the inspector.
This commit is contained in:
parent
b00137df38
commit
dd3b011f15
Notes:
github-actions[bot]
2024-09-03 09:13:16 +00:00
Author: https://github.com/AtkinsSJ
Commit: dd3b011f15
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1168
Reviewed-by: https://github.com/trflynn89
2 changed files with 30 additions and 15 deletions
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2022, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2019-2022, Andreas Kling <kling@serenityos.org>
|
||||||
|
* Copyright (c) 2022-2024, Sam Atkins <sam@ladybird.org>
|
||||||
* Copyright (c) 2024, Tim Ledbetter <timledbetter@gmail.com>
|
* Copyright (c) 2024, Tim Ledbetter <timledbetter@gmail.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
@ -7,6 +8,7 @@
|
||||||
|
|
||||||
#include <LibWeb/Bindings/CSSStyleSheetPrototype.h>
|
#include <LibWeb/Bindings/CSSStyleSheetPrototype.h>
|
||||||
#include <LibWeb/Bindings/Intrinsics.h>
|
#include <LibWeb/Bindings/Intrinsics.h>
|
||||||
|
#include <LibWeb/CSS/CSSImportRule.h>
|
||||||
#include <LibWeb/CSS/CSSStyleSheet.h>
|
#include <LibWeb/CSS/CSSStyleSheet.h>
|
||||||
#include <LibWeb/CSS/Parser/Parser.h>
|
#include <LibWeb/CSS/Parser/Parser.h>
|
||||||
#include <LibWeb/CSS/StyleComputer.h>
|
#include <LibWeb/CSS/StyleComputer.h>
|
||||||
|
@ -101,10 +103,10 @@ CSSStyleSheet::CSSStyleSheet(JS::Realm& realm, CSSRuleList& rules, MediaList& me
|
||||||
for (auto& rule : *m_rules)
|
for (auto& rule : *m_rules)
|
||||||
rule->set_parent_style_sheet(this);
|
rule->set_parent_style_sheet(this);
|
||||||
|
|
||||||
recalculate_namespaces();
|
recalculate_rule_caches();
|
||||||
|
|
||||||
m_rules->on_change = [this]() {
|
m_rules->on_change = [this]() {
|
||||||
recalculate_namespaces();
|
recalculate_rule_caches();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +125,7 @@ void CSSStyleSheet::visit_edges(Cell::Visitor& visitor)
|
||||||
visitor.visit(m_default_namespace_rule);
|
visitor.visit(m_default_namespace_rule);
|
||||||
visitor.visit(m_constructor_document);
|
visitor.visit(m_constructor_document);
|
||||||
visitor.visit(m_namespace_rules);
|
visitor.visit(m_namespace_rules);
|
||||||
|
visitor.visit(m_import_rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/cssom/#dom-cssstylesheet-insertrule
|
// https://www.w3.org/TR/cssom/#dom-cssstylesheet-insertrule
|
||||||
|
@ -340,34 +343,43 @@ Optional<FlyString> CSSStyleSheet::namespace_uri(StringView namespace_prefix) co
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSSStyleSheet::recalculate_namespaces()
|
void CSSStyleSheet::recalculate_rule_caches()
|
||||||
{
|
{
|
||||||
m_default_namespace_rule = nullptr;
|
m_default_namespace_rule = nullptr;
|
||||||
m_namespace_rules.clear();
|
m_namespace_rules.clear();
|
||||||
|
m_import_rules.clear();
|
||||||
|
|
||||||
for (JS::NonnullGCPtr<CSSRule> rule : *m_rules) {
|
for (auto const& rule : *m_rules) {
|
||||||
|
// "Any @import rules must precede all other valid at-rules and style rules in a style sheet
|
||||||
|
// (ignoring @charset and @layer statement rules) and must not have any other valid at-rules
|
||||||
|
// or style rules between it and previous @import rules, or else the @import rule is invalid."
|
||||||
|
// https://drafts.csswg.org/css-cascade-5/#at-import
|
||||||
|
//
|
||||||
// "Any @namespace rules must follow all @charset and @import rules and precede all other
|
// "Any @namespace rules must follow all @charset and @import rules and precede all other
|
||||||
// non-ignored at-rules and style rules in a style sheet.
|
// non-ignored at-rules and style rules in a style sheet.
|
||||||
// ...
|
// ...
|
||||||
// A syntactically invalid @namespace rule (whether malformed or misplaced) must be ignored."
|
// A syntactically invalid @namespace rule (whether malformed or misplaced) must be ignored."
|
||||||
// https://drafts.csswg.org/css-namespaces/#syntax
|
// https://drafts.csswg.org/css-namespaces/#syntax
|
||||||
switch (rule->type()) {
|
switch (rule->type()) {
|
||||||
case CSSRule::Type::Import:
|
case CSSRule::Type::Import: {
|
||||||
continue;
|
// @import rules must appear before @namespace rules, so skip this if we've seen @namespace.
|
||||||
|
if (!m_namespace_rules.is_empty())
|
||||||
case CSSRule::Type::Namespace:
|
continue;
|
||||||
|
m_import_rules.append(verify_cast<CSSImportRule>(*rule));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case CSSRule::Type::Namespace: {
|
||||||
|
auto& namespace_rule = verify_cast<CSSNamespaceRule>(*rule);
|
||||||
|
if (!namespace_rule.namespace_uri().is_empty() && namespace_rule.prefix().is_empty())
|
||||||
|
m_default_namespace_rule = namespace_rule;
|
||||||
|
|
||||||
|
m_namespace_rules.set(namespace_rule.prefix(), namespace_rule);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
// Any other types mean that further @namespace rules are invalid, so we can stop here.
|
// Any other types mean that further @namespace rules are invalid, so we can stop here.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& namespace_rule = verify_cast<CSSNamespaceRule>(*rule);
|
|
||||||
if (!namespace_rule.namespace_uri().is_empty() && namespace_rule.prefix().is_empty())
|
|
||||||
m_default_namespace_rule = namespace_rule;
|
|
||||||
|
|
||||||
m_namespace_rules.set(namespace_rule.prefix(), namespace_rule);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,8 @@ public:
|
||||||
|
|
||||||
Optional<FlyString> namespace_uri(StringView namespace_prefix) const;
|
Optional<FlyString> namespace_uri(StringView namespace_prefix) const;
|
||||||
|
|
||||||
|
Vector<JS::NonnullGCPtr<CSSImportRule>> const& import_rules() const { return m_import_rules; }
|
||||||
|
|
||||||
Optional<URL::URL> base_url() const { return m_base_url; }
|
Optional<URL::URL> base_url() const { return m_base_url; }
|
||||||
void set_base_url(Optional<URL::URL> base_url) { m_base_url = move(base_url); }
|
void set_base_url(Optional<URL::URL> base_url) { m_base_url = move(base_url); }
|
||||||
|
|
||||||
|
@ -87,7 +89,7 @@ private:
|
||||||
virtual void initialize(JS::Realm&) override;
|
virtual void initialize(JS::Realm&) override;
|
||||||
virtual void visit_edges(Cell::Visitor&) override;
|
virtual void visit_edges(Cell::Visitor&) override;
|
||||||
|
|
||||||
void recalculate_namespaces();
|
void recalculate_rule_caches();
|
||||||
|
|
||||||
void set_constructed(bool constructed) { m_constructed = constructed; }
|
void set_constructed(bool constructed) { m_constructed = constructed; }
|
||||||
void set_disallow_modification(bool disallow_modification) { m_disallow_modification = disallow_modification; }
|
void set_disallow_modification(bool disallow_modification) { m_disallow_modification = disallow_modification; }
|
||||||
|
@ -97,6 +99,7 @@ private:
|
||||||
JS::GCPtr<CSSRuleList> m_rules;
|
JS::GCPtr<CSSRuleList> m_rules;
|
||||||
JS::GCPtr<CSSNamespaceRule> m_default_namespace_rule;
|
JS::GCPtr<CSSNamespaceRule> m_default_namespace_rule;
|
||||||
HashMap<FlyString, JS::GCPtr<CSSNamespaceRule>> m_namespace_rules;
|
HashMap<FlyString, JS::GCPtr<CSSNamespaceRule>> m_namespace_rules;
|
||||||
|
Vector<JS::NonnullGCPtr<CSSImportRule>> m_import_rules;
|
||||||
|
|
||||||
JS::GCPtr<StyleSheetList> m_style_sheet_list;
|
JS::GCPtr<StyleSheetList> m_style_sheet_list;
|
||||||
JS::GCPtr<CSSRule> m_owner_css_rule;
|
JS::GCPtr<CSSRule> m_owner_css_rule;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue