diff options
-rw-r--r-- | layout/base/nsCSSFrameConstructor.cpp | 122 | ||||
-rw-r--r-- | layout/base/nsCSSFrameConstructor.h | 6 | ||||
-rw-r--r-- | layout/forms/nsComboboxControlFrame.cpp | 2 | ||||
-rw-r--r-- | layout/forms/nsComboboxControlFrame.h | 6 | ||||
-rw-r--r-- | layout/generic/nsHTMLParts.h | 3 |
5 files changed, 49 insertions, 90 deletions
diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index d5b21f8d1..5a1036232 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -3076,7 +3076,7 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsFrameConstructorState& aState, // The drop-down list's frame is created explicitly. The combobox frame shares its content // with the drop-down list. nsFrameState flags = NS_BLOCK_FLOAT_MGR; - nsContainerFrame* comboboxFrame = + nsComboboxControlFrame* comboboxFrame = NS_NewComboboxControlFrame(mPresShell, styleContext, flags); // Save the history state so we don't restore during construction @@ -3091,10 +3091,6 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsFrameConstructorState& aState, aState.AddChild(comboboxFrame, aFrameItems, content, styleContext, aParentFrame); - nsIComboboxControlFrame* comboBox = do_QueryFrame(comboboxFrame); - NS_ASSERTION(comboBox, "NS_NewComboboxControlFrame returned frame that " - "doesn't implement nsIComboboxControlFrame"); - // Resolve pseudo element style for the dropdown list RefPtr<nsStyleContext> listStyle; listStyle = mPresShell->StyleSet()-> @@ -3109,7 +3105,7 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsFrameConstructorState& aState, listControlFrame->SetComboboxFrame(comboboxFrame); } // Notify combobox that it should use the listbox as it's popup - comboBox->SetDropDown(listFrame); + comboboxFrame->SetDropDown(listFrame); NS_ASSERTION(!listFrame->IsAbsPosContainingBlock(), "Ended up with positioned dropdown list somehow."); @@ -3130,10 +3126,29 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsFrameConstructorState& aState, // Create display and button frames from the combobox's anonymous content. // The anonymous content is appended to existing anonymous content for this // element (the scrollbars). - nsFrameItems childItems; - CreateAnonymousFrames(aState, content, comboboxFrame, - aItem.mPendingBinding, childItems); + + // nsComboboxControlFrame needs special frame creation behavior for its first + // piece of anonymous content, which means that we can't take the normal + // ProcessChildren path. + AutoTArray<nsIAnonymousContentCreator::ContentInfo, 2> newAnonymousItems; + DebugOnly<nsresult> rv = GetAnonymousContent(content, comboboxFrame, newAnonymousItems); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + MOZ_ASSERT(newAnonymousItems.Length() == 2); + + // Manually create a frame for the special NAC. + MOZ_ASSERT(newAnonymousItems[0].mContent == comboboxFrame->GetDisplayNode()); + newAnonymousItems.RemoveElementAt(0); + nsIFrame* customFrame = comboboxFrame->CreateFrameForDisplayNode(); + MOZ_ASSERT(customFrame); + customFrame->AddStateBits(NS_FRAME_ANONYMOUSCONTENTCREATOR_CONTENT); + childItems.AddChild(customFrame); + + // The other piece of NAC can take the normal path. + FrameConstructionItemList fcItems; + AddFCItemsForAnonymousContent(aState, comboboxFrame, newAnonymousItems, + fcItems); + ConstructFramesFromItemList(aState, fcItems, comboboxFrame, childItems); comboboxFrame->SetInitialChildList(kPrincipalList, childItems); @@ -4095,71 +4110,6 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt } } -// after the node has been constructed and initialized create any -// anonymous content a node needs. -nsresult -nsCSSFrameConstructor::CreateAnonymousFrames(nsFrameConstructorState& aState, - nsIContent* aParent, - nsContainerFrame* aParentFrame, - PendingBinding* aPendingBinding, - nsFrameItems& aChildItems) -{ - AutoTArray<nsIAnonymousContentCreator::ContentInfo, 4> newAnonymousItems; - nsresult rv = GetAnonymousContent(aParent, aParentFrame, newAnonymousItems); - NS_ENSURE_SUCCESS(rv, rv); - - uint32_t count = newAnonymousItems.Length(); - if (count == 0) { - return NS_OK; - } - - nsFrameConstructorState::PendingBindingAutoPusher pusher(aState, - aPendingBinding); - TreeMatchContext::AutoAncestorPusher ancestorPusher(aState.mTreeMatchContext); - if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) { - ancestorPusher.PushAncestorAndStyleScope(aParent->AsElement()); - } else { - ancestorPusher.PushStyleScope(aParent->AsElement()); - } - - nsComboboxControlFrame* comboboxFrame = do_QueryFrame(aParentFrame); - - InsertionPoint insertion(aParentFrame, aParent); - for (uint32_t i=0; i < count; i++) { - nsIContent* content = newAnonymousItems[i].mContent; - NS_ASSERTION(content, "null anonymous content?"); - NS_ASSERTION(!newAnonymousItems[i].mStyleContext, "Unexpected style context"); - NS_ASSERTION(newAnonymousItems[i].mChildren.IsEmpty(), - "This method is not currently used with frames that implement " - "nsIAnonymousContentCreator::CreateAnonymousContent to " - "output a list where the items have their own children"); - - if (comboboxFrame && comboboxFrame->GetDisplayNode() == content) { - // Combo box frames have a custom hook to create frames for the anonymous - // text node. This is the last vestigial trace of an old custom hook that - // allowed arbitrary custom frame creation by any nsIAnonymousContentCreator - // implementation. It's possible that this could all be refactored away. - nsIFrame* customFrame = comboboxFrame->CreateFrameForDisplayNode(); - MOZ_ASSERT(customFrame); - customFrame->AddStateBits(NS_FRAME_ANONYMOUSCONTENTCREATOR_CONTENT); - aChildItems.AddChild(customFrame); - } else { - FrameConstructionItemList items; - { - // Skip parent display based style-fixup during our - // AddFrameConstructionItems() call: - TreeMatchContext::AutoParentDisplayBasedStyleFixupSkipper - parentDisplayBasedStyleFixupSkipper(aState.mTreeMatchContext); - - AddFrameConstructionItems(aState, content, true, insertion, items); - } - ConstructFramesFromItemList(aState, items, aParentFrame, aChildItems); - } - } - - return NS_OK; -} - static void SetFlagsOnSubtree(nsIContent *aNode, uintptr_t aFlagsToSet) { @@ -4576,11 +4526,25 @@ nsCSSFrameConstructor::BeginBuildingScrollFrame(nsFrameConstructorState& aState, // if there are any anonymous children for the scroll frame, create // frames for them. - // Pass a null pending binding: we don't care how constructors for any of - // this anonymous content order with anything else. It's never been - // consistent anyway. - CreateAnonymousFrames(aState, aContent, gfxScrollFrame, nullptr, - anonymousItems); + // + // We can't take the normal ProcessChildren path, because the NAC needs to + // be parented to the scrollframe, and everything else needs to be parented + // to the scrolledframe. + AutoTArray<nsIAnonymousContentCreator::ContentInfo, 4> scrollNAC; + DebugOnly<nsresult> rv = GetAnonymousContent(aContent, gfxScrollFrame, scrollNAC); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + if (scrollNAC.Length() > 0) { + TreeMatchContext::AutoAncestorPusher ancestorPusher(aState.mTreeMatchContext); + if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) { + ancestorPusher.PushAncestorAndStyleScope(aContent->AsElement()); + } else { + ancestorPusher.PushStyleScope(aContent->AsElement()); + } + + FrameConstructionItemList items; + AddFCItemsForAnonymousContent(aState, gfxScrollFrame, scrollNAC, items); + ConstructFramesFromItemList(aState, items, gfxScrollFrame, anonymousItems); + } aNewFrame = gfxScrollFrame; diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index 7d1b8d42f..89e5594e4 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -1440,12 +1440,6 @@ private: nsFrameItems& aFrameItems); static bool AtLineBoundary(FCItemIterator& aIter); - nsresult CreateAnonymousFrames(nsFrameConstructorState& aState, - nsIContent* aParent, - nsContainerFrame* aParentFrame, - PendingBinding* aPendingBinding, - nsFrameItems& aChildItems); - nsresult GetAnonymousContent(nsIContent* aParent, nsIFrame* aParentFrame, nsTArray<nsIAnonymousContentCreator::ContentInfo>& aAnonContent); diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index 9d8d639ee..98a91b9f5 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -115,7 +115,7 @@ NS_IMPL_ISUPPORTS(nsComboButtonListener, // static class data member for Bug 32920 nsComboboxControlFrame* nsComboboxControlFrame::sFocused = nullptr; -nsContainerFrame* +nsComboboxControlFrame* NS_NewComboboxControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, nsFrameState aStateFlags) { nsComboboxControlFrame* it = new (aPresShell) nsComboboxControlFrame(aContext); diff --git a/layout/forms/nsComboboxControlFrame.h b/layout/forms/nsComboboxControlFrame.h index 5f190814a..de713576f 100644 --- a/layout/forms/nsComboboxControlFrame.h +++ b/layout/forms/nsComboboxControlFrame.h @@ -55,9 +55,9 @@ class nsComboboxControlFrame final : public nsBlockFrame, public: NS_DECL_QUERYFRAME_TARGET(nsComboboxControlFrame) - friend nsContainerFrame* NS_NewComboboxControlFrame(nsIPresShell* aPresShell, - nsStyleContext* aContext, - nsFrameState aFlags); + friend nsComboboxControlFrame* NS_NewComboboxControlFrame(nsIPresShell* aPresShell, + nsStyleContext* aContext, + nsFrameState aFlags); friend class nsComboboxDisplayFrame; explicit nsComboboxControlFrame(nsStyleContext* aContext); diff --git a/layout/generic/nsHTMLParts.h b/layout/generic/nsHTMLParts.h index 89a7a6edd..243c432b2 100644 --- a/layout/generic/nsHTMLParts.h +++ b/layout/generic/nsHTMLParts.h @@ -11,6 +11,7 @@ #include "nscore.h" #include "nsISupports.h" #include "nsIFrame.h" +class nsComboboxControlFrame; class nsIAtom; class nsNodeInfoManager; class nsIContent; @@ -161,7 +162,7 @@ nsIFrame* NS_NewNativeSelectControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); nsContainerFrame* NS_NewListControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); -nsContainerFrame* +nsComboboxControlFrame* NS_NewComboboxControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, nsFrameState aFlags); nsIFrame* NS_NewProgressFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); |