Bumping manifests a=b2g-bump
[gecko.git] / layout / xul / nsRootBoxFrame.cpp
blob583f3c7a7d115911085df8dcd9a3a83cff24ab2e
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsHTMLParts.h"
7 #include "nsStyleConsts.h"
8 #include "nsGkAtoms.h"
9 #include "nsIPresShell.h"
10 #include "nsBoxFrame.h"
11 #include "nsStackLayout.h"
12 #include "nsIRootBox.h"
13 #include "nsIContent.h"
14 #include "nsXULTooltipListener.h"
15 #include "nsFrameManager.h"
16 #include "mozilla/BasicEvents.h"
18 using namespace mozilla;
20 // Interface IDs
22 //#define DEBUG_REFLOW
24 // static
25 nsIRootBox*
26 nsIRootBox::GetRootBox(nsIPresShell* aShell)
28 if (!aShell) {
29 return nullptr;
31 nsIFrame* rootFrame = aShell->FrameManager()->GetRootFrame();
32 if (!rootFrame) {
33 return nullptr;
36 if (rootFrame) {
37 rootFrame = rootFrame->GetFirstPrincipalChild();
40 nsIRootBox* rootBox = do_QueryFrame(rootFrame);
41 return rootBox;
44 class nsRootBoxFrame : public nsBoxFrame, public nsIRootBox {
45 public:
47 friend nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
49 explicit nsRootBoxFrame(nsStyleContext* aContext);
51 NS_DECL_QUERYFRAME
52 NS_DECL_FRAMEARENA_HELPERS
54 virtual nsPopupSetFrame* GetPopupSetFrame() MOZ_OVERRIDE;
55 virtual void SetPopupSetFrame(nsPopupSetFrame* aPopupSet) MOZ_OVERRIDE;
56 virtual nsIContent* GetDefaultTooltip() MOZ_OVERRIDE;
57 virtual void SetDefaultTooltip(nsIContent* aTooltip) MOZ_OVERRIDE;
58 virtual nsresult AddTooltipSupport(nsIContent* aNode) MOZ_OVERRIDE;
59 virtual nsresult RemoveTooltipSupport(nsIContent* aNode) MOZ_OVERRIDE;
61 virtual void AppendFrames(ChildListID aListID,
62 nsFrameList& aFrameList) MOZ_OVERRIDE;
63 virtual void InsertFrames(ChildListID aListID,
64 nsIFrame* aPrevFrame,
65 nsFrameList& aFrameList) MOZ_OVERRIDE;
66 virtual void RemoveFrame(ChildListID aListID,
67 nsIFrame* aOldFrame) MOZ_OVERRIDE;
69 virtual void Reflow(nsPresContext* aPresContext,
70 nsHTMLReflowMetrics& aDesiredSize,
71 const nsHTMLReflowState& aReflowState,
72 nsReflowStatus& aStatus) MOZ_OVERRIDE;
73 virtual nsresult HandleEvent(nsPresContext* aPresContext,
74 WidgetGUIEvent* aEvent,
75 nsEventStatus* aEventStatus) MOZ_OVERRIDE;
77 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
78 const nsRect& aDirtyRect,
79 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
81 /**
82 * Get the "type" of the frame
84 * @see nsGkAtoms::rootFrame
86 virtual nsIAtom* GetType() const MOZ_OVERRIDE;
88 virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
90 // Override bogus IsFrameOfType in nsBoxFrame.
91 if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced))
92 return false;
93 return nsBoxFrame::IsFrameOfType(aFlags);
96 #ifdef DEBUG_FRAME_DUMP
97 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
98 #endif
100 nsPopupSetFrame* mPopupSetFrame;
102 protected:
103 nsIContent* mDefaultTooltip;
106 //----------------------------------------------------------------------
108 nsContainerFrame*
109 NS_NewRootBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
111 return new (aPresShell) nsRootBoxFrame(aContext);
114 NS_IMPL_FRAMEARENA_HELPERS(nsRootBoxFrame)
116 nsRootBoxFrame::nsRootBoxFrame(nsStyleContext* aContext):
117 nsBoxFrame(aContext, true)
119 mPopupSetFrame = nullptr;
121 nsCOMPtr<nsBoxLayout> layout;
122 NS_NewStackLayout(PresContext()->PresShell(), layout);
123 SetLayoutManager(layout);
126 void
127 nsRootBoxFrame::AppendFrames(ChildListID aListID,
128 nsFrameList& aFrameList)
130 MOZ_ASSERT(aListID == kPrincipalList, "unexpected child list ID");
131 MOZ_ASSERT(mFrames.IsEmpty(), "already have a child frame");
132 nsBoxFrame::AppendFrames(aListID, aFrameList);
135 void
136 nsRootBoxFrame::InsertFrames(ChildListID aListID,
137 nsIFrame* aPrevFrame,
138 nsFrameList& aFrameList)
140 // Because we only support a single child frame inserting is the same
141 // as appending.
142 MOZ_ASSERT(!aPrevFrame, "unexpected previous sibling frame");
143 AppendFrames(aListID, aFrameList);
146 void
147 nsRootBoxFrame::RemoveFrame(ChildListID aListID,
148 nsIFrame* aOldFrame)
150 NS_ASSERTION(aListID == kPrincipalList, "unexpected child list ID");
151 if (aOldFrame == mFrames.FirstChild()) {
152 nsBoxFrame::RemoveFrame(aListID, aOldFrame);
153 } else {
154 MOZ_CRASH("unknown aOldFrame");
158 #ifdef DEBUG_REFLOW
159 int32_t gReflows = 0;
160 #endif
162 void
163 nsRootBoxFrame::Reflow(nsPresContext* aPresContext,
164 nsHTMLReflowMetrics& aDesiredSize,
165 const nsHTMLReflowState& aReflowState,
166 nsReflowStatus& aStatus)
168 DO_GLOBAL_REFLOW_COUNT("nsRootBoxFrame");
170 #ifdef DEBUG_REFLOW
171 gReflows++;
172 printf("----Reflow %d----\n", gReflows);
173 #endif
174 return nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
177 void
178 nsRootBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
179 const nsRect& aDirtyRect,
180 const nsDisplayListSet& aLists)
182 // root boxes don't need a debug border/outline or a selection overlay...
183 // They *may* have a background propagated to them, so force creation
184 // of a background display list element.
185 DisplayBorderBackgroundOutline(aBuilder, aLists, true);
187 BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists);
190 nsresult
191 nsRootBoxFrame::HandleEvent(nsPresContext* aPresContext,
192 WidgetGUIEvent* aEvent,
193 nsEventStatus* aEventStatus)
195 NS_ENSURE_ARG_POINTER(aEventStatus);
196 if (nsEventStatus_eConsumeNoDefault == *aEventStatus) {
197 return NS_OK;
200 if (aEvent->message == NS_MOUSE_BUTTON_UP) {
201 nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
204 return NS_OK;
207 // REVIEW: The override here was doing nothing since nsBoxFrame is our
208 // parent class
209 nsIAtom*
210 nsRootBoxFrame::GetType() const
212 return nsGkAtoms::rootFrame;
215 nsPopupSetFrame*
216 nsRootBoxFrame::GetPopupSetFrame()
218 return mPopupSetFrame;
221 void
222 nsRootBoxFrame::SetPopupSetFrame(nsPopupSetFrame* aPopupSet)
224 // Under normal conditions this should only be called once. However,
225 // if something triggers ReconstructDocElementHierarchy, we will
226 // destroy this frame's child (the nsDocElementBoxFrame), but not this
227 // frame. This will cause the popupset to remove itself by calling
228 // |SetPopupSetFrame(nullptr)|, and then we'll be able to accept a new
229 // popupset. Since the anonymous content is associated with the
230 // nsDocElementBoxFrame, we'll get a new popupset when the new doc
231 // element box frame is created.
232 if (!mPopupSetFrame || !aPopupSet) {
233 mPopupSetFrame = aPopupSet;
234 } else {
235 NS_NOTREACHED("Popup set is already defined! Only 1 allowed.");
239 nsIContent*
240 nsRootBoxFrame::GetDefaultTooltip()
242 return mDefaultTooltip;
245 void
246 nsRootBoxFrame::SetDefaultTooltip(nsIContent* aTooltip)
248 mDefaultTooltip = aTooltip;
251 nsresult
252 nsRootBoxFrame::AddTooltipSupport(nsIContent* aNode)
254 NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
256 nsXULTooltipListener *listener = nsXULTooltipListener::GetInstance();
257 if (!listener)
258 return NS_ERROR_OUT_OF_MEMORY;
260 return listener->AddTooltipSupport(aNode);
263 nsresult
264 nsRootBoxFrame::RemoveTooltipSupport(nsIContent* aNode)
266 // XXjh yuck, I'll have to implement a way to get at
267 // the tooltip listener for a given node to make
268 // this work. Not crucial, we aren't removing
269 // tooltips from any nodes in the app just yet.
270 return NS_ERROR_NOT_IMPLEMENTED;
273 NS_QUERYFRAME_HEAD(nsRootBoxFrame)
274 NS_QUERYFRAME_ENTRY(nsIRootBox)
275 NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
277 #ifdef DEBUG_FRAME_DUMP
278 nsresult
279 nsRootBoxFrame::GetFrameName(nsAString& aResult) const
281 return MakeFrameName(NS_LITERAL_STRING("RootBox"), aResult);
283 #endif