Bug 1527353 [wpt PR 15335] - [LayoutNG] Invalidate layout when OOF-positioned gets added/removed., a=testonly
authorIan Kilpatrick <ikilpatrick@chromium.org>
Tue, 05 Mar 2019 12:14:48 +0000
changeset 464547 43322b4cde08
parent 464546 35d0e81b48a8
child 464548 51e1957476b2
push id35717
push useraciure@mozilla.com
push dateSun, 17 Mar 2019 09:45:26 +0000
treeherdermozilla-central@e0861be8d6c0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1527353, 15335, 635619, 1396777, 632256
milestone67.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 1527353 [wpt PR 15335] - [LayoutNG] Invalidate layout when OOF-positioned gets added/removed., a=testonly Automatic update from web-platform-tests [LayoutNG] Invalidate layout when OOF-positioned gets added/removed. This patch allows us to reuse a cached layout result when we have OOF-positioned descendants in the result. In order to do this whenever a OOF-positioned object gets added or removed we invalidate the parent chain for all objects which may contain this element inside its layout result. There are more optimal versions of this approach, which I've noted inside a comment, but this seems good enough for now. Bug: 635619 Change-Id: I4b29fcc26154dcd76cee55455d83558c6cf798fa Reviewed-on: https://chromium-review.googlesource.com/c/1396777 Reviewed-by: Emil A Eklund <eae@chromium.org> Reviewed-by: Morten Stenshorne <mstensho@chromium.org> Reviewed-by: Aleks Totic <atotic@chromium.org> Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org> Cr-Commit-Position: refs/heads/master@{#632256} -- wpt-commits: bbe1144015e708f62b9ae30b3770884db94e504b wpt-pr: 15335
testing/web-platform/tests/css/css-position/position-absolute-dynamic-containing-block.html
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-position/position-absolute-dynamic-containing-block.html
@@ -0,0 +1,140 @@
+<!DOCTYPE html>
+<title>CSS Position: position:absolute dynamic containing block</title>
+<link rel="author" title="mailto:atotic@google.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://drafts.csswg.org/css-position-3/#def-cb">
+<meta name="assert" content="Tests changes in containing block for out-of-flow positioned descendants.">
+<style>
+
+#outer {
+  width: 400px;
+  height: 300px;
+  outline: black solid 1px;
+}
+#intermediate {
+  width: 300px;
+  height: 200px;
+  outline: gray solid 1px;
+}
+#target {
+  background: green;
+}
+.abs {
+  position: absolute;
+  top: 0;
+  left: 0;
+  bottom: 0;
+  right: 0;
+}
+.fixed {
+  position: fixed;
+  top: 0;
+  left: 0;
+  bottom: 0;
+  right: 0;
+}
+.abs-container {
+  position: relative;
+}
+.fixed-container {
+  will-change: transform;
+}
+div {
+  padding: 5px;
+}
+</style>
+<!-- This tests potential caching of out-of-flow positioned descendants. -->
+<div id="outer">
+  <div>
+    <div id="intermediate">
+      <div>
+        <div id="target">TTT</div>
+        <div id="noLayout1"></div>
+      </div>
+      <div id="noLayout2"></div>
+    </div>
+  </div>
+</div>
+<script>
+  let outer = document.querySelector("#outer");
+  let intermediate = document.querySelector("#intermediate");
+  let target = document.querySelector("#target");
+  let padding = 5;
+
+  function cleanup() {
+    outer.className = "";
+    intermediate.className = "";
+    target.className = "";
+    document.body.offsetTop;
+  }
+
+  test( t => {
+    t.add_cleanup(cleanup);
+    outer.classList.add("abs-container");
+    target.classList.add("abs");
+    assert_equals(target.offsetHeight, outer.offsetHeight);
+    intermediate.classList.add("abs-container");
+    assert_equals(target.offsetHeight, intermediate.offsetHeight);
+  }, "abs containing block moves from outer to intermediate" );
+  test( t => {
+    t.add_cleanup(cleanup);
+    target.classList.add("abs");
+    intermediate.classList.add("abs-container");
+    assert_equals(target.offsetHeight, intermediate.offsetHeight);
+    outer.classList.add("abs-container");
+    assert_equals(target.offsetHeight, intermediate.offsetHeight);
+    intermediate.classList.remove("abs-container");
+    assert_equals(target.offsetHeight, outer.offsetHeight);
+  }, "abs containing block moves from intermediate to outer" );
+  test( t => {
+    t.add_cleanup(cleanup);
+    target.classList.add("abs");
+    outer.classList.add("abs-container");
+    assert_equals(target.offsetHeight, outer.offsetHeight);
+    target.classList.remove("abs");
+    assert_equals(target.offsetWidth, intermediate.offsetWidth - 4 * padding);
+  }, "target is no longer absolute");
+  test( t => {
+    t.add_cleanup(cleanup);
+    outer.classList.add("abs-container");
+    assert_equals(target.offsetWidth, intermediate.offsetWidth - 4 * padding);
+    target.classList.add("abs");
+    assert_equals(target.offsetHeight, outer.offsetHeight);
+  }, "target becomes absolute");
+
+ // Repeat same tests with fixed
+  test( t => {
+    t.add_cleanup(cleanup);
+    outer.classList.add("fixed-container");
+    target.classList.add("fixed");
+    assert_equals(target.offsetHeight, outer.offsetHeight);
+    intermediate.classList.add("fixed-container");
+    assert_equals(target.offsetHeight, intermediate.offsetHeight);
+  }, "fixed containing block moves from outer to intermediate" );
+  test( t => {
+    t.add_cleanup(cleanup);
+    target.classList.add("fixed");
+    intermediate.classList.add("fixed-container");
+    assert_equals(target.offsetHeight, intermediate.offsetHeight);
+    outer.classList.add("fixed-container");
+    assert_equals(target.offsetHeight, intermediate.offsetHeight);
+    intermediate.classList.remove("fixed-container");
+    assert_equals(target.offsetHeight, outer.offsetHeight);
+  }, "fixed containing block moves from intermediate to outer" );
+  test( t => {
+    t.add_cleanup(cleanup);
+    target.classList.add("fixed");
+    outer.classList.add("fixed-container");
+    assert_equals(target.offsetHeight, outer.offsetHeight);
+    target.classList.remove("fixed");
+    assert_equals(target.offsetWidth, intermediate.offsetWidth - 4 * padding);
+  }, "target is no longer fixed");
+  test( t => {
+    t.add_cleanup(cleanup);
+    outer.classList.add("fixed-container");
+    assert_equals(target.offsetWidth, intermediate.offsetWidth - 4 * padding);
+    target.classList.add("fixed");
+    assert_equals(target.offsetHeight, outer.offsetHeight);
+  }, "target becomes fixed");
+</script>