mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-31 23:42:52 +00:00
LibWeb: Ensure |=
value selector handles multiple segments correctly
Previously, the `|=` would not compare strings containing `-` characters correctly because it would only compare the element attribute up to the first `-` character.
This commit is contained in:
parent
1c3d849b8b
commit
74c803c87b
Notes:
github-actions[bot]
2025-04-28 10:30:50 +00:00
Author: https://github.com/tcl3
Commit: 74c803c87b
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4495
Reviewed-by: https://github.com/AtkinsSJ ✅
5 changed files with 148 additions and 4 deletions
|
@ -291,6 +291,10 @@ static inline bool matches_attribute(CSS::Selector::SimpleSelector::Attribute co
|
|||
return !attribute.value.is_empty()
|
||||
&& attr->value().contains(attribute.value, case_sensitivity);
|
||||
case CSS::Selector::SimpleSelector::Attribute::MatchType::StartsWithSegment: {
|
||||
// https://www.w3.org/TR/CSS2/selector.html#attribute-selectors
|
||||
// [att|=val]
|
||||
// Represents an element with the att attribute, its value either being exactly "val" or beginning with "val" immediately followed by "-" (U+002D).
|
||||
|
||||
auto const& element_attr_value = attr->value();
|
||||
if (element_attr_value.is_empty()) {
|
||||
// If the attribute value on element is empty, the selector is true
|
||||
|
@ -300,10 +304,19 @@ static inline bool matches_attribute(CSS::Selector::SimpleSelector::Attribute co
|
|||
if (attribute.value.is_empty()) {
|
||||
return false;
|
||||
}
|
||||
auto segments = element_attr_value.bytes_as_string_view().split_view('-');
|
||||
|
||||
auto element_attribute_length = element_attr_value.bytes_as_string_view().length();
|
||||
auto attribute_length = attribute.value.bytes_as_string_view().length();
|
||||
if (element_attribute_length < attribute_length)
|
||||
return false;
|
||||
|
||||
if (attribute_length == element_attribute_length) {
|
||||
return case_insensitive_match
|
||||
? Infra::is_ascii_case_insensitive_match(segments.first(), attribute.value)
|
||||
: segments.first() == attribute.value;
|
||||
? Infra::is_ascii_case_insensitive_match(element_attr_value, attribute.value)
|
||||
: element_attr_value == attribute.value;
|
||||
}
|
||||
|
||||
return element_attr_value.starts_with_bytes(attribute.value, case_insensitive_match ? CaseSensitivity::CaseInsensitive : CaseSensitivity::CaseSensitive) && element_attr_value.bytes_as_string_view()[attribute_length] == '-';
|
||||
}
|
||||
case CSS::Selector::SimpleSelector::Attribute::MatchType::StartsWithString:
|
||||
return !attribute.value.is_empty()
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.green {
|
||||
background-color: green;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div class="green">This line should be green</div>
|
||||
<div class="green">This line should be green</div>
|
||||
<div class="green">This line should be green</div>
|
||||
<div class="green">This line should be green</div>
|
||||
<p class="green">This line should be green <em>and this should be green too</em></p>
|
||||
|
||||
<div>This line should NOT be green</div>
|
||||
<div>This line should NOT be green</div>
|
||||
<div>This line should NOT be green</div>
|
||||
<div>This line should NOT be green</div>
|
||||
<div>This line should NOT be green</div>
|
||||
<div>This line should NOT be green<p>This line should NOT be green</p></div>
|
||||
<p>This line should NOT be green <em>and this should not be green either</em></p>
|
||||
</body>
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reference</title>
|
||||
<style>
|
||||
.green {
|
||||
background-color: green;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div class="green">This line should be green</div>
|
||||
<div class="green">This line should be green</div>
|
||||
<div class="green">This line should be green</div>
|
||||
<div class="green">This line should be green</div>
|
||||
<div class="green">This line should be green</div>
|
||||
<p class="green">This line should be green <em>and this should be green too</em></p>
|
||||
|
||||
<div>This line should NOT be green</div>
|
||||
<div>This line should NOT be green</div>
|
||||
<div>This line should NOT be green</div>
|
||||
<div>This line should NOT be green</div>
|
||||
<div>This line should NOT be green<p>This line should NOT be green</p></div>
|
||||
<p>This line should NOT be green <em>and this should not be green either</em></p>
|
||||
</body>
|
|
@ -0,0 +1,41 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>CSS Test: lang attribute selector - att |= val</title>
|
||||
<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org"/>
|
||||
<link rel="author" title="Eira Monstad, Opera Software ASA" href="mailto:public-testsuites@opera.com"/>
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS21/selector.html#attribute-selectors"/>
|
||||
<link rel="match" href="../../../../../expected/wpt-import/css/CSS2/selector/attribute-value-selector-009-ref.html" />
|
||||
<meta name="flags" content="nonHTML"/>
|
||||
<meta name="assert" content="lang attribute selector with 'att |= val' in XHTML should be case sensitive, and match hyphen-separated list"/>
|
||||
<style type="text/css"><![CDATA[
|
||||
div[title |= "es"] { color:white;background-color:green; }
|
||||
p[title |= "es"] { color:white;background-color:green; }
|
||||
div[title |= "en-GB"] { color:white;background-color:green; }
|
||||
p[title |= "fr"] { color:white;background-color:green; }
|
||||
em[title |= "de"] { color:white;background-color:green; }
|
||||
div[lang=" no"] { color:white;background-color:green; }
|
||||
]]></style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div title="es">This line should be green</div>
|
||||
<div title="es-MX">This line should be green</div>
|
||||
|
||||
<div title="en-GB">This line should be green</div>
|
||||
<div title="en-GB-scouse">This line should be green</div>
|
||||
|
||||
<p title="es">This line should be green <em>and this should be green too</em></p>
|
||||
|
||||
<div lang="no">This line should NOT be green</div>
|
||||
<div title="ES">This line should NOT be green</div>
|
||||
<div title="MX-es">This line should NOT be green</div>
|
||||
|
||||
<div title="en-US">This line should NOT be green</div>
|
||||
<div title="en">This line should NOT be green</div>
|
||||
|
||||
<div title="fr">This line should NOT be green<p>This line should NOT be green</p></div>
|
||||
<p title="de">This line should NOT be green <em>and this should not be green either</em></p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Test: lang attribute selector - att |= val</title>
|
||||
<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
|
||||
<link rel="author" title="Eira Monstad, Opera Software ASA" href="mailto:public-testsuites@opera.com">
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS21/selector.html#attribute-selectors">
|
||||
<link rel="match" href="../../../../../expected/wpt-import/css/CSS2/selector/attribute-value-selector-010-ref.html" />
|
||||
<meta name="flags" content="HTMLonly">
|
||||
<meta name="assert" content="lang attribute selector with 'att |= val' in HTML should not be case sensitive, and match hyphen-separated list">
|
||||
<style type="text/css">
|
||||
div[lang |= "es"] { color:white;background-color:green; }
|
||||
p[lang |= "es"] { color:white;background-color:green; }
|
||||
div[lang |= "en-GB"] { color:white;background-color:green; }
|
||||
p[lang |= "fr"] { color:white;background-color:green; }
|
||||
em[lang |= "de"] { color:white;background-color:green; }
|
||||
div[xml:lang |= "it"] { color:white;background-color:green; }
|
||||
div[lang |= "ch"] { color:white;background-color:green; }
|
||||
div[lang=" no"] { color:white;background-color:green; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div lang="es">This line should be green</div>
|
||||
<div lang="es-MX">This line should be green</div>
|
||||
<div lang="ES">This line should be green</div>
|
||||
|
||||
<div lang="en-GB">This line should be green</div>
|
||||
<div lang="en-GB-scouse">This line should be green</div>
|
||||
|
||||
<p lang="es">This line should be green <em>and this should be green too</em></p>
|
||||
|
||||
<div lang="no">This line should NOT be green</div>
|
||||
<div lang="MX-es">This line should NOT be green</div>
|
||||
|
||||
<div lang="en-US">This line should NOT be green</div>
|
||||
<div lang="en">This line should NOT be green</div>
|
||||
|
||||
<div lang="fr">This line should NOT be green<p>This line should NOT be green</p></div>
|
||||
<p lang="de">This line should NOT be green <em>and this should not be green either</em></p>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue