diff options
author | Andreas Kling <kling@serenityos.org> | 2020-05-26 23:07:19 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-26 23:07:19 +0200 |
commit | 5069d380a8678062d9ca6f5127a8cadb545dbb3e (patch) | |
tree | a3818eef26967e165ca07ca160e6aa3208aaad03 /Libraries/LibWeb | |
parent | 16accb71a35ad4c947cd9fefc6dc97c2a1ce3adb (diff) | |
download | serenity-5069d380a8678062d9ca6f5127a8cadb545dbb3e.zip |
LibWeb: Let Element cache its list of classes
Instead of string splitting every time you call Element::has_class(),
we now split the "class" attribute value when it changes, and cache
the individual classes as FlyStrings in Element::m_classes.
This makes has_class() significantly faster and moves the pain point
of selector matching somewhere else.
Diffstat (limited to 'Libraries/LibWeb')
-rw-r--r-- | Libraries/LibWeb/DOM/Element.cpp | 20 | ||||
-rw-r--r-- | Libraries/LibWeb/DOM/Element.h | 4 |
2 files changed, 15 insertions, 9 deletions
diff --git a/Libraries/LibWeb/DOM/Element.cpp b/Libraries/LibWeb/DOM/Element.cpp index 85fbfc90dc..6b546b97c3 100644 --- a/Libraries/LibWeb/DOM/Element.cpp +++ b/Libraries/LibWeb/DOM/Element.cpp @@ -97,14 +97,10 @@ void Element::set_attributes(Vector<Attribute>&& attributes) parse_attribute(attribute.name(), attribute.value()); } -bool Element::has_class(const StringView& class_name) const +bool Element::has_class(const FlyString& class_name) const { - auto value = attribute("class"); - if (value.is_empty()) - return false; - auto parts = value.split_view(' '); - for (auto& part : parts) { - if (part == class_name) + for (auto& class_ : m_classes) { + if (class_ == class_name) return true; } return false; @@ -140,8 +136,16 @@ RefPtr<LayoutNode> Element::create_layout_node(const StyleProperties* parent_sty return adopt(*new LayoutInline(*this, move(style))); } -void Element::parse_attribute(const FlyString&, const String&) +void Element::parse_attribute(const FlyString& name, const String& value) { + if (name == "class") { + auto new_classes = value.split_view(' '); + m_classes.clear(); + m_classes.ensure_capacity(new_classes.size()); + for (auto& new_class : new_classes) { + m_classes.unchecked_append(new_class); + } + } } enum class StyleDifference { diff --git a/Libraries/LibWeb/DOM/Element.h b/Libraries/LibWeb/DOM/Element.h index 70c9d83f6b..7fbf3ab394 100644 --- a/Libraries/LibWeb/DOM/Element.h +++ b/Libraries/LibWeb/DOM/Element.h @@ -58,7 +58,7 @@ public: callback(attribute.name(), attribute.value()); } - bool has_class(const StringView&) const; + bool has_class(const FlyString&) const; virtual void apply_presentational_hints(StyleProperties&) const { } virtual void parse_attribute(const FlyString& name, const String& value); @@ -86,6 +86,8 @@ private: Vector<Attribute> m_attributes; RefPtr<StyleProperties> m_resolved_style; + + Vector<FlyString> m_classes; }; template<> |