summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--layout/base/nsCSSFrameConstructor.cpp122
-rw-r--r--layout/base/nsCSSFrameConstructor.h6
-rw-r--r--layout/forms/nsComboboxControlFrame.cpp2
-rw-r--r--layout/forms/nsComboboxControlFrame.h6
-rw-r--r--layout/generic/nsHTMLParts.h3
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);