Bug 1640051 - Pull child's next-in-flow up after moving the child from overflow list to principal child list. r=dholbert

This is an extension to Bug 1271392 part 2.
https://hg.mozilla.org/mozilla-central/rev/98710f78e04da1294b72517b5c5d7e0841eeb326

In flex/grid container P1's NormalizeChildLists(), when pulling up a
first-in-flow frame F1 into the principal child list, we've already made
sure its next-in-flow F2 is in P1's next-in-flow P2's respective
overflow list.

However, when reflowing P2, F2's next-in-flow may still be away in any
of P2's next continuation chain, not necessary in P2's immediate
next-in-flow P3. We'd want to pull up F2's next-in-flow (if any) after
we move F2 from P2's overflow list into principal child list.

This satisfies the assertion when calling
SanityCheckChildListsBeforeReflow() on P3, i.e. any P2 children's
next-in-flow should be in P3.

Differential Revision: https://phabricator.services.mozilla.com/D78850
This commit is contained in:
Ting-Yu Lin 2020-06-12 19:14:25 +00:00
Родитель fb21526937
Коммит 0c810869ed
3 изменённых файлов: 54 добавлений и 21 удалений

Просмотреть файл

@ -0,0 +1,20 @@
<style>
* {
column-width: 0em;
font-weight: bold;
overflow-wrap: break-word
}
</style>
<script>
window.onload = () => {
a.style.setProperty("display", "flex")
}
</script>
<time>AAAAAAAAAAAAAAAAAA</time>
<content style="font-size: large">AAAAAAAAAAAAAA</content>
<layer>AAAAAAAAAAA</layer>
<pre id="a" wrap="">
<dir>
<li>AAAAAAAAAAAAAAA</li>
</pre>
<svg>

Просмотреть файл

@ -770,4 +770,5 @@ load 1630385.html
load 1633434.html
load 1633828.html
load 1640028.html
load 1640051.html
load 1640275.html

Просмотреть файл

@ -1828,6 +1828,34 @@ void nsContainerFrame::NormalizeChildLists() {
}
}
// Pull up item's next-in-flow (if any) into aItems, and reparent it to our
// next-in-flow, unless its parent is already our next-in-flow (to avoid
// leaving a hole there).
auto PullItemsNextInFlow = [this](const nsFrameList& aItems) {
auto* firstNIF = static_cast<nsContainerFrame*>(GetNextInFlow());
if (!firstNIF) {
return;
}
nsFrameList childNIFs;
nsFrameList childOCNIFs;
for (auto* child : aItems) {
auto* childNIF = child->GetNextInFlow();
if (childNIF && childNIF->GetParent() != firstNIF) {
auto* parent = childNIF->GetParent();
parent->StealFrame(childNIF);
ReparentFrame(childNIF, parent, firstNIF);
if (childNIF->HasAnyStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER)) {
childOCNIFs.AppendFrame(nullptr, childNIF);
} else {
childNIFs.AppendFrame(nullptr, childNIF);
}
}
}
// Merge aItems' NIFs into our NIF's respective overflow child lists.
firstNIF->MergeSortedOverflow(childNIFs);
firstNIF->MergeSortedExcessOverflowContainers(childOCNIFs);
};
// Merge our own overflow frames into our principal child list,
// except those that are a next-in-flow for one of our items.
DebugOnly<bool> foundOwnPushedChild = false;
@ -1848,6 +1876,10 @@ void nsContainerFrame::NormalizeChildLists() {
}
f = next;
}
if (items.NotEmpty()) {
PullItemsNextInFlow(items);
}
MergeSortedFrameLists(mFrames, items, GetContent());
if (ourOverflow->IsEmpty()) {
DestroyOverflowList();
@ -1885,7 +1917,6 @@ void nsContainerFrame::NormalizeChildLists() {
RemoveStateBits(didPushItemsBit);
nsFrameList items;
auto* nif = static_cast<nsContainerFrame*>(GetNextInFlow());
auto* firstNIF = nif;
DebugOnly<bool> nifNeedPushedItem = false;
while (nif) {
nsFrameList nifItems;
@ -1929,26 +1960,7 @@ void nsContainerFrame::NormalizeChildLists() {
}
if (!items.IsEmpty()) {
// Pull up the first next-in-flow of the pulled up items too, unless its
// parent is our nif (to avoid leaving a hole there).
nsFrameList childNIFs;
nsFrameList childOCNIFs;
for (auto* child : items) {
auto* childNIF = child->GetNextInFlow();
if (childNIF && childNIF->GetParent() != firstNIF) {
auto* parent = childNIF->GetParent();
parent->StealFrame(childNIF);
ReparentFrame(childNIF, parent, firstNIF);
if ((childNIF->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) {
childOCNIFs.AppendFrame(nullptr, childNIF);
} else {
childNIFs.AppendFrame(nullptr, childNIF);
}
}
}
// Merge items' NIFs into our NIF's respective overflow child lists.
firstNIF->MergeSortedOverflow(childNIFs);
firstNIF->MergeSortedExcessOverflowContainers(childOCNIFs);
PullItemsNextInFlow(items);
}
MOZ_ASSERT(