diff options
author | Sam Atkins <atkinssj@gmail.com> | 2021-07-12 17:30:40 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-07-14 13:31:00 +0200 |
commit | 776b1f45487eb5f541f079239c209d1aa3c9e5cf (patch) | |
tree | 8cae90ffe6fc04c9f62977c5f1eee9676bd1c487 | |
parent | 8cae79cc8de78c510f25a4f86ac4da00f5640590 (diff) | |
download | serenity-776b1f45487eb5f541f079239c209d1aa3c9e5cf.zip |
LibWeb: Make CSS::Selector reference counted
The end goal is to make the PseudoClass::not_selector be a Selector
instead of a String that is repeatedly re-parsed. But since Selector
contains a Vector of ComplexSelectors, which each have a Vector of
SimpleSelectors, it's probably a good idea to not be passing them
around by value anyway. :^)
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSStyleRule.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSStyleRule.h | 9 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/DeprecatedCSSParser.cpp | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/DeprecatedCSSParser.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp | 26 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/Parser.h | 12 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Selector.h | 11 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/ParentNode.cpp | 12 |
9 files changed, 48 insertions, 38 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleRule.cpp index a5ff41b4b9..75a570344d 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleRule.cpp @@ -8,7 +8,7 @@ namespace Web::CSS { -CSSStyleRule::CSSStyleRule(Vector<Selector>&& selectors, NonnullRefPtr<CSSStyleDeclaration>&& declaration) +CSSStyleRule::CSSStyleRule(NonnullRefPtrVector<Selector>&& selectors, NonnullRefPtr<CSSStyleDeclaration>&& declaration) : m_selectors(move(selectors)) , m_declaration(move(declaration)) { diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleRule.h b/Userland/Libraries/LibWeb/CSS/CSSStyleRule.h index 41dce31a78..b0c636323f 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleRule.h @@ -7,6 +7,7 @@ #pragma once +#include <AK/NonnullRefPtr.h> #include <AK/NonnullRefPtrVector.h> #include <LibWeb/CSS/CSSRule.h> #include <LibWeb/CSS/CSSStyleDeclaration.h> @@ -19,23 +20,23 @@ class CSSStyleRule : public CSSRule { AK_MAKE_NONMOVABLE(CSSStyleRule); public: - static NonnullRefPtr<CSSStyleRule> create(Vector<Selector>&& selectors, NonnullRefPtr<CSSStyleDeclaration>&& declaration) + static NonnullRefPtr<CSSStyleRule> create(NonnullRefPtrVector<Selector>&& selectors, NonnullRefPtr<CSSStyleDeclaration>&& declaration) { return adopt_ref(*new CSSStyleRule(move(selectors), move(declaration))); } ~CSSStyleRule(); - const Vector<Selector>& selectors() const { return m_selectors; } + const NonnullRefPtrVector<Selector>& selectors() const { return m_selectors; } const CSSStyleDeclaration& declaration() const { return m_declaration; } virtual StringView class_name() const { return "CSSStyleRule"; }; virtual Type type() const { return Type::Style; }; private: - CSSStyleRule(Vector<Selector>&&, NonnullRefPtr<CSSStyleDeclaration>&&); + CSSStyleRule(NonnullRefPtrVector<Selector>&&, NonnullRefPtr<CSSStyleDeclaration>&&); - Vector<Selector> m_selectors; + NonnullRefPtrVector<Selector> m_selectors; NonnullRefPtr<CSSStyleDeclaration> m_declaration; }; diff --git a/Userland/Libraries/LibWeb/CSS/Parser/DeprecatedCSSParser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/DeprecatedCSSParser.cpp index 513d6d6bc7..6e7972d8f4 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/DeprecatedCSSParser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/DeprecatedCSSParser.cpp @@ -683,10 +683,10 @@ public: return; complex_selectors.first().relation = CSS::Selector::ComplexSelector::Relation::None; - current_rule.selectors.append(CSS::Selector(move(complex_selectors))); + current_rule.selectors.append(CSS::Selector::create(move(complex_selectors))); } - Optional<CSS::Selector> parse_individual_selector() + RefPtr<CSS::Selector> parse_individual_selector() { parse_selector(); if (current_rule.selectors.is_empty()) @@ -1037,7 +1037,7 @@ private: NonnullRefPtrVector<CSS::CSSRule> rules; struct CurrentRule { - Vector<CSS::Selector> selectors; + NonnullRefPtrVector<CSS::Selector> selectors; Vector<CSS::StyleProperty> properties; HashMap<String, CSS::StyleProperty> custom_properties; }; @@ -1050,7 +1050,7 @@ private: StringView css; }; -Optional<CSS::Selector> parse_selector(const CSS::DeprecatedParsingContext& context, const StringView& selector_text) +RefPtr<CSS::Selector> parse_selector(const CSS::DeprecatedParsingContext& context, const StringView& selector_text) { CSSParser parser(context, selector_text); return parser.parse_individual_selector(); diff --git a/Userland/Libraries/LibWeb/CSS/Parser/DeprecatedCSSParser.h b/Userland/Libraries/LibWeb/CSS/Parser/DeprecatedCSSParser.h index 64f755f0b4..e60c056ded 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/DeprecatedCSSParser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/DeprecatedCSSParser.h @@ -31,7 +31,7 @@ namespace Web { RefPtr<CSS::CSSStyleSheet> parse_css(const CSS::DeprecatedParsingContext&, const StringView&); RefPtr<CSS::CSSStyleDeclaration> parse_css_declaration(const CSS::DeprecatedParsingContext&, const StringView&); RefPtr<CSS::StyleValue> parse_css_value(const CSS::DeprecatedParsingContext&, const StringView&, CSS::PropertyID property_id = CSS::PropertyID::Invalid); -Optional<CSS::Selector> parse_selector(const CSS::DeprecatedParsingContext&, const StringView&); +RefPtr<CSS::Selector> parse_selector(const CSS::DeprecatedParsingContext&, const StringView&); RefPtr<CSS::LengthStyleValue> parse_line_width(const CSS::DeprecatedParsingContext&, const StringView&); RefPtr<CSS::ColorStyleValue> parse_color(const CSS::DeprecatedParsingContext&, const StringView&); diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index bbf5e49cfb..4e5480e147 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -171,55 +171,55 @@ NonnullRefPtr<CSSStyleSheet> Parser::parse_as_stylesheet(TokenStream<T>& tokens) return stylesheet; } -Vector<Selector> Parser::parse_a_selector() +NonnullRefPtrVector<Selector> Parser::parse_a_selector() { return parse_a_selector(m_token_stream); } template<typename T> -Vector<Selector> Parser::parse_a_selector(TokenStream<T>& tokens) +NonnullRefPtrVector<Selector> Parser::parse_a_selector(TokenStream<T>& tokens) { dbgln_if(CSS_PARSER_TRACE, "Parser::parse_a_selector"); auto comma_separated_lists = parse_as_comma_separated_list_of_component_values(tokens); - Vector<Selector> selectors; + NonnullRefPtrVector<Selector> selectors; for (auto& selector_parts : comma_separated_lists) { auto stream = TokenStream(selector_parts); auto selector = parse_single_selector(stream); - if (selector.has_value()) - selectors.append(selector.value()); + if (selector) + selectors.append(selector.release_nonnull()); } return selectors; } -Vector<Selector> Parser::parse_a_relative_selector() +NonnullRefPtrVector<Selector> Parser::parse_a_relative_selector() { return parse_a_relative_selector(m_token_stream); } template<typename T> -Vector<Selector> Parser::parse_a_relative_selector(TokenStream<T>& tokens) +NonnullRefPtrVector<Selector> Parser::parse_a_relative_selector(TokenStream<T>& tokens) { dbgln_if(CSS_PARSER_TRACE, "Parser::parse_a_relative_selector"); auto comma_separated_lists = parse_as_comma_separated_list_of_component_values(tokens); - Vector<Selector> selectors; + NonnullRefPtrVector<Selector> selectors; for (auto& selector_parts : comma_separated_lists) { auto stream = TokenStream(selector_parts); auto selector = parse_single_selector(stream, true); - if (selector.has_value()) - selectors.append(selector.value()); + if (selector) + selectors.append(selector.release_nonnull()); } return selectors; } template<typename T> -Optional<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is_relative) +RefPtr<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is_relative) { dbgln_if(CSS_PARSER_TRACE, "Parser::parse_single_selector"); @@ -555,7 +555,7 @@ Optional<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is if (!is_relative) selectors.first().relation = Selector::ComplexSelector::Relation::None; - return Selector(move(selectors)); + return Selector::create(move(selectors)); } NonnullRefPtrVector<StyleRule> Parser::consume_a_list_of_rules(bool top_level) @@ -1145,7 +1145,7 @@ RefPtr<CSSRule> Parser::convert_to_rule(NonnullRefPtr<StyleRule> rule) } else { auto prelude_stream = TokenStream(rule->m_prelude); - Vector<Selector> selectors = parse_a_selector(prelude_stream); + auto selectors = parse_a_selector(prelude_stream); auto declaration = convert_to_declaration(*rule->m_block); if (declaration && !selectors.is_empty()) return CSSStyleRule::create(move(selectors), move(*declaration)); diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 0db9a72af4..3e46103f51 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -8,6 +8,8 @@ #pragma once #include <AK/NonnullOwnPtrVector.h> +#include <AK/NonnullRefPtrVector.h> +#include <AK/RefPtr.h> #include <AK/Vector.h> #include <LibWeb/CSS/Parser/DeclarationOrAtRule.h> #include <LibWeb/CSS/Parser/StyleBlockRule.h> @@ -110,19 +112,19 @@ public: Vector<Vector<StyleComponentValueRule>> parse_as_comma_separated_list_of_component_values(TokenStream<T>&); template<typename T> - Optional<Selector> parse_single_selector(TokenStream<T>&, bool is_relative = false); + RefPtr<Selector> parse_single_selector(TokenStream<T>&, bool is_relative = false); Optional<Selector::SimpleSelector::NthChildPattern> parse_nth_child_pattern(TokenStream<StyleComponentValueRule>&); // FIXME: https://www.w3.org/TR/selectors-4/ // Contrary to the name, these parse a comma-separated list of selectors, according to the spec. - Vector<Selector> parse_a_selector(); + NonnullRefPtrVector<Selector> parse_a_selector(); template<typename T> - Vector<Selector> parse_a_selector(TokenStream<T>&); + NonnullRefPtrVector<Selector> parse_a_selector(TokenStream<T>&); - Vector<Selector> parse_a_relative_selector(); + NonnullRefPtrVector<Selector> parse_a_relative_selector(); template<typename T> - Vector<Selector> parse_a_relative_selector(TokenStream<T>&); + NonnullRefPtrVector<Selector> parse_a_relative_selector(TokenStream<T>&); RefPtr<StyleValue> parse_css_value(PropertyID, TokenStream<StyleComponentValueRule>&); diff --git a/Userland/Libraries/LibWeb/CSS/Selector.h b/Userland/Libraries/LibWeb/CSS/Selector.h index d9cb4c710b..b7c0f18e16 100644 --- a/Userland/Libraries/LibWeb/CSS/Selector.h +++ b/Userland/Libraries/LibWeb/CSS/Selector.h @@ -8,12 +8,13 @@ #pragma once #include <AK/FlyString.h> +#include <AK/RefCounted.h> #include <AK/String.h> #include <AK/Vector.h> namespace Web::CSS { -class Selector { +class Selector : public RefCounted<Selector> { public: struct SimpleSelector { enum class Type { @@ -112,7 +113,11 @@ public: CompoundSelector compound_selector; }; - explicit Selector(Vector<ComplexSelector>&&); + static NonnullRefPtr<Selector> create(Vector<ComplexSelector>&& complex_selectors) + { + return adopt_ref(*new Selector(move(complex_selectors))); + } + ~Selector(); Vector<ComplexSelector> const& complex_selectors() const { return m_complex_selectors; } @@ -120,6 +125,8 @@ public: u32 specificity() const; private: + explicit Selector(Vector<ComplexSelector>&&); + Vector<ComplexSelector> m_complex_selectors; }; diff --git a/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp b/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp index f94d8c425d..efd9938453 100644 --- a/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp +++ b/Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp @@ -117,9 +117,9 @@ static bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoClass cons if (pseudo_class.not_selector.is_empty()) return false; auto not_selector = Web::parse_selector(CSS::DeprecatedParsingContext(element), pseudo_class.not_selector); - if (!not_selector.has_value()) + if (!not_selector) return false; - auto not_matches = matches(not_selector.value(), element); + auto not_matches = matches(not_selector.release_nonnull(), element); return !not_matches; } case CSS::Selector::SimpleSelector::PseudoClass::Type::NthChild: diff --git a/Userland/Libraries/LibWeb/DOM/ParentNode.cpp b/Userland/Libraries/LibWeb/DOM/ParentNode.cpp index 904a1f4945..447954e6b2 100644 --- a/Userland/Libraries/LibWeb/DOM/ParentNode.cpp +++ b/Userland/Libraries/LibWeb/DOM/ParentNode.cpp @@ -14,14 +14,14 @@ namespace Web::DOM { RefPtr<Element> ParentNode::query_selector(const StringView& selector_text) { auto selector = parse_selector(CSS::DeprecatedParsingContext(*this), selector_text); - if (!selector.has_value()) + if (!selector) return {}; - dump_selector(selector.value()); + dump_selector(selector.release_nonnull()); RefPtr<Element> result; for_each_in_inclusive_subtree_of_type<Element>([&](auto& element) { - if (SelectorEngine::matches(selector.value(), element)) { + if (SelectorEngine::matches(selector.release_nonnull(), element)) { result = element; return IterationDecision::Break; } @@ -34,14 +34,14 @@ RefPtr<Element> ParentNode::query_selector(const StringView& selector_text) NonnullRefPtrVector<Element> ParentNode::query_selector_all(const StringView& selector_text) { auto selector = parse_selector(CSS::DeprecatedParsingContext(*this), selector_text); - if (!selector.has_value()) + if (!selector) return {}; - dump_selector(selector.value()); + dump_selector(selector.release_nonnull()); NonnullRefPtrVector<Element> elements; for_each_in_inclusive_subtree_of_type<Element>([&](auto& element) { - if (SelectorEngine::matches(selector.value(), element)) { + if (SelectorEngine::matches(selector.release_nonnull(), element)) { elements.append(element); } return IterationDecision::Continue; |