mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 00:32:11 +00:00
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:
parent
730d8e4209
commit
782a58f0b1
9
layout/forms/crashtests/1600207.html
Normal file
9
layout/forms/crashtests/1600207.html
Normal file
@ -0,0 +1,9 @@
|
||||
<style>
|
||||
:not(isindex) {
|
||||
columns: 0px;
|
||||
margin-top: 1%;
|
||||
}
|
||||
</style>
|
||||
<fieldset>
|
||||
<output>
|
||||
<br></br>
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user