Commit 980bc9b6 authored by Ian Kilpatrick's avatar Ian Kilpatrick Committed by Commit Bot

[css-layout-api] Add LayoutEdges.

This allows web developers to access pre-computed sizes for the border,
scrollbar, and padding "edges".

This adds two types of tests:
1) Uses the standard "green box" approach of testing the script values
   match what is expected.
2) Positions four children at each corner (using edges) are positioned
   the same as using an abs-pos technique.

Bug: 726125
Change-Id: I3b53be9b44989d919cb657d4eabc6d3a1a79181b
Reviewed-on: https://chromium-review.googlesource.com/c/1252776
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: default avatarAleks Totic <atotic@chromium.org>
Reviewed-by: default avatarMorten Stenshorne <mstensho@chromium.org>
Cr-Commit-Position: refs/heads/master@{#599680}
parent 06b33689
<!DOCTYPE html>
<style>
td { text-align: center; }
.parent {
box-sizing: border-box;
width: 60px;
height: 60px;
border: solid;
border-width: 1px 2px 3px 4px;
padding: 0px 4px 8px 12px;
position: relative;
}
.child {
position: absolute;
width: 10px;
height: 10px;
background: green;
}
.top-left {
top: 0;
left: 12px;
}
.top-right {
top: 0;
right: 4px;
}
.bottom-left {
bottom: 8px;
left: 12px;
}
.bottom-right {
bottom: 8px;
right: 4px;
}
</style>
<table>
<tr>
<td></td>
<td colspan=2>LTR</td>
<td colspan=2>RTL</td>
</tr>
<tr>
<td></td>
<td>Y</td>
<td>X</td>
<td>Y</td>
<td>X</td>
</tr>
<tr>
<td>HTB</td>
<td>
<div class="parent" style="writing-mode: horizontal-tb; direction: ltr; overflow-y: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: horizontal-tb; direction: ltr; overflow-x: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: horizontal-tb; direction: rtl; overflow-y: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: horizontal-tb; direction: rtl; overflow-x: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
</tr>
<tr>
<td>VRL</td>
<td>
<div class="parent" style="writing-mode: vertical-rl; direction: ltr; overflow-y: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-rl; direction: ltr; overflow-x: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-rl; direction: rtl; overflow-y: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-rl; direction: rtl; overflow-x: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
</tr>
<tr>
<td>VLR</td>
<td>
<div class="parent" style="writing-mode: vertical-lr; direction: ltr; overflow-y: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-lr; direction: ltr; overflow-x: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-lr; direction: rtl; overflow-y: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-lr; direction: rtl; overflow-x: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
</tr>
</table>
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
<link rel="match" href="all-ref.html">
<meta name="assert" content="This test checks that 'all' sizes are passed to the layout correctly." />
<style>
td { text-align: center; }
.parent {
box-sizing: border-box;
width: 60px;
height: 60px;
border: solid;
border-width: 1px 2px 3px 4px;
padding: 0px 4px 8px 12px;
position: relative;
background: red;
}
@supports (display: layout(test)) {
.parent {
display: layout(test);
background: initial;
}
}
.child {
width: 10px;
height: 10px;
background: green;
}
</style>
<!--
This test works by placing four children in each corner of the layout using the edges.
The reference to this test uses absolute positioning to achieve the same effect.
-->
<table>
<tr>
<td></td>
<td colspan=2>LTR</td>
<td colspan=2>RTL</td>
</tr>
<tr>
<td></td>
<td>Y</td>
<td>X</td>
<td>Y</td>
<td>X</td>
</tr>
<tr>
<td>HTB</td>
<td>
<div class="parent" style="writing-mode: horizontal-tb; direction: ltr; overflow-y: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: horizontal-tb; direction: ltr; overflow-x: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: horizontal-tb; direction: rtl; overflow-y: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: horizontal-tb; direction: rtl; overflow-x: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
</tr>
<tr>
<td>VRL</td>
<td>
<div class="parent" style="writing-mode: vertical-rl; direction: ltr; overflow-y: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-rl; direction: ltr; overflow-x: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-rl; direction: rtl; overflow-y: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-rl; direction: rtl; overflow-x: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
</tr>
<tr>
<td>VLR</td>
<td>
<div class="parent" style="writing-mode: vertical-lr; direction: ltr; overflow-y: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-lr; direction: ltr; overflow-x: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-lr; direction: rtl; overflow-y: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-lr; direction: rtl; overflow-x: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
</tr>
</table>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script id="code" type="text/worklet">
registerLayout('test', class {
*intrinsicSizes() {}
*layout(children, edges, constraints) {
const topLeftFragment = yield children[0].layoutNextFragment();
const topRightFragment = yield children[1].layoutNextFragment();
const bottomLeftFragment = yield children[2].layoutNextFragment();
const bottomRightFragment = yield children[3].layoutNextFragment();
topLeftFragment.inlineOffset = edges.inlineStart;
topLeftFragment.blockOffset = edges.blockStart;
topRightFragment.inlineOffset =
constraints.fixedInlineSize - topRightFragment.inlineSize - edges.inlineEnd;
topRightFragment.blockOffset = edges.blockStart;
bottomLeftFragment.inlineOffset = edges.inlineStart;
bottomLeftFragment.blockOffset =
constraints.fixedBlockSize - bottomLeftFragment.blockSize - edges.blockEnd;
bottomRightFragment.inlineOffset =
constraints.fixedInlineSize - bottomRightFragment.inlineSize - edges.inlineEnd;
bottomRightFragment.blockOffset =
constraints.fixedBlockSize - bottomRightFragment.blockSize - edges.blockEnd;
return {childFragments: [
topLeftFragment,
topRightFragment,
bottomLeftFragment,
bottomRightFragment
]};
}
});
</script>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
</script>
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
<link rel="match" href="../green-square-ref.html">
<meta name="assert" content="This test checks that border sizes are passed to the layout correctly." />
<style>
.test {
writing-mode: horizontal-tb;
direction: rtl;
background: red;
box-sizing: border-box;
width: 100px;
--edges-inline-start-expected: 8;
--edges-inline-end-expected: 20;
--edges-block-start-expected: 10;
--edges-block-end-expected: 0;
font-size: 8px;
border-color: transparent;
border-style: solid;
border-width: 10px 1em 0 20px;
}
@supports (display: layout(test)) {
.test {
display: layout(test);
background: green;
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test"></div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: '../support/edges.js'});
</script>
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
<link rel="match" href="../green-square-ref.html">
<meta name="assert" content="This test checks that border sizes are passed to the layout correctly." />
<style>
.test {
writing-mode: horizontal-tb;
background: red;
box-sizing: border-box;
width: 100px;
--edges-inline-start-expected: 20;
--edges-inline-end-expected: 8;
--edges-block-start-expected: 10;
--edges-block-end-expected: 0;
font-size: 8px;
border-color: transparent;
border-style: solid;
border-width: 10px 1em 0 20px;
}
@supports (display: layout(test)) {
.test {
display: layout(test);
background: green;
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test"></div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: '../support/edges.js'});
</script>
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
<link rel="match" href="../green-square-ref.html">
<meta name="assert" content="This test checks that border sizes are passed to the layout correctly." />
<style>
.test {
writing-mode: vertical-lr;
direction: rtl;
background: red;
box-sizing: border-box;
height: 100px;
--edges-inline-start-expected: 0;
--edges-inline-end-expected: 10;
--edges-block-start-expected: 20;
--edges-block-end-expected: 8;
font-size: 8px;
border-color: transparent;
border-style: solid;
border-width: 10px 1em 0 20px;
}
@supports (display: layout(test)) {
.test {
display: layout(test);
background: green;
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test"></div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: '../support/edges.js'});
</script>
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
<link rel="match" href="../green-square-ref.html">
<meta name="assert" content="This test checks that border sizes are passed to the layout correctly." />
<style>
.test {
writing-mode: vertical-lr;
background: red;
box-sizing: border-box;
height: 100px;
--edges-inline-start-expected: 10;
--edges-inline-end-expected: 0;
--edges-block-start-expected: 20;
--edges-block-end-expected: 8;
font-size: 8px;
border-color: transparent;
border-style: solid;
border-width: 10px 1em 0 20px;
}
@supports (display: layout(test)) {
.test {
display: layout(test);
background: green;
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test"></div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: '../support/edges.js'});
</script>
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
<link rel="match" href="../green-square-ref.html">
<meta name="assert" content="This test checks that border sizes are passed to the layout correctly." />
<style>
.test {
writing-mode: vertical-rl;
direction: rtl;
background: red;
box-sizing: border-box;
height: 100px;
--edges-inline-start-expected: 0;
--edges-inline-end-expected: 10;
--edges-block-start-expected: 8;
--edges-block-end-expected: 20;
font-size: 8px;
border-color: transparent;
border-style: solid;
border-width: 10px 1em 0 20px;
}
@supports (display: layout(test)) {
.test {
display: layout(test);
background: green;
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test"></div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: '../support/edges.js'});
</script>
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
<link rel="match" href="../green-square-ref.html">
<meta name="assert" content="This test checks that border sizes are passed to the layout correctly." />
<style>
.test {
writing-mode: vertical-rl;
background: red;
box-sizing: border-box;
height: 100px;
--edges-inline-start-expected: 10;
--edges-inline-end-expected: 0;
--edges-block-start-expected: 8;
--edges-block-end-expected: 20;
font-size: 8px;
border-color: transparent;
border-style: solid;
border-width: 10px 1em 0 20px;
}
@supports (display: layout(test)) {
.test {
display: layout(test);
background: green;
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test"></div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: '../support/edges.js'});
</script>
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
<link rel="match" href="../green-square-ref.html">
<meta name="assert" content="This test checks that padding sizes are passed to the layout correctly." />
<style>
.test {
writing-mode: horizontal-tb;
direction: rtl;
background: red;
box-sizing: border-box;
width: 100px;
--edges-inline-start-expected: 8;
--edges-inline-end-expected: 20;
--edges-block-start-expected: 10;
--edges-block-end-expected: 0;
font-size: 8px;
padding: 10px 1em 0 20px;
}
@supports (display: layout(test)) {
.test {
display: layout(test);
background: green;
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test"></div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: '../support/edges.js'});
</script>
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
<link rel="match" href="../green-square-ref.html">
<meta name="assert" content="This test checks that padding sizes are passed to the layout correctly." />
<style>
.test {
writing-mode: horizontal-tb;
background: red;
box-sizing: border-box;
width: 100px;
--edges-inline-start-expected: 20;
--edges-inline-end-expected: 8;
--edges-block-start-expected: 10;
--edges-block-end-expected: 0;
font-size: 8px;
padding: 10px 1em 0 20px;
}
@supports (display: layout(test)) {
.test {
display: layout(test);
background: green;
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test"></div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: '../support/edges.js'});
</script>
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
<link rel="match" href="../green-square-ref.html">
<meta name="assert" content="This test checks that padding sizes are passed to the layout correctly." />
<style>
.test {
writing-mode: vertical-lr;
direction: rtl;
background: red;
box-sizing: border-box;
height: 100px;
--edges-inline-start-expected: 0;
--edges-inline-end-expected: 10;
--edges-block-start-expected: 20;
--edges-block-end-expected: 8;
font-size: 8px;
padding: 10px 1em 0 20px;
}
@supports (display: layout(test)) {
.test {
display: layout(test);
background: green;
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test"></div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: '../support/edges.js'});
</script>
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
<link rel="match" href="../green-square-ref.html">
<meta name="assert" content="This test checks that padding sizes are passed to the layout correctly." />
<style>
.test {
writing-mode: vertical-lr;
background: red;
box-sizing: border-box;
height: 100px;
--edges-inline-start-expected: 10;
--edges-inline-end-expected: 0;
--edges-block-start-expected: 20;
--edges-block-end-expected: 8;
font-size: 8px;
padding: 10px 1em 0 20px;
}
@supports (display: layout(test)) {
.test {
display: layout(test);
background: green;
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test"></div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: '../support/edges.js'});
</script>
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
<link rel="match" href="../green-square-ref.html">
<meta name="assert" content="This test checks that padding sizes are passed to the layout correctly." />
<style>
.test {
writing-mode: vertical-rl;
direction: rtl;
background: red;
box-sizing: border-box;
height: 100px;
--edges-inline-start-expected: 0;
--edges-inline-end-expected: 10;
--edges-block-start-expected: 8;
--edges-block-end-expected: 20;
font-size: 8px;
padding: 10px 1em 0 20px;
}
@supports (display: layout(test)) {
.test {
display: layout(test);
background: green;
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test"></div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: '../support/edges.js'});
</script>
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
<link rel="match" href="../green-square-ref.html">
<meta name="assert" content="This test checks that padding sizes are passed to the layout correctly." />
<style>
.test {
writing-mode: vertical-rl;
background: red;
box-sizing: border-box;
height: 100px;
--edges-inline-start-expected: 10;
--edges-inline-end-expected: 0;
--edges-block-start-expected: 8;
--edges-block-end-expected: 20;
font-size: 8px;
padding: 10px 1em 0 20px;
}
@supports (display: layout(test)) {
.test {
display: layout(test);
background: green;
}
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<div class="test"></div>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, {url: '../support/edges.js'});
</script>
<!DOCTYPE html>
<style>
td { text-align: center; }
.parent {
box-sizing: border-box;
width: 50px;
height: 50px;
border: solid;
position: relative;
}
.child {
position: absolute;
width: 10px;
height: 10px;
background: green;
}
.top-left {
top: 0;
left: 0;
}
.top-right {
top: 0;
right: 0;
}
.bottom-left {
bottom: 0;
left: 0;
}
.bottom-right {
bottom: 0;
right: 0;
}
</style>
<table>
<tr>
<td></td>
<td colspan=2>LTR</td>
<td colspan=2>RTL</td>
</tr>
<tr>
<td></td>
<td>Y</td>
<td>X</td>
<td>Y</td>
<td>X</td>
</tr>
<tr>
<td>HTB</td>
<td>
<div class="parent" style="writing-mode: horizontal-tb; direction: ltr; overflow-y: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: horizontal-tb; direction: ltr; overflow-x: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: horizontal-tb; direction: rtl; overflow-y: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: horizontal-tb; direction: rtl; overflow-x: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
</tr>
<tr>
<td>VRL</td>
<td>
<div class="parent" style="writing-mode: vertical-rl; direction: ltr; overflow-y: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-rl; direction: ltr; overflow-x: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-rl; direction: rtl; overflow-y: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-rl; direction: rtl; overflow-x: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
</tr>
<tr>
<td>VLR</td>
<td>
<div class="parent" style="writing-mode: vertical-lr; direction: ltr; overflow-y: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-lr; direction: ltr; overflow-x: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-lr; direction: rtl; overflow-y: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-lr; direction: rtl; overflow-x: scroll;">
<div class="child top-left"></div>
<div class="child top-right"></div>
<div class="child bottom-left"></div>
<div class="child bottom-right"></div>
</div>
</td>
</tr>
</table>
<!DOCTYPE html>
<html class=reftest-wait>
<link rel="help" href="https://drafts.css-houdini.org/css-layout-api/#dom-layoutedges">
<link rel="match" href="scrollbar-ref.html">
<meta name="assert" content="This test checks that scrollbar sizes are passed to the layout correctly." />
<style>
td { text-align: center; }
.parent {
box-sizing: border-box;
width: 50px;
height: 50px;
border: solid;
position: relative;
background: red;
}
@supports (display: layout(test)) {
.parent {
display: layout(test);
background: initial;
}
}
.child {
width: 10px;
height: 10px;
background: green;
}
</style>
<!--
This test works by placing four children in each corner of the layout using the edges.
The reference to this test uses absolute positioning to achieve the same effect.
-->
<table>
<tr>
<td></td>
<td colspan=2>LTR</td>
<td colspan=2>RTL</td>
</tr>
<tr>
<td></td>
<td>Y</td>
<td>X</td>
<td>Y</td>
<td>X</td>
</tr>
<tr>
<td>HTB</td>
<td>
<div class="parent" style="writing-mode: horizontal-tb; direction: ltr; overflow-y: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: horizontal-tb; direction: ltr; overflow-x: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: horizontal-tb; direction: rtl; overflow-y: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: horizontal-tb; direction: rtl; overflow-x: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
</tr>
<tr>
<td>VRL</td>
<td>
<div class="parent" style="writing-mode: vertical-rl; direction: ltr; overflow-y: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-rl; direction: ltr; overflow-x: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-rl; direction: rtl; overflow-y: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-rl; direction: rtl; overflow-x: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
</tr>
<tr>
<td>VLR</td>
<td>
<div class="parent" style="writing-mode: vertical-lr; direction: ltr; overflow-y: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-lr; direction: ltr; overflow-x: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-lr; direction: rtl; overflow-y: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
<td>
<div class="parent" style="writing-mode: vertical-lr; direction: rtl; overflow-x: scroll;">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</td>
</tr>
</table>
<script src="/common/reftest-wait.js"></script>
<script src="/common/worklet-reftest.js"></script>
<script id="code" type="text/worklet">
registerLayout('test', class {
*intrinsicSizes() {}
*layout(children, edges, constraints) {
const topLeftFragment = yield children[0].layoutNextFragment();
const topRightFragment = yield children[1].layoutNextFragment();
const bottomLeftFragment = yield children[2].layoutNextFragment();
const bottomRightFragment = yield children[3].layoutNextFragment();
topLeftFragment.inlineOffset = edges.inlineStart;
topLeftFragment.blockOffset = edges.blockStart;
topRightFragment.inlineOffset =
constraints.fixedInlineSize - topRightFragment.inlineSize - edges.inlineEnd;
topRightFragment.blockOffset = edges.blockStart;
bottomLeftFragment.inlineOffset = edges.inlineStart;
bottomLeftFragment.blockOffset =
constraints.fixedBlockSize - bottomLeftFragment.blockSize - edges.blockEnd;
bottomRightFragment.inlineOffset =
constraints.fixedInlineSize - bottomRightFragment.inlineSize - edges.inlineEnd;
bottomRightFragment.blockOffset =
constraints.fixedBlockSize - bottomRightFragment.blockSize - edges.blockEnd;
return {childFragments: [
topLeftFragment,
topRightFragment,
bottomLeftFragment,
bottomRightFragment
]};
}
});
</script>
<script>
importWorkletAndTerminateTestAfterAsyncPaint(CSS.layoutWorklet, document.getElementById('code').textContent);
</script>
import {areArraysEqual} from '/common/arrays.js';
function parseNumber(value) {
const num = parseInt(value.toString());
if (isNaN(num)) return 0;
return num;
}
registerLayout('test', class {
static get inputProperties() {
return [
'--edges-inline-start-expected',
'--edges-inline-end-expected',
'--edges-block-start-expected',
'--edges-block-end-expected',
];
}
*intrinsicSizes() {}
*layout(children, edges, constraints, styleMap) {
const actual = this.constructor.inputProperties.map(
prop => parseNumber(styleMap.get(prop))
);
const expected = [
edges.inlineStart,
edges.inlineEnd,
edges.blockStart,
edges.blockEnd,
];
if (!areArraysEqual(expected, actual)) {
return {autoBlockSize: 0, childFragments: []};
}
return {autoBlockSize: 100, childFragment: []};
}
});
...@@ -304,6 +304,7 @@ core_idl_files = ...@@ -304,6 +304,7 @@ core_idl_files =
"intersection_observer/intersection_observer_entry.idl", "intersection_observer/intersection_observer_entry.idl",
"invisible_dom/activate_invisible_event.idl", "invisible_dom/activate_invisible_event.idl",
"layout/custom/layout_constraints.idl", "layout/custom/layout_constraints.idl",
"layout/custom/layout_edges.idl",
"layout/custom/layout_fragment.idl", "layout/custom/layout_fragment.idl",
"layout/custom/layout_fragment_request.idl", "layout/custom/layout_fragment_request.idl",
"layout/custom/layout_child.idl", "layout/custom/layout_child.idl",
......
...@@ -46,6 +46,8 @@ blink_core_sources("layout") { ...@@ -46,6 +46,8 @@ blink_core_sources("layout") {
"custom/custom_layout_child.h", "custom/custom_layout_child.h",
"custom/custom_layout_constraints.cc", "custom/custom_layout_constraints.cc",
"custom/custom_layout_constraints.h", "custom/custom_layout_constraints.h",
"custom/custom_layout_edges.cc",
"custom/custom_layout_edges.h",
"custom/custom_layout_fragment.cc", "custom/custom_layout_fragment.cc",
"custom/custom_layout_fragment.h", "custom/custom_layout_fragment.h",
"custom/custom_layout_fragment_request.cc", "custom/custom_layout_fragment_request.cc",
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/layout/custom/custom_layout_constraints.h" #include "third_party/blink/renderer/core/layout/custom/custom_layout_constraints.h"
#include "third_party/blink/renderer/core/layout/custom/custom_layout_edges.h"
#include "third_party/blink/renderer/core/layout/custom/custom_layout_fragment.h" #include "third_party/blink/renderer/core/layout/custom/custom_layout_fragment.h"
#include "third_party/blink/renderer/core/layout/custom/fragment_result_options.h" #include "third_party/blink/renderer/core/layout/custom/fragment_result_options.h"
#include "third_party/blink/renderer/core/layout/custom/layout_custom.h" #include "third_party/blink/renderer/core/layout/custom/layout_custom.h"
...@@ -112,6 +113,8 @@ bool CSSLayoutDefinition::Instance::Layout( ...@@ -112,6 +113,8 @@ bool CSSLayoutDefinition::Instance::Layout(
return false; return false;
} }
CustomLayoutEdges* edges = CustomLayoutEdges::Create(layout_custom);
LayoutUnit fixed_block_size(-1); LayoutUnit fixed_block_size(-1);
if (IsLogicalHeightDefinite(layout_custom)) { if (IsLogicalHeightDefinite(layout_custom)) {
LayoutBox::LogicalExtentComputedValues computed_values; LayoutBox::LogicalExtentComputedValues computed_values;
...@@ -132,10 +135,8 @@ bool CSSLayoutDefinition::Instance::Layout( ...@@ -132,10 +135,8 @@ bool CSSLayoutDefinition::Instance::Layout(
layout_custom.GetNode(), definition_->native_invalidation_properties_, layout_custom.GetNode(), definition_->native_invalidation_properties_,
definition_->custom_invalidation_properties_); definition_->custom_invalidation_properties_);
// TODO(ikilpatrick): Fill in layout constraints, and edges.
Vector<v8::Local<v8::Value>> argv = { Vector<v8::Local<v8::Value>> argv = {
children, children, ToV8(edges, context->Global(), isolate),
v8::Undefined(isolate), // edges
ToV8(constraints, context->Global(), isolate), ToV8(constraints, context->Global(), isolate),
ToV8(style_map, context->Global(), isolate), ToV8(style_map, context->Global(), isolate),
}; };
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/layout/custom/custom_layout_edges.h"
#include "third_party/blink/renderer/core/layout/custom/layout_custom.h"
namespace blink {
CustomLayoutEdges* CustomLayoutEdges::Create(
const LayoutCustom& layout_custom) {
PhysicalToLogical<LayoutUnit> logical_scrollbar(
layout_custom.StyleRef().GetWritingMode(),
layout_custom.StyleRef().Direction(),
/* top */ LayoutUnit(), layout_custom.RightScrollbarWidth(),
layout_custom.BottomScrollbarHeight(),
layout_custom.LeftScrollbarWidth());
return new CustomLayoutEdges(
layout_custom.BorderAndPaddingStart() + logical_scrollbar.InlineStart(),
layout_custom.BorderAndPaddingEnd() + logical_scrollbar.InlineEnd(),
layout_custom.BorderAndPaddingBefore() + logical_scrollbar.BlockStart(),
layout_custom.BorderAndPaddingAfter() + logical_scrollbar.BlockEnd());
}
CustomLayoutEdges::CustomLayoutEdges(LayoutUnit inline_start,
LayoutUnit inline_end,
LayoutUnit block_start,
LayoutUnit block_end)
: inline_start_(inline_start),
inline_end_(inline_end),
block_start_(block_start),
block_end_(block_end) {}
CustomLayoutEdges::~CustomLayoutEdges() = default;
} // namespace blink
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_CUSTOM_CUSTOM_LAYOUT_EDGES_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_CUSTOM_CUSTOM_LAYOUT_EDGES_H_
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class LayoutCustom;
class LayoutUnit;
// Represents the border, scrollbar, and padding edges given to the custom
// layout.
class CustomLayoutEdges : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
static CustomLayoutEdges* Create(const LayoutCustom&);
~CustomLayoutEdges() override;
// layout_edges.idl
double inlineStart() const { return inline_start_; }
double inlineEnd() const { return inline_end_; }
double blockStart() const { return block_start_; }
double blockEnd() const { return block_end_; }
double inlineSum() const { return inline_start_ + inline_end_; }
double blockSum() const { return block_start_ + block_end_; }
private:
CustomLayoutEdges(LayoutUnit inline_start,
LayoutUnit inline_end,
LayoutUnit block_start,
LayoutUnit block_end);
double inline_start_;
double inline_end_;
double block_start_;
double block_end_;
DISALLOW_COPY_AND_ASSIGN(CustomLayoutEdges);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_CUSTOM_CUSTOM_LAYOUT_EDGES_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// https://drafts.css-houdini.org/css-layout-api/#layoutedges
[
Exposed=LayoutWorklet,
ImplementedAs=CustomLayoutEdges,
RuntimeEnabled=CSSLayoutAPI
]
interface LayoutEdges {
readonly attribute double inlineStart;
readonly attribute double inlineEnd;
readonly attribute double blockStart;
readonly attribute double blockEnd;
[ImplementedAs=inlineSum] readonly attribute double inline;
[ImplementedAs=blockSum] readonly attribute double block;
};
...@@ -288,6 +288,7 @@ class CORE_EXPORT LayoutBoxModelObject : public LayoutObject { ...@@ -288,6 +288,7 @@ class CORE_EXPORT LayoutBoxModelObject : public LayoutObject {
LayoutUnit BorderAndPaddingStart() const { LayoutUnit BorderAndPaddingStart() const {
return BorderStart() + PaddingStart(); return BorderStart() + PaddingStart();
} }
LayoutUnit BorderAndPaddingEnd() const { return BorderEnd() + PaddingEnd(); }
DISABLE_CFI_PERF LayoutUnit BorderAndPaddingBefore() const { DISABLE_CFI_PERF LayoutUnit BorderAndPaddingBefore() const {
return BorderBefore() + PaddingBefore(); return BorderBefore() + PaddingBefore();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment