<!DOCTYPE html>
<meta charset="utf-8">
<title>Dynamic change to style containment</title>
<link rel="help" href="https://drafts.csswg.org/css-contain/#contain-property">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1765615">
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<meta name="assert" content="Verify style containment is properly updated after dynamic change to the contain property.">
<style>
/* Selectors for contain */
#none .wrapper {
contain: none;
}
#style .wrapper {
contain: style;
}
#none_to_style .wrapper {
contain: none;
}
#style_to_none .wrapper {
contain: style;
}
/* Selectors for testing counters */
.set_counter_to_9 {
counter-set: testcounter 9;
}
.increment_counter {
counter-increment: testcounter;
}
.set_counter_to_10 {
counter-set: testcounter 10;
}
span.print_counter::after {
font: 25px/1 Ahem;
content: counters(testcounter, ".");
}
/* Selectors for testing quotes */
.open_quote::after {
content: open-quote;
}
.close_quote::after {
content: close-quote;
}
.no_open_quote::after {
content: no-open-quote;
}
.no_close_quote::after {
content: no-close-quote;
}
span.print_quotes::before, span.print_quotes::after {
font: 25px/1 Ahem;
quotes: "A" "" "BB" "" "CCC" "" "DDDD" "" "EEEEE" "" "FFFFF" "" "GGGGGG" "" "HHHHHHH" "" "IIIIIIII" "" "JJJJJJJJJ" "";
}
span.print_quotes::before {
content: open-quote;
}
span.print_quotes::after {
content: no-close-quote;
}
</style>
<body>
<div id="log"></div>
<div id="none">
<div class="set_counter_to_9"></div>
<span><span class="print_counter"></span></span>
<div class="wrapper">
<span class="increment_counter"></span>
</div>
<span><span class="print_counter"></span></span>
<div class="set_counter_to_9"></div>
<span><span class="print_counter"></span></span>
<div class="wrapper">
<span class="set_counter_to_10"></span>
</div>
<span><span class="print_counter"></span></span>
<span><span class="print_quotes"></span></span>
<div class="wrapper">
<span class="open_quote"></span>
</div>
<span><span class="print_quotes"></span></span>
<span><span class="print_quotes"></span></span>
<div class="wrapper">
<span class="close_quote"></span>
</div>
<span><span class="print_quotes"></span></span>
<span><span class="print_quotes"></span></span>
<div class="wrapper">
<span class="no_open_quote"></span>
</div>
<span><span class="print_quotes"></span></span>
<span><span class="print_quotes"></span></span>
<div class="wrapper">
<span class="no_close_quote"></span>
</div>
<span><span class="print_quotes"></span></span>
</div>
<div id="style">
<div class="set_counter_to_9"></div>
<span><span class="print_counter"></span></span>
<div class="wrapper">
<span class="increment_counter"></span>
</div>
<span><span class="print_counter"></span></span>
<div class="set_counter_to_9"></div>
<span><span class="print_counter"></span></span>
<div class="wrapper">
<span class="set_counter_to_10"></span>
</div>
<span><span class="print_counter"></span></span>
<span><span class="print_quotes"></span></span>
<div class="wrapper">
<span class="open_quote"></span>
</div>
<span><span class="print_quotes"></span></span>
<span><span class="print_quotes"></span></span>
<div class="wrapper">
<span class="close_quote"></span>
</div>
<span><span class="print_quotes"></span></span>
<span><span class="print_quotes"></span></span>
<div class="wrapper">
<span class="no_open_quote"></span>
</div>
<span><span class="print_quotes"></span></span>
<span><span class="print_quotes"></span></span>
<div class="wrapper">
<span class="no_close_quote"></span>
</div>
<span><span class="print_quotes"></span></span>
</div>
<div id="none_to_style">
<div class="set_counter_to_9"></div>
<span><span class="print_counter"></span></span>
<div class="wrapper">
<span class="increment_counter"></span>
</div>
<span><span class="print_counter"></span></span>
<div class="set_counter_to_9"></div>
<span><span class="print_counter"></span></span>
<div class="wrapper">
<span class="set_counter_to_10"></span>
</div>
<span><span class="print_counter"></span></span>
<span><span class="print_quotes"></span></span>
<div class="wrapper">
<span class="open_quote"></span>
</div>
<span><span class="print_quotes"></span></span>
<span><span class="print_quotes"></span></span>
<div class="wrapper">
<span class="close_quote"></span>
</div>
<span><span class="print_quotes"></span></span>
<span><span class="print_quotes"></span></span>
<div class="wrapper">
<span class="no_open_quote"></span>
</div>
<span><span class="print_quotes"></span></span>
<span><span class="print_quotes"></span></span>
<div class="wrapper">
<span class="no_close_quote"></span>
</div>
<span><span class="print_quotes"></span></span>
</div>
<div id="style_to_none">
<div class="set_counter_to_9"></div>
<span><span class="print_counter"></span></span>
<div class="wrapper">
<span class="increment_counter"></span>
</div>
<span><span class="print_counter"></span></span>
<div class="set_counter_to_9"></div>
<span><span class="print_counter"></span></span>
<div class="wrapper">
<span class="set_counter_to_10"></span>
</div>
<span><span class="print_counter"></span></span>
<span><span class="print_quotes"></span></span>
<div class="wrapper">
<span class="open_quote"></span>
</div>
<span><span class="print_quotes"></span></span>
<span><span class="print_quotes"></span></span>
<div class="wrapper">
<span class="close_quote"></span>
</div>
<span><span class="print_quotes"></span></span>
<span><span class="print_quotes"></span></span>
<div class="wrapper">
<span class="no_open_quote"></span>
</div>
<span><span class="print_quotes"></span></span>
<span><span class="print_quotes"></span></span>
<div class="wrapper">
<span class="no_close_quote"></span>
</div>
<span><span class="print_quotes"></span></span>
</div>
<script>
function verifyStyleContainment(id, applied) {
let container = document.getElementById(id);
// To verify style containment for counters and quotes, we check whether
// the properties in the wrapper affect the string length of generated
// content.
function haveSameStringLength(box1, box2) {
const ahemFontSizePx = 25;
return Math.abs(box2.width - box1.width) < ahemFontSizePx / 2;
}
let counter_box =
Array.from(container.getElementsByClassName("print_counter"))
.map(e => e.parentNode.getBoundingClientRect());
let quote_box =
Array.from(container.getElementsByClassName("print_quotes"))
.map(e => e.parentNode.getBoundingClientRect());
assert_equals(haveSameStringLength(counter_box[0], counter_box[1]), applied, "increment-counter");
assert_equals(haveSameStringLength(counter_box[2], counter_box[3]), applied, "set-counter");
assert_equals(haveSameStringLength(quote_box[0], quote_box[1]), applied, "open-quote");
assert_equals(haveSameStringLength(quote_box[2], quote_box[3]), applied, "close-quote");
assert_equals(haveSameStringLength(quote_box[4], quote_box[5]), applied, "no-open-quote");
assert_equals(haveSameStringLength(quote_box[6], quote_box[7]), applied, "no-close-quote");
}
function setContain(id, value) {
let container = document.getElementById(id);
Array.from(container.getElementsByClassName("wrapper"))
.forEach(element => element.style.contain = value);
}
promise_test(async () => {
await document.fonts.ready;
verifyStyleContainment("none", /*applied=*/ false);
}, "contain: none");
promise_test(async () => {
await document.fonts.ready;
verifyStyleContainment("style", /*applied=*/ true);
}, "contain: style");
promise_test(async () => {
await document.fonts.ready;
setContain("none_to_style", "style");
verifyStyleContainment("none_to_style", /*applied=*/ true);
}, "switching contain from none to style");
promise_test(async () => {
await document.fonts.ready;
setContain("style_to_none", "none");
verifyStyleContainment("style_to_none", /*applied=*/ false);
}, "switching contain from style to none");
</script>
</body>