mirror of
https://github.com/RGBCube/serenity
synced 2025-07-23 19:37:34 +00:00
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. :^)
This commit is contained in:
parent
89bfde29dc
commit
29d78bba4b
3 changed files with 55 additions and 16 deletions
|
@ -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.
|
// 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()) {
|
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_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;
|
size_t attribute_index = 1;
|
||||||
if (attribute_index >= attribute_parts.size())
|
while (attribute_parts.at(attribute_index).is(Token::TokenType::Whitespace)) {
|
||||||
return simple_selector;
|
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;
|
simple_selector.attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::ExactValueMatch;
|
||||||
attribute_index++;
|
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) == " ~") {
|
while (attribute_parts.at(attribute_index).is(Token::TokenType::Whitespace)) {
|
||||||
simple_selector.attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::Contains;
|
attribute_index++;
|
||||||
attribute_index += 2;
|
if (attribute_index >= attribute_parts.size()) {
|
||||||
|
dbgln("Attribute selector ended without a value to match.");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attribute_parts.at(attribute_index) == " |") {
|
auto& value_part = attribute_parts.at(attribute_index);
|
||||||
simple_selector.attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::StartsWith;
|
if (!value_part.is(Token::TokenType::Ident) && !value_part.is(Token::TokenType::String)) {
|
||||||
attribute_index += 2;
|
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;
|
return simple_selector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,7 +533,7 @@ NonnullRefPtr<StyleBlockRule> Parser::consume_a_simple_block()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
block->m_values.append(value.to_string());
|
block->m_values.append(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <AK/RefCounted.h>
|
#include <AK/RefCounted.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
#include <LibWeb/CSS/Parser/StyleComponentValueRule.h>
|
||||||
#include <LibWeb/CSS/Parser/Token.h>
|
#include <LibWeb/CSS/Parser/Token.h>
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
@ -24,12 +25,12 @@ public:
|
||||||
bool is_paren() const { return m_token.is_open_paren(); }
|
bool is_paren() const { return m_token.is_open_paren(); }
|
||||||
bool is_square() const { return m_token.is_open_square(); }
|
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;
|
String to_string() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Token m_token;
|
Token m_token;
|
||||||
Vector<String> m_values;
|
Vector<StyleComponentValueRule> m_values;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,7 @@ String StyleBlockRule::to_string() const
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
|
|
||||||
builder.append(m_token.bracket_string());
|
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());
|
builder.append(m_token.bracket_mirror_string());
|
||||||
|
|
||||||
return builder.to_string();
|
return builder.to_string();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue