Skip to content

Commit

Permalink
Support new syntax of attr()
Browse files Browse the repository at this point in the history
Support attr()'s new syntax function according to CSS Values 5 spec [0]:

attr() = attr( <attr-name> <attr-type>? , <declaration-value>?)

This CL only implements the basic attr() support and does not include
security concerns handling, described in [1].

[0] https://drafts.csswg.org/css-values-5/#attr-notation
[1] w3c/csswg-drafts#5092

Bug: 40320391
Change-Id: I6703ea6a6e59cec7579dce0df6e411de238361f6
  • Loading branch information
tursunova authored and chromium-wpt-export-bot committed Jul 4, 2024
1 parent cbcca1c commit ad9e4f1
Showing 1 changed file with 153 additions and 0 deletions.
153 changes: 153 additions & 0 deletions css/css-values/attr-all-types.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<!DOCTYPE html>
<title>CSS Values and Units Test: attr</title>
<meta name="assert" content="test attr values">
<link rel="help" href="https://drafts.csswg.org/css-values-5/#attr-notations">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<html>
<body>
<div id="attr"></div>
<div id="expected"></div>
</body>
</html>

<script>
const dimensionTypeToUnits = {
"length": ["em", "ex", "cap", "ch", "ic", "rem", "lh", "rlh", "vw", "vh ", "vi", "vb", "vmin", "vmax"],
"angle": ["deg", "grad", "rad", "turn"],
"time": ["ms", "ms"],
"frequency": ["Hz", "kHz"],
"flex": ["fr"]
};
const dimensionTypeToProperty = {
"length": ["width"],
"angle": ["font-style"],
"time": ["transition-duration"],
"flex": ["grid-template-columns"]
}

function test_valid_attr(property, attrString, attrValue, expectedValue) {
var elem = document.getElementById("attr");
elem.setAttribute("data-foo", attrValue);
elem.style[property]= attrString;

var expectedElem = document.getElementById("expected");
expectedElem.style[property] = expectedValue;

test(() => {
assert_equals(window.getComputedStyle(elem).getPropertyValue(property),
window.getComputedStyle(expectedElem).getPropertyValue(property),
"Value \'" + attrString + "\', where \'data-foo=" + attrValue +
"\' should be valid for the property \'" + property + "\'.");
});

elem.style[property] = null;
expectedElem.style[property] = null;
}

function test_invalid_attr(property, attrString, attrValue) {
var elem = document.getElementById("attr");
var expectedValue = window.getComputedStyle(elem).getPropertyValue(property);

elem.setAttribute("data-foo", attrValue);
elem.style[property]= attrString;

test(() => {
assert_equals(window.getComputedStyle(elem).getPropertyValue(property), expectedValue,
"Setting property \'" + property + "\' to the value \'" + attrString +
"\', where \'data-foo=" + attrValue + "\' should not change it's value.");
});
elem.style[property] = null;
}

function test_dimension_types_and_units() {
for(const [type, units] of Object.entries(dimensionTypeToUnits)) {
const property = dimensionTypeToProperty[type];
const val = "3";
units.forEach(unit => {
const expectedValue = val + unit;

const dimensionTypeAttrString = 'attr(data-foo ' + type + ')';
test_valid_attr(property, dimensionTypeAttrString, expectedValue, expectedValue);

const dimensionUnitAttrString = 'attr(data-foo ' + unit + ')';
test_valid_attr(property, dimensionUnitAttrString, val, expectedValue);
});
}
}

test_valid_attr('content', 'attr(data-foo string)', 'abc', '"abc"');
test_valid_attr('content', 'attr(data-foo string)', 'attr(data-foo)', '"attr(data-foo)"');

test_valid_attr('background-color', 'attr(data-foo color)', 'red', 'red');
test_valid_attr('background-color', 'attr(data-foo color)', '#ff0099aa', '#ff0099aa');
test_valid_attr('background-color', 'attr(data-foo color, red)', '10', 'red');
test_valid_attr('background-color', 'attr(data-foo color, green)', '1000px', 'green');
test_valid_attr('background-color', 'attr(data-foo color, green)', 'rgb(255, 0, 0)', 'green');

test_valid_attr('font-weight', 'attr(data-foo number)', '10', '10');
test_valid_attr('font-weight', 'attr(data-foo number, 30)', '10px', '30');
test_valid_attr('font-weight', 'attr(data-foo number, calc(10 + 20))', '10px', '30');

