Bug 1427908: Never reenter synchronously into frame construction. r=bz

We remove async from the DOM all the time now since bug 1389743.

We could, before this patch, recurse into frame construction in a sync way, due
to the way we handle the weird insertion cases for <fieldset>, <details>, and
<mathml>.

This patch makes those also async, making the IssueSingleInsertNotifications
condition unnecessary.

MozReview-Commit-ID: LujPaYPwA4G

--HG--
extra : rebase_source : 3fc9dc9589a0c43f9f211e22873bf6b960d416f7
This commit is contained in:
Emilio Cobos Álvarez 2018-01-03 05:51:12 +01:00
parent dfcbe8d912
commit 6b2dceda02
2 changed files with 23 additions and 38 deletions

View File

@ -7324,36 +7324,27 @@ nsCSSFrameConstructor::CreateNeededFrames()
void
nsCSSFrameConstructor::IssueSingleInsertNofications(nsIContent* aContainer,
nsIContent* aStartChild,
nsIContent* aEndChild,
InsertionKind aInsertionKind)
nsIContent* aEndChild)
{
for (nsIContent* child = aStartChild;
child != aEndChild;
child = child->GetNextSibling()) {
if ((child->GetPrimaryFrame() || GetDisplayNoneStyleFor(child) ||
GetDisplayContentsStyleFor(child))
#ifdef MOZ_XUL
// Except listboxes suck, so do NOT skip anything here if
// we plan to notify a listbox.
&& !MaybeGetListBoxBodyFrame(aContainer, child)
#endif
) {
// Already have a frame or undisplayed entry for this content; a
// previous ContentRangeInserted in this loop must have reconstructed
// its insertion parent. Skip it.
continue;
}
// listboxes suck.
MOZ_ASSERT(MaybeGetListBoxBodyFrame(aContainer, child) ||
(!child->GetPrimaryFrame() &&
!GetDisplayNoneStyleFor(child) &&
!GetDisplayContentsStyleFor(child)));
// Call ContentRangeInserted with this node.
ContentRangeInserted(aContainer, child, child->GetNextSibling(),
mTempFrameTreeState, aInsertionKind, nullptr);
mTempFrameTreeState, InsertionKind::Sync, nullptr);
}
}
nsCSSFrameConstructor::InsertionPoint
nsCSSFrameConstructor::GetRangeInsertionPoint(nsIContent* aContainer,
nsIContent* aStartChild,
nsIContent* aEndChild,
InsertionKind aInsertionKind)
nsIContent* aEndChild)
{
// See if we have an XBL insertion point. If so, then that's our
// real parent frame; if not, then the frame hasn't been built yet
@ -7372,8 +7363,7 @@ nsCSSFrameConstructor::GetRangeInsertionPoint(nsIContent* aContainer,
// Now comes the fun part. For each inserted child, make a
// ContentInserted call as if it had just gotten inserted and
// let ContentInserted handle the mess.
IssueSingleInsertNofications(aContainer, aStartChild, aEndChild,
aInsertionKind);
IssueSingleInsertNofications(aContainer, aStartChild, aEndChild);
insertionPoint.mParentFrame = nullptr;
}
}
@ -7534,8 +7524,7 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer,
LAYOUT_PHASE_TEMP_EXIT();
InsertionPoint insertion =
GetRangeInsertionPoint(aContainer, aFirstNewContent, nullptr,
aInsertionKind);
GetRangeInsertionPoint(aContainer, aFirstNewContent, nullptr);
nsContainerFrame*& parentFrame = insertion.mParentFrame;
LAYOUT_PHASE_TEMP_REENTER();
if (!parentFrame) {
@ -7558,7 +7547,7 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer,
if (parentFrame->IsFrameOfType(nsIFrame::eMathML)) {
LAYOUT_PHASE_TEMP_EXIT();
RecreateFramesForContent(parentFrame->GetContent(), aInsertionKind);
RecreateFramesForContent(parentFrame->GetContent(), InsertionKind::Async);
LAYOUT_PHASE_TEMP_REENTER();
return;
}
@ -7929,8 +7918,7 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
// We don't handle a range insert to a listbox parent, issue single
// ContertInserted calls for each node inserted.
LAYOUT_PHASE_TEMP_EXIT();
IssueSingleInsertNofications(aContainer, aStartChild, aEndChild,
aInsertionKind);
IssueSingleInsertNofications(aContainer, aStartChild, aEndChild);
LAYOUT_PHASE_TEMP_REENTER();
return;
}
@ -8026,8 +8014,7 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
// Get our insertion point. If we need to issue single ContentInserted's
// GetRangeInsertionPoint will take care of that for us.
LAYOUT_PHASE_TEMP_EXIT();
insertion = GetRangeInsertionPoint(aContainer, aStartChild, aEndChild,
aInsertionKind);
insertion = GetRangeInsertionPoint(aContainer, aStartChild, aEndChild);
LAYOUT_PHASE_TEMP_REENTER();
}
@ -8043,8 +8030,7 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
if (!isSingleInsert && !isRangeInsertSafe) {
// must fall back to a single ContertInserted for each child in the range
LAYOUT_PHASE_TEMP_EXIT();
IssueSingleInsertNofications(aContainer, aStartChild, aEndChild,
aInsertionKind);
IssueSingleInsertNofications(aContainer, aStartChild, aEndChild);
LAYOUT_PHASE_TEMP_REENTER();
return;
}
@ -8071,7 +8057,7 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
// to locate this legend in the inserted frames and extract it.
LAYOUT_PHASE_TEMP_EXIT();
RecreateFramesForContent(insertion.mParentFrame->GetContent(),
aInsertionKind);
InsertionKind::Async);
LAYOUT_PHASE_TEMP_REENTER();
return;
}
@ -8086,7 +8072,7 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
// to handle the insertion.
LAYOUT_PHASE_TEMP_EXIT();
RecreateFramesForContent(insertion.mParentFrame->GetContent(),
aInsertionKind);
InsertionKind::Async);
LAYOUT_PHASE_TEMP_REENTER();
return;
}
@ -8098,10 +8084,12 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
return;
}
// FIXME(emilio): This looks terribly inefficient if you insert elements deep
// in a MathML subtree.
if (insertion.mParentFrame->IsFrameOfType(nsIFrame::eMathML)) {
LAYOUT_PHASE_TEMP_EXIT();
RecreateFramesForContent(insertion.mParentFrame->GetContent(),
aInsertionKind);
InsertionKind::Async);
LAYOUT_PHASE_TEMP_REENTER();
return;
}
@ -8182,8 +8170,7 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
// must fall back to a single ContertInserted for each child in the range
LAYOUT_PHASE_TEMP_EXIT();
IssueSingleInsertNofications(aContainer, aStartChild, aEndChild,
aInsertionKind);
IssueSingleInsertNofications(aContainer, aStartChild, aEndChild);
LAYOUT_PHASE_TEMP_REENTER();
return;
}

View File

@ -133,8 +133,7 @@ private:
// [aStartChild, aEndChild).
void IssueSingleInsertNofications(nsIContent* aContainer,
nsIContent* aStartChild,
nsIContent* aEndChild,
InsertionKind);
nsIContent* aEndChild);
/**
* Data that represents an insertion point for some child content.
@ -176,8 +175,7 @@ private:
*/
InsertionPoint GetRangeInsertionPoint(nsIContent* aContainer,
nsIContent* aStartChild,
nsIContent* aEndChild,
InsertionKind);
nsIContent* aEndChild);
// Returns true if parent was recreated due to frameset child, false otherwise.
bool MaybeRecreateForFrameset(nsIFrame* aParentFrame,