mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +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: https://github.com/LadybirdBrowser/ladybird/commit/dd3b011f159 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) 2022-2024, Sam Atkins <sam@ladybird.org>
|
||||
* Copyright (c) 2024, Tim Ledbetter <timledbetter@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
|
@ -7,6 +8,7 @@
|
|||
|
||||
#include <LibWeb/Bindings/CSSStyleSheetPrototype.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/CSS/CSSImportRule.h>
|
||||
#include <LibWeb/CSS/CSSStyleSheet.h>
|
||||
#include <LibWeb/CSS/Parser/Parser.h>
|
||||
#include <LibWeb/CSS/StyleComputer.h>
|
||||
|
@ -101,10 +103,10 @@ CSSStyleSheet::CSSStyleSheet(JS::Realm& realm, CSSRuleList& rules, MediaList& me
|
|||
for (auto& rule : *m_rules)
|
||||
rule->set_parent_style_sheet(this);
|
||||
|
||||
recalculate_namespaces();
|
||||
recalculate_rule_caches();
|
||||
|
||||
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_constructor_document);
|
||||
visitor.visit(m_namespace_rules);
|
||||
visitor.visit(m_import_rules);
|
||||
}
|
||||
|
||||
// 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_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
|
||||
// non-ignored at-rules and style rules in a style sheet.
|
||||
// ...
|
||||
// A syntactically invalid @namespace rule (whether malformed or misplaced) must be ignored."
|
||||
// https://drafts.csswg.org/css-namespaces/#syntax
|
||||
switch (rule->type()) {
|
||||
case CSSRule::Type::Import:
|
||||
continue;
|
||||
|
||||
case CSSRule::Type::Namespace:
|
||||
case CSSRule::Type::Import: {
|
||||
// @import rules must appear before @namespace rules, so skip this if we've seen @namespace.
|
||||
if (!m_namespace_rules.is_empty())
|
||||
continue;
|
||||
m_import_rules.append(verify_cast<CSSImportRule>(*rule));
|
||||
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:
|
||||
// Any other types mean that further @namespace rules are invalid, so we can stop here.
|
||||
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;
|
||||
|
||||
Vector<JS::NonnullGCPtr<CSSImportRule>> const& import_rules() const { return m_import_rules; }
|
||||
|
||||
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); }
|
||||
|
||||
|
@ -87,7 +89,7 @@ private:
|
|||
virtual void initialize(JS::Realm&) 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_disallow_modification(bool disallow_modification) { m_disallow_modification = disallow_modification; }
|
||||
|
@ -97,6 +99,7 @@ private:
|
|||
JS::GCPtr<CSSRuleList> m_rules;
|
||||
JS::GCPtr<CSSNamespaceRule> m_default_namespace_rule;
|
||||
HashMap<FlyString, JS::GCPtr<CSSNamespaceRule>> m_namespace_rules;
|
||||
Vector<JS::NonnullGCPtr<CSSImportRule>> m_import_rules;
|
||||
|
||||
JS::GCPtr<StyleSheetList> m_style_sheet_list;
|
||||
JS::GCPtr<CSSRule> m_owner_css_rule;
|
||||
|
|
Loading…
Reference in a new issue