1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsPopupSetFrame.h"
10 #include "nsIContent.h"
11 #include "nsPresContext.h"
12 #include "mozilla/ComputedStyle.h"
13 #include "nsBoxLayoutState.h"
14 #include "nsIScrollableFrame.h"
15 #include "nsIPopupContainer.h"
16 #include "nsMenuPopupFrame.h"
18 typedef mozilla::ComputedStyle ComputedStyle
;
20 nsIFrame
* NS_NewPopupSetFrame(nsIPresShell
* aPresShell
, ComputedStyle
* aStyle
) {
21 return new (aPresShell
) nsPopupSetFrame(aStyle
, aPresShell
->GetPresContext());
24 NS_IMPL_FRAMEARENA_HELPERS(nsPopupSetFrame
)
26 void nsPopupSetFrame::Init(nsIContent
* aContent
, nsContainerFrame
* aParent
,
27 nsIFrame
* aPrevInFlow
) {
28 nsBoxFrame::Init(aContent
, aParent
, aPrevInFlow
);
30 // Normally the root box is our grandparent, but in case of wrapping
31 // it can be our great-grandparent.
32 nsIPopupContainer
* popupContainer
=
33 nsIPopupContainer::GetPopupContainer(PresContext()->GetPresShell());
35 popupContainer
->SetPopupSetFrame(this);
39 void nsPopupSetFrame::AppendFrames(ChildListID aListID
,
40 nsFrameList
& aFrameList
) {
41 if (aListID
== kPopupList
) {
42 AddPopupFrameList(aFrameList
);
45 nsBoxFrame::AppendFrames(aListID
, aFrameList
);
48 void nsPopupSetFrame::RemoveFrame(ChildListID aListID
, nsIFrame
* aOldFrame
) {
49 if (aListID
== kPopupList
) {
50 RemovePopupFrame(aOldFrame
);
53 nsBoxFrame::RemoveFrame(aListID
, aOldFrame
);
56 void nsPopupSetFrame::InsertFrames(ChildListID aListID
, nsIFrame
* aPrevFrame
,
57 nsFrameList
& aFrameList
) {
58 if (aListID
== kPopupList
) {
59 AddPopupFrameList(aFrameList
);
62 nsBoxFrame::InsertFrames(aListID
, aPrevFrame
, aFrameList
);
65 void nsPopupSetFrame::SetInitialChildList(ChildListID aListID
,
66 nsFrameList
& aChildList
) {
67 if (aListID
== kPopupList
) {
68 NS_ASSERTION(mPopupList
.IsEmpty(),
69 "SetInitialChildList on non-empty child list");
70 AddPopupFrameList(aChildList
);
73 nsBoxFrame::SetInitialChildList(aListID
, aChildList
);
76 const nsFrameList
& nsPopupSetFrame::GetChildList(ChildListID aListID
) const {
77 if (kPopupList
== aListID
) {
80 return nsBoxFrame::GetChildList(aListID
);
83 void nsPopupSetFrame::GetChildLists(nsTArray
<ChildList
>* aLists
) const {
84 nsBoxFrame::GetChildLists(aLists
);
85 mPopupList
.AppendIfNonempty(aLists
, kPopupList
);
88 void nsPopupSetFrame::DestroyFrom(nsIFrame
* aDestructRoot
,
89 PostDestroyData
& aPostDestroyData
) {
90 mPopupList
.DestroyFramesFrom(aDestructRoot
, aPostDestroyData
);
92 // Normally the root box is our grandparent, but in case of wrapping
93 // it can be our great-grandparent.
94 nsIPopupContainer
* popupContainer
=
95 nsIPopupContainer::GetPopupContainer(PresContext()->GetPresShell());
97 popupContainer
->SetPopupSetFrame(nullptr);
100 nsBoxFrame::DestroyFrom(aDestructRoot
, aPostDestroyData
);
104 nsPopupSetFrame::DoXULLayout(nsBoxLayoutState
& aState
) {
106 nsresult rv
= nsBoxFrame::DoXULLayout(aState
);
108 // lay out all of our currently open popups.
109 for (nsFrameList::Enumerator
e(mPopupList
); !e
.AtEnd(); e
.Next()) {
110 nsMenuPopupFrame
* popupChild
= static_cast<nsMenuPopupFrame
*>(e
.get());
111 popupChild
->LayoutPopup(aState
, nullptr, nullptr, false);
117 void nsPopupSetFrame::RemovePopupFrame(nsIFrame
* aPopup
) {
118 MOZ_ASSERT((aPopup
->GetStateBits() & NS_FRAME_OUT_OF_FLOW
) &&
119 aPopup
->IsMenuPopupFrame(),
120 "removing wrong type of frame in popupset's ::popupList");
122 mPopupList
.DestroyFrame(aPopup
);
125 void nsPopupSetFrame::AddPopupFrameList(nsFrameList
& aPopupFrameList
) {
127 for (nsFrameList::Enumerator
e(aPopupFrameList
); !e
.AtEnd(); e
.Next()) {
128 NS_ASSERTION((e
.get()->GetStateBits() & NS_FRAME_OUT_OF_FLOW
) &&
129 e
.get()->IsMenuPopupFrame(),
130 "adding wrong type of frame in popupset's ::popupList");
133 mPopupList
.InsertFrames(nullptr, nullptr, aPopupFrameList
);