mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 00:05:36 +00:00
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:
parent
dfcbe8d912
commit
6b2dceda02
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user