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 522165 a7ee2a24d89807ed007b8c244bf1d78dfab483af
parent 522164 5fb707e280c13e4f7e61d437c66dd59940078ac1
child 522166 e63c628980332dd9094a0cd37e66765574e021e2
push id10871
push usercbrindusan@mozilla.com
push dateMon, 18 Mar 2019 15:49:32 +0000
treeherdermozilla-beta@018abdd16060 [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>