LibWeb: Make style containment influence quotes

This commit is contained in:
Psychpsyo 2025-02-06 17:07:12 +01:00 committed by Sam Atkins
commit 402d8220dd
Notes: github-actions[bot] 2025-02-06 17:45:51 +00:00
19 changed files with 380 additions and 0 deletions

View file

@ -573,6 +573,8 @@ void TreeBuilder::update_layout_tree(DOM::Node& dom_node, TreeBuilder::Context&
return false;
}();
auto prior_quote_nesting_level = m_quote_nesting_level;
if (should_create_layout_node)
update_layout_tree_before_children(dom_node, *layout_node, context, element_has_content_visibility_hidden);
@ -617,6 +619,14 @@ void TreeBuilder::update_layout_tree(DOM::Node& dom_node, TreeBuilder::Context&
restructure_block_node_in_inline_parent(static_cast<NodeWithStyleAndBoxModelMetrics&>(*layout_node));
}
// https://www.w3.org/TR/css-contain-2/#containment-style
// Giving an element style containment has the following effects:
// 2. The effects of the 'content' propertys 'open-quote', 'close-quote', 'no-open-quote' and 'no-close-quote' must
// be scoped to the elements sub-tree.
if (dom_node.is_element() && (static_cast<DOM::Element&>(dom_node)).has_style_containment()) {
m_quote_nesting_level = prior_quote_nesting_level;
}
dom_node.set_needs_layout_tree_update(false);
dom_node.set_child_needs_layout_tree_update(false);
}

View file

@ -0,0 +1,20 @@
<!doctype html>
<link rel="help" href="http://crbug.com/329231572">
<style>
#test { contain: style; }
</style>
<body>
<q id="test"></q>
<div>
<template shadowrootmode="open">
<slot></slot>
</template>
<q id="test2"></q>
</div>
<script>
test.offsetTop;
test2.slot = "1";
test2.appendChild(test);
test.offsetTop;
</script>
</body>

View file

@ -0,0 +1,8 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test reference</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<p>Test passes if the text below is "A1Z" (not including the quotation marks).<p>
<div>A1Z</div>

View file

@ -0,0 +1,8 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test reference</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<p>Test passes if the text below is "AZZ" (not including the quotation marks).<p>
<div>AZZ</span></div>

View file

@ -0,0 +1,8 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test reference</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<p>Test passes if the text below is "AZ" (not including the quotation marks).<p>
<div>AZ</div>

View file

@ -0,0 +1,12 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test: nested style containment and the quote element following a style boundary without any quotes</title>
<link rel="author" title="Martin Robinson" href="mailto:mrobinson@igalia.com">
<link rel=help href="https://drafts.csswg.org/css-contain-1/#containment-style">
<div>
<div>
<q></q>
</div>
</div>

View file

