Improve repeated fixed-positioned layout logic.

What we had didn't work if there were nested out-of-flow positioned
elements. One thing was that if such nested OOFs caused additional
fragmentainers to be created, the fixed-positioned elements wouldn't be
repeated in those new fragmentainers.

Another problem was that we would end up with duplicate fragments for
the same OOF node (in the same fragmentainer!), if that node was nested
inside an absolutely positioned node. What triggered this was the double
layout of all OOFs, that we used to perform at the last fragmentainer
(the one we'd perform when is_known_to_be_very_last_fragmentainer got
set to true in LayoutOOFsInFragmentainer()). If any outer absolutely
positioned node had another OOFs inside, that inner OOF would be
propagated twice, eventually getting duplicate entries in
pending_descendants in the next call to LayoutOOFsInFragmentainer().
This could lead to DCHECK failures and crashes.

The only reason for doing layout twice for all OOFs in the last
fragmentainer, was to finalize the repeated nodes (deep-clone the
fragments, and make sure that the last fragment didn't have an outgoing
break token). But this isn't really necessary, if we split the
finalizing part of NGBlockNode::LayoutRepeatableRoot() into a separate
function, that NGOutOfFlowLayoutPart can call on its own.

Do that, and move all the logic one step up, to
LayoutFragmentainerDescendants(), where we have more control. This way
we can resume repetition of nodes, if nested OOFs causes creation of
additional fragmentainers.

Note that some of the new tests also pass without this CL.

