Bug 1657453 [wpt PR 24898] - Reland again "Use border box or layout overflow rect for layout shift tracking", a=testonly
authorXianzhu Wang <wangxianzhu@chromium.org>
Fri, 07 Aug 2020 12:45:24 +0000
changeset 544839 571458658bacee7d58d4c5e6e5587c370b8d2b47
parent 544838 ec620dcbbe8128643c8979fffeea698acf043c5d
child 544840 2b41a9728fab28ae67ede27252fda82d1885dc1b
push id37701
push userrmaries@mozilla.com
push dateSat, 15 Aug 2020 21:17:39 +0000
treeherdermozilla-central@ffc01c0f13a8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1657453, 24898, 2319538, 2333648, 2336301, 2335647, 1108622, 795179
milestone81.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1657453 [wpt PR 24898] - Reland again "Use border box or layout overflow rect for layout shift tracking", a=testonly Automatic update from web-platform-tests Reland again "Use border box or layout overflow rect for layout shift tracking" Original patch: crrev.com/c/2319538 First reland: crrev.com/c/2333648 Changes in this patch (https://chromium-review.googlesource.com/c/chromium/src/+/2336301/1..10) 1. Fixed use-after-free of ContainingBlockScope. Similar to the first revert, the issue was because it was allocated in PaintInvalidatorContext which is in a vector replacing the real stack. ContainingBlockScope::outer_ might point to an invalid address if the vector was reallocated. Now use std::unique_ptr<ContainingBlockScope> in PaintInvalidatorContext. This increases the cost a bit but not much because ContainingBlockScope is created for LayoutBlockFlow with inline children only. 2. Rebased on crrev.com/c/2335647 which avoids memory regression caused by the original CL, and enables LayoutShiftTracker to use more accurate previous rects for shifted boxes. 3. Simplify LayoutShiftTracker::ReattachHook[::Scope]. Bug: 1108622 Change-Id: I7b4a85675483f7006ade8925c159a7882f08ec27 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2336301 Reviewed-by: Steve Kobes <skobes@chromium.org> Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org> Cr-Commit-Position: refs/heads/master@{#795179} -- wpt-commits: 70f8d7999f7af89efa26bd96567dbb7417aec4c5 wpt-pr: 24898
testing/web-platform/tests/layout-instability/child-shift-with-parent-overflow-hidden.html
testing/web-platform/tests/layout-instability/child-shift-with-parent.html
testing/web-platform/tests/layout-instability/inline-flow-shift-vertical-rl.html
testing/web-platform/tests/layout-instability/inline-flow-shift.html
testing/web-platform/tests/layout-instability/outline.html
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/layout-instability/child-shift-with-parent-overflow-hidden.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<title>Layout Instability: parent (with overflow:hidden) and child moved together</title>
+<link rel="help" href="https://wicg.github.io/layout-instability/" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/util.js"></script>
+<div id="parent" style="position: relative; width: 200px; height: 200px;
+                        border: 50px solid blue; overflow: hidden">
+  <div id="child" style="height: 400px"></div>
+</div>
+<script>
+
+promise_test(async () => {
+  const watcher = new ScoreWatcher;
+
+  // Wait for the initial render to complete.
+  await waitForAnimationFrames(2);
+
+  // Modify the position of the div.
+  const parent = document.querySelector("#parent");
+  parent.style.top = '100px';
+
+  // Only the parent area should be reported.
+  const expectedScore = computeExpectedScore(300 * (300 + 100), 100);
+
+  // Observer fires after the frame is painted.
+  assert_equals(watcher.score, 0);
+  await watcher.promise;
+  assert_equals(watcher.score, expectedScore);
+}, 'Parent (with overflow:hidden) and child moved together.');
+
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/layout-instability/child-shift-with-parent.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>Layout Instability: parent/child moved together</title>
+<link rel="help" href="https://wicg.github.io/layout-instability/" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/util.js"></script>
+<div id="parent" style="position: relative; width: 100px; height: 100px; border: 100px solid blue">
+  <div id="child" style="height: 300px"></div>
+</div>
+<script>
+
+promise_test(async () => {
+  const watcher = new ScoreWatcher;
+
+  // Wait for the initial render to complete.
+  await waitForAnimationFrames(2);
+
+  // Modify the position of the div.
+  const parent = document.querySelector("#parent");
+  parent.style.top = '100px';
+
+  // If the implementation reports child and parent separately
+  // (overlapping are should be excluded):
+  const expectedScoreMin = computeExpectedScore(300 * (300 + 100) + 100 * 100, 100);
+  // If the implementation reports parent bounding box (including child):
+  const expectedScoreMax = computeExpectedScore(300 * (400 + 100), 100);
+
+  // Observer fires after the frame is painted.
+  assert_equals(watcher.score, 0);
+  await watcher.promise;
+  assert_between_inclusive(watcher.score, expectedScoreMin, expectedScoreMax);
+}, 'Parent/child movement.');
+
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/layout-instability/inline-flow-shift-vertical-rl.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<title>Layout Instability: vertical-rl inline/text movement is detected</title>
+<link rel="help" href="https://wicg.github.io/layout-instability/" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/util.js"></script>
+<body style="writing-mode: vertical-rl">
+<div style="height: 200px; font-size: 20px; line-height: 25px">
+  1AAAAAAA<br>
+  2AAAAAAA<br>
+  3AAAAAAA<br>
+  <div id="inline-block" style="display: inline-block; width: 50px">4AAAAAAA</div><br>
+  5AAAAAAA<br>
+  6AAAAAAA<br>
+  7AAAAAAA<br>
+</div>
+<script>
+
+promise_test(async () => {
+  const watcher = new ScoreWatcher;
+
+  // Wait for the initial render to complete.
+  await waitForAnimationFrames(2);
+
+  // Modify the position of the div.
+  const inline_block = document.querySelector("#inline-block");
+  inline_block.style.width = '100px';
+
+  // The lines below the inline-block are shifted down by 50px.
+  // The implementation may measure the real width of the shifted text
+  // or use the available width (i.e. width of the containing block).
+  // Also tolerate extra 10% error.
+  const text_width = inline_block.offsetWidth;
+  const expectedScoreMin = computeExpectedScore(text_width * (30 * 3 + 50), 50) * 0.9;
+  const expectedScoreMax = computeExpectedScore(200 * (30 * 3 + 50), 50) * 1.1;
+
+  // Observer fires after the frame is painted.
+  assert_equals(watcher.score, 0);
+  await watcher.promise;
+  assert_between_exclusive(watcher.score, expectedScoreMin, expectedScoreMax);
+}, 'Vertical-rl inline flow movement.');
+
+</script>
+</body>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/layout-instability/inline-flow-shift.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<title>Layout Instability: inline/text movement is detected</title>
+<link rel="help" href="https://wicg.github.io/layout-instability/" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/util.js"></script>
+<div style="width: 200px; font-size: 20px; line-height: 25px">
+  1AAAAAAA<br>
+  2AAAAAAA<br>
+  3AAAAAAA<br>
+  <div id="inline-block" style="display: inline-block; height: 50px">4AAAAAAA</div><br>
+  5AAAAAAA<br>
+  6AAAAAAA<br>
+  7AAAAAAA<br>
+</div>
+<script>
+
+promise_test(async () => {
+  const watcher = new ScoreWatcher;
+
+  // Wait for the initial render to complete.
+  await waitForAnimationFrames(2);
+
+  // Modify the position of the div.
+  const inline_block = document.querySelector("#inline-block");
+  inline_block.style.height = '100px';
+
+  // The lines below the inline-block are shifted down by 50px.
+  // The implementation may measure the real width of the shifted text
+  // or use the available width (i.e. width of the containing block).
+  // Also tolerate extra 10% error.
+  const text_width = inline_block.offsetWidth;
+  const expectedScoreMin = computeExpectedScore(text_width * (30 * 3 + 50), 50) * 0.9;
+  const expectedScoreMax = computeExpectedScore(200 * (30 * 3 + 50), 50) * 1.1;
+
+  // Observer fires after the frame is painted.
+  assert_equals(watcher.score, 0);
+  await watcher.promise;
+  assert_between_exclusive(watcher.score, expectedScoreMin, expectedScoreMax);
+}, 'Inline flow movement.');
+
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/layout-instability/outline.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<title>Layout Instability: outline doesn't contribute to layout shift</title>
+<link rel="help" href="https://wicg.github.io/layout-instability/" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/util.js"></script>
+<div id="target" style="width: 300px; height: 300px"></div>
+<script>
+promise_test(async () => {
+  const watcher = new ScoreWatcher;
+
+  // Wait for the initial render to complete.
+  await waitForAnimationFrames(2);
+
+  // Add outline for target. This should not generate a shift.
+  target.style.outline = "10px solid blue";
+
+  await waitForAnimationFrames(3);
+  assert_equals(watcher.score, 0);
+}, "Outline.");
+</script>