test_valid_attr('font-size', 'attr(data-foo percentage)', '10%', '10%');
test_valid_attr('font-size', 'attr(data-foo percentage, 10px)', 'abc', '10px');
test_valid_attr('--x', 'attr(data-foo percentage, abc)', '10', 'abc');

test_valid_attr('width', 'attr(data-foo length)', '10px', '10px');
test_valid_attr('width', 'attr(data-foo length, red)', '10px', '10px');
test_valid_attr('width', 'attr(data-foo length, 42px)', 'calc(1px + 3px)', '42px');

test_valid_attr('font-style', 'attr(data-foo angle)', '10deg', '10deg');
test_valid_attr('font-style', 'attr(data-foo angle, 10deg)', '30', '10deg');
test_valid_attr('font-style', 'attr(data-foo angle, italic)', '30', 'italic');

test_valid_attr('transition-duration', 'attr(data-foo time)', '10ms', '10ms');
test_valid_attr('transition-duration', 'attr(data-foo time, 30s)', '10m', '30s');
test_valid_attr('transition-duration', 'attr(data-foo time, calc(10s + 20s))', '10m', '30s');

test_valid_attr('grid-template-columns', '30px attr(data-foo flex)', '1fr', '30px 1fr');
test_valid_attr('grid-template-columns', 'attr(data-foo flex, 3fr)', '1fr 1fr', '3fr');
test_valid_attr('grid-template-columns', 'attr(data-foo flex, calc(1px + 2px))', '10px', '3px');

test_valid_attr('height', 'attr(data-foo px)', '10', '10px');
test_valid_attr('width', 'calc(attr(data-foo px) + 1px)', '10', '11px');
test_valid_attr('--x', 'attr(data-foo px) 11px', '10', '10px 11px');

test_dimension_types_and_units();

test_invalid_attr('background-color', 'attr(data-foo color)', 'rgb(0 255 0)');
test_invalid_attr('background-color', 'attr(data-foo color)', 'color-mix(in lch, red, pink)');
test_invalid_attr('background-color', 'attr(data-foo color)', 'light-dark(#333b3c, #efefec)');
test_invalid_attr('background-color', 'attr(data-foo red)', 'abc');
test_invalid_attr('background-color', 'attr(data-foo, red)', 'abc');

test_invalid_attr('font-size', 'attr(data-foo number)', '10');
test_invalid_attr('font-weight', 'attr(data-foo number,)', '10');
test_invalid_attr('font-weight', 'attr(data-foo number)', 'calc(1 + 3)');

test_invalid_attr('font-size', 'attr(data-foo percentage)', 'abc');
test_invalid_attr('font-size', 'attr(data-foo percentage)', '10% a');
test_invalid_attr('font-size', 'attr(data-foo percentage, 10rad)', 'abc');

test_invalid_attr('width', 'attr(data-foo length)', '10');
test_invalid_attr('width', 'attr(data-foo length, 30)', 'calc(10 + 20)');
test_invalid_attr('width', 'attr(data-foo length, calc(10 + 20))', 'abc');

test_invalid_attr('font-style', 'attr(data-foo angle)', '10%');
test_invalid_attr('font-style', 'attr(data-foo angle)', 'calc(10px + 20px)');
test_invalid_attr('font-style', 'attr(data-foo angle, calc(10 + 20))', 'calc(10px + 20px)');

test_invalid_attr('transition-duration', 'attr(data-foo time)', '10');
test_invalid_attr('transition-duration', 'attr(data-foo time)', '10 ms');
test_invalid_attr('transition-duration', 'attr(data-foo time)', 'calc(1ms + 2ms)s');

test_invalid_attr('grid-template-columns', 'attr(data-foo flex)', '10px');
test_invalid_attr('grid-template-columns', 'attr(data-foo flex)', '"30fr"');
test_invalid_attr('grid-template-columns', 'attr(data-foo flex, calc(1deg + 2deg))', '10px');

test_invalid_attr('width', 'attr(data-foo px)', '10px');
test_invalid_attr('height', 'attr(data-foo fr)', '10');
test_invalid_attr('transition-duration', 'attr(data-foo ms)', '10px');
test_invalid_attr('transition-duration', 'attr(data-foo ms)', '10px foo');
</script>

0 comments on commit ad9e4f1

Please sign in to comment.