Bug: 1399456
Change-Id: I5556873b7bc044c9d5aed6761bade05194b741f7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4157412
Reviewed-by: Alison Maher <almaher@microsoft.com>
Commit-Queue: Morten Stenshorne <mstensho@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1091727}
diff --git a/css/css-break/fixedpos-001-print-ref.html b/css/css-break/fixedpos-001-print-ref.html
new file mode 100644
index 0000000..3d66305
--- /dev/null
+++ b/css/css-break/fixedpos-001-print-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<style>
+  body { margin: 0; }
+</style>
+<div style="position:absolute; bottom:0;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-100vh;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-200vh;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; top:0;">
+  There should be three pages.
+</div>
diff --git a/css/css-break/fixedpos-001-print.html b/css/css-break/fixedpos-001-print.html
new file mode 100644
index 0000000..04feb96
--- /dev/null
+++ b/css/css-break/fixedpos-001-print.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1399456">
+<link rel="match" href="fixedpos-001-print-ref.html">
+<style>
+  body { margin: 0; }
+</style>
+<div style="position:fixed; bottom:0;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; height:300vh;">
+  There should be three pages.
+</div>
diff --git a/css/css-break/fixedpos-002-print-ref.html b/css/css-break/fixedpos-002-print-ref.html
new file mode 100644
index 0000000..3d66305
--- /dev/null
+++ b/css/css-break/fixedpos-002-print-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<style>
+  body { margin: 0; }
+</style>
+<div style="position:absolute; bottom:0;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-100vh;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-200vh;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; top:0;">
+  There should be three pages.
+</div>
diff --git a/css/css-break/fixedpos-002-print.html b/css/css-break/fixedpos-002-print.html
new file mode 100644
index 0000000..c23c6be
--- /dev/null
+++ b/css/css-break/fixedpos-002-print.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1399456">
+<link rel="match" href="fixedpos-002-print-ref.html">
+<style>
+  body { margin: 0; }
+</style>
+<div style="position:absolute; height:300vh;">
+  There should be three pages.
+  <div style="position:fixed; bottom:0;">
+    This should repeat on every page.
+  </div>
+</div>
diff --git a/css/css-break/fixedpos-003-print-ref.html b/css/css-break/fixedpos-003-print-ref.html
new file mode 100644
index 0000000..3d66305
--- /dev/null
+++ b/css/css-break/fixedpos-003-print-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<style>
+  body { margin: 0; }
+</style>
+<div style="position:absolute; bottom:0;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-100vh;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-200vh;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; top:0;">
+  There should be three pages.
+</div>
diff --git a/css/css-break/fixedpos-003-print.html b/css/css-break/fixedpos-003-print.html
new file mode 100644
index 0000000..1b06257
--- /dev/null
+++ b/css/css-break/fixedpos-003-print.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1399456">
+<link rel="match" href="fixedpos-003-print-ref.html">
+<style>
+  body { margin: 0; }
+</style>
+<div style="height:300vh;">
+  There should be three pages.
+</div>
+<div style="position:fixed; bottom:0;">
+  This should repeat on every page.
+</div>
diff --git a/css/css-break/fixedpos-004-print-ref.html b/css/css-break/fixedpos-004-print-ref.html
new file mode 100644
index 0000000..3e3473b
--- /dev/null
+++ b/css/css-break/fixedpos-004-print-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<style>
+  body { margin: 0; }
+</style>
+<div style="position:absolute; bottom:0; margin-bottom:2em;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-100vh; margin-bottom:2em;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-200vh; margin-bottom:2em;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:0;">
+  This should also repeat on every page.
+</div>
+<div style="position:absolute; bottom:-100vh;">
+  This should also repeat on every page.
+</div>
+<div style="position:absolute; bottom:-200vh;">
+  This should also repeat on every page.
+</div>
+<div style="position:absolute; top:0;">
+  There should be three pages.
+</div>
diff --git a/css/css-break/fixedpos-004-print.html b/css/css-break/fixedpos-004-print.html
new file mode 100644
index 0000000..c138e9c
--- /dev/null
+++ b/css/css-break/fixedpos-004-print.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1399456">
+<link rel="match" href="fixedpos-004-print-ref.html">
+<style>
+  body { margin: 0; }
+</style>
+<div style="position:fixed; bottom:2em;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute;">
+  There should be three pages.
+  <div style="position:absolute; top:0; height:300vh;">
+    <div style="position:fixed; bottom:0;">
+      This should also repeat on every page.
+    </div>
+  </div>
+</div>
diff --git a/css/css-break/fixedpos-005-print-ref.html b/css/css-break/fixedpos-005-print-ref.html
new file mode 100644
index 0000000..e692ff8d
--- /dev/null
+++ b/css/css-break/fixedpos-005-print-ref.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<style>
+  body { margin: 0; }
+</style>
+<div style="position:absolute; bottom:0; margin-bottom:2em;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-100vh; margin-bottom:2em;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-200vh; margin-bottom:2em;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-300vh; margin-bottom:2em;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-400vh; margin-bottom:2em;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:0;">
+  This should also repeat on every page.
+</div>
+<div style="position:absolute; bottom:-100vh;">
+  This should also repeat on every page.
+</div>
+<div style="position:absolute; bottom:-200vh;">
+  This should also repeat on every page.
+</div>
+<div style="position:absolute; bottom:-300vh;">
+  This should also repeat on every page.
+</div>
+<div style="position:absolute; bottom:-400vh;">
+  This should also repeat on every page.
+</div>
+<div style="height:100vh;">
+  There should be five pages.
+</div>
+<div style="height:300vh;">
+  This should be on the second page.
+</div>
+This should be on the fifth page.
diff --git a/css/css-break/fixedpos-005-print.html b/css/css-break/fixedpos-005-print.html
new file mode 100644
index 0000000..0a2edc7
--- /dev/null
+++ b/css/css-break/fixedpos-005-print.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1399456">
+<link rel="match" href="fixedpos-005-print-ref.html">
+<style>
+  body { margin: 0; }
+</style>
+<div style="height:300vh;">
+  There should be five pages.
+</div>
+<div style="position:fixed; bottom:2em;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; top:100vh;">
+  This should be on the second page.
+  <div style="position:fixed; bottom:0;">
+    This should also repeat on every page.
+  </div>
+  <div style="position:absolute; top:300vh;">
+    This should be on the fifth page.
+  </div>
+</div>
diff --git a/css/css-break/fixedpos-006-print-ref.html b/css/css-break/fixedpos-006-print-ref.html
new file mode 100644
index 0000000..b03e1d7
--- /dev/null
+++ b/css/css-break/fixedpos-006-print-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<style>
+  body { margin: 0; }
+</style>
+<div style="position:absolute; bottom:0; margin-bottom:4em;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-100vh; margin-bottom:4em;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-200vh; margin-bottom:4em;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-300vh; margin-bottom:4em;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-400vh; margin-bottom:4em;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; bottom:0; margin-bottom:2em;">
+  This should also repeat on every page.
+</div>
+<div style="position:absolute; bottom:-100vh; margin-bottom:2em;">
+  This should also repeat on every page.
+</div>
+<div style="position:absolute; bottom:-200vh; margin-bottom:2em;">
+  This should also repeat on every page.
+</div>
+<div style="position:absolute; bottom:-300vh; margin-bottom:2em;">
+  This should also repeat on every page.
+</div>
+<div style="position:absolute; bottom:-400vh; margin-bottom:2em;">
+  This should also repeat on every page.
+</div>
+<div style="position:absolute; bottom:0;">
+  Even this should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-100vh;">
+  Even this should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-200vh;">
+  Even this should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-300vh;">
+  Even this should repeat on every page.
+</div>
+<div style="position:absolute; bottom:-400vh;">
+  Even this should repeat on every page.
+</div>
+<div style="height:100vh;">
+  There should be five pages.
+</div>
+<div style="height:100vh;">
+  This should be on the second page.
+</div>
+This should be on the third page.
diff --git a/css/css-break/fixedpos-006-print.html b/css/css-break/fixedpos-006-print.html
new file mode 100644
index 0000000..2386c16
--- /dev/null
+++ b/css/css-break/fixedpos-006-print.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1399456">
+<link rel="match" href="fixedpos-006-print-ref.html">
+<style>
+  body { margin: 0; }
+</style>
+There should be five pages.
+<div style="position:fixed; bottom:4em;">
+  This should repeat on every page.
+</div>
+<div style="position:absolute; top:100vh;">
+  This should be on the second page.
+  <div style="position:fixed; bottom:2em;">
+    This should also repeat on every page.
+  </div>
+  <div style="position:absolute; top:100vh; height:300vh;">
+    This should be on the third page.
+    <div style="position:fixed; bottom:0;">
+      Even this should repeat on every page.
+    </div>
+  </div>
+</div>
diff --git a/css/css-break/fixedpos-007-print-ref.html b/css/css-break/fixedpos-007-print-ref.html
new file mode 100644
index 0000000..f576c93
--- /dev/null
+++ b/css/css-break/fixedpos-007-print-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<style>
+  body { margin: 0; }
+</style>
+<div style="margin-top:4em;">
+  There should be three pages.
+</div>
+<div style="position:absolute; top:0;">
+  This should be repeated on every page.
+</div>
+<div style="position:absolute; top:100vh;">
+  This should be repeated on every page.
+</div>
+<div style="position:absolute; top:200vh;">
+  This should be repeated on every page.
+</div>
+<div style="position:absolute; top:0; margin-top:2em;">
+  This should also be repeated on every page.
+</div>
+<div style="position:absolute; top:100vh; margin-top:2em;">
+  This should also be repeated on every page.
+</div>
+<div style="position:absolute; top:200vh; margin-top:2em;">
+  This should also be repeated on every page.
+</div>
diff --git a/css/css-break/fixedpos-007-print.html b/css/css-break/fixedpos-007-print.html
new file mode 100644
index 0000000..8dcb700
--- /dev/null
+++ b/css/css-break/fixedpos-007-print.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1399456">
+<link rel="match" href="fixedpos-007-print-ref.html">
+<style>
+  body { margin: 0; }
+</style>
+<div style="margin-top:4em;">
+  There should be three pages.
+</div>
+<div style="position:absolute; top:50vh;">
+  <div style="height:250vh;"></div>
+  <div style="position:fixed; top:0;">
+    This should be repeated on every page.
+  </div>
+</div>
+<div style="position:fixed; top:2em;">
+  This should also be repeated on every page.
+</div>
diff --git a/css/css-break/fixedpos-008-print-ref.html b/css/css-break/fixedpos-008-print-ref.html
new file mode 100644
index 0000000..6ed2528
--- /dev/null
+++ b/css/css-break/fixedpos-008-print-ref.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<style>
+  body { margin: 0; }
+</style>
+<div style="margin-top:4em;">
+  There should be six pages.
+</div>
+<div style="position:absolute; top:0;">
+  This should be repeated on every page.
+</div>
+<div style="position:absolute; top:100vh;">
+  This should be repeated on every page.
+</div>
+<div style="position:absolute; top:200vh;">
+  This should be repeated on every page.
+</div>
+<div style="position:absolute; top:300vh;">
+  This should be repeated on every page.
+</div>
+<div style="position:absolute; top:400vh;">
+  This should be repeated on every page.
+</div>
+<div style="position:absolute; top:500vh;">
+  This should be repeated on every page.
+</div>
+<div style="position:absolute; bottom:0;">
+  This should also be repeated on every page.
+</div>
+<div style="position:absolute; bottom:-100vh;">
+  This should also be repeated on every page.
+</div>
+<div style="position:absolute; bottom:-200vh;">
+  This should also be repeated on every page.
+</div>
+<div style="position:absolute; bottom:-300vh;">
+  This should also be repeated on every page.
+</div>
+<div style="position:absolute; bottom:-400vh;">
+  This should also be repeated on every page.
+</div>
+<div style="position:absolute; bottom:-500vh;">
+  This should also be repeated on every page.
+</div>
diff --git a/css/css-break/fixedpos-008-print.html b/css/css-break/fixedpos-008-print.html
new file mode 100644
index 0000000..02b5d63
--- /dev/null
+++ b/css/css-break/fixedpos-008-print.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1399456">
+<link rel="match" href="fixedpos-008-print-ref.html">
+<style>
+  body { margin: 0; }
+</style>
+<div style="margin-top:4em;">
+  There should be six pages.
+</div>
+<div style="position:fixed; top:0;">
+  This should be repeated on every page.
+</div>
+<div style="position:absolute; top:50vh;">
+  <div style="height:250vh;"></div>
+  <div style="position:absolute; top:0;">
+    <div style="position:absolute; top:500vh; height:10px;">
+      <div style="position:fixed; bottom:0;">
+        This should also be repeated on every page.
+      </div>
+    </div>
+  </div>
+</div>