1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 15:27:35 +00:00

LibWeb: Add remaining CSS AttributeMatchTypes

This adds:
- ContainsString     [att*=val]
- StartsWithSegment  [att|=val]
- StartsWithString   [att^=val]
- EndsWithString     [att$=val]

Renamed AttributeMatchType::Contains to ::ContainsWord for clarity.
This commit is contained in:
Sam Atkins 2021-07-01 15:31:44 +01:00 committed by Andreas Kling
parent 29d78bba4b
commit 7fefe34797
5 changed files with 38 additions and 10 deletions

View file

@ -478,7 +478,7 @@ public:
attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::ExactValueMatch; attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::ExactValueMatch;
} else if (ch == '~') { } else if (ch == '~') {
consume_one(); consume_one();
attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::Contains; attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::ContainsWord;
} }
attribute_name = String::copy(buffer); attribute_name = String::copy(buffer);
buffer.clear(); buffer.clear();

View file

@ -189,12 +189,12 @@ Vector<CSS::Selector::ComplexSelector> Parser::parse_selectors(Vector<StyleCompo
} }
if (delim_part.token().delim() == "~") { if (delim_part.token().delim() == "~") {
simple_selector.attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::Contains; simple_selector.attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::ContainsWord;
attribute_index++; attribute_index++;
} }
if (delim_part.token().delim() == "|") { if (delim_part.token().delim() == "|") {
simple_selector.attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::StartsWith; simple_selector.attribute_match_type = CSS::Selector::SimpleSelector::AttributeMatchType::StartsWithSegment;
attribute_index++; attribute_index++;
} }
} }

View file

@ -60,8 +60,11 @@ public:
None, None,
HasAttribute, HasAttribute,
ExactValueMatch, ExactValueMatch,
Contains, ContainsWord, // [att~=val]
StartsWith, ContainsString, // [att*=val]
StartsWithSegment, // [att|=val]
StartsWithString, // [att^=val]
EndsWithString, // [att$=val]
}; };
AttributeMatchType attribute_match_type { AttributeMatchType::None }; AttributeMatchType attribute_match_type { AttributeMatchType::None };

View file

@ -180,10 +180,26 @@ static bool matches(const CSS::Selector::SimpleSelector& component, const DOM::E
if (element.attribute(component.attribute_name) != component.attribute_value) if (element.attribute(component.attribute_name) != component.attribute_value)
return false; return false;
break; break;
case CSS::Selector::SimpleSelector::AttributeMatchType::Contains: case CSS::Selector::SimpleSelector::AttributeMatchType::ContainsWord:
if (!element.attribute(component.attribute_name).split(' ').contains_slow(component.attribute_value)) if (!element.attribute(component.attribute_name).split(' ').contains_slow(component.attribute_value))
return false; return false;
break; break;
case CSS::Selector::SimpleSelector::AttributeMatchType::ContainsString:
if (!element.attribute(component.attribute_name).contains(component.attribute_value))
return false;
break;
case CSS::Selector::SimpleSelector::AttributeMatchType::StartsWithSegment:
if (element.attribute(component.attribute_name).split('-').first() != component.attribute_value)
return false;
break;
case CSS::Selector::SimpleSelector::AttributeMatchType::StartsWithString:
if (!element.attribute(component.attribute_name).starts_with(component.attribute_value))
return false;
break;
case CSS::Selector::SimpleSelector::AttributeMatchType::EndsWithString:
if (!element.attribute(component.attribute_name).ends_with(component.attribute_value))
return false;
break;
default: default:
break; break;
} }

View file

@ -325,11 +325,20 @@ void dump_selector(StringBuilder& builder, const CSS::Selector& selector)
case CSS::Selector::SimpleSelector::AttributeMatchType::ExactValueMatch: case CSS::Selector::SimpleSelector::AttributeMatchType::ExactValueMatch:
attribute_match_type_description = "ExactValueMatch"; attribute_match_type_description = "ExactValueMatch";
break; break;
case CSS::Selector::SimpleSelector::AttributeMatchType::Contains: case CSS::Selector::SimpleSelector::AttributeMatchType::ContainsWord:
attribute_match_type_description = "Contains"; attribute_match_type_description = "ContainsWord";
break; break;
case CSS::Selector::SimpleSelector::AttributeMatchType::StartsWith: case CSS::Selector::SimpleSelector::AttributeMatchType::ContainsString:
attribute_match_type_description = "StartsWith"; attribute_match_type_description = "ContainsString";
break;
case CSS::Selector::SimpleSelector::AttributeMatchType::StartsWithSegment:
attribute_match_type_description = "StartsWithSegment";
break;
case CSS::Selector::SimpleSelector::AttributeMatchType::StartsWithString:
attribute_match_type_description = "StartsWithString";
break;
case CSS::Selector::SimpleSelector::AttributeMatchType::EndsWithString:
attribute_match_type_description = "EndsWithString";
break; break;
} }