summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-02-10 18:50:58 +0100
committerAndreas Kling <kling@serenityos.org>2022-02-10 20:52:11 +0100
commit031296cf7b8e39ef3ee0780a66d98ab1d98cac9a (patch)
tree4514dcbbeb5ae59597ae32a7c50d6eba52a02ca1 /Userland/Libraries/LibWeb
parent646b37d1a9b1a7974d8815ed3ea888946e3a45d4 (diff)
downloadserenity-031296cf7b8e39ef3ee0780a66d98ab1d98cac9a.zip
LibWeb: Add "ID" buckets to StyleComputer::RuleCache
We can skip rules that require a specific ID when matching against any element that doesn't have that ID.
Diffstat (limited to 'Userland/Libraries/LibWeb')
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleComputer.cpp14
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleComputer.h1
2 files changed, 14 insertions, 1 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
index af6440153f..4e692e779a 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
+++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
@@ -77,6 +77,10 @@ Vector<MatchingRule> StyleComputer::collect_matching_rules(DOM::Element const& e
if (auto it = m_rule_cache->rules_by_class.find(class_name); it != m_rule_cache->rules_by_class.end())
rules_to_run.extend(it->value);
}
+ if (auto id = element.get_attribute(HTML::AttributeNames::id); !id.is_null()) {
+ if (auto it = m_rule_cache->rules_by_id.find(id); it != m_rule_cache->rules_by_id.end())
+ rules_to_run.extend(it->value);
+ }
rules_to_run.extend(m_rule_cache->other_rules);
Vector<MatchingRule> matching_rules;
@@ -984,6 +988,7 @@ void StyleComputer::build_rule_cache()
m_rule_cache = make<RuleCache>();
size_t num_class_rules = 0;
+ size_t num_id_rules = 0;
Vector<MatchingRule> matching_rules;
size_t style_sheet_index = 0;
@@ -996,6 +1001,12 @@ void StyleComputer::build_rule_cache()
bool added_to_bucket = false;
for (auto const& simple_selector : selector.compound_selectors().last().simple_selectors) {
+ if (simple_selector.type == CSS::Selector::SimpleSelector::Type::Id) {
+ m_rule_cache->rules_by_id.ensure(simple_selector.value).append(move(matching_rule));
+ ++num_id_rules;
+ added_to_bucket = true;
+ break;
+ }
if (simple_selector.type == CSS::Selector::SimpleSelector::Type::Class) {
m_rule_cache->rules_by_class.ensure(simple_selector.value).append(move(matching_rule));
++num_class_rules;
@@ -1015,9 +1026,10 @@ void StyleComputer::build_rule_cache()
if constexpr (LIBWEB_CSS_DEBUG) {
dbgln("Built rule cache!");
+ dbgln(" ID: {}", num_id_rules);
dbgln(" Class: {}", num_class_rules);
dbgln(" Other: {}", m_rule_cache->other_rules.size());
- dbgln(" Total: {}", num_class_rules + m_rule_cache->other_rules.size());
+ dbgln(" Total: {}", num_class_rules + num_id_rules + m_rule_cache->other_rules.size());
}
m_rule_cache->generation = m_document.style_sheets().generation();
diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.h b/Userland/Libraries/LibWeb/CSS/StyleComputer.h
index b366b17cf4..e17f8a99c5 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleComputer.h
+++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.h
@@ -96,6 +96,7 @@ private:
DOM::Document& m_document;
struct RuleCache {
+ HashMap<FlyString, Vector<MatchingRule>> rules_by_id;
HashMap<FlyString, Vector<MatchingRule>> rules_by_class;
Vector<MatchingRule> other_rules;
int generation { 0 };