Bug 1474768: Fix nsInlineFrame::ReflowInlineFrame to properly detect whether we'll pull from a next-in-flow. r=dbaron

The key difference is checking the overflow lists from the next in flows, which
is something that PullOneFrame does but ReflowInlineFrame didn't.

MozReview-Commit-ID: I1JwOOeIBo9
This commit is contained in:
Emilio Cobos Álvarez 2018-07-21 01:09:24 +02:00
Родитель 3742f072f3
Коммит 33cdb446f0
4 изменённых файлов: 54 добавлений и 9 удалений

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

@ -0,0 +1,22 @@
<style>
* {
max-height: 0mm;
}
:not(script) {
columns: 0px;
border-right-style: dashed;
}
</style>
<script>
function go() {
a.replaceWith(b);
}
</script>
<body onload=go()>
<data>
<video></video>
<br></br>
<span>
<ol>
<li id="a"></li>
<form id="b">

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

@ -701,3 +701,4 @@ load 1461039.html
load 1461979-1.html
load 1467239.html
load 1472403.html
load 1474768.html

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

@ -697,6 +697,24 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
#endif
}
// Returns whether there's any remaining frame to pull.
/* static */ bool
nsInlineFrame::HasFramesToPull(nsInlineFrame* aNextInFlow)
{
while (aNextInFlow) {
if (!aNextInFlow->mFrames.IsEmpty()) {
return true;
}
if (const nsFrameList* overflow = aNextInFlow->GetOverflowFrames()) {
if (!overflow->IsEmpty()) {
return true;
}
}
aNextInFlow = static_cast<nsInlineFrame*>(aNextInFlow->GetNextInFlow());
}
return false;
}
void
nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext,
const ReflowInput& aReflowInput,
@ -738,17 +756,11 @@ nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext,
if (nextFrame) {
aStatus.SetIncomplete();
PushFrames(aPresContext, nextFrame, aFrame, irs);
}
else {
} else {
// We must return an incomplete status if there are more child
// frames remaining in a next-in-flow that follows this frame.
nsInlineFrame* nextInFlow = static_cast<nsInlineFrame*>(GetNextInFlow());
while (nextInFlow) {
if (nextInFlow->mFrames.NotEmpty()) {
if (HasFramesToPull(static_cast<nsInlineFrame*>(GetNextInFlow()))) {
aStatus.SetIncomplete();
break;
}
nextInFlow = static_cast<nsInlineFrame*>(nextInFlow->GetNextInFlow());
}
}
return;
@ -767,6 +779,11 @@ nsInlineFrame::PullOneFrame(nsPresContext* aPresContext, InlineReflowInput& irs)
{
nsIFrame* frame = nullptr;
nsInlineFrame* nextInFlow = irs.mNextInFlow;
#ifdef DEBUG
bool willPull = HasFramesToPull(nextInFlow);
#endif
while (nextInFlow) {
frame = nextInFlow->mFrames.FirstChild();
if (!frame) {
@ -813,6 +830,7 @@ nsInlineFrame::PullOneFrame(nsPresContext* aPresContext, InlineReflowInput& irs)
irs.mNextInFlow = nextInFlow;
}
MOZ_ASSERT(!!frame == willPull);
return frame;
}

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

@ -159,6 +159,10 @@ protected:
nsIFrame* aFrame,
nsReflowStatus& aStatus);
// Returns whether there's any frame that PullOneFrame would pull from
// aNextInFlow or any of aNextInFlow's next-in-flows.
static bool HasFramesToPull(nsInlineFrame* aNextInFlow);
virtual nsIFrame* PullOneFrame(nsPresContext*, InlineReflowInput&);
virtual void PushFrames(nsPresContext* aPresContext,