Backed out 4 changesets (bug 1799343) for causing multiple crashes. CLOSED TREE
Backed out changeset 3150074bccfd (bug 1799343) Backed out changeset 7f6358a0b692 (bug 1799343) Backed out changeset 34f040f379b1 (bug 1799343) Backed out changeset a609c8c27ca8 (bug 1799343)
This commit is contained in:
@@ -204,6 +204,7 @@ static FrameCtorDebugFlags gFlags[] = {
|
||||
#endif
|
||||
|
||||
#include "nsMenuFrame.h"
|
||||
#include "nsPopupSetFrame.h"
|
||||
#include "nsTreeColFrame.h"
|
||||
|
||||
//------------------------------------------------------------------
|
||||
@@ -220,6 +221,8 @@ nsIFrame* NS_NewSplitterFrame(PresShell* aPresShell, ComputedStyle* aStyle);
|
||||
|
||||
nsIFrame* NS_NewMenuPopupFrame(PresShell* aPresShell, ComputedStyle* aStyle);
|
||||
|
||||
nsIFrame* NS_NewPopupSetFrame(PresShell* aPresShell, ComputedStyle* aStyle);
|
||||
|
||||
nsIFrame* NS_NewMenuFrame(PresShell* aPresShell, ComputedStyle* aStyle,
|
||||
uint32_t aFlags);
|
||||
|
||||
@@ -601,6 +604,9 @@ class MOZ_STACK_CLASS nsFrameConstructorState {
|
||||
PresShell* mPresShell;
|
||||
nsFrameManager* mFrameManager;
|
||||
|
||||
// Frames destined for the kPopupList.
|
||||
AbsoluteFrameList mPopupList;
|
||||
|
||||
// Containing block information for out-of-flow frames.
|
||||
AbsoluteFrameList mFixedList;
|
||||
AbsoluteFrameList mAbsoluteList;
|
||||
@@ -632,6 +638,11 @@ class MOZ_STACK_CLASS nsFrameConstructorState {
|
||||
// abs-pos lists together.
|
||||
bool mFixedPosIsAbsPos;
|
||||
|
||||
// A boolean to indicate whether we have a "pending" popupgroup. That is, we
|
||||
// have already created the FrameConstructionItem for the root popupgroup but
|
||||
// we have not yet created the relevant frame.
|
||||
bool mHavePendingPopupgroup;
|
||||
|
||||
// If false (which is the default) then call SetPrimaryFrame() as needed
|
||||
// during frame construction. If true, don't make any SetPrimaryFrame()
|
||||
// calls, except for generated content which doesn't have a primary frame
|
||||
@@ -734,11 +745,13 @@ class MOZ_STACK_CLASS nsFrameConstructorState {
|
||||
* positioned
|
||||
* @param aCanBeFloated pass false if the frame isn't allowed to be
|
||||
* floated
|
||||
* @param aIsOutOfFlowPopup pass true if the frame is an out-of-flow popup
|
||||
* (XUL-only)
|
||||
*/
|
||||
void AddChild(nsIFrame* aNewFrame, nsFrameList& aFrameList,
|
||||
nsIContent* aContent, nsContainerFrame* aParentFrame,
|
||||
bool aCanBePositioned = true, bool aCanBeFloated = true,
|
||||
bool aInsertAfter = false,
|
||||
bool aIsOutOfFlowPopup = false, bool aInsertAfter = false,
|
||||
nsIFrame* aInsertAfterFrame = nullptr);
|
||||
|
||||
/**
|
||||
@@ -776,6 +789,7 @@ class MOZ_STACK_CLASS nsFrameConstructorState {
|
||||
AbsoluteFrameList* GetOutOfFlowFrameList(nsIFrame* aNewFrame,
|
||||
bool aCanBePositioned,
|
||||
bool aCanBeFloated,
|
||||
bool aIsOutOfFlowPopup,
|
||||
nsFrameState* aPlaceholderType);
|
||||
|
||||
void ConstructBackdropFrameFor(nsIContent* aContent, nsIFrame* aFrame);
|
||||
@@ -789,6 +803,7 @@ nsFrameConstructorState::nsFrameConstructorState(
|
||||
: mPresContext(aPresShell->GetPresContext()),
|
||||
mPresShell(aPresShell),
|
||||
mFrameManager(aPresShell->FrameConstructor()),
|
||||
mPopupList(nullptr),
|
||||
mFixedList(aFixedContainingBlock),
|
||||
mAbsoluteList(aAbsoluteContainingBlock),
|
||||
mFloatedList(aFloatContainingBlock),
|
||||
@@ -805,8 +820,14 @@ nsFrameConstructorState::nsFrameConstructorState(
|
||||
// block, use the abs-pos containing block's abs-pos list for fixed-pos
|
||||
// frames.
|
||||
mFixedPosIsAbsPos(aFixedContainingBlock == aAbsoluteContainingBlock),
|
||||
mHavePendingPopupgroup(false),
|
||||
mCreatingExtraFrames(false),
|
||||
mHasRenderedLegend(false) {
|
||||
nsIPopupContainer* popupContainer =
|
||||
nsIPopupContainer::GetPopupContainer(aPresShell);
|
||||
if (popupContainer) {
|
||||
mPopupList.mContainingBlock = popupContainer->GetPopupSetFrame();
|
||||
}
|
||||
MOZ_COUNT_CTOR(nsFrameConstructorState);
|
||||
}
|
||||
|
||||
@@ -833,6 +854,7 @@ void nsFrameConstructorState::ProcessFrameInsertionsForAllLists() {
|
||||
ProcessFrameInsertions(mFloatedList, nsIFrame::kFloatList);
|
||||
ProcessFrameInsertions(mAbsoluteList, nsIFrame::kAbsoluteList);
|
||||
ProcessFrameInsertions(mFixedList, nsIFrame::kFixedList);
|
||||
ProcessFrameInsertions(mPopupList, nsIFrame::kPopupList);
|
||||
}
|
||||
|
||||
void nsFrameConstructorState::PushAbsoluteContainingBlock(
|
||||
@@ -1032,7 +1054,12 @@ void nsFrameConstructorState::ReparentFloats(nsContainerFrame* aNewParent) {
|
||||
|
||||
AbsoluteFrameList* nsFrameConstructorState::GetOutOfFlowFrameList(
|
||||
nsIFrame* aNewFrame, bool aCanBePositioned, bool aCanBeFloated,
|
||||
nsFrameState* aPlaceholderType) {
|
||||
bool aIsOutOfFlowPopup, nsFrameState* aPlaceholderType) {
|
||||
if (MOZ_UNLIKELY(aIsOutOfFlowPopup)) {
|
||||
MOZ_ASSERT(mPopupList.mContainingBlock, "Must have a popup set frame!");
|
||||
*aPlaceholderType = PLACEHOLDER_FOR_POPUP;
|
||||
return &mPopupList;
|
||||
}
|
||||
const nsStyleDisplay* disp = aNewFrame->StyleDisplay();
|
||||
if (aCanBeFloated && disp->IsFloatingStyle()) {
|
||||
*aPlaceholderType = PLACEHOLDER_FOR_FLOAT;
|
||||
@@ -1084,7 +1111,7 @@ void nsFrameConstructorState::ConstructBackdropFrameFor(nsIContent* aContent,
|
||||
|
||||
nsFrameState placeholderType;
|
||||
AbsoluteFrameList* frameList =
|
||||
GetOutOfFlowFrameList(backdropFrame, true, true, &placeholderType);
|
||||
GetOutOfFlowFrameList(backdropFrame, true, true, false, &placeholderType);
|
||||
MOZ_ASSERT(placeholderType & PLACEHOLDER_FOR_TOPLAYER);
|
||||
|
||||
nsIFrame* placeholder = nsCSSFrameConstructor::CreatePlaceholderFrameFor(
|
||||
@@ -1098,13 +1125,13 @@ void nsFrameConstructorState::ConstructBackdropFrameFor(nsIContent* aContent,
|
||||
void nsFrameConstructorState::AddChild(
|
||||
nsIFrame* aNewFrame, nsFrameList& aFrameList, nsIContent* aContent,
|
||||
nsContainerFrame* aParentFrame, bool aCanBePositioned, bool aCanBeFloated,
|
||||
bool aInsertAfter, nsIFrame* aInsertAfterFrame) {
|
||||
bool aIsOutOfFlowPopup, bool aInsertAfter, nsIFrame* aInsertAfterFrame) {
|
||||
MOZ_ASSERT(!aNewFrame->GetNextSibling(), "Shouldn't happen");
|
||||
|
||||
nsFrameState placeholderType;
|
||||
AbsoluteFrameList* outOfFlowFrameList =
|
||||
GetOutOfFlowFrameList(aNewFrame, aCanBePositioned, aCanBeFloated,
|
||||
&placeholderType);
|
||||
aIsOutOfFlowPopup, &placeholderType);
|
||||
|
||||
// The comments in GetGeometricParent regarding root table frames
|
||||
// all apply here, unfortunately. Thus, we need to check whether
|
||||
@@ -1161,7 +1188,8 @@ MOZ_NEVER_INLINE void nsFrameConstructorState::ProcessFrameInsertions(
|
||||
aChildListID == nsIFrame::kAbsoluteList) || \
|
||||
((&aFrameList == &mFixedList || &aFrameList == &mTopLayerFixedList) && \
|
||||
aChildListID == nsIFrame::kFixedList)
|
||||
MOZ_ASSERT(NS_NONXUL_LIST_TEST,
|
||||
MOZ_ASSERT(NS_NONXUL_LIST_TEST || (&aFrameList == &mPopupList &&
|
||||
aChildListID == nsIFrame::kPopupList),
|
||||
"Unexpected aFrameList/aChildListID combination");
|
||||
|
||||
if (aFrameList.IsEmpty()) {
|
||||
@@ -2510,6 +2538,9 @@ nsIFrame* nsCSSFrameConstructor::ConstructDocElementFrame(
|
||||
mDocElementContainingBlock->AppendFrames(kPrincipalList,
|
||||
std::move(frameList));
|
||||
|
||||
MOZ_ASSERT(!state.mHavePendingPopupgroup,
|
||||
"Should have proccessed pending popup group by now");
|
||||
|
||||
return newFrame;
|
||||
}
|
||||
|
||||
@@ -3654,11 +3685,15 @@ void nsCSSFrameConstructor::ConstructFrameFromItemInternal(
|
||||
} else {
|
||||
newFrame = (*data->mFunc.mCreationFunc)(mPresShell, computedStyle);
|
||||
|
||||
const bool allowOutOfFlow = !(bits & FCDATA_DISALLOW_OUT_OF_FLOW);
|
||||
const bool isPopup = aItem.mIsPopup;
|
||||
bool allowOutOfFlow = !(bits & FCDATA_DISALLOW_OUT_OF_FLOW);
|
||||
bool isPopup = aItem.mIsPopup;
|
||||
NS_ASSERTION(
|
||||
!isPopup || (aState.mPopupList.mContainingBlock &&
|
||||
aState.mPopupList.mContainingBlock->IsPopupSetFrame()),
|
||||
"Should have a containing block here!");
|
||||
|
||||
nsContainerFrame* geometricParent =
|
||||
isPopup ? aState.mTopLayerAbsoluteList.mContainingBlock
|
||||
isPopup ? aState.mPopupList.mContainingBlock
|
||||
: (allowOutOfFlow
|
||||
? aState.GetGeometricParent(*display, aParentFrame)
|
||||
: aParentFrame);
|
||||
@@ -3746,6 +3781,17 @@ void nsCSSFrameConstructor::ConstructFrameFromItemInternal(
|
||||
|
||||
nsContainerFrame* newFrameAsContainer = do_QueryFrame(newFrame);
|
||||
if (newFrameAsContainer) {
|
||||
// Icky XUL stuff, sadly
|
||||
|
||||
if (aItem.mIsRootPopupgroup) {
|
||||
NS_ASSERTION(nsIPopupContainer::GetPopupContainer(mPresShell) &&
|
||||
nsIPopupContainer::GetPopupContainer(mPresShell)
|
||||
->GetPopupSetFrame() == newFrame,
|
||||
"Unexpected PopupSetFrame");
|
||||
aState.mPopupList.mContainingBlock = newFrameAsContainer;
|
||||
aState.mHavePendingPopupgroup = false;
|
||||
}
|
||||
|
||||
// Process the child content if requested
|
||||
nsFrameList childList;
|
||||
nsFrameConstructorSaveState absoluteSaveState;
|
||||
@@ -4043,6 +4089,7 @@ nsCSSFrameConstructor::FindXULTagData(const Element& aElement,
|
||||
#else
|
||||
SIMPLE_XUL_CREATE(menubar, NS_NewMenuBarFrame),
|
||||
#endif /* XP_MACOSX */
|
||||
SIMPLE_TAG_CHAIN(popupgroup, nsCSSFrameConstructor::FindPopupGroupData),
|
||||
SIMPLE_XUL_CREATE(iframe, NS_NewSubDocumentFrame),
|
||||
SIMPLE_XUL_CREATE(editor, NS_NewSubDocumentFrame),
|
||||
SIMPLE_XUL_CREATE(browser, NS_NewSubDocumentFrame),
|
||||
@@ -4054,6 +4101,19 @@ nsCSSFrameConstructor::FindXULTagData(const Element& aElement,
|
||||
return FindDataByTag(aElement, aStyle, sXULTagData, ArrayLength(sXULTagData));
|
||||
}
|
||||
|
||||
/* static */
|
||||
const nsCSSFrameConstructor::FrameConstructionData*
|
||||
nsCSSFrameConstructor::FindPopupGroupData(const Element& aElement,
|
||||
ComputedStyle&) {
|
||||
if (!aElement.IsRootOfNativeAnonymousSubtree()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static constexpr FrameConstructionData sPopupSetData =
|
||||
SIMPLE_XUL_FCDATA(NS_NewPopupSetFrame);
|
||||
return &sPopupSetData;
|
||||
}
|
||||
|
||||
/* static */
|
||||
const nsCSSFrameConstructor::FrameConstructionData*
|
||||
nsCSSFrameConstructor::FindXULButtonData(const Element& aElement,
|
||||
@@ -4461,7 +4521,8 @@ nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay& aDisplay,
|
||||
}
|
||||
case StyleDisplayInside::MozPopup: {
|
||||
static constexpr FrameConstructionData data(
|
||||
NS_NewMenuPopupFrame, FCDATA_IS_POPUP | FCDATA_SKIP_ABSPOS_PUSH);
|
||||
NS_NewMenuPopupFrame, FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_IS_POPUP |
|
||||
FCDATA_SKIP_ABSPOS_PUSH);
|
||||
return &data;
|
||||
}
|
||||
default:
|
||||
@@ -5322,6 +5383,11 @@ void nsCSSFrameConstructor::AddFrameConstructionItemsInternal(
|
||||
(data->mBits & FCDATA_IS_POPUP) && (!aParentFrame || // Parent is inline
|
||||
!aParentFrame->IsMenuFrame());
|
||||
|
||||
if (isPopup && !aState.mPopupList.mContainingBlock &&
|
||||
!aState.mHavePendingPopupgroup) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t bits = data->mBits;
|
||||
|
||||
// Inside colgroups, suppress everything except columns.
|
||||
@@ -5355,6 +5421,11 @@ void nsCSSFrameConstructor::AddFrameConstructionItemsInternal(
|
||||
// This corresponds to the Release in ConstructFramesFromItem.
|
||||
item->mContent->AddRef();
|
||||
}
|
||||
item->mIsRootPopupgroup = aContent->IsRootOfNativeAnonymousSubtree() &&
|
||||
aContent->IsXULElement(nsGkAtoms::popupgroup);
|
||||
if (item->mIsRootPopupgroup) {
|
||||
aState.mHavePendingPopupgroup = true;
|
||||
}
|
||||
item->mIsPopup = isPopup;
|
||||
|
||||
if (canHavePageBreak && display.BreakAfter()) {
|
||||
@@ -5526,6 +5597,16 @@ void nsCSSFrameConstructor::ConstructFramesFromItem(
|
||||
}
|
||||
}
|
||||
|
||||
void nsCSSFrameConstructor::ReconstructDocElementHierarchy(
|
||||
InsertionKind aInsertionKind) {
|
||||
Element* rootElement = mDocument->GetRootElement();
|
||||
if (!rootElement) {
|
||||
/* nothing to do */
|
||||
return;
|
||||
}
|
||||
RecreateFramesForContent(rootElement, aInsertionKind);
|
||||
}
|
||||
|
||||
nsContainerFrame* nsCSSFrameConstructor::GetAbsoluteContainingBlock(
|
||||
nsIFrame* aFrame, ContainingBlockType aType) {
|
||||
// Starting with aFrame, look for a frame that is absolutely positioned or
|
||||
@@ -8283,6 +8364,16 @@ bool nsCSSFrameConstructor::MaybeRecreateContainerForFrameRemoval(
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aFrame->IsPopupSetFrame()) {
|
||||
nsIPopupContainer* popupContainer =
|
||||
nsIPopupContainer::GetPopupContainer(mPresShell);
|
||||
if (popupContainer && popupContainer->GetPopupSetFrame() == aFrame) {
|
||||
TRACE("PopupSet");
|
||||
ReconstructDocElementHierarchy(InsertionKind::Async);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Reconstruct if inflowFrame is parent's only child, and parent is, or has,
|
||||
// a non-fluid continuation, i.e. it was split by bidi resolution
|
||||
if (!inFlowFrame->GetPrevSibling() && !inFlowFrame->GetNextSibling() &&
|
||||
@@ -9590,7 +9681,9 @@ void nsCSSFrameConstructor::ProcessChildren(
|
||||
itemsToConstruct.SetLineBoundaryAtEnd(true);
|
||||
}
|
||||
|
||||
// Create any anonymous frames we need here.
|
||||
// Create any anonymous frames we need here. This must happen before the
|
||||
// non-anonymous children are processed to ensure that popups are never
|
||||
// constructed before the popupset.
|
||||
AutoTArray<nsIAnonymousContentCreator::ContentInfo, 4> anonymousItems;
|
||||
GetAnonymousContent(aContent, aPossiblyLeafFrame, anonymousItems);
|
||||
#ifdef DEBUG
|
||||
@@ -9953,7 +10046,7 @@ nsFirstLetterFrame* nsCSSFrameConstructor::CreateFloatingLetterFrame(
|
||||
}
|
||||
|
||||
aState.AddChild(letterFrame, aResult, letterContent, aParentFrame, false,
|
||||
true, true, prevSibling);
|
||||
true, false, true, prevSibling);
|
||||
|
||||
if (nextTextFrame) {
|
||||
aResult.AppendFrame(nullptr, nextTextFrame);
|
||||
|
||||
Reference in New Issue
Block a user