LibWeb: Fix CSS tag seletor case sensitivity for SVG elements

They can appear in HTML documents but must not be matched
according to the HTML spec.
This commit is contained in:
Psychpsyo 2025-01-08 23:07:23 +01:00 committed by Sam Atkins
parent 7757df5bb5
commit bb5d1ac4a3
Notes: github-actions[bot] 2025-01-13 12:12:59 +00:00
7 changed files with 63 additions and 2 deletions

View file

@ -910,10 +910,15 @@ static bool fast_matches_simple_selector(CSS::Selector::SimpleSelector const& si
case CSS::Selector::SimpleSelector::Type::Universal: case CSS::Selector::SimpleSelector::Type::Universal:
return matches_namespace(simple_selector.qualified_name(), element, context.style_sheet_for_rule); return matches_namespace(simple_selector.qualified_name(), element, context.style_sheet_for_rule);
case CSS::Selector::SimpleSelector::Type::TagName: case CSS::Selector::SimpleSelector::Type::TagName:
if (element.document().document_type() == DOM::Document::Type::HTML) { // https://html.spec.whatwg.org/#case-sensitivity-of-selectors
// When comparing a CSS element type selector to the names of HTML elements in HTML documents, the CSS element type selector must first be converted to ASCII lowercase. The
// same selector when compared to other elements must be compared according to its original case. In both cases, to match the values must be identical to each other (and therefore
// the comparison is case sensitive).
if (element.namespace_uri() == Namespace::HTML && element.document().document_type() == DOM::Document::Type::HTML) {
if (simple_selector.qualified_name().name.lowercase_name != element.local_name()) if (simple_selector.qualified_name().name.lowercase_name != element.local_name())
return false; return false;
} else if (!Infra::is_ascii_case_insensitive_match(simple_selector.qualified_name().name.name, element.local_name())) { } else if (simple_selector.qualified_name().name.name != element.local_name()) {
// NOTE: Any other elements are either SVG, XHTML or MathML, all of which are case-sensitive.
return false; return false;
} }
return matches_namespace(simple_selector.qualified_name(), element, context.style_sheet_for_rule); return matches_namespace(simple_selector.qualified_name(), element, context.style_sheet_for_rule);

View file

@ -0,0 +1,4 @@
<!DOCTYPE html>
<div style="color:green;">
This should be green.
</div>

View file

@ -0,0 +1,6 @@
<!DOCTYPE html>
<svg viewBox="0 0 200 200">
<foreignObject width="200" height="200">
<span style="color:green;">This should be green.</span>
</foreignObject>
</svg>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<div>
This should not be red.
</div>
</html>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<link rel="match" href="../expected/css-tag-selector-case-sensitivity-html.html" />
<style>
DIV {
color: green;
}
</style>
<div>
This should be green.
</div>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<link rel="match" href="../expected/css-tag-selector-case-sensitivity-svg.html" />
<style>
foreignObject * {
color: green;
}
foreignobject * {
color: red;
}
</style>
<svg viewBox="0 0 200 200">
<foreignObject width="200" height="200">
<span>This should be green.</span>
</foreignObject>
</svg>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<link rel="match" href="../expected/css-tag-selector-case-sensitivity-xhtml.xhtml" />
<style>
DIV {
color: red;
}
</style>
<div>
This should not be red.
</div>
</html>