summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@gmail.com>2021-07-01 14:54:27 +0100
committerAndreas Kling <kling@serenityos.org>2021-07-11 23:19:56 +0200
commit29d78bba4bd0fa2768a63f365f15f2ad4cfb05e6 (patch)
tree7ee1da5a2e1b5be673dc4dbb1c4e32f5dd0b0913 /Userland
parent89bfde29dc2d9fd27fceb5b1de9cdd7bb5389f3a (diff)
downloadserenity-29d78bba4bd0fa2768a63f365f15f2ad4cfb05e6.zip
LibWeb: Use StyleComponentValueRules for StyleBlockRule's values
Noticed while doing this that attribute selectors have two different ways of saying "starts with", and so AttributeMatchType::StartsWith needs a better name. But I'll change that when I add the missing types. These class names are a mouthful to fit in a commit message. :^)
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp64
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/StyleBlockRule.h5
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/StyleRules.cpp2
3 files changed, 55 insertions, 16 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
index 4411a6ee32..fa945f30a6 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
+++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
@@ -152,31 +152,69 @@ Vector<CSS::Selector::ComplexSelector> Parser::parse_selectors(Vector<StyleCompo
// FIXME: Attribute selectors want to be their own Selector::SimpleSelector::Type according to the spec.
if (current_value.is_block() && current_value.block().is_square()) {
- Vector<String> attribute_parts = current_value.block().values();
+ Vector<StyleComponentValueRule> const& attribute_parts = current_value.block().values();
+
+ // FIXME: Handle namespace prefix for attribute name.
+ auto& attribute_part = attribute_parts.first();
+ if (!attribute_part.is(Token::TokenType::Ident)) {
+ dbgln("Expected ident for attribute name, got: '{}'", attribute_part.to_string());
+ return {};
+ }
simple_selector.attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::HasAttribute;
- simple_selector.attribute_name = attribute_parts.first();
+ simple_selector.attribute_name = attribute_part.token().ident();
size_t attribute_index = 1;
- if (attribute_index >= attribute_parts.size())
- return simple_selector;
+ while (attribute_parts.at(attribute_index).is(Token::TokenType::Whitespace)) {
+ attribute_index++;
+ if (attribute_index >= attribute_parts.size())
+ return simple_selector;
+ }
- if (attribute_parts.at(attribute_index) == " =") {
+ auto& delim_part = attribute_parts.at(attribute_index);
+ if (!delim_part.is(Token::TokenType::Delim)) {
+ dbgln("Expected a delim for attribute comparison, got: '{}'", delim_part.to_string());
+ return {};
+ }
+
+ if (delim_part.token().delim() == "=") {
simple_selector.attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::ExactValueMatch;
attribute_index++;
+ } else {
+ attribute_index++;
+ auto& delim_second_part = attribute_parts.at(attribute_index);
+ if (!(delim_part.is(Token::TokenType::Delim) && delim_part.token().delim() == "=")) {
+ dbgln("Expected a double delim for attribute comparison, got: '{}{}'", delim_part.to_string(), delim_second_part.to_string());
+ return {};
+ }
+
+ if (delim_part.token().delim() == "~") {
+ simple_selector.attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::Contains;
+ attribute_index++;
+ }
+
+ if (delim_part.token().delim() == "|") {
+ simple_selector.attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::StartsWith;
+ attribute_index++;
+ }
}
- if (attribute_parts.at(attribute_index) == " ~") {
- simple_selector.attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::Contains;
- attribute_index += 2;
+ while (attribute_parts.at(attribute_index).is(Token::TokenType::Whitespace)) {
+ attribute_index++;
+ if (attribute_index >= attribute_parts.size()) {
+ dbgln("Attribute selector ended without a value to match.");
+ return {};
+ }
}
- if (attribute_parts.at(attribute_index) == " |") {
- simple_selector.attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::StartsWith;
- attribute_index += 2;
+ auto& value_part = attribute_parts.at(attribute_index);
+ if (!value_part.is(Token::TokenType::Ident) && !value_part.is(Token::TokenType::String)) {
+ dbgln("Expected a string or ident for the value to match attribute against, got: '{}'", value_part.to_string());
+ return {};
}
+ simple_selector.attribute_value = value_part.token().is_ident() ? value_part.token().ident() : value_part.token().string();
- simple_selector.attribute_value = attribute_parts.at(attribute_index);
+ // FIXME: Handle case-sensitivity suffixes. https://www.w3.org/TR/selectors-4/#attribute-case
return simple_selector;
}
@@ -495,7 +533,7 @@ NonnullRefPtr<StyleBlockRule> Parser::consume_a_simple_block()
continue;
}
}
- block->m_values.append(value.to_string());
+ block->m_values.append(value);
}
}
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/StyleBlockRule.h b/Userland/Libraries/LibWeb/CSS/Parser/StyleBlockRule.h
index a270351671..63f6cf047b 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/StyleBlockRule.h
+++ b/Userland/Libraries/LibWeb/CSS/Parser/StyleBlockRule.h
@@ -9,6 +9,7 @@
#include <AK/RefCounted.h>
#include <AK/Vector.h>
+#include <LibWeb/CSS/Parser/StyleComponentValueRule.h>
#include <LibWeb/CSS/Parser/Token.h>
namespace Web::CSS {
@@ -24,12 +25,12 @@ public:
bool is_paren() const { return m_token.is_open_paren(); }
bool is_square() const { return m_token.is_open_square(); }
- Vector<String> const& values() const { return m_values; }
+ Vector<StyleComponentValueRule> const& values() const { return m_values; }
String to_string() const;
private:
Token m_token;
- Vector<String> m_values;
+ Vector<StyleComponentValueRule> m_values;
};
}
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/StyleRules.cpp b/Userland/Libraries/LibWeb/CSS/Parser/StyleRules.cpp
index 3c21c712d0..7080e21466 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/StyleRules.cpp
+++ b/Userland/Libraries/LibWeb/CSS/Parser/StyleRules.cpp
@@ -119,7 +119,7 @@ String StyleBlockRule::to_string() const
StringBuilder builder;
builder.append(m_token.bracket_string());
- append_raw(builder, ", ", m_values);
+ append_with_to_string(builder, ", ", m_values);
builder.append(m_token.bracket_mirror_string());
return builder.to_string();