Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 18 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /css/css-values/attr-cycle.tentative.html - WPT Dashboard Interop Dashboard
<!DOCTYPE html>
<title>CSS Values and Units Test: attr</title>
<meta name="assert" content="test attr values">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="attr"></div>
<div id="expected"></div>
<script>
function test_attr_cycle(property, propertyValue, attrValue) {
var elem = document.getElementById("attr");
var expectedValue = window.getComputedStyle(elem).getPropertyValue(property);
elem.setAttribute("data-foo", attrValue);
elem.style.setProperty(property, propertyValue);
test(() => {
assert_equals(window.getComputedStyle(elem).getPropertyValue(property), expectedValue,
"Setting property \'" + property + "\' to the value \'" + propertyValue +
"\', where \'data-foo=" + attrValue + "\' should not change it's value.");
});
elem.style.setProperty(property, null);
}
function test_attr_no_cycle(property, propertyValue, attrValue, expectedValue) {
var elem = document.getElementById("attr");
elem.setAttribute("data-foo", attrValue);
elem.style.setProperty(property, propertyValue);
var expectedElem = document.getElementById("expected");
expectedElem.style.setProperty(property, expectedValue);
test(() => {
assert_equals(window.getComputedStyle(elem).getPropertyValue(property),
window.getComputedStyle(expectedElem).getPropertyValue(property),
"Value \'" + propertyValue + "\', where \'data-foo=" + attrValue +
"\' should be valid for the property \'" + property + "\'.");
});
elem.style.setProperty(property, null);
expectedElem.style.setProperty(property, null);
}
/* Simple cycle */
test_attr_cycle('--x', 'attr(data-foo type(<ident>))', 'attr(data-foo)');
test_attr_cycle('--x', 'attr(data-foo type(<length>))', 'attr(data-foo type(<length>))');
test_attr_cycle('--y', 'attr(data-foo type(*))', 'attr(data-foo type(*))');
var attrElem = document.getElementById("attr");
attrElem.setAttribute('data-bar', 'attr(data-foo)');
test_attr_cycle('--y', 'attr(data-foo type(*))', 'attr(data-bar type(*))');
attrElem.removeAttribute('data-bar');
/* Cycle with attr() and var() */
attrElem.style.setProperty('--x', 'attr(data-foo type(*))');
test_attr_cycle('--y', 'attr(data-foo type(*))', 'var(--x)');
attrElem.style.setProperty('--x', null);
attrElem.setAttribute('data-bar', 'var(--y)');
test_attr_cycle('--y', 'attr(data-foo type(<string>))', 'attr(data-bar type(<string>))');
attrElem.removeAttribute('data-bar');
attrElem.setAttribute('data-bar', 'var(--x)');
test_attr_cycle('--x', 'attr(data-foo type(*), attr(data-bar))', 'attr(data-foo type(*))');
attrElem.removeAttribute('data-bar');
attrElem.style.setProperty('--x', 'attr(data-foo type(*))');
attrElem.setAttribute('data-bar', 'var(--x)');
test_attr_cycle('--y', 'attr(data-foo type(*))', 'attr(data-bar type(*), 11) var(--x)');
attrElem.style.setProperty('--x', null);
attrElem.removeAttribute('data-bar');
/* Cycle with fallback */
test_attr_cycle('--x', 'attr(data-foo type(<length>), 11px)', 'attr(data-foo type(<length>))');
test_attr_cycle('--x', 'attr(data-foo type(<length>))', 'attr(data-foo type(<length>), 11px)');
test_attr_cycle('--y', 'attr(data-foo type(*), 11px)', 'attr(data-foo type(*))');
attrElem.setAttribute('data-bar', '11px');
test_attr_cycle('--x', 'attr(data-foo type(<length>), attr(data-bar type(<length>)))', 'attr(data-foo type(*))');
attrElem.removeAttribute('data-bar');
attrElem.setAttribute('data-bar', 'abc');
test_attr_cycle('--y', 'attr(data-foo type(*), attr(data-bar))', 'attr(data-foo type(*))');
attrElem.removeAttribute('data-bar');
/* Cycle with var() and fallback */
attrElem.style.setProperty('--x', 'var(--y)');
test_attr_cycle('--y', 'var(--x, 100)', 'var(--y)');
attrElem.style.setProperty('--x', null);
attrElem.setAttribute('data-bar', 'var(--y)');
attrElem.style.setProperty('--x', 'attr(data-foo)');
test_attr_cycle('--y', 'attr(data-foo type(*))', 'attr(data-bar type(*), 11) var(--x, 3)');
attrElem.style.setProperty('--x', null);
attrElem.removeAttribute('data-bar');
/* Cycle in fallback */
test_attr_cycle('--y', 'attr(data-foo type(*), var(--y))', '3');
test_attr_cycle('--y', 'attr(data-foo type(*), attr(data-foo))', '3');
attrElem.style.setProperty('--x', 'var(--y)');
test_attr_cycle('--y', 'attr(data-foo type(*), var(--x))', '3');
attrElem.style.setProperty('--x', null);
attrElem.setAttribute('data-bar', 'attr(data-foo type(*))');
test_attr_cycle('--y', 'attr(data-foo type(*), attr(data-bar type(*)))', '3');
attrElem.removeAttribute('data-bar');
/* No cycle, use raw CSS string without substitution */
attrElem.setAttribute('data-bar', 'var(--y)');
test_attr_no_cycle('--y', 'attr(data-foo type(<string>))', 'attr(data-bar type(<string>))', '');
attrElem.removeAttribute('data-bar');
attrElem.style.setProperty('--x', 'attr(data-foo)');
attrElem.setAttribute('data-bar', 'var(--x)');
test_attr_no_cycle('--y', 'attr(data-foo type(*))', 'attr(data-bar, 11) var(--x, 3)', '"var(--x)" "attr(data-bar, 11) var(--x, 3)"');
attrElem.removeAttribute('data-bar');
attrElem.style.setProperty('--x', null);
</script>