LCOV - code coverage report
Current view: top level - layout/xul - nsMenuFrame.h (source / functions) Hit Total Coverage
Test: output.info Lines: 8 16 50.0 %
Date: 2017-07-14 16:53:18 Functions: 5 11 45.5 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       5             : 
       6             : //
       7             : // nsMenuFrame
       8             : //
       9             : 
      10             : #ifndef nsMenuFrame_h__
      11             : #define nsMenuFrame_h__
      12             : 
      13             : #include "nsIAtom.h"
      14             : #include "nsCOMPtr.h"
      15             : 
      16             : #include "nsBoxFrame.h"
      17             : #include "nsFrameList.h"
      18             : #include "nsGkAtoms.h"
      19             : #include "nsMenuParent.h"
      20             : #include "nsXULPopupManager.h"
      21             : #include "nsINamed.h"
      22             : #include "nsIReflowCallback.h"
      23             : #include "nsITimer.h"
      24             : #include "mozilla/Attributes.h"
      25             : 
      26             : nsIFrame* NS_NewMenuFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
      27             : nsIFrame* NS_NewMenuItemFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
      28             : 
      29             : class nsIContent;
      30             : 
      31             : #define NS_STATE_ACCELTEXT_IS_DERIVED  NS_STATE_BOX_CHILD_RESERVED
      32             : 
      33             : // the type of menuitem
      34             : enum nsMenuType {
      35             :   // a normal menuitem where a command is carried out when activated
      36             :   eMenuType_Normal = 0,
      37             :   // a menuitem with a checkmark that toggles when activated
      38             :   eMenuType_Checkbox = 1,
      39             :   // a radio menuitem where only one of it and its siblings with the same
      40             :   // name attribute can be checked at a time
      41             :   eMenuType_Radio = 2
      42             : };
      43             : 
      44             : enum nsMenuListType {
      45             :   eNotMenuList,      // not a menulist
      46             :   eReadonlyMenuList, // <menulist/>
      47             :   eEditableMenuList  // <menulist editable="true"/>
      48             : };
      49             : 
      50             : class nsMenuFrame;
      51             : 
      52             : /**
      53             :  * nsMenuTimerMediator is a wrapper around an nsMenuFrame which can be safely
      54             :  * passed to timers. The class is reference counted unlike the underlying
      55             :  * nsMenuFrame, so that it will exist as long as the timer holds a reference
      56             :  * to it. The callback is delegated to the contained nsMenuFrame as long as
      57             :  * the contained nsMenuFrame has not been destroyed.
      58             :  */
      59             : class nsMenuTimerMediator final : public nsITimerCallback,
      60             :                                   public nsINamed
      61             : {
      62             : public:
      63             :   explicit nsMenuTimerMediator(nsMenuFrame* aFrame);
      64             : 
      65             :   NS_DECL_ISUPPORTS
      66             :   NS_DECL_NSITIMERCALLBACK
      67             :   NS_DECL_NSINAMED
      68             : 
      69             :   void ClearFrame();
      70             : 
      71             : private:
      72             :   ~nsMenuTimerMediator();
      73             : 
      74             :   // Pointer to the wrapped frame.
      75             :   nsMenuFrame* mFrame;
      76             : };
      77             : 
      78             : class nsMenuFrame final : public nsBoxFrame
      79             :                         , public nsIReflowCallback
      80             : {
      81             : public:
      82             :   explicit nsMenuFrame(nsStyleContext* aContext);
      83             : 
      84             :   NS_DECL_QUERYFRAME
      85         263 :   NS_DECL_FRAMEARENA_HELPERS(nsMenuFrame)
      86             : 
      87             :   NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState) override;
      88             :   virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override;
      89             :   virtual nsSize GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState) override;
      90             : 
      91             :   virtual void Init(nsIContent*       aContent,
      92             :                     nsContainerFrame* aParent,
      93             :                     nsIFrame*         aPrevInFlow) override;
      94             : 
      95             : #ifdef DEBUG_LAYOUT
      96             :   virtual nsresult SetXULDebug(nsBoxLayoutState& aState, bool aDebug) override;
      97             : #endif
      98             : 
      99             :   // The following methods are all overridden so that the menupopup
     100             :   // can be stored in a separate list, so that it doesn't impact reflow of the
     101             :   // actual menu item at all.
     102             :   virtual const nsFrameList& GetChildList(ChildListID aList) const override;
     103             :   virtual void GetChildLists(nsTArray<ChildList>* aLists) const override;
     104             :   virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
     105             : 
     106             :   // Overridden to prevent events from going to children of the menu.
     107             :   virtual void BuildDisplayListForChildren(nsDisplayListBuilder*   aBuilder,
     108             :                                            const nsRect&           aDirtyRect,
     109             :                                            const nsDisplayListSet& aLists) override;
     110             : 
     111             :   // this method can destroy the frame
     112             :   virtual nsresult HandleEvent(nsPresContext* aPresContext,
     113             :                                mozilla::WidgetGUIEvent* aEvent,
     114             :                                nsEventStatus* aEventStatus) override;
     115             : 
     116             :   virtual void SetInitialChildList(ChildListID  aListID,
     117             :                                    nsFrameList& aChildList) override;
     118             :   virtual void AppendFrames(ChildListID     aListID,
     119             :                             nsFrameList&    aFrameList) override;
     120             :   virtual void InsertFrames(ChildListID     aListID,
     121             :                             nsIFrame*       aPrevFrame,
     122             :                             nsFrameList&    aFrameList) override;
     123             :   virtual void RemoveFrame(ChildListID     aListID,
     124             :                            nsIFrame*       aOldFrame) override;
     125             : 
     126             :   NS_IMETHOD SelectMenu(bool aActivateFlag);
     127             : 
     128             :   virtual nsIScrollableFrame* GetScrollTargetFrame() override;
     129             : 
     130             :   // Retrieve the element that the menu should be anchored to. By default this is
     131             :   // the menu itself. However, the anchor attribute may refer to the value of an
     132             :   // anonid within the menu's binding, or, if not found, the id of an element in
     133             :   // the document.
     134             :   nsIContent* GetAnchor();
     135             : 
     136             :   /**
     137             :    * NOTE: OpenMenu will open the menu asynchronously.
     138             :    */
     139             :   void OpenMenu(bool aSelectFirstItem);
     140             :   // CloseMenu closes the menu asynchronously
     141             :   void CloseMenu(bool aDeselectMenu);
     142             : 
     143           0 :   bool IsChecked() { return mChecked; }
     144             : 
     145             :   NS_IMETHOD GetActiveChild(nsIDOMElement** aResult);
     146             :   NS_IMETHOD SetActiveChild(nsIDOMElement* aChild);
     147             : 
     148             :   // called when the Enter key is pressed while the menuitem is the current
     149             :   // one in its parent popup. This will carry out the command attached to
     150             :   // the menuitem. If the menu should be opened, this frame will be returned,
     151             :   // otherwise null will be returned.
     152             :   nsMenuFrame* Enter(mozilla::WidgetGUIEvent* aEvent);
     153             : 
     154             :   // Return the nearest menu bar or menupopup ancestor frame.
     155             :   nsMenuParent* GetMenuParent() const;
     156             : 
     157           0 :   const nsAString& GetRadioGroupName() { return mGroupName; }
     158           0 :   nsMenuType GetMenuType() { return mType; }
     159             :   nsMenuPopupFrame* GetPopup();
     160             : 
     161             :   /**
     162             :    * @return true if this frame has a popup child frame.
     163             :    */
     164         547 :   bool HasPopup() const
     165             :   {
     166         547 :     return (GetStateBits() & NS_STATE_MENU_HAS_POPUP_LIST) != 0;
     167             :   }
     168             : 
     169             : 
     170             :   // nsMenuFrame methods
     171             : 
     172         231 :   bool IsOnMenuBar() const
     173             :   {
     174         231 :     nsMenuParent* menuParent = GetMenuParent();
     175         231 :     return menuParent && menuParent->IsMenuBar();
     176             :   }
     177             :   bool IsOnActiveMenuBar() const
     178             :   {
     179             :     nsMenuParent* menuParent = GetMenuParent();
     180             :     return menuParent && menuParent->IsMenuBar() && menuParent->IsActive();
     181             :   }
     182             :   virtual bool IsOpen();
     183             :   virtual bool IsMenu();
     184             :   nsMenuListType GetParentMenuListType();
     185             :   bool IsDisabled();
     186             :   void ToggleMenuState();
     187             : 
     188             :   // indiciate that the menu's popup has just been opened, so that the menu
     189             :   // can update its open state. This method modifies the open attribute on
     190             :   // the menu, so the frames could be gone after this call.
     191             :   void PopupOpened();
     192             :   // indiciate that the menu's popup has just been closed, so that the menu
     193             :   // can update its open state. The menu should be unhighlighted if
     194             :   // aDeselectedMenu is true. This method modifies the open attribute on
     195             :   // the menu, so the frames could be gone after this call.
     196             :   void PopupClosed(bool aDeselectMenu);
     197             : 
     198             :   // returns true if this is a menu on another menu popup. A menu is a submenu
     199             :   // if it has a parent popup or menupopup.
     200           0 :   bool IsOnMenu() const
     201             :   {
     202           0 :     nsMenuParent* menuParent = GetMenuParent();
     203           0 :     return menuParent && menuParent->IsMenu();
     204             :   }
     205          15 :   void SetIsMenu(bool aIsMenu) { mIsMenu = aIsMenu; }
     206             : 
     207             : #ifdef DEBUG_FRAME_DUMP
     208           0 :   virtual nsresult GetFrameName(nsAString& aResult) const override
     209             :   {
     210           0 :       return MakeFrameName(NS_LITERAL_STRING("Menu"), aResult);
     211             :   }
     212             : #endif
     213             : 
     214             :   static bool IsSizedToPopup(nsIContent* aContent, bool aRequireAlways);
     215             : 
     216             :   // nsIReflowCallback
     217             :   virtual bool ReflowFinished() override;
     218             :   virtual void ReflowCallbackCanceled() override;
     219             : 
     220             : protected:
     221             :   friend class nsMenuTimerMediator;
     222             :   friend class nsASyncMenuInitialization;
     223             :   friend class nsMenuAttributeChangedEvent;
     224             : 
     225             :   /**
     226             :    * Initialize the popup list to the first popup frame within
     227             :    * aChildList. Removes the popup, if any, from aChildList.
     228             :    */
     229             :   void SetPopupFrame(nsFrameList& aChildList);
     230             : 
     231             :   /**
     232             :    * Get the popup frame list from the frame property.
     233             :    * @return the property value if it exists, nullptr otherwise.
     234             :    */
     235             :   nsFrameList* GetPopupList() const;
     236             : 
     237             :   /**
     238             :    * Destroy the popup list property.  The list must exist and be empty.
     239             :    */
     240             :   void DestroyPopupList();
     241             : 
     242             :   // Update the menu's type (normal, checkbox, radio).
     243             :   // This method can destroy the frame.
     244             :   void UpdateMenuType();
     245             :   // Update the checked state of the menu, and for radios, clear any other
     246             :   // checked items. This method can destroy the frame.
     247             :   void UpdateMenuSpecialState();
     248             : 
     249             :   // Examines the key node and builds the accelerator.
     250             :   void BuildAcceleratorText(bool aNotify);
     251             : 
     252             :   // Called to execute our command handler. This method can destroy the frame.
     253             :   void Execute(mozilla::WidgetGUIEvent *aEvent);
     254             : 
     255             :   // This method can destroy the frame
     256             :   virtual nsresult AttributeChanged(int32_t aNameSpaceID,
     257             :                                     nsIAtom* aAttribute,
     258             :                                     int32_t aModType) override;
     259           1 :   virtual ~nsMenuFrame() { }
     260             : 
     261             :   bool SizeToPopup(nsBoxLayoutState& aState, nsSize& aSize);
     262             : 
     263             :   bool ShouldBlink();
     264             :   void StartBlinking(mozilla::WidgetGUIEvent* aEvent, bool aFlipChecked);
     265             :   void StopBlinking();
     266             :   void CreateMenuCommandEvent(mozilla::WidgetGUIEvent* aEvent,
     267             :                               bool aFlipChecked);
     268             :   void PassMenuCommandEventToPopupManager();
     269             : 
     270             : protected:
     271             : #ifdef DEBUG_LAYOUT
     272             :   nsresult SetXULDebug(nsBoxLayoutState& aState, nsIFrame* aList, bool aDebug);
     273             : #endif
     274             :   nsresult Notify(nsITimer* aTimer);
     275             : 
     276             :   bool mIsMenu; // Whether or not we can even have children or not.
     277             :   bool mChecked;              // are we checked?
     278             :   bool mIgnoreAccelTextChange; // temporarily set while determining the accelerator key
     279             :   bool mReflowCallbackPosted;
     280             :   nsMenuType mType;
     281             : 
     282             :   // Reference to the mediator which wraps this frame.
     283             :   RefPtr<nsMenuTimerMediator> mTimerMediator;
     284             : 
     285             :   nsCOMPtr<nsITimer> mOpenTimer;
     286             :   nsCOMPtr<nsITimer> mBlinkTimer;
     287             : 
     288             :   uint8_t mBlinkState; // 0: not blinking, 1: off, 2: on
     289             :   RefPtr<nsXULMenuCommandEvent> mDelayedMenuCommandEvent;
     290             : 
     291             :   nsString mGroupName;
     292             : 
     293             : }; // class nsMenuFrame
     294             : 
     295             : #endif

Generated by: LCOV version 1.13