Bug 1452889: Handle appending multiple items to a listbox correctly. r=bz
What happened in bug 1446368 is the following: We append two items to an empty listbox. We can't construct lazily because this is XUL, so that goes through IssueSingleInsertNotifications for each of the items. When we insert the first one we call LazilyStyleNewChildRange _only on the first sibling_, yet the listbox code tries to construct frames for the next sibling too from CreateRows. The next sibling is unstyled, so we panic. Instead of handling it in ContentRangeInserted but not ContentAppended, just do it in the listbox-specific code instead, which looks slightly cleaner (though we can't assert we're constructing async). This should fix the case where the listbox is display: none or what not which, combined with the patch in bug 1303605, supersede the backed out patch in bug 1429088, which was backed out because listboxes suck. MozReview-Commit-ID: D7UQ41S6Ras
This commit is contained in:
@@ -7073,19 +7073,18 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aFirstNewContent,
|
||||
return;
|
||||
}
|
||||
|
||||
if (aInsertionKind == InsertionKind::Async &&
|
||||
MaybeConstructLazily(CONTENTAPPEND, aFirstNewContent)) {
|
||||
LazilyStyleNewChildRange(aFirstNewContent, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
// We couldn't construct lazily. Make Servo eagerly traverse the new content
|
||||
// if needed (when aInsertionKind == InsertionKind::Sync, we know that the
|
||||
// styles are up-to-date already).
|
||||
if (aInsertionKind == InsertionKind::Async) {
|
||||
if (MaybeConstructLazily(CONTENTAPPEND, aFirstNewContent)) {
|
||||
LazilyStyleNewChildRange(aFirstNewContent, nullptr);
|
||||
return;
|
||||
}
|
||||
// We couldn't construct lazily. Make Servo eagerly traverse the new content
|
||||
// if needed (when aInsertionKind == InsertionKind::Sync, we know that the
|
||||
// styles are up-to-date already).
|
||||
StyleNewChildRange(aFirstNewContent, nullptr);
|
||||
}
|
||||
|
||||
|
||||
LAYOUT_PHASE_TEMP_EXIT();
|
||||
if (MaybeRecreateForFrameset(parentFrame, aFirstNewContent, nullptr)) {
|
||||
LAYOUT_PHASE_TEMP_REENTER();
|
||||
@@ -7423,14 +7422,6 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aStartChild,
|
||||
}
|
||||
#endif
|
||||
|
||||
auto styleNewChildRangeEagerly =
|
||||
[this, aInsertionKind, aStartChild, aEndChild]() {
|
||||
// When aInsertionKind == InsertionKind::Sync, we know that the
|
||||
// styles are up-to-date already.
|
||||
if (aInsertionKind == InsertionKind::Async) {
|
||||
StyleNewChildRange(aStartChild, aEndChild);
|
||||
}
|
||||
};
|
||||
|
||||
bool isSingleInsert = (aStartChild->GetNextSibling() == aEndChild);
|
||||
NS_ASSERTION(isSingleInsert ||
|
||||
@@ -7441,8 +7432,6 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aStartChild,
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
if (aStartChild->GetParent() && IsXULListBox(aStartChild->GetParent())) {
|
||||
// For XUL list box, we need to style the new children eagerly.
|
||||
styleNewChildRangeEagerly();
|
||||
if (isSingleInsert) {
|
||||
// The insert case in NotifyListBoxBody doesn't use "old next sibling".
|
||||
if (NotifyListBoxBody(mPresShell->GetPresContext(),
|
||||
@@ -7528,16 +7517,17 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aStartChild,
|
||||
return;
|
||||
}
|
||||
|
||||
if (aInsertionKind == InsertionKind::Async &&
|
||||
MaybeConstructLazily(CONTENTINSERT, aStartChild)) {
|
||||
LazilyStyleNewChildRange(aStartChild, aEndChild);
|
||||
return;
|
||||
if (aInsertionKind == InsertionKind::Async) {
|
||||
if (MaybeConstructLazily(CONTENTINSERT, aStartChild)) {
|
||||
LazilyStyleNewChildRange(aStartChild, aEndChild);
|
||||
return;
|
||||
}
|
||||
// We couldn't construct lazily. Make Servo eagerly traverse the new content
|
||||
// if needed (when aInsertionKind == InsertionKind::Sync, we know that the
|
||||
// styles are up-to-date already).
|
||||
StyleNewChildRange(aStartChild, aEndChild);
|
||||
}
|
||||
|
||||
// We couldn't construct lazily. Make Servo eagerly traverse the new content
|
||||
// if needed.
|
||||
styleNewChildRangeEagerly();
|
||||
|
||||
bool isAppend, isRangeInsertSafe;
|
||||
nsIFrame* prevSibling = GetInsertionPrevSibling(&insertion, aStartChild,
|
||||
&isAppend, &isRangeInsertSafe);
|
||||
@@ -11118,6 +11108,10 @@ nsCSSFrameConstructor::CreateListBoxContent(nsContainerFrame* aParentFrame,
|
||||
GetFloatContainingBlock(aParentFrame),
|
||||
do_AddRef(mTempFrameTreeState));
|
||||
|
||||
if (aChild->IsElement() && !aChild->AsElement()->HasServoData()) {
|
||||
mPresShell->StyleSet()->StyleNewSubtree(aChild->AsElement());
|
||||
}
|
||||
|
||||
RefPtr<ComputedStyle> computedStyle = ResolveComputedStyle(aChild);
|
||||
|
||||
// Pre-check for display "none" - only if we find that, do we create
|
||||
|
||||
Reference in New Issue
Block a user