mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-15 14:02:20 +00:00
Tests: Import attr()-related WPT tests
This commit is contained in:
parent
72a7a18502
commit
5d1ba658c9
Notes:
github-actions[bot]
2025-07-16 13:49:19 +00:00
Author: https://github.com/AtkinsSJ
Commit: 5d1ba658c9
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5400
Reviewed-by: https://github.com/tcl3 ✅
24 changed files with 958 additions and 0 deletions
18
Tests/LibWeb/Crash/wpt-import/css/css-values/attr-crash.html
Normal file
18
Tests/LibWeb/Crash/wpt-import/css/css-values/attr-crash.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS Values and Units Test: attr</title>
|
||||
<meta name="assert" content="Test attr use after free crash">
|
||||
<link rel="help" href="https://crbug.com/365802556">
|
||||
<head>
|
||||
<style>
|
||||
#div {
|
||||
--prop: attr(data-foo type(<ident>));
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="div" data-foo="aaa123\aaa123aaa">Content</div>
|
||||
</body>
|
||||
<script>
|
||||
var elem = document.getElementById("div");
|
||||
getComputedStyle(elem).getPropertyValue("--prop");
|
||||
</script>
|
|
@ -0,0 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" href="https://crbug.com/405422528">
|
||||
<div data-crash="sibling-index()" style="width: attr(data-crash px)"></div>
|
||||
<div data-crash="sign(1em - 1px)" style="width: attr(data-crash px)"></div>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS Values Test: attr() in pseudo element ::slotted</title>
|
||||
<div class=host>
|
||||
<template shadowrootmode=open>
|
||||
<style>
|
||||
::slotted(div) {
|
||||
color: green;
|
||||
}
|
||||
</style>
|
||||
<slot></slot>
|
||||
</template>
|
||||
<div>PASS if green</div>
|
||||
</div>
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<style>
|
||||
#one::after {
|
||||
content: "Fallback value";
|
||||
}
|
||||
|
||||
#two::after {
|
||||
content: "Not fallback value";
|
||||
}
|
||||
|
||||
#three::after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
#four::after {
|
||||
content: "Not fallback value";
|
||||
}
|
||||
|
||||
#five::after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
#six::after {
|
||||
content: "";
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="one"></div>
|
||||
<div id="two"></div>
|
||||
<div id="three"></div>
|
||||
<div id="four"></div>
|
||||
<div id="five"></div>
|
||||
<div id="six"></div>
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>
|
||||
CSS Values and Units Test:
|
||||
Viewport units are interpolated correctly (reference rendering)
|
||||
</title>
|
||||
|
||||
<link
|
||||
rel="author"
|
||||
title="François REMY"
|
||||
href="mailto:fremycompany.developer@yahoo.fr"
|
||||
/ >
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
html, body { margin: 0px; padding: 0px; }
|
||||
|
||||
html { background: white; overflow: hidden; }
|
||||
#outer { position: relative; background: green; }
|
||||
|
||||
#outer { width: 200px; height: 200px; }
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="outer"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>
|
||||
CSS Values and Units Test:
|
||||
Attribute references (colors)
|
||||
</title>
|
||||
<meta name="assert" content="
|
||||
Invalid color values in referenced attributes are replaced by the fallback value
|
||||
" />
|
||||
|
||||
<link
|
||||
rel="author"
|
||||
title="François REMY"
|
||||
href="mailto:fremycompany.developer@yahoo.fr"
|
||||
/ >
|
||||
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/>
|
||||
|
||||
<link
|
||||
rel="match"
|
||||
href="../../../../expected/wpt-import/css/css-values/reference/200-200-green.html"
|
||||
/>
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
html, body { margin: 0px; padding: 0px; }
|
||||
|
||||
html { background: white; overflow: hidden; }
|
||||
#outer { position: relative; background: red; width: 200px; height: 200px; }
|
||||
|
||||
#outer { background: attr(data-test type(<color>), green); }
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="outer" data-test="qqffuutt"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS Values Test: attr() in pseudo element ::slotted</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-values/#attr-notation">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-values/attr-in-slotted-ref.html">
|
||||
<div class=host>
|
||||
<template shadowrootmode=open>
|
||||
<style>
|
||||
::slotted(div) {
|
||||
color: red;
|
||||
color: attr(data-color type(<color>), yellow);
|
||||
}
|
||||
</style>
|
||||
<slot data-color=blue></slot>
|
||||
</template>
|
||||
<div data-color=green>PASS if green</div>
|
||||
</div>
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>
|
||||
CSS Values and Units Test:
|
||||
Attribute references (length)
|
||||
</title>
|
||||
<meta name="assert" content="
|
||||
When the value of referenced attribute isn't a valid length, the fallback value is unsed instead.
|
||||
" />
|
||||
|
||||
<link
|
||||
rel="author"
|
||||
title="François REMY"
|
||||
href="mailto:fremycompany.developer@yahoo.fr"
|
||||
/ >
|
||||
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/>
|
||||
|
||||
<link
|
||||
rel="match"
|
||||
href="../../../../expected/wpt-import/css/css-values/reference/200-200-green.html"
|
||||
/>
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
html, body { margin: 0px; padding: 0px; }
|
||||
|
||||
html { background: white; overflow: hidden; }
|
||||
#outer { position: relative; background: green; }
|
||||
|
||||
#outer { width: attr(data-test type(<length>), 200px); height: 200px; }
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="outer" data-test="qqffuutt"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>
|
||||
CSS Values and Units Test:
|
||||
Attribute references (length)
|
||||
</title>
|
||||
<meta name="assert" content="
|
||||
The value of referenced attribute is used correctly as a length (even if it's 0).
|
||||
" />
|
||||
|
||||
<link
|
||||
rel="author"
|
||||
title="François REMY"
|
||||
href="mailto:fremycompany.developer@yahoo.fr"
|
||||
/ >
|
||||
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/>
|
||||
|
||||
<link
|
||||
rel="match"
|
||||
href="../../../../expected/wpt-import/css/css-values/reference/200-200-green.html"
|
||||
/>
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
html, body { margin: 0px; padding: 0px; }
|
||||
|
||||
html { background: white; overflow: hidden; }
|
||||
#outer { position: relative; background: green; }
|
||||
#outer2 { background: red; }
|
||||
|
||||
#outer { width: 200px; height: 200px; }
|
||||
#outer2 { width: 200px; width: attr(data-test type(<length>), 0); height: 200px; }
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="outer"></div>
|
||||
<div id="outer2" data-test="0"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-values-5/#attr-notation">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-values/attr-notype-fallback-ref.html">
|
||||
<style>
|
||||
#one::after {
|
||||
content: attr(does-not-exist, "Fallback value");
|
||||
}
|
||||
|
||||
#two::after {
|
||||
content: attr(does-exist, "Fallback value");
|
||||
}
|
||||
|
||||
#three::after {
|
||||
content: attr(does-not-exist, invalid);
|
||||
}
|
||||
|
||||
#four::after {
|
||||
content: attr(does-exist, invalid);
|
||||
}
|
||||
|
||||
#five::after {
|
||||
content: attr(does-exist, "Fallback value");
|
||||
}
|
||||
|
||||
#six::after {
|
||||
content: attr(does-exist, "Fallback value");
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="one"></div>
|
||||
<div id="two" does-exist="Not fallback value"></div>
|
||||
<div id="three"></div>
|
||||
<div id="four" does-exist="Not fallback value"></div>
|
||||
<div id="five" does-exist=""></div>
|
||||
<div id="six" does-exist></div>
|
|
@ -0,0 +1,6 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Pass CSS Values Test: attr() IACVT
|
|
@ -0,0 +1,6 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Fail
|
||||
Fail style query should implement to true
|
|
@ -0,0 +1,28 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 22 tests
|
||||
|
||||
2 Pass
|
||||
20 Fail
|
||||
Fail CSS Values and Units Test: attr
|
||||
Fail CSS Values and Units Test: attr 1
|
||||
Fail CSS Values and Units Test: attr 2
|
||||
Fail CSS Values and Units Test: attr 3
|
||||
Fail CSS Values and Units Test: attr 4
|
||||
Fail CSS Values and Units Test: attr 5
|
||||
Fail CSS Values and Units Test: attr 6
|
||||
Fail CSS Values and Units Test: attr 7
|
||||
Fail CSS Values and Units Test: attr 8
|
||||
Fail CSS Values and Units Test: attr 9
|
||||
Fail CSS Values and Units Test: attr 10
|
||||
Fail CSS Values and Units Test: attr 11
|
||||
Fail CSS Values and Units Test: attr 12
|
||||
Pass CSS Values and Units Test: attr 13
|
||||
Fail CSS Values and Units Test: attr 14
|
||||
Fail CSS Values and Units Test: attr 15
|
||||
Fail CSS Values and Units Test: attr 16
|
||||
Fail CSS Values and Units Test: attr 17
|
||||
Fail CSS Values and Units Test: attr 18
|
||||
Pass CSS Values and Units Test: attr 19
|
||||
Fail CSS Values and Units Test: attr 20
|
||||
Fail CSS Values and Units Test: attr 21
|
|
@ -0,0 +1,6 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Fail
|
||||
Fail CSS Values and Units Test: attr() invalidation
|
|
@ -0,0 +1,11 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 5 tests
|
||||
|
||||
1 Pass
|
||||
4 Fail
|
||||
Pass Sanity check
|
||||
Fail Attribute in null-namespace is substituted
|
||||
Fail Fallback is taken when attribute does not exist in null-namespace
|
||||
Fail Attribute in null-namespace is substituted (JS)
|
||||
Fail Fallback is taken when attribute does not does exist in null-namespace (JS)
|
|
@ -0,0 +1,28 @@
|
|||
Harness status: Error
|
||||
|
||||
Found 22 tests
|
||||
|
||||
14 Pass
|
||||
8 Fail
|
||||
Pass '--x: image-set(attr(data-foo))' with data-foo="https://does-not-exist.test/404.png"
|
||||
Pass 'background-image: image-set(attr(data-foo))' with data-foo="https://does-not-exist.test/404.png"
|
||||
Fail 'background-image: image-set("https://does-not-exist.test/404.png")' with data-foo="https://does-not-exist.test/404.png"
|
||||
Pass '--x: src(attr(data-foo))' with data-foo="https://does-not-exist.test/404.png"
|
||||
Fail 'background-image: src(attr(data-foo))' with data-foo="https://does-not-exist.test/404.png"
|
||||
Fail 'background-image: src("https://does-not-exist.test/404.png")' with data-foo="https://does-not-exist.test/404.png"
|
||||
Pass '--x: src(string("https://does-not-exist.test" attr(data-foo)))' with data-foo="/404.png"
|
||||
Pass 'background-image: src(string("https://does-not-exist.test" attr(data-foo)))' with data-foo="/404.png"
|
||||
Fail 'background-image: src(string("https://does-not-exist.test/""404.png"))' with data-foo="/404.png"
|
||||
Fail '--x: attr(data-foo type(<url>))' with data-foo="url(https://does-not-exist.test/404.png)"
|
||||
Pass 'background-image: attr(data-foo type(<url>))' with data-foo="url(https://does-not-exist.test/404.png)"
|
||||
Pass 'background-image: url("https://does-not-exist.test/404.png")' with data-foo="url(https://does-not-exist.test/404.png)"
|
||||
Pass '--x: image(attr(data-foo))' with data-foo="https://does-not-exist.test/404.png"
|
||||
Pass 'background-image: image(attr(data-foo))' with data-foo="https://does-not-exist.test/404.png"
|
||||
Fail 'background-image: image("https://does-not-exist.test/404.png")' with data-foo="https://does-not-exist.test/404.png"
|
||||
Fail 'background-image: url(https://does-not-exist.test/404.png), attr(data-foo type(<image>))' with data-foo="linear-gradient(#000000, #ffffff)"
|
||||
Fail '--x: image-set(var(--y, attr(data-foo)))' with data-foo="https://does-not-exist.test/404.png"
|
||||
Pass 'background-image: image-set(var(--y, attr(data-foo)))' with data-foo="https://does-not-exist.test/404.png"
|
||||
Pass '--x: image-set(var(--some-string))' with data-foo="https://does-not-exist.test/404.png"
|
||||
Pass 'background-image: image-set(var(--some-string))' with data-foo="https://does-not-exist.test/404.png"
|
||||
Pass '--x: image-set(var(--some-string-list))' with data-foo="https://does-not-exist.test/404.png"
|
||||
Pass 'background-image: image-set(var(--some-string-list))' with data-foo="https://does-not-exist.test/404.png"
|
|
@ -0,0 +1,6 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Pass CSS Values and Units Test: attr() security limitations in universal selector
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS Values Test: attr() IACVT</title>
|
||||
<meta name="assert" content="Fail to substitute attr() should be IACVT.">
|
||||
<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>
|
||||
<style>
|
||||
#expected {
|
||||
background-color: red;
|
||||
}
|
||||
#test {
|
||||
background-color: red;
|
||||
background-color: attr(data-color type(<color>));
|
||||
}
|
||||
</style>
|
||||
<div id="test" data-color=333></div>
|
||||
<div id="expected"></div>
|
||||
|
||||
<script>
|
||||
var elem = document.getElementById("test");
|
||||
var value = window.getComputedStyle(elem).getPropertyValue("background-color");
|
||||
|
||||
var expected_elem = document.getElementById("expected");
|
||||
var expected_value = window.getComputedStyle(expected_elem).getPropertyValue("background-color");
|
||||
test(() => {
|
||||
assert_not_equals(value, expected_value);
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS Values and Units Test: attr() in container style queries</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-conditional-5/#container-queries">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
#container {
|
||||
--foo: bar;
|
||||
}
|
||||
@container style(--foo: attr(data-foo type(<custom-ident>))) {
|
||||
#target { color: green; }
|
||||
}
|
||||
</style>
|
||||
<div id="container" data-foo="bar">
|
||||
<div id="target">Should be green</div>
|
||||
</div>
|
||||
<script>
|
||||
test(() => {
|
||||
assert_equals(getComputedStyle(target).color, "rgb(0, 128, 0)");
|
||||
}, "style query should implement to true");
|
||||
</script>
|
|
@ -0,0 +1,124 @@
|
|||
<!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>
|
||||
|
||||
<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 unused fallbacks */
|
||||
test_attr_no_cycle('--y', 'attr(data-foo type(*), var(--y))', '3', '3');
|
||||
test_attr_no_cycle('--y', 'attr(data-foo type(*), attr(data-foo))', '3', '3');
|
||||
|
||||
attrElem.style.setProperty('--x', 'var(--y)');
|
||||
test_attr_no_cycle('--y', 'attr(data-foo type(*), var(--x))', '3', '3');
|
||||
attrElem.style.setProperty('--x', null);
|
||||
|
||||
attrElem.setAttribute('data-bar', 'attr(data-foo type(*))');
|
||||
test_attr_no_cycle('--y', 'attr(data-foo type(*), attr(data-bar type(*)))', '3', '3');
|
||||
attrElem.removeAttribute('data-bar');
|
||||
|
||||
/* Cycle in fallback */
|
||||
test_attr_cycle('--y', 'attr(data-unknown type(*), var(--y))', '3');
|
||||
|
||||
/* 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>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS Values and Units Test: attr() invalidation</title>
|
||||
<meta name="assert" content="Test attr() invalidation">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-values/#attr-notation">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
div {
|
||||
width: attr(data-foo type(<length>));
|
||||
}
|
||||
</style>
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<div id="div" data-foo="10px"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script>
|
||||
setup({ single_test: true });
|
||||
let elem = document.getElementById("div");
|
||||
let old_width = window.getComputedStyle(elem).getPropertyValue("width");
|
||||
elem.setAttribute("data-foo", "30px");
|
||||
let new_width = window.getComputedStyle(elem).getPropertyValue("width");
|
||||
assert_not_equals(new_width, old_width);
|
||||
done();
|
||||
</script>
|
|
@ -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,0 +1,272 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS Values and Units Test: attr() security limitations</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-values-5/#attr-security">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
|
||||
<style>
|
||||
@property --some-string {
|
||||
syntax: "<string>";
|
||||
inherits: false;
|
||||
initial-value: "empty";
|
||||
}
|
||||
@property --some-string-list {
|
||||
syntax: "<string>+";
|
||||
inherits: false;
|
||||
initial-value: "empty";
|
||||
}
|
||||
div {
|
||||
--condition-val: 3;
|
||||
--str: text;
|
||||
--true: true;
|
||||
--some-string: attr(data-foo);
|
||||
--some-string-list: "https://does-not-exist2.test/404.png" attr(data-foo);
|
||||
--some-other-url: attr(data-foo);
|
||||
--image-set-valid: url("https://does-not-exist.test/404.png") type(attr(data-foo));
|
||||
--image-set-invalid: attr(data-foo type(<url>)) 1x;
|
||||
}
|
||||
</style>
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<div id="attr"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script>
|
||||
function test_attr(property, attrString, attrValue, expectedValue) {
|
||||
var elem = document.getElementById("attr");
|
||||
elem.setAttribute("data-foo", attrValue);
|
||||
elem.style.setProperty(property, attrString);
|
||||
|
||||
test(() => {
|
||||
assert_equals(window.getComputedStyle(elem).getPropertyValue(property),
|
||||
expectedValue);
|
||||
}, `'${property}: ${attrString}' with data-foo="${attrValue}"`);
|
||||
|
||||
elem.style.setProperty(property, null);
|
||||
}
|
||||
|
||||
function test_registered_custom_property(customPropertyName, customPropertySyntax, customPropertyInitialValue,
|
||||
attrValue, expectedValue) {
|
||||
window.CSS.registerProperty({
|
||||
name: customPropertyName,
|
||||
syntax: customPropertySyntax,
|
||||
inherits: false,
|
||||
initialValue: customPropertyInitialValue,
|
||||
});
|
||||
var elem = document.getElementById("attr");
|
||||
elem.setAttribute("data-foo", attrValue);
|
||||
var attrString = "attr(data-foo type(" + customPropertySyntax + "))";
|
||||
elem.style.setProperty(customPropertyName, attrString);
|
||||
test(() => {
|
||||
assert_equals(window.getComputedStyle(elem).getPropertyValue(customPropertyName),
|
||||
expectedValue);
|
||||
}, `'${customPropertyName}: ${attrString}' with data-foo="${attrValue}"`);
|
||||
elem.style.setProperty(customPropertyName, null);
|
||||
}
|
||||
|
||||
// Direct use.
|
||||
test_attr('--x',
|
||||
'image-set(attr(data-foo))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'image-set("https://does-not-exist.test/404.png")');
|
||||
test_attr('background-image',
|
||||
'image-set(attr(data-foo))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'none');
|
||||
test_attr('background-image',
|
||||
'image-set("https://does-not-exist.test/404.png")',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'image-set(url("https://does-not-exist.test/404.png") 1dppx)');
|
||||
|
||||
test_attr('--x',
|
||||
'src(attr(data-foo))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'src("https://does-not-exist.test/404.png")');
|
||||
test_attr('background-image',
|
||||
'src(attr(data-foo))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'none');
|
||||
test_attr('background-image',
|
||||
'src("https://does-not-exist.test/404.png")',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'src(url("https://does-not-exist.test/404.png"))');
|
||||
|
||||
// The following string() function is under discussion in the working group and does not exist yet.
|
||||
test_attr('--x',
|
||||
'src(string("https://does-not-exist.test" attr(data-foo)))',
|
||||
'/404.png',
|
||||
'src(string("https://does-not-exist.test" "/404.png"))');
|
||||
test_attr('background-image',
|
||||
'src(string("https://does-not-exist.test" attr(data-foo)))',
|
||||
'/404.png',
|
||||
'none');
|
||||
test_attr('background-image',
|
||||
'src(string("https://does-not-exist.test/""404.png"))',
|
||||
'/404.png',
|
||||
'src(url("https://does-not-exist.test/404.png"))');
|
||||
|
||||
test_attr('--x',
|
||||
'attr(data-foo type(<url>))',
|
||||
'url(https://does-not-exist.test/404.png)',
|
||||
'url("https://does-not-exist.test/404.png")');
|
||||
test_attr('background-image',
|
||||
'attr(data-foo type(<url>))',
|
||||
'url(https://does-not-exist.test/404.png)',
|
||||
'none');
|
||||
test_attr('background-image',
|
||||
'url("https://does-not-exist.test/404.png")',
|
||||
'url(https://does-not-exist.test/404.png)',
|
||||
'url("https://does-not-exist.test/404.png")');
|
||||
|
||||
test_attr('--x',
|
||||
'image(attr(data-foo))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'image("https://does-not-exist.test/404.png")');
|
||||
test_attr('background-image',
|
||||
'image(attr(data-foo))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'none');
|
||||
test_attr('background-image',
|
||||
'image("https://does-not-exist.test/404.png")',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'image(url("https://does-not-exist.test/404.png"))');
|
||||
|
||||
test_attr('background-image',
|
||||
'url(https://does-not-exist.test/404.png), attr(data-foo type(<image>))',
|
||||
'linear-gradient(#000000, #ffffff)',
|
||||
'url("https://does-not-exist.test/404.png"), linear-gradient(rgb(0, 0, 0), rgb(255, 255, 255))');
|
||||
|
||||
// The remaining tests use image-set(), but should be equivalent for image() etc.
|
||||
|
||||
// Test in a fallback.
|
||||
test_attr('--x',
|
||||
'image-set(var(--y, attr(data-foo)))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'image-set("https://does-not-exist.test/404.png")');
|
||||
test_attr('background-image',
|
||||
'image-set(var(--y, attr(data-foo)))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'none');
|
||||
|
||||
// Test via a registered custom property.
|
||||
test_attr('--x',
|
||||
'image-set(var(--some-string))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'image-set("https://does-not-exist.test/404.png")');
|
||||
test_attr('background-image',
|
||||
'image-set(var(--some-string))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'none');
|
||||
|
||||
// Test via a registered custom property (list).
|
||||
test_attr('--x',
|
||||
'image-set(var(--some-string-list))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'image-set("https://does-not-exist2.test/404.png" "https://does-not-exist.test/404.png")');
|
||||
test_attr('background-image',
|
||||
'image-set(var(--some-string-list))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'none');
|
||||
test_registered_custom_property('--registered-url', '<url>', 'url("https://does-not-exist.test/empty-url")', 'https://does-not-exist.test/404.png', 'url("https://does-not-exist.test/empty-url")');
|
||||
test_registered_custom_property('--registered-color', '<color>', 'red', 'blue', 'rgb(0, 0, 255)');
|
||||
|
||||
// Test via a non-registered custom property.
|
||||
test_attr('--x',
|
||||
'image-set(var(--some-other-url))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'image-set("https://does-not-exist.test/404.png")');
|
||||
test_attr('background-image',
|
||||
'image-set(var(--some-other-url))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'none');
|
||||
|
||||
// Test multiple token substitution
|
||||
test_attr('background-image',
|
||||
'attr(data-foo type(*))',
|
||||
'url(https://does-not-exist.test/404.png), linear-gradient(black, white)',
|
||||
'none');
|
||||
|
||||
// Test total attr()-tainting for substitution values
|
||||
test_attr('background-image',
|
||||
'image-set(var(--image-set-valid))',
|
||||
'image/jpeg',
|
||||
'none');
|
||||
test_attr('background-image',
|
||||
'image-set(var(--image-set-invalid))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'none');
|
||||
|
||||
// Test attr-tainting carries through if() function.
|
||||
test_attr('--x',
|
||||
'image-set(if(style(--true): attr(data-foo);))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'image-set("https://does-not-exist.test/404.png")');
|
||||
test_attr('background-image',
|
||||
'image-set(if(style(--true): attr(data-foo);))',
|
||||
'https://does-not-exist.test/404.png',
|
||||
'none');
|
||||
test_attr('background-image',
|
||||
`image-set(
|
||||
if(style(--true): url(https://does-not-exist-2.test/404.png);
|
||||
else: attr(data-foo);))`,
|
||||
'https://does-not-exist-2.test/404.png',
|
||||
'image-set(url("https://does-not-exist-2.test/404.png") 1dppx)');
|
||||
test_attr('background-image',
|
||||
`image-set(
|
||||
if(style(--some-string): url(https://does-not-exist.test/404.png);))`,
|
||||
'https://does-not-exist.test/404.png',
|
||||
'none');
|
||||
test_attr('background-image',
|
||||
`image-set(
|
||||
if(style(--condition-val: attr(data-foo type(*))): url(https://does-not-exist.test/404.png);))`,
|
||||
'3',
|
||||
'none');
|
||||
test_attr('background-image',
|
||||
`image-set(
|
||||
if(style(--condition-val: attr(data-foo type(*))): url(https://does-not-exist.test/404.png);
|
||||
style(--true): url(https://does-not-exist.test/404.png);
|
||||
else: url(https://does-not-exist.test/404.png);))`,
|
||||
'1',
|
||||
'none');
|
||||
test_attr('background-image',
|
||||
`image-set(if(style(--true): url(https://does-not-exist.test/404.png);
|
||||
style(--condition-val): url(https://does-not-exist.test/404.png);
|
||||
else: url(https://does-not-exist.test/404.png);))`,
|
||||
'attr(data-foo type(*))',
|
||||
'image-set(url("https://does-not-exist.test/404.png") 1dppx)');
|
||||
test_attr('background-image',
|
||||
`image-set(
|
||||
if(style(--condition-val: if(style(--true): attr(data-foo type(*));)): url(https://does-not-exist.test/404.png);))`,
|
||||
'3',
|
||||
'none');
|
||||
test_attr('--x',
|
||||
`image-set(if(style(--condition-val: if(style(--true): attr(data-foo type(*));)): url(https://does-not-exist.test/404.png);))`,
|
||||
'3',
|
||||
'image-set(url(https://does-not-exist.test/404.png))');
|
||||
test_attr('--x',
|
||||
`image-set(if(style(--condition-val >= attr(data-foo type(*))): url(https://does-not-exist.test/404.png);))`,
|
||||
'3',
|
||||
'image-set(url(https://does-not-exist.test/404.png))');
|
||||
test_attr('background-image',
|
||||
`image-set(
|
||||
if(style(--condition-val >= attr(data-foo type(*))): url(https://does-not-exist.test/404.png);))`,
|
||||
'3',
|
||||
'none');
|
||||
test_attr('background-image',
|
||||
`image-set(
|
||||
if(style(--condition-val < attr(data-foo type(*))): url(https://does-not-exist.test/404.png);))`,
|
||||
'3',
|
||||
'none');
|
||||
test_attr('background-image',
|
||||
`image-set(
|
||||
if(style(--str < attr(data-foo type(*))): url(https://does-not-exist.test/404.png);))`,
|
||||
'3',
|
||||
'none');
|
||||
test_attr('background-image',
|
||||
`image-set(
|
||||
if(style(--condition-val < attr(data-foo type(*))): url(https://does-not-exist.test/404.png);))`,
|
||||
'text',
|
||||
'none');
|
||||
</script>
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS Values and Units Test: attr() security limitations in universal selector </title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-values-5/#attr-security">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
|
||||
<style>
|
||||
@property --some-string {
|
||||
syntax: "<string>";
|
||||
inherits: true;
|
||||
initial-value: "empty";
|
||||
}
|
||||
* {
|
||||
--some-string: "https://does-not-exist.test/404.png";
|
||||
}
|
||||
div {
|
||||
--some-string: attr(data-foo);
|
||||
background-image: image-set(var(--some-string));
|
||||
}
|
||||
</style>
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<div id="attr" data-foo="https://does-not-exist.test/404.png"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script>
|
||||
var elem = document.getElementById("attr");
|
||||
test(() => {
|
||||
assert_equals(window.getComputedStyle(elem).getPropertyValue('background-image'),
|
||||
'none',
|
||||
"'background-image: attr(data-foo)' with data-foo='https://does-not-exist.test/404.png'");
|
||||
});
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue