Bug 1600207 - Make GetInner()/GetLegend() robust also in presence of additional continuations on the principal child list. r=TYLin

Also, don't drain OverflowList unless we need to.
And make EnsureChildContinuation deal with continuations going from being
normal continuations to overflow-continuations (and vice versa) better.

Differential Revision: https://phabricator.services.mozilla.com/D55644

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Mats Palmgren 2019-12-09 11:24:50 +00:00
parent 730d8e4209
commit 782a58f0b1
3 changed files with 51 additions and 28 deletions

View File

@ -0,0 +1,9 @@
<style>
:not(isindex) {
columns: 0px;
margin-top: 1%;
}
</style>
<fieldset>
<output>
<br></br>

View File

@ -73,4 +73,5 @@ asserts(1-4) load 1460787-1.html
load 1464165-1.html
load 1471157.html
load 1488219.html
load 1600207.html
load 1600367.html

View File

@ -75,23 +75,21 @@ nsRect nsFieldSetFrame::VisualBorderRectRelativeToSelf() const {
}
nsContainerFrame* nsFieldSetFrame::GetInner() const {
nsIFrame* last = mFrames.LastChild();
if (last &&
last->Style()->GetPseudoType() == PseudoStyleType::fieldsetContent) {
return static_cast<nsContainerFrame*>(last);
for (nsIFrame* child : mFrames) {
if (child->Style()->GetPseudoType() == PseudoStyleType::fieldsetContent) {
return static_cast<nsContainerFrame*>(child);
}
}
MOZ_ASSERT(mFrames.LastChild() == mFrames.FirstChild());
return nullptr;
}
nsIFrame* nsFieldSetFrame::GetLegend() const {
if (mFrames.FirstChild() == GetInner()) {
MOZ_ASSERT(mFrames.LastChild() == mFrames.FirstChild());
return nullptr;
for (nsIFrame* child : mFrames) {
if (child->Style()->GetPseudoType() != PseudoStyleType::fieldsetContent) {
return child;
}
}
MOZ_ASSERT(mFrames.FirstChild() &&
mFrames.FirstChild()->GetContentInsertionFrame()->IsLegendFrame());
return mFrames.FirstChild();
return nullptr;
}
class nsDisplayFieldSetBorder final : public nsPaintedDisplayItem {
@ -410,13 +408,18 @@ void nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
this);
mFrames.InsertFrames(this, nullptr, *prevOverflowFrames);
}
DrainSelfOverflowList();
}
bool reflowInner;
bool reflowLegend;
nsIFrame* legend = GetLegend();
nsIFrame* inner = GetInner();
nsContainerFrame* inner = GetInner();
if (!legend || !inner) {
if (DrainSelfOverflowList()) {
legend = GetLegend();
inner = GetInner();
}
}
if (aReflowInput.ShouldReflowAllKids() || GetNextInFlow()) {
reflowInner = inner != nullptr;
reflowLegend = legend != nullptr;
@ -888,31 +891,41 @@ void nsFieldSetFrame::EnsureChildContinuation(nsIFrame* aChild,
MOZ_ASSERT(!aChild->GetNextInFlow());
}
} else {
nsFrameList nifs;
if (!nif) {
auto* pc = PresContext();
auto* fc = pc->PresShell()->FrameConstructor();
nif = fc->CreateContinuingFrame(pc, aChild, this);
if (aStatus.IsOverflowIncomplete()) {
nif->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
if (nsFrameList* eoc =
GetPropTableFrames(ExcessOverflowContainersProperty())) {
eoc->AppendFrame(nullptr, nif);
}
nifs = nsFrameList(nif, nif);
} else {
// Steal all nifs and push them again in case they are currently on
// the wrong list.
for (nsIFrame* n = nif; n; n = n->GetNextInFlow()) {
n->GetParent()->StealFrame(n);
nifs.AppendFrame(this, n);
if (aStatus.IsOverflowIncomplete()) {
n->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
} else {
SetPropTableFrames(new (PresShell()) nsFrameList(nif, nif),
ExcessOverflowContainersProperty());
}
} else {
if (nsFrameList* oc = GetOverflowFrames()) {
oc->AppendFrame(nullptr, nif);
} else {
SetOverflowFrames(nsFrameList(nif, nif));
n->RemoveStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
}
}
}
if (aStatus.IsOverflowIncomplete()) {
if (nsFrameList* eoc =
GetPropTableFrames(ExcessOverflowContainersProperty())) {
eoc->AppendFrames(nullptr, nifs);
} else {
SetPropTableFrames(new (PresShell()) nsFrameList(nifs),
ExcessOverflowContainersProperty());
}
} else {
if (aStatus.IsOverflowIncomplete()) {
for (nsIFrame* n = nif; n; n = n->GetNextInFlow()) {
n->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
}
if (nsFrameList* oc = GetOverflowFrames()) {
oc->AppendFrames(nullptr, nifs);
} else {
SetOverflowFrames(nifs);
}
}
}