layout/xul/nsRootBoxFrame.cpp

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     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)
    27 {
    28   if (!aShell) {
    29     return nullptr;
    30   }
    31   nsIFrame* rootFrame = aShell->FrameManager()->GetRootFrame();
    32   if (!rootFrame) {
    33     return nullptr;
    34   }
    36   if (rootFrame) {
    37     rootFrame = rootFrame->GetFirstPrincipalChild();
    38   }
    40   nsIRootBox* rootBox = do_QueryFrame(rootFrame);
    41   return rootBox;
    42 }
    44 class nsRootBoxFrame : public nsBoxFrame, public nsIRootBox {
    45 public:
    47   friend nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
    49   nsRootBoxFrame(nsIPresShell* aShell, 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 nsresult AppendFrames(ChildListID     aListID,
    62                                 nsFrameList&    aFrameList) MOZ_OVERRIDE;
    63   virtual nsresult InsertFrames(ChildListID     aListID,
    64                                 nsIFrame*       aPrevFrame,
    65                                 nsFrameList&    aFrameList) MOZ_OVERRIDE;
    66   virtual nsresult RemoveFrame(ChildListID     aListID,
    67                                nsIFrame*       aOldFrame) MOZ_OVERRIDE;
    69   virtual nsresult 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
    83    *
    84    * @see nsGkAtoms::rootFrame
    85    */
    86   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
    88   virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
    89   {
    90     // Override bogus IsFrameOfType in nsBoxFrame.
    91     if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced))
    92       return false;
    93     return nsBoxFrame::IsFrameOfType(aFlags);
    94   }
    96 #ifdef DEBUG_FRAME_DUMP
    97   virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
    98 #endif
   100   nsPopupSetFrame* mPopupSetFrame;
   102 protected:
   103   nsIContent* mDefaultTooltip;
   104 };
   106 //----------------------------------------------------------------------
   108 nsIFrame*
   109 NS_NewRootBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
   110 {
   111   return new (aPresShell) nsRootBoxFrame (aPresShell, aContext);
   112 }
   114 NS_IMPL_FRAMEARENA_HELPERS(nsRootBoxFrame)
   116 nsRootBoxFrame::nsRootBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext):
   117   nsBoxFrame(aShell, aContext, true)
   118 {
   119   mPopupSetFrame = nullptr;
   121   nsCOMPtr<nsBoxLayout> layout;
   122   NS_NewStackLayout(aShell, layout);
   123   SetLayoutManager(layout);
   124 }
   126 nsresult
   127 nsRootBoxFrame::AppendFrames(ChildListID     aListID,
   128                              nsFrameList&    aFrameList)
   129 {
   130   nsresult  rv;
   132   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list ID");
   133   NS_PRECONDITION(mFrames.IsEmpty(), "already have a child frame");
   134   if (aListID != kPrincipalList) {
   135     // We only support the principal child list.
   136     rv = NS_ERROR_INVALID_ARG;
   137   } else if (!mFrames.IsEmpty()) {
   138     // We only allow a single child frame.
   139     rv = NS_ERROR_FAILURE;
   140   } else {
   141     rv = nsBoxFrame::AppendFrames(aListID, aFrameList);
   142   }
   144   return rv;
   145 }
   147 nsresult
   148 nsRootBoxFrame::InsertFrames(ChildListID     aListID,
   149                              nsIFrame*       aPrevFrame,
   150                              nsFrameList&    aFrameList)
   151 {
   152   nsresult  rv;
   154   // Because we only support a single child frame inserting is the same
   155   // as appending.
   156   NS_PRECONDITION(!aPrevFrame, "unexpected previous sibling frame");
   157   if (aPrevFrame) {
   158     rv = NS_ERROR_UNEXPECTED;
   159   } else {
   160     rv = AppendFrames(aListID, aFrameList);
   161   }
   163   return rv;
   164 }
   166 nsresult
   167 nsRootBoxFrame::RemoveFrame(ChildListID     aListID,
   168                             nsIFrame*       aOldFrame)
   169 {
   170   nsresult  rv;
   172   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list ID");
   173   if (aListID != kPrincipalList) {
   174     // We only support the principal child list.
   175     rv = NS_ERROR_INVALID_ARG;
   176   } else if (aOldFrame == mFrames.FirstChild()) {
   177     rv = nsBoxFrame::RemoveFrame(aListID, aOldFrame);
   178   } else {
   179     rv = NS_ERROR_FAILURE;
   180   }
   182   return rv;
   183 }
   185 #ifdef DEBUG_REFLOW
   186 int32_t gReflows = 0;
   187 #endif
   189 nsresult
   190 nsRootBoxFrame::Reflow(nsPresContext*           aPresContext,
   191                        nsHTMLReflowMetrics&     aDesiredSize,
   192                        const nsHTMLReflowState& aReflowState,
   193                        nsReflowStatus&          aStatus)
   194 {
   195   DO_GLOBAL_REFLOW_COUNT("nsRootBoxFrame");
   197 #ifdef DEBUG_REFLOW
   198   gReflows++;
   199   printf("----Reflow %d----\n", gReflows);
   200 #endif
   201   return nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
   202 }
   204 void
   205 nsRootBoxFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
   206                                  const nsRect&           aDirtyRect,
   207                                  const nsDisplayListSet& aLists)
   208 {
   209   // root boxes don't need a debug border/outline or a selection overlay...
   210   // They *may* have a background propagated to them, so force creation
   211   // of a background display list element.
   212   DisplayBorderBackgroundOutline(aBuilder, aLists, true);
   214   BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists);
   215 }
   217 nsresult
   218 nsRootBoxFrame::HandleEvent(nsPresContext* aPresContext,
   219                             WidgetGUIEvent* aEvent,
   220                             nsEventStatus* aEventStatus)
   221 {
   222   NS_ENSURE_ARG_POINTER(aEventStatus);
   223   if (nsEventStatus_eConsumeNoDefault == *aEventStatus) {
   224     return NS_OK;
   225   }
   227   if (aEvent->message == NS_MOUSE_BUTTON_UP) {
   228     nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
   229   }
   231   return NS_OK;
   232 }
   234 // REVIEW: The override here was doing nothing since nsBoxFrame is our
   235 // parent class
   236 nsIAtom*
   237 nsRootBoxFrame::GetType() const
   238 {
   239   return nsGkAtoms::rootFrame;
   240 }
   242 nsPopupSetFrame*
   243 nsRootBoxFrame::GetPopupSetFrame()
   244 {
   245   return mPopupSetFrame;
   246 }
   248 void
   249 nsRootBoxFrame::SetPopupSetFrame(nsPopupSetFrame* aPopupSet)
   250 {
   251   // Under normal conditions this should only be called once.  However,
   252   // if something triggers ReconstructDocElementHierarchy, we will
   253   // destroy this frame's child (the nsDocElementBoxFrame), but not this
   254   // frame.  This will cause the popupset to remove itself by calling
   255   // |SetPopupSetFrame(nullptr)|, and then we'll be able to accept a new
   256   // popupset.  Since the anonymous content is associated with the
   257   // nsDocElementBoxFrame, we'll get a new popupset when the new doc
   258   // element box frame is created.
   259   if (!mPopupSetFrame || !aPopupSet) {
   260     mPopupSetFrame = aPopupSet;
   261   } else {
   262     NS_NOTREACHED("Popup set is already defined! Only 1 allowed.");
   263   }
   264 }
   266 nsIContent*
   267 nsRootBoxFrame::GetDefaultTooltip()
   268 {
   269   return mDefaultTooltip;
   270 }
   272 void
   273 nsRootBoxFrame::SetDefaultTooltip(nsIContent* aTooltip)
   274 {
   275   mDefaultTooltip = aTooltip;
   276 }
   278 nsresult
   279 nsRootBoxFrame::AddTooltipSupport(nsIContent* aNode)
   280 {
   281   NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
   283   nsXULTooltipListener *listener = nsXULTooltipListener::GetInstance();
   284   if (!listener)
   285     return NS_ERROR_OUT_OF_MEMORY;
   287   return listener->AddTooltipSupport(aNode);
   288 }
   290 nsresult
   291 nsRootBoxFrame::RemoveTooltipSupport(nsIContent* aNode)
   292 {
   293   // XXjh yuck, I'll have to implement a way to get at
   294   // the tooltip listener for a given node to make 
   295   // this work.  Not crucial, we aren't removing 
   296   // tooltips from any nodes in the app just yet.
   297   return NS_ERROR_NOT_IMPLEMENTED;
   298 }
   300 NS_QUERYFRAME_HEAD(nsRootBoxFrame)
   301   NS_QUERYFRAME_ENTRY(nsIRootBox)
   302 NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
   304 #ifdef DEBUG_FRAME_DUMP
   305 nsresult
   306 nsRootBoxFrame::GetFrameName(nsAString& aResult) const
   307 {
   308   return MakeFrameName(NS_LITERAL_STRING("RootBox"), aResult);
   309 }
   310 #endif

mercurial