@ -0,0 +1,7 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS-contain test reference: style containment dynamic containment set invalidation</title>
<link rel="author" title="Daniil Sakhapov" href="sakhapov@google.com">
<p>Test passes if the text below is "A1(19" (not including the quotation marks).<p>
<div>A<div>1 (</div>1 9</div>

View file

@ -0,0 +1,7 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS-contain test reference: style containment dynamic containment set unset invalidation</title>
<link rel="author" title="Daniil Sakhapov" href="sakhapov@google.com">
<p>Test passes if the text below is "A1(+-" (not including the quotation marks).<p>
<div>A<div>1 (</div>+ -</div>

View file

@ -0,0 +1,7 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS-contain test reference: style containment dynamic containment set unset set invalidation</title>
<link rel="author" title="Daniil Sakhapov" href="sakhapov@google.com">
<p>Test passes if the text below is "A119" (not including the quotation marks).<p>
<div>A<div>1</div>1 9</div>

View file

@ -0,0 +1,7 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS-contain test reference: style containment invalidation with elements in different subtrees</title>
<link rel="author" title="Daniil Sakhapov" href="sakhapov@google.com">
<p>Test passes if the text below is "A111119" (not including the quotation marks).<p>
<div>A<div>1 1</div><div>1 1</div>1 9</div>

View file

@ -0,0 +1,28 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test: style containment and open-quote</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<meta name=flags content="">
<meta name=assert content="style containment cause the open-quote value of the content property are scoped to the element's subtree">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/quote-scoping-001-ref.html">
<link rel=help href="https://drafts.csswg.org/css-contain-1/#containment-style">
<style>
div {
quotes: "A" "Z" "1" "9";
}
div::before, span::before {
content: open-quote;
}
div::after {
content: close-quote;
}
span {
contain: style;
}
</style>
<p>Test passes if the text below is "A1Z" (not including the quotation marks).<p>
<div><span></span></div>

View file

@ -0,0 +1,28 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test: style containment and close-quote</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<meta name=flags content="">
<meta name=assert content="style containment cause the close-quote value of the content property are scoped to the element's subtree">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/quote-scoping-002-ref.html">
<link rel=help href="https://drafts.csswg.org/css-contain-1/#containment-style">
<style>
div {
quotes: "A" "Z" "1" "9";
}
div::before {
content: open-quote;
}
div::after, span::after {
content: close-quote;
}
span {
contain: style;
}
</style>
<p>Test passes if the text below is "AZZ" (not including the quotation marks).<p>
<div><span></span></div>

View file

@ -0,0 +1,32 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test: style containment and no-open-quote</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<meta name=flags content="">
<meta name=assert content="style containment cause the no-open-quote value of the content property are scoped to the element's subtree">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/quote-scoping-003-ref.html">
<link rel=help href="https://drafts.csswg.org/css-contain-1/#containment-style">
<style>
div {
quotes: "A" "Z" "1" "9";
}
div::before{
content: open-quote;
}
span::before {
content: no-open-quote;
}
div::after {
content: close-quote;
}
span {
contain: style;
}
</style>
<p>Test passes if the text below is "AZ" (not including the quotation marks).<p>
<div><span></span></div>

View file

@ -0,0 +1,32 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test: style containment and no-close-quote</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
<meta name=flags content="">
<meta name=assert content="style containment cause the no-close-quote value of the content property are scoped to the element's subtree">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/quote-scoping-003-ref.html">
<link rel=help href="https://drafts.csswg.org/css-contain-1/#containment-style">
<style>
div {
quotes: "A" "Z" "1" "9";
}
div::before{
content: open-quote;
}
span::after {
content: no-close-quote;
}
div::after {
content: close-quote;
}
span {
contain: style;
}
</style>
<p>Test passes if the text below is "AZ" (not including the quotation marks).<p>
<div><span></span></div>

View file

@ -0,0 +1,13 @@
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CSS-contain test: nested style containment and the quote element following a style boundary without any quotes</title>
<link rel="author" title="Martin Robinson" href="mailto:mrobinson@igalia.com">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/quote-scoping-empty-style-boundaries-ref.html">
<link rel=help href="https://drafts.csswg.org/css-contain-1/#containment-style">
<div style="contain: style;">
<div style="contain: style;">
<q></q>
</div>
</div>

View file

@ -0,0 +1,35 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS-contain test: style containment dynamic containment set invalidation</title>
<link rel="author" title="Daniil Sakhapov" href="sakhapov@google.com">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/quote-scoping-invalidation-001-ref.html">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-style">
<style>
#root {
quotes: "A" "Z" "1" "9" "(" ")" "+" "-";
}
#root::before, #root span::before {
content: open-quote;
}
#root::after {
content: close-quote;
}
.contain-style {
contain: style;
}
</style>
<p>Test passes if the text below is "A1(19" (not including the quotation marks).<p>
<div id="root">
<div id="scope">
<span id="span1"></span>
<span id="span2"></span>
</div>
<span></span>
</div>
<script>
document.body.offsetTop;
scope.style.contain = "style";
</script>

View file

@ -0,0 +1,37 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS-contain test: style containment dynamic containment set unset invalidation</title>
<link rel="author" title="Daniil Sakhapov" href="sakhapov@google.com">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/quote-scoping-invalidation-002-ref.html">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-style">
<style>
#root {
quotes: "A" "Z" "1" "9" "(" ")" "+" "-";
}
#root::before, #root span::before {
content: open-quote;
}
#root::after {
content: close-quote;
}
.contain-style {
contain: style;
}
</style>
<p>Test passes if the text below is "A1(+-" (not including the quotation marks).<p>
<div id="root">
<div id="scope">
<span id="span1"></span>
<span id="span2"></span>
</div>
<span></span>
</div>
<script>
document.body.offsetTop;
scope.style.contain = "style";
document.body.offsetTop;
scope.style.contain = "";
</script>

View file

@ -0,0 +1,41 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS-contain test: style containment dynamic containment set unset set invalidation</title>
<link rel="author" title="Daniil Sakhapov" href="sakhapov@google.com">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/quote-scoping-invalidation-003-ref.html">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-style">
<style>
#root {
quotes: "A" "Z" "1" "9" "(" ")" "+" "-";
}
#root::before, #root span::before {
content: open-quote;
}
#root::after {
content: close-quote;
}
.contain-style {
contain: style;
}
</style>
<p>Test passes if the text below is "A119" (not including the quotation marks).<p>
<div id="root">
<div id="scope">
<span id="span1"></span>
<span id="span2"></span>
</div>
<span></span>
</div>
<script>
document.body.offsetTop;
scope.style.contain = "style";
document.body.offsetTop;
scope.style.contain = "";
document.body.offsetTop;
scope.style.contain = "style";
document.body.offsetTop;
span1.remove();
</script>

View file

@ -0,0 +1,40 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS-contain test: style containment invalidation with elements in different subtrees</title>
<link rel="author" title="Daniil Sakhapov" href="sakhapov@google.com">
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/quote-scoping-invalidation-004-ref.html">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-style">
<style>
#root {
quotes: "A" "Z" "1" "9" "(" ")" "+" "-";
}
#root::before, #root span::before {
content: open-quote;
}
#root::after {
content: close-quote;
}
.contain-style {
contain: style;
}
</style>
<p>Test passes if the text below is "A111119" (not including the quotation marks).<p>
<div id="root">
<div class="contain-style">
<span id="span1"></span>
<span id="span2"></span>
</div>
<div class="contain-style">
<span id="span3"></span>
<span id="span4"></span>
</div>
<span></span>
</div>
<script>
document.body.offsetTop;
span1.className = "contain-style";
span3.className = "contain-style";
</script>