diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/css/css-nesting | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/css/css-nesting')
19 files changed, 823 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/css-nesting/conditional-properties-ref.html b/testing/web-platform/tests/css/css-nesting/conditional-properties-ref.html new file mode 100644 index 0000000000..0285acbf33 --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/conditional-properties-ref.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<title>Properties in nested conditional rules</title> +<link rel="author" title="Adam Argyle" href="mailto:argyle@google.com"> +<link rel="help" href="https://drafts.csswg.org/css-nesting-1/"> +<style> + .test { + background-color: red; + width: 100px; + height: 100px; + display: grid; + } + + @media (min-width: 50px) { + .test-5 > div { + background-color: green; + } + } + + @supports (display: grid) { + .test-10 { + background-color: green; + } + } + + body * + * { + margin-top: 8px; + } +</style> +<body> + <p>Tests pass if <strong>block is green</strong></p> + <div class="test test-5"><div></div></div> + <div class="test test-10"><div></div></div> +</body> diff --git a/testing/web-platform/tests/css/css-nesting/conditional-properties.html b/testing/web-platform/tests/css/css-nesting/conditional-properties.html new file mode 100644 index 0000000000..122b8635c1 --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/conditional-properties.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<title>Properties in nested conditional rules</title> +<link rel="author" title="Adam Argyle" href="mailto:argyle@google.com"> +<link rel="help" href="https://drafts.csswg.org/css-nesting-1/"> +<link rel="match" href="conditional-properties-ref.html"> +<style> + .test { + background-color: red; + width: 100px; + height: 100px; + display: grid; + } + + .test-5 { + @media (min-width: 50px) { + background-color: green; + } + } + + .test-10 { + @supports (display: grid) { + background-color: green; + } + } + + body * + * { + margin-top: 8px; + } +</style> +<body> + <p>Tests pass if <strong>block is green</strong></p> + <div class="test test-5"><div></div></div> + <div class="test test-10"><div></div></div> +</body> diff --git a/testing/web-platform/tests/css/css-nesting/conditional-rules-ref.html b/testing/web-platform/tests/css/css-nesting/conditional-rules-ref.html new file mode 100644 index 0000000000..945ed30513 --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/conditional-rules-ref.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<title>Conditional rules with nesting</title> +<link rel="author" title="Adam Argyle" href="mailto:argyle@google.com"> +<link rel="help" href="https://drafts.csswg.org/css-nesting-1/"> +<style> + .test { + background-color: red; + width: 100px; + height: 100px; + display: grid; + } + + @media (min-width: 50px) { + .test-5 > div { + background-color: green; + } + } + + @supports (display: grid) { + .test-10 { + background-color: green; + } + } + + body * + * { + margin-top: 8px; + } +</style> +<body> + <p>Tests pass if <strong>block is green</strong></p> + <div class="test test-5"><div></div></div> + <div class="test test-10"><div></div></div> +</body> diff --git a/testing/web-platform/tests/css/css-nesting/conditional-rules.html b/testing/web-platform/tests/css/css-nesting/conditional-rules.html new file mode 100644 index 0000000000..be925d5d87 --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/conditional-rules.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<title>Conditional rules with nesting</title> +<link rel="author" title="Adam Argyle" href="mailto:argyle@google.com"> +<link rel="help" href="https://drafts.csswg.org/css-nesting-1/"> +<link rel="match" href="conditional-rules-ref.html"> +<style> + .test { + background-color: red; + width: 100px; + height: 100px; + display: grid; + } + + .test-5 { + @media (min-width: 50px) { + & { + background-color: green; + } + } + } + + .test-10 { + @supports (display: grid) { + & { + background-color: green; + } + } + } + + body * + * { + margin-top: 8px; + } +</style> +<body> + <p>Tests pass if <strong>block is green</strong></p> + <div class="test test-5"><div></div></div> + <div class="test test-10"><div></div></div> +</body> diff --git a/testing/web-platform/tests/css/css-nesting/cssom.html b/testing/web-platform/tests/css/css-nesting/cssom.html new file mode 100644 index 0000000000..c7150cec5d --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/cssom.html @@ -0,0 +1,127 @@ +<!doctype html> +<title>Simple CSSOM manipulation of subrules</title> +<link rel="author" title="Steinar H. Gunderson" href="mailto:sesse@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-nesting-1/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style id="ss"></style> + +<script> + test(() => { + let [ss] = document.styleSheets; + assert_equals(ss.cssRules.length, 0); + ss.insertRule('.a { color: red; }'); + assert_equals(ss.cssRules.length, 1); + assert_equals(ss.cssRules[0].cssText, '.a { color: red; }'); + + // Test inserting sub-cssRules, at various positions. + ss.cssRules[0].insertRule('& .b { color: green; }'); + ss.cssRules[0].insertRule('& .c { color: blue; }', 1); + ss.cssRules[0].insertRule('& .d { color: hotpink; }', 1); + assert_equals(ss.cssRules[0].cssText, +`.a { + color: red; + & .b { color: green; } + & .d { color: hotpink; } + & .c { color: blue; } +}`, 'inserting should work'); + + // Test deleting a rule. + ss.cssRules[0].deleteRule(1); + assert_equals(ss.cssRules[0].cssText, +`.a { + color: red; + & .b { color: green; } + & .c { color: blue; } +}`, 'deleting should work'); + }); + + // Test that out-of-bounds throws exceptions and does not affect the stylesheet. + const sampleSheetText = +`.a { + color: red; + & .b { color: green; } + & .c { color: blue; } +}`; + + test(() => { + document.getElementById('ss').innerHTML = sampleSheetText; + let [ss] = document.styleSheets; + assert_throws_dom('IndexSizeError', () => { ss.cssRules[0].insertRule('& .broken {}', 3); }); + assert_equals(ss.cssRules[0].cssText, sampleSheetText, 'unchanged after no-insert'); + }); + + test(() => { + document.getElementById('ss').innerHTML = sampleSheetText; + let [ss] = document.styleSheets; + assert_throws_dom('IndexSizeError', () => { ss.cssRules[0].insertRule('& .broken {}', -1); }); + assert_equals(ss.cssRules[0].cssText, sampleSheetText, 'unchanged after no-insert'); + }); + + test(() => { + document.getElementById('ss').innerHTML = sampleSheetText; + let [ss] = document.styleSheets; + assert_throws_dom('IndexSizeError', () => { ss.cssRules[0].deleteRule(5); }); + assert_equals(ss.cssRules[0].cssText, sampleSheetText, 'unchanged after no-delete'); + }); + + test(() => { + document.getElementById('ss').innerHTML = sampleSheetText; + let [ss] = document.styleSheets; + assert_equals(ss.cssRules[0].cssRules[2], undefined, 'subscript out-of-bounds returns undefined'); + assert_equals(ss.cssRules[0].cssRules.item(2), null, 'item() out-of-bounds returns null'); + assert_equals(ss.cssRules[0].cssText, sampleSheetText, 'unchanged after no-access'); + }); + + // Test that inserting an invalid rule throws an exception. + test(() => { + document.getElementById('ss').innerHTML = sampleSheetText; + let [ss] = document.styleSheets; + let exception; + assert_throws_dom('SyntaxError', () => { ss.cssRules[0].insertRule('% {}'); }); + assert_equals(ss.cssRules[0].cssText, sampleSheetText, 'unchanged after invalid rule'); + }); + + // Test that we can get out single rule through .cssRules. + test(() => { + document.getElementById('ss').innerHTML = sampleSheetText; + let [ss] = document.styleSheets; + assert_equals(ss.cssRules[0].cssRules[1].cssText, '& .c { color: blue; }'); + }); + + // Test that we can insert a @supports rule, that it serializes in the right place + // and has the right parent. Note that the indentation is broken per-spec. + test(() => { + document.getElementById('ss').innerHTML = sampleSheetText; + let [ss] = document.styleSheets; + ss.cssRules[0].insertRule('@supports selector(&) { & div { font-size: 10px; }}', 1); + assert_equals(ss.cssRules[0].cssText, +`.a { + color: red; + & .b { color: green; } + @supports selector(&) { + & div { font-size: 10px; } +} + & .c { color: blue; } +}`, '@supports is added'); + + assert_equals(ss.cssRules[0].cssRules[1].parentRule, ss.cssRules[0]); + ss.cssRules[0].deleteRule(1); + assert_equals(ss.cssRules[0].cssText, sampleSheetText); + }); + + // Nested rules are not part of declaration lists, and thus should not + // be possible to insert with .style. + test(() => { + document.getElementById('ss').innerHTML = sampleSheetText; + let [ss] = document.styleSheets; + ss.cssRules[0].style = 'color: olivedrab; &.d { color: peru; }'; + assert_equals(ss.cssRules[0].cssText, +`.a { + color: olivedrab; + & .b { color: green; } + & .c { color: blue; } +}`, 'color is changed, new rule is ignored'); + }); +</script> diff --git a/testing/web-platform/tests/css/css-nesting/delete-other-rule-crash.html b/testing/web-platform/tests/css/css-nesting/delete-other-rule-crash.html new file mode 100644 index 0000000000..bde7c554e8 --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/delete-other-rule-crash.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<body> +<title>Crash with lazy parsing child rules and stylesheet copy-on-write</title> +<link rel="help" href="https://crbug.com/1404879"> +<link href="../support/delete-other-rule-crash.css" rel="stylesheet"> +<script src="/common/gc.js"></script> +<script> +addEventListener('DOMContentLoaded', async () => { + requestAnimationFrame(async () => { + document.styleSheets[0].deleteRule(0); + await garbageCollect(); + document.styleSheets[0].cssRules[0].cssText; + }); +}); +</script> diff --git a/testing/web-platform/tests/css/css-nesting/implicit-nesting-ref.html b/testing/web-platform/tests/css/css-nesting/implicit-nesting-ref.html new file mode 100644 index 0000000000..006216b60e --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/implicit-nesting-ref.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<title>Implicit nesting</title> +<link rel="author" title="Steinar H. Gunderson" href="mailto:sesse@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-nesting-1/"> +<style> + .test { + background-color: green; + width: 100px; + height: 100px; + display: grid; + } + + body * + * { + margin-top: 8px; + } +</style> +<body> + <p>Tests pass if <strong>block is green</strong></p> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> +</body> diff --git a/testing/web-platform/tests/css/css-nesting/implicit-nesting.html b/testing/web-platform/tests/css/css-nesting/implicit-nesting.html new file mode 100644 index 0000000000..05b9e04fa8 --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/implicit-nesting.html @@ -0,0 +1,61 @@ +<!DOCTYPE html> +<title>Implicit nesting</title> +<link rel="author" title="Steinar H. Gunderson" href="mailto:sesse@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-nesting-1/"> +<link rel="match" href="implicit-nesting-ref.html"> +<style> + .test { + background-color: red; + width: 100px; + height: 100px; + display: grid; + } + + .test-1 { + > div { + background-color: green; + } + } + + .test-2 { + .test-2-child { + background-color: green; + } + } + .test-2-child { + background-color: red; + } + + .test-3-child { + background-color: red; + } + .test-3-child { + .test-3 & { + background-color: green; + } + } + + .test-4 { + :is(&) { + background-color: green; + } + } + + .test { + :is(.test-5, &.does-not-exist) { + background-color: green; + } + } + + body * + * { + margin-top: 8px; + } +</style> +<body> + <p>Tests pass if <strong>block is green</strong></p> + <div class="test test-1"><div></div></div> + <div class="test test-2"><div class="test-2-child"></div></div> + <div class="test test-3"><div class="test-3-child"></div></div> + <div class="test test-4"></div> + <div class="test test-5"></div> +</body> diff --git a/testing/web-platform/tests/css/css-nesting/implicit-parent-insertion-crash.html b/testing/web-platform/tests/css/css-nesting/implicit-parent-insertion-crash.html new file mode 100644 index 0000000000..4be1e1c8f9 --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/implicit-parent-insertion-crash.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<body> +<title>Use-after-free when inserting implicit parent selector</title> +<link rel="help" href="https://crbug.com/1380313"> +<style> +:root { + :lang(en), :lang(en) { + } +} +</style> +<div lang="en"></div> +<script> + // Allocate a large chunk of memory, to trigger a GC. + new Int32Array(536870911); +</script> + diff --git a/testing/web-platform/tests/css/css-nesting/invalid-inner-rules.html b/testing/web-platform/tests/css/css-nesting/invalid-inner-rules.html new file mode 100644 index 0000000000..219dcac3f5 --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/invalid-inner-rules.html @@ -0,0 +1,56 @@ +<!doctype html> +<title>Simple CSSOM manipulation of subrules</title> +<link rel="author" title="Steinar H. Gunderson" href="mailto:sesse@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-nesting-1/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style id="ss"> +div { + /* This is not a conditional rule, and thus cannot be in nesting context. */ + @layer { + &.a { font-size: 10px; } + } + + @media screen { + &.a { color: red; } + + /* Same. */ + @layer { + &.a { font-size: 10px; } + } + } +} +</style> + +<script> + test(() => { + let [ss] = document.styleSheets; + assert_equals(ss.cssRules.length, 1); + + // The @layer rule should be ignored. + assert_equals(ss.cssRules[0].cssText, +`div { + @media screen { + &.a { color: red; } +} +}`); + }); + + test(() => { + let [ss] = document.styleSheets; + assert_equals(ss.cssRules.length, 1); + assert_throws_dom('HierarchyRequestError', + () => { ss.cssRules[0].cssRules[0].insertRule('@layer {}', 0); }); + assert_throws_dom('HierarchyRequestError', + () => { ss.cssRules[0].insertRule('@layer {}', 0); }); + + // The @layer rules should be ignored (again). + assert_equals(ss.cssRules[0].cssText, +`div { + @media screen { + &.a { color: red; } +} +}`); + }); +</script> diff --git a/testing/web-platform/tests/css/css-nesting/invalidation-001.html b/testing/web-platform/tests/css/css-nesting/invalidation-001.html new file mode 100644 index 0000000000..a9a4284cc3 --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/invalidation-001.html @@ -0,0 +1,33 @@ +<!doctype html> +<title>CSS Selectors nested invalidation on changed parent</title> +<link rel="author" title="Steinar H. Gunderson" href="mailto:sesse@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-nesting-1/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> + .b { + color: red; + } + .a { + & .b { + color: green; + } + } +</style> + +<div id="container"> + <div id="child" class="b"> + Test passes if color is green. + </div> +</div> + +<script> + test(() => { + let container = document.getElementById('container'); + let child = document.getElementById('child'); + assert_equals(getComputedStyle(child).color, 'rgb(255, 0, 0)'); + container.classList.add('a'); + assert_equals(getComputedStyle(child).color, 'rgb(0, 128, 0)'); + }); +</script> diff --git a/testing/web-platform/tests/css/css-nesting/invalidation-002.html b/testing/web-platform/tests/css/css-nesting/invalidation-002.html new file mode 100644 index 0000000000..8419c4526e --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/invalidation-002.html @@ -0,0 +1,33 @@ +<!doctype html> +<title>CSS Selectors nested invalidation on changed child</title> +<link rel="author" title="Steinar H. Gunderson" href="mailto:sesse@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-nesting-1/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> + .a { + color: green; + } + .a { + & .b { + color: red; + } + } +</style> + +<div id="container" class="a"> + <div id="child" class="b"> + Test passes if color is green. + </div> +</div> + +<script> + test(() => { + let container = document.getElementById('container'); + let child = document.getElementById('child'); + assert_equals(getComputedStyle(child).color, 'rgb(255, 0, 0)'); + child.classList.remove('b'); + assert_equals(getComputedStyle(child).color, 'rgb(0, 128, 0)'); + }); +</script> diff --git a/testing/web-platform/tests/css/css-nesting/invalidation-003.html b/testing/web-platform/tests/css/css-nesting/invalidation-003.html new file mode 100644 index 0000000000..d1d6d4b9ae --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/invalidation-003.html @@ -0,0 +1,34 @@ +<!doctype html> +<title>CSS Selectors nested invalidation with :has()</title> +<link rel="author" title="Steinar H. Gunderson" href="mailto:sesse@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-nesting-1/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> + .a { + color: red; + :has(&) { + color: green; + } + } +</style> + +<div id="container"> + Test passes if color is green. + <div> + <div id="child"></div> + </div> +</div> + +<script> + test(() => { + let container = document.getElementById('container'); + let child = document.getElementById('child'); + assert_equals(getComputedStyle(container).color, 'rgb(0, 0, 0)'); + assert_equals(getComputedStyle(child).color, 'rgb(0, 0, 0)'); + child.classList.add('a'); + assert_equals(getComputedStyle(container).color, 'rgb(0, 128, 0)'); + assert_equals(getComputedStyle(child).color, 'rgb(255, 0, 0)'); + }); +</script> diff --git a/testing/web-platform/tests/css/css-nesting/invalidation-004.html b/testing/web-platform/tests/css/css-nesting/invalidation-004.html new file mode 100644 index 0000000000..a66c47cf16 --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/invalidation-004.html @@ -0,0 +1,30 @@ +<!doctype html> +<title>CSS Selectors nested invalidation through @media by selectorText</title> +<link rel="author" title="Steinar H. Gunderson" href="mailto:sesse@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-nesting-1/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> + .b { + color: red; + } + & { + @media screen { + &.b { color: green; } + } + } +</style> + +<div id="elem" class="a b"> + Test passes if color is green. +</div> + +<script> + test(() => { + let elem = document.getElementById('elem'); + assert_equals(getComputedStyle(elem).color, 'rgb(255, 0, 0)'); + document.styleSheets[0].rules[1].selectorText = '.a'; + assert_equals(getComputedStyle(elem).color, 'rgb(0, 128, 0)'); + }); +</script> diff --git a/testing/web-platform/tests/css/css-nesting/nesting-basic-ref.html b/testing/web-platform/tests/css/css-nesting/nesting-basic-ref.html new file mode 100644 index 0000000000..c2f7c66949 --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/nesting-basic-ref.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<title>Basic nesting</title> +<link rel="author" title="Adam Argyle" href="mailto:argyle@google.com"> +<link rel="help" href="https://drafts.csswg.org/css-nesting-1/"> +<style> + .test { + background-color: green; + width: 100px; + height: 100px; + display: grid; + } + + body * + * { + margin-top: 8px; + } +</style> +<body> + <p>Tests pass if <strong>block is green</strong></p> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> +</body> diff --git a/testing/web-platform/tests/css/css-nesting/nesting-basic.html b/testing/web-platform/tests/css/css-nesting/nesting-basic.html new file mode 100644 index 0000000000..6bc727a731 --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/nesting-basic.html @@ -0,0 +1,103 @@ +<!DOCTYPE html> +<title>Basic nesting</title> +<link rel="author" title="Adam Argyle" href="mailto:argyle@google.com"> +<link rel="help" href="https://drafts.csswg.org/css-nesting-1/"> +<link rel="match" href="nesting-basic-ref.html"> +<style> + .test { + background-color: red; + width: 100px; + height: 100px; + display: grid; + } + + .test-1 { + & > div { + background-color: green; + } + } + + .test-2 { + & > div { + background-color: green; + } + } + + .test-3 { + & .test-3-child { + background-color: green; + } + } + + span > b { + .test-4 section & { + display: inline-block; + background-color: green; + width: 100%; + height: 100%; + } + + .test-4 section > & { + background-color: red; + } + } + + .test-6 { + &.test { + background-color: green; + } + } + + .test-7, .t7- { + & + .test-7-child, &.t7-- { + background-color: green; + } + } + + .test-8 { + & { + background-color: green; + } + } + + .test-9 { + &:is(.t9-, &.t9--) { + background-color: green; + } + } + + .test-10 { + & { + background-color: green; + } + background-color: red; + } + + .test-11 { + & { + background-color: red; + } + background-color: green !important; + } + + body * + * { + margin-top: 8px; + } +</style> +<body> + <p>Tests pass if <strong>block is green</strong></p> + <div class="test test-1"><div></div></div> + <div class="test test-2"><div></div></div> + <div class="test test-3"><div class="test-3-child"></div></div> + <div class="test test-4"> + <section> + <span><b></b></span> + </section> + </div> + <div class="test test-6"><div></div></div> + <div class="test t7- t7--"><div class="test-7-child"></div></div> + <div class="test test-8"><div></div></div> + <div class="test test-9 t9-- t9-"><div></div></div> + <div class="test test-10"><div></div></div> + <div class="test test-11"><div></div></div> +</body> diff --git a/testing/web-platform/tests/css/css-nesting/parsing.html b/testing/web-platform/tests/css/css-nesting/parsing.html new file mode 100644 index 0000000000..66d1566586 --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/parsing.html @@ -0,0 +1,43 @@ +<!doctype html> +<title>CSS Selectors parsing</title> +<link rel="author" title="Adam Argyle" href="mailto:argyle@google.com"> +<link rel="help" href="https://drafts.csswg.org/css-nesting-1/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style id="test-sheet"></style> +<script> + let [ss] = document.styleSheets + + const beforeEach = () => { + while (ss.rules.length) + ss.removeRule(0) + } + + const testRules = [ + `.foo {\n & { color: green; }\n}`, // 🐰 + `.foo {\n &.bar { color: green; }\n}`, + `.foo {\n & .bar { color: green; }\n}`, + `.foo {\n & > .bar { color: green; }\n}`, + `.foo {\n &:is(.bar, &.baz) { color: green; }\n}`, + `.foo {\n .bar& { color: green; }\n}`, + `.foo {\n .bar & { color: green; }\n}`, + `.foo {\n .bar > & { color: green; }\n}`, + `.foo, .bar {\n & + .baz, &.qux { color: green; }\n}`, + `.foo {\n & .bar & .baz & .qux { color: green; }\n}`, + `.foo {\n @media (min-width: 50px) {\n & { color: green; }\n}\n}`, + `.foo {\n @media (min-width: 50px) { color: green; }\n}`, + `main {\n & > section, & > article {\n & > header { color: green; }\n}\n}`, + ] + + testRules.forEach(testRule => { + test(function() { + beforeEach() + ss.insertRule(testRule) + // todo? + // when parsing is being ready/prototyped, + // switch to crawling nested rules instead of comparing text + assert_equals(ss.rules[0].cssText, testRule) + }, testRule) + }) +</script> diff --git a/testing/web-platform/tests/css/css-nesting/pseudo-part-crash.html b/testing/web-platform/tests/css/css-nesting/pseudo-part-crash.html new file mode 100644 index 0000000000..3ab521d71c --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/pseudo-part-crash.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>Nesting pseudo element selectors should not crash</title> +<link rel="help" href="https://crbug.com/1376227"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7912"> +<style> + div::part(x) { + & { + color: red; + } + } +</style> diff --git a/testing/web-platform/tests/css/css-nesting/serialize-group-rules-with-decls.tentative.html b/testing/web-platform/tests/css/css-nesting/serialize-group-rules-with-decls.tentative.html new file mode 100644 index 0000000000..c3b6bb7be7 --- /dev/null +++ b/testing/web-platform/tests/css/css-nesting/serialize-group-rules-with-decls.tentative.html @@ -0,0 +1,69 @@ +<!doctype html> +<title>Serialization of declarations in group rules</title> +<link rel="author" title="Steinar H. Gunderson" href="mailto:sesse@chromium.org"> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7850"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style id="test-sheet"></style> +<script> + function serialize(cssText) { + let [ss] = document.styleSheets; + while (ss.rules.length) { + ss.removeRule(0) + } + ss.insertRule(cssText); + return ss.rules[0].cssText; + } + + function assert_unchanged(cssText) { + assert_equals(serialize(cssText), cssText); + } + + function assert_becomes(cssText, serializedCssText) { + assert_equals(serialize(cssText), serializedCssText); + } + + // Declarations are serialized on one line, rules on two. + test(() => { + assert_unchanged("@media screen {\n div { color: red; background-color: green; }\n}"); + assert_unchanged("div {\n @media screen { color: red; background-color: green; }\n}"); + }); + + // Mixed declarations/rules are on two lines. + test(() => { + assert_unchanged("div {\n @supports selector(&) {\n color: red; background-color: green;\n &:hover { color: navy; }\n}\n}"); + }); + + // & {} rules are removed if and only if they are first, and they have no children. + test(() => { + assert_becomes("div { @media screen { & { color: red; } }", + "div {\n @media screen { color: red; }\n}"); + assert_becomes("div { @media screen { & { color: red; &:hover { } } }", + "div {\n @media screen {\n & {\n color: red;\n &:hover { }\n}\n}\n}"); + assert_becomes("div { @media screen { &.cls { color: red; } & { color: red; }", + "div {\n @media screen {\n &.cls { color: red; }\n & { color: red; }\n}\n}"); + assert_becomes("div { @media screen { & { color: red; } & { color: red; }", + "div {\n @media screen {\n color: red;\n & { color: red; }\n}\n}"); + assert_becomes("div { @media screen { color: red; & { color: red; }", + "div {\n @media screen {\n color: red;\n & { color: red; }\n}\n}"); + assert_becomes("div { @media screen { color: red; & { color: blue; }", + "div {\n @media screen {\n color: red;\n & { color: blue; }\n}\n}"); + assert_becomes("div { @media screen { &, p > & { color: blue; }", + "div {\n @media screen {\n &, p > & { color: blue; }\n}\n}"); + }); + + // They are not removed from regular rules. + test(() => { + assert_becomes("div { & { color: red; } }", "div {\n & { color: red; }\n}"); + }); + + // Empty rules (confusingly?) serialize different between style rules + // and conditional group rules. + test(() => { + assert_unchanged("@media screen {\n}"); + assert_unchanged("div { }"); + assert_unchanged("div {\n @media screen {\n}\n}"); + assert_unchanged("@media screen {\n div { }\n}"); + }); +</script> |