summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@gmail.com>2021-07-12 17:30:40 +0100
committerAndreas Kling <kling@serenityos.org>2021-07-14 13:31:00 +0200
commit776b1f45487eb5f541f079239c209d1aa3c9e5cf (patch)
tree8cae90ffe6fc04c9f62977c5f1eee9676bd1c487
parent8cae79cc8de78c510f25a4f86ac4da00f5640590 (diff)
downloadserenity-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.cpp2
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSStyleRule.h9
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/DeprecatedCSSParser.cpp8
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/DeprecatedCSSParser.h2
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp26
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.h12
-rw-r--r--Userland/Libraries/LibWeb/CSS/Selector.h11
-rw-r--r--Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp4
-rw-r--r--Userland/Libraries/LibWeb/DOM/ParentNode.cpp12
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;