Fix RecalcLayoutOverflow() for multicol in LayoutNGBlockFragmentation

The fragmentainer in multicol is still using a legacy layout object.
When we reach the fragment of the column, we get
a LayoutMultiColumnFlowThread legacy object,
and we call LayoutBlock::RecalcLayoutOverflow().
That means that we start to use the legacy layout code
to recalc the layout overflow.

To fix this this patch is skipping the fragmentainers
in RecalcChildLayoutOverflow(), and going to the children directly.
The fragmentainers have the positioned objects as children,
so we process them properly.

The patch also uses AllowPostLayoutScope to avoid DCHECK failures,
as all the recalc layout overflow code uses PostLayout.

This only fixes the scrollable-overflow-transform-dynamic-008.html test
when LayoutNGBlockFragmentation is enabled.
Only the first test case pass, due to an invalidation issue related to
multicol and positioned elements (see crbug.com/1223220).

BUG=1221181,1223220
TEST=external/wpt/css/css-multicol/multicol-overflow-positioned-transform-001.html
TEST=external/wpt/css/css-multicol/multicol-overflow-transform-001.html

Change-Id: I8ecda520551f2c3e832f2e77cdedcb1fc17fe99f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2968984
Reviewed-by: Morten Stenshorne <mstensho@chromium.org>
Reviewed-by: Alison Maher <almaher@microsoft.com>
Commit-Queue: Manuel Rego <rego@igalia.com>
Cr-Commit-Position: refs/heads/master@{#897304}
diff --git a/css/css-multicol/multicol-overflow-positioned-transform-001.html b/css/css-multicol/multicol-overflow-positioned-transform-001.html
new file mode 100644
index 0000000..f0a22b9
--- /dev/null
+++ b/css/css-multicol/multicol-overflow-positioned-transform-001.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Multi-column: Scrollable Overflow Transform Dynamic Positioned Element</title>
+<link rel="author" titlae="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-multicol/" />
+<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable" />
+<meta name="assert" content="Checks that changes on an element's transform contribute to the scrollable overflow on a positioned element in a multicol.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+  .container {
+    position: absolute;
+    width: 100px;
+    height: 100px;
+    overflow: auto;
+    background: silver;
+    border: solid thick;
+  }
+
+  .element {
+    width: 50px;
+    height: 50px;
+    background: lime;
+  }
+</style>
+
+<div style="column-count: 2;">
+
+  <div style="position: relative;">
+
+    <div id="container1" style="top: 0px;" class="container">
+      <div id="element1" style="transform: translateX(20px);" class="element"></div>
+    </div>
+
+    <div id="container2" style="top: 150px;" class="container">
+      <div id="element2" style="transform: translateY(30px);" class="element"></div>
+    </div>
+
+    <div id="container3" style="top: 300px;" class="container">
+      <div id="element3" style="transform: translate(20px, 30px);" class="element"></div>
+    </div>
+
+  </div>
+
+</div>
+
+<script>
+  test(() => {
+    assert_equals(container1.scrollWidth, 100);
+    element1.style.transform = "translateX(200px)";
+    assert_equals(container1.scrollWidth, 250);
+  }, "Check scrollWidth before and after transform chage");
+
+  test(() => {
+    assert_equals(container2.scrollHeight, 100);
+    element2.style.transform = "translateY(300px)";
+    assert_equals(container2.scrollHeight, 350);
+  }, "Check scrollHeight before and after transform chage");
+
+  test(() => {
+    assert_equals(container3.scrollWidth, 100);
+    assert_equals(container3.scrollHeight, 100);
+    element3.style.transform = "translate(200px, 300px)";
+    assert_equals(container3.scrollWidth, 250);
+    assert_equals(container3.scrollHeight, 350);
+  }, "Check scrollWidth and scrollHeight before and after transform chage");
+</script>
diff --git a/css/css-multicol/multicol-overflow-transform-001.html b/css/css-multicol/multicol-overflow-transform-001.html
new file mode 100644
index 0000000..97608a2
--- /dev/null
+++ b/css/css-multicol/multicol-overflow-transform-001.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Multi-column: Scrollable Overflow Transform Dynamic</title>
+<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-multicol/" />
+<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable" />
+<meta name="assert" content="Checks that changes on an element's transform contribute to the scrollable overflow on an element in a multicol.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+  .container {
+    width: 100px;
+    height: 100px;
+    overflow: auto;
+    background: silver;
+    border: solid thick;
+  }
+
+  .element {
+    width: 50px;
+    height: 50px;
+    background: lime;
+  }
+</style>
+
+<div style="column-count: 2;">
+
+  <div style="position: relative;">
+
+    <div id="container1" class="container">
+      <div id="element1" style="transform: translateX(20px);" class="element"></div>
+    </div>
+
+    <div id="container2" class="container">
+      <div id="element2" style="transform: translateY(30px);" class="element"></div>
+    </div>
+
+    <div id="container3" class="container">
+      <div id="element3" style="transform: translate(20px, 30px);" class="element"></div>
+    </div>
+
+  </div>
+
+</div>
+
+<script>
+  test(() => {
+    assert_equals(container1.scrollWidth, 100);
+    element1.style.transform = "translateX(200px)";
+    assert_equals(container1.scrollWidth, 250);
+  }, "Check scrollWidth before and after transform chage");
+
+  test(() => {
+    assert_equals(container2.scrollHeight, 100);
+    element2.style.transform = "translateY(300px)";
+    assert_equals(container2.scrollHeight, 350);
+  }, "Check scrollHeight before and after transform chage");
+
+  test(() => {
+    assert_equals(container3.scrollWidth, 100);
+    assert_equals(container3.scrollHeight, 100);
+    element3.style.transform = "translate(200px, 300px)";
+    assert_equals(container3.scrollWidth, 250);
+    assert_equals(container3.scrollHeight, 350);
+  }, "Check scrollWidth and scrollHeight before and after transform chage");
+</script>