Skip to content

Commit

Permalink
[attr] Look up attribute by local-name and null-namespace
Browse files Browse the repository at this point in the history
When the namespace part of the <attr-name> is omitted, it defaults
to the null-namespace. We currently implement this with Element::
getAttribute, which gives the wrong result, since it returns
the first attribute with the given qualified name [1].

Note: the lookup is now effectively the same as what "old"
(non-substitution) attr() did.

Note: while Element::getAttribute lower-cases the attribute name
(for HTML documents), Element::getAttributeNS does not [2].

[1] https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name
[2] https://dom.spec.whatwg.org/#concept-element-attributes-get-by-namespace

Issue: 387281256
Change-Id: If42dbe210402b95f03c3d7419c161970b6c3f612
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6140914
Reviewed-by: Rune Lillesveen <[email protected]>
Commit-Queue: Anders Hartvoll Ruud <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1401853}
  • Loading branch information
andruud authored and chromium-wpt-export-bot committed Jan 3, 2025
1 parent 504ab4f commit 1187770
Showing 1 changed file with 76 additions and 0 deletions.
76 changes: 76 additions & 0 deletions css/css-values/attr-null-namespace.xhtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:nsfoo="http://nsfoo.org"
xmlns:nsbar="http://nsbar.org">
<head>
<title>CSS Values: attr() substitution with implicit null namespace</title>
<link rel="help" href="https://drafts.csswg.org/css-values-5/#attr-notation"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id="target"
nsfoo:data-x="value1"
nsbar:data-x="value2"
data-x="value3"

nsfoo:data-y="value4"
nsbar:data-y="value5">
Test
</div>
<style>
#target {
--x: attr(data-x type(*), fallback);
--y: attr(data-y type(*), fallback);
--z: attr(data-z type(*), fallback);
--w: attr(data-w type(*), fallback);
}
</style>
<script>
test(() => {
let e = document.getElementById("target");
assert_equals("value1", e.getAttributeNS("http://nsfoo.org", "data-x"));
assert_equals("value2", e.getAttributeNS("http://nsbar.org", "data-x"));
assert_equals("value3", e.getAttributeNS(null, "data-x"));

assert_equals("value4", e.getAttributeNS("http://nsfoo.org", "data-y"));
assert_equals("value5", e.getAttributeNS("http://nsbar.org", "data-y"));
assert_equals(null, e.getAttributeNS(null, "data-y"));
}, "Sanity check");

test(() => {
let e = document.getElementById("target");
assert_equals(getComputedStyle(e).getPropertyValue("--x"), "value3");
}, "Attribute in null-namespace is substituted");

test(() => {
let e = document.getElementById("target");
assert_equals(getComputedStyle(e).getPropertyValue("--y"), "fallback");
}, "Fallback is taken when attribute does not exist in null-namespace");

test((t) => {
let e = document.getElementById("target");
t.add_cleanup(() => {
e.removeAttributeNS("http://nsfoo.org", "data-z");
e.removeAttributeNS("http://nsbar.org", "data-z");
e.removeAttributeNS(null, "data-z");
});
e.setAttributeNS("http://nsfoo.org", "data-z", "value6");
e.setAttributeNS("http://nsbar.org", "data-z", "value7");
e.setAttributeNS(null, "data-z", "value8");
assert_equals(getComputedStyle(e).getPropertyValue("--z"), "value8");
}, "Attribute in null-namespace is substituted (JS)");

test((t) => {
let e = document.getElementById("target");
t.add_cleanup(() => {
e.removeAttributeNS("http://nsfoo.org", "data-w");
e.removeAttributeNS("http://nsbar.org", "data-w");
});
e.setAttributeNS("http://nsfoo.org", "data-w", "value9");
e.setAttributeNS("http://nsbar.org", "data-w", "value10");
assert_equals(getComputedStyle(e).getPropertyValue("--w"), "fallback");
}, "Fallback is taken when attribute does not does exist in null-namespace (JS)");
</script>
</body>
</html>

0 comments on commit 1187770

Please sign in to comment.