LCOV - app.info - objdir/dist/include/nsXULPopupManager.h

LCOV - code coverage report
| Current view: | directory - objdir/dist/include - nsXULPopupManager.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 41 | 0 | 0.0 %
| Date: | 2012-04-21 | Functions: | 25 | 0 | 0.0 %

           1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
           2                 : /* ***** BEGIN LICENSE BLOCK *****
           3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           4                 :  *
           5                 :  * The contents of this file are subject to the Mozilla Public License Version
           6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           7                 :  * the License. You may obtain a copy of the License at
           8                 :  * http://www.mozilla.org/MPL/
           9                 :  *
          10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          12                 :  * for the specific language governing rights and limitations under the
          13                 :  * License.
          14                 :  *
          15                 :  * The Original Code is mozilla.org code.
          16                 :  *
          17                 :  * The Initial Developer of the Original Code is Neil Deakin
          18                 :  * Portions created by the Initial Developer are Copyright (C) 2006
          19                 :  * the Initial Developer. All Rights Reserved.
          20                 :  *
          21                 :  * Contributor(s):
          22                 :  *
          23                 :  * Alternatively, the contents of this file may be used under the terms of
          24                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          25                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          26                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          27                 :  * of those above. If you wish to allow use of your version of this file only
          28                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          29                 :  * use your version of this file under the terms of the MPL, indicate your
          30                 :  * decision by deleting the provisions above and replace them with the notice
          31                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          32                 :  * the provisions above, a recipient may use your version of this file under
          33                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          34                 :  *
          35                 :  * ***** END LICENSE BLOCK ***** */
          36                 :
          37                 : /**
          38                 :  * The XUL Popup Manager keeps track of all open popups.
          39                 :  */
          40                 :
          41                 : #ifndef nsXULPopupManager_h__
          42                 : #define nsXULPopupManager_h__
          43                 :
          44                 : #include "prlog.h"
          45                 : #include "nsGUIEvent.h"
          46                 : #include "nsIContent.h"
          47                 : #include "nsIRollupListener.h"
          48                 : #include "nsIDOMEventListener.h"
          49                 : #include "nsPoint.h"
          50                 : #include "nsCOMPtr.h"
          51                 : #include "nsTArray.h"
          52                 : #include "nsITimer.h"
          53                 : #include "nsIReflowCallback.h"
          54                 : #include "nsThreadUtils.h"
          55                 : #include "nsStyleConsts.h"
          56                 :
          57                 : // X.h defines KeyPress
          58                 : #ifdef KeyPress
          59                 : #undef KeyPress
          60                 : #endif
          61                 :
          62                 : /**
          63                 :  * There are two types that are used:
          64                 :  *   - dismissable popups such as menus, which should close up when there is a
          65                 :  *     click outside the popup. In this situation, the entire chain of menus
          66                 :  *     above should also be closed.
          67                 :  *   - panels, which stay open until a request is made to close them. This
          68                 :  *     type is used by tooltips.
          69                 :  *
          70                 :  * When a new popup is opened, it is appended to the popup chain, stored in a
          71                 :  * linked list in mPopups for dismissable menus and panels or mNoHidePanels
          72                 :  * for tooltips and panels with noautohide="true".
          73                 :  * Popups are stored in this list linked from newest to oldest. When a click
          74                 :  * occurs outside one of the open dismissable popups, the chain is closed by
          75                 :  * calling Rollup.
          76                 :  */
          77                 :
          78                 : class nsMenuFrame;
          79                 : class nsMenuPopupFrame;
          80                 : class nsMenuBarFrame;
          81                 : class nsMenuParent;
          82                 : class nsIDOMKeyEvent;
          83                 : class nsIDocShellTreeItem;
          84                 :
          85                 : // when a menu command is executed, the closemenu attribute may be used
          86                 : // to define how the menu should be closed up
          87                 : enum CloseMenuMode {
          88                 :   CloseMenuMode_Auto, // close up the chain of menus, default value
          89                 :   CloseMenuMode_None, // don't close up any menus
          90                 :   CloseMenuMode_Single // close up only the menu the command is inside
          91                 : };
          92                 :
          93                 : /**
          94                 :  * nsNavigationDirection: an enum expressing navigation through the menus in
          95                 :  * terms which are independent of the directionality of the chrome. The
          96                 :  * terminology, derived from XSL-FO and CSS3 (e.g.
          97                 :  * http://www.w3.org/TR/css3-text/#TextLayout), is BASE (Before, After, Start,
          98                 :  * End), with the addition of First and Last (mapped to Home and End
          99                 :  * respectively).
         100                 :  *
         101                 :  * In languages such as English where the inline progression is left-to-right
         102                 :  * and the block progression is top-to-bottom (lr-tb), these terms will map out
         103                 :  * as in the following diagram
         104                 :  *
         105                 :  *  --- inline progression --->
         106                 :  *
         107                 :  *           First              |
         108                 :  *           ...                |
         109                 :  *           Before             |
         110                 :  *         +--------+         block
         111                 :  *   Start |        | End  progression
         112                 :  *         +--------+           |
         113                 :  *           After              |
         114                 :  *           ...                |
         115                 :  *           Last               V
         116                 :  *
         117                 :  */
         118                 :
         119                 : enum nsNavigationDirection {
         120                 :   eNavigationDirection_Last,
         121                 :   eNavigationDirection_First,
         122                 :   eNavigationDirection_Start,
         123                 :   eNavigationDirection_Before,
         124                 :   eNavigationDirection_End,
         125                 :   eNavigationDirection_After
         126                 : };
         127                 :
         128                 : #define NS_DIRECTION_IS_INLINE(dir) (dir == eNavigationDirection_Start ||     \
         129                 :                                      dir == eNavigationDirection_End)
         130                 : #define NS_DIRECTION_IS_BLOCK(dir) (dir == eNavigationDirection_Before || \
         131                 :                                     dir == eNavigationDirection_After)
         132                 : #define NS_DIRECTION_IS_BLOCK_TO_EDGE(dir) (dir == eNavigationDirection_First ||    \
         133                 :                                             dir == eNavigationDirection_Last)
         134                 :
         135                 : PR_STATIC_ASSERT(NS_STYLE_DIRECTION_LTR == 0 && NS_STYLE_DIRECTION_RTL == 1);
         136                 : PR_STATIC_ASSERT((NS_VK_HOME == NS_VK_END + 1) &&
         137                 :                  (NS_VK_LEFT == NS_VK_END + 2) &&
         138                 :                  (NS_VK_UP == NS_VK_END + 3) &&
         139                 :                  (NS_VK_RIGHT == NS_VK_END + 4) &&
         140                 :                  (NS_VK_DOWN == NS_VK_END + 5));
         141                 :
         142                 : /**
         143                 :  * DirectionFromKeyCodeTable: two arrays, the first for left-to-right and the
         144                 :  * other for right-to-left, that map keycodes to values of
         145                 :  * nsNavigationDirection.
         146                 :  */
         147                 : extern const nsNavigationDirection DirectionFromKeyCodeTable[2][6];
         148                 :
         149                 : #define NS_DIRECTION_FROM_KEY_CODE(frame, keycode)                     \
         150                 :   (DirectionFromKeyCodeTable[frame->GetStyleVisibility()->mDirection]  \
         151                 :                             [keycode - NS_VK_END])
         152                 :
         153                 : // nsMenuChainItem holds info about an open popup. Items are stored in a
         154                 : // doubly linked list. Note that the linked list is stored beginning from
         155                 : // the lowest child in a chain of menus, as this is the active submenu.
         156                 : class nsMenuChainItem
         157                 : {
         158                 : private:
         159                 :   nsMenuPopupFrame* mFrame; // the popup frame
         160                 :   nsPopupType mPopupType; // the popup type of the frame
         161                 :   bool mIsContext; // true for context menus
         162                 :   bool mOnMenuBar; // true if the menu is on a menu bar
         163                 :   bool mIgnoreKeys; // true if keyboard listeners should not be used
         164                 :
         165                 :   nsMenuChainItem* mParent;
         166                 :   nsMenuChainItem* mChild;
         167                 :
         168                 : public:
         169               0 :   nsMenuChainItem(nsMenuPopupFrame* aFrame, bool aIsContext, nsPopupType aPopupType)
         170                 :     : mFrame(aFrame),
         171                 :       mPopupType(aPopupType),
         172                 :       mIsContext(aIsContext),
         173                 :       mOnMenuBar(false),
         174                 :       mIgnoreKeys(false),
         175                 :       mParent(nsnull),
         176               0 :       mChild(nsnull)
         177                 :   {
         178               0 :     NS_ASSERTION(aFrame, "null frame passed to nsMenuChainItem constructor");
         179               0 :     MOZ_COUNT_CTOR(nsMenuChainItem);
         180               0 :   }
         181                 :
         182               0 :   ~nsMenuChainItem()
         183                 :   {
         184               0 :     MOZ_COUNT_DTOR(nsMenuChainItem);
         185               0 :   }
         186                 :
         187                 :   nsIContent* Content();
         188               0 :   nsMenuPopupFrame* Frame() { return mFrame; }
         189               0 :   nsPopupType PopupType() { return mPopupType; }
         190               0 :   bool IsMenu() { return mPopupType == ePopupTypeMenu; }
         191               0 :   bool IsContextMenu() { return mIsContext; }
         192               0 :   bool IgnoreKeys() { return mIgnoreKeys; }
         193                 :   bool IsOnMenuBar() { return mOnMenuBar; }
         194               0 :   void SetIgnoreKeys(bool aIgnoreKeys) { mIgnoreKeys = aIgnoreKeys; }
         195               0 :   void SetOnMenuBar(bool aOnMenuBar) { mOnMenuBar = aOnMenuBar; }
         196               0 :   nsMenuChainItem* GetParent() { return mParent; }
         197               0 :   nsMenuChainItem* GetChild() { return mChild; }
         198                 :
         199                 :   // set the parent of this item to aParent, also changing the parent
         200                 :   // to have this as a child.
         201                 :   void SetParent(nsMenuChainItem* aParent);
         202                 :
         203                 :   // removes an item from the chain. The root pointer must be supplied in case
         204                 :   // the item is the first item in the chain in which case the pointer will be
         205                 :   // set to the next item, or null if there isn't another item. After detaching,
         206                 :   // this item will not have a parent or a child.
         207                 :   void Detach(nsMenuChainItem** aRoot);
         208                 : };
         209                 :
         210                 : // this class is used for dispatching popupshowing events asynchronously.
         211                 : class nsXULPopupShowingEvent : public nsRunnable
         212               0 : {
         213                 : public:
         214               0 :   nsXULPopupShowingEvent(nsIContent *aPopup,
         215                 :                          bool aIsContextMenu,
         216                 :                          bool aSelectFirstItem)
         217                 :     : mPopup(aPopup),
         218                 :       mIsContextMenu(aIsContextMenu),
         219               0 :       mSelectFirstItem(aSelectFirstItem)
         220                 :   {
         221               0 :     NS_ASSERTION(aPopup, "null popup supplied to nsXULPopupShowingEvent constructor");
         222               0 :   }
         223                 :
         224                 :   NS_IMETHOD Run();
         225                 :
         226                 : private:
         227                 :   nsCOMPtr<nsIContent> mPopup;
         228                 :   bool mIsContextMenu;
         229                 :   bool mSelectFirstItem;
         230                 : };
         231                 :
         232                 : // this class is used for dispatching popuphiding events asynchronously.
         233                 : class nsXULPopupHidingEvent : public nsRunnable
         234               0 : {
         235                 : public:
         236               0 :   nsXULPopupHidingEvent(nsIContent *aPopup,
         237                 :                         nsIContent* aNextPopup,
         238                 :                         nsIContent* aLastPopup,
         239                 :                         nsPopupType aPopupType,
         240                 :                         bool aDeselectMenu)
         241                 :     : mPopup(aPopup),
         242                 :       mNextPopup(aNextPopup),
         243                 :       mLastPopup(aLastPopup),
         244                 :       mPopupType(aPopupType),
         245               0 :       mDeselectMenu(aDeselectMenu)
         246                 :   {
         247               0 :     NS_ASSERTION(aPopup, "null popup supplied to nsXULPopupHidingEvent constructor");
         248                 :     // aNextPopup and aLastPopup may be null
         249               0 :   }
         250                 :
         251                 :   NS_IMETHOD Run();
         252                 :
         253                 : private:
         254                 :   nsCOMPtr<nsIContent> mPopup;
         255                 :   nsCOMPtr<nsIContent> mNextPopup;
         256                 :   nsCOMPtr<nsIContent> mLastPopup;
         257                 :   nsPopupType mPopupType;
         258                 :   bool mDeselectMenu;
         259                 : };
         260                 :
         261                 : // this class is used for dispatching menu command events asynchronously.
         262                 : class nsXULMenuCommandEvent : public nsRunnable
         263               0 : {
         264                 : public:
         265               0 :   nsXULMenuCommandEvent(nsIContent *aMenu,
         266                 :                         bool aIsTrusted,
         267                 :                         bool aShift,
         268                 :                         bool aControl,
         269                 :                         bool aAlt,
         270                 :                         bool aMeta,
         271                 :                         bool aUserInput,
         272                 :                         bool aFlipChecked)
         273                 :     : mMenu(aMenu),
         274                 :       mIsTrusted(aIsTrusted),
         275                 :       mShift(aShift),
         276                 :       mControl(aControl),
         277                 :       mAlt(aAlt),
         278                 :       mMeta(aMeta),
         279                 :       mUserInput(aUserInput),
         280                 :       mFlipChecked(aFlipChecked),
         281               0 :       mCloseMenuMode(CloseMenuMode_Auto)
         282                 :   {
         283               0 :     NS_ASSERTION(aMenu, "null menu supplied to nsXULMenuCommandEvent constructor");
         284               0 :   }
         285                 :
         286                 :   NS_IMETHOD Run();
         287                 :
         288               0 :   void SetCloseMenuMode(CloseMenuMode aCloseMenuMode) { mCloseMenuMode = aCloseMenuMode; }
         289                 :
         290                 : private:
         291                 :   nsCOMPtr<nsIContent> mMenu;
         292                 :   bool mIsTrusted;
         293                 :   bool mShift;
         294                 :   bool mControl;
         295                 :   bool mAlt;
         296                 :   bool mMeta;
         297                 :   bool mUserInput;
         298                 :   bool mFlipChecked;
         299                 :   CloseMenuMode mCloseMenuMode;
         300                 : };
         301                 :
         302                 : class nsXULPopupManager : public nsIDOMEventListener,
         303                 :                           public nsIRollupListener,
         304                 :                           public nsITimerCallback,
         305                 :                           public nsIObserver
         306                 : {
         307                 :
         308                 : public:
         309                 :   friend class nsXULPopupShowingEvent;
         310                 :   friend class nsXULPopupHidingEvent;
         311                 :   friend class nsXULMenuCommandEvent;
         312                 :
         313                 :   NS_DECL_ISUPPORTS
         314                 :   NS_DECL_NSIOBSERVER
         315                 :   NS_DECL_NSITIMERCALLBACK
         316                 :   NS_DECL_NSIDOMEVENTLISTENER
         317                 :
         318                 :   // nsIRollupListener
         319                 :   virtual nsIContent* Rollup(PRUint32 aCount, bool aGetLastRolledUp = false);
         320                 :   virtual bool ShouldRollupOnMouseWheelEvent();
         321                 :   virtual bool ShouldRollupOnMouseActivate();
         322                 :   virtual PRUint32 GetSubmenuWidgetChain(nsTArray<nsIWidget*> *aWidgetChain);
         323                 :
         324                 :   static nsXULPopupManager* sInstance;
         325                 :
         326                 :   // initialize and shutdown methods called by nsLayoutStatics
         327                 :   static nsresult Init();
         328                 :   static void Shutdown();
         329                 :
         330                 :   // returns a weak reference to the popup manager instance, could return null
         331                 :   // if a popup manager could not be allocated
         332                 :   static nsXULPopupManager* GetInstance();
         333                 :
         334                 :   void AdjustPopupsOnWindowChange(nsPIDOMWindow* aWindow);
         335                 :
         336                 :   // get the frame for a content node aContent if the frame's type
         337                 :   // matches aFrameType. Otherwise, return null. If aShouldFlush is true,
         338                 :   // then the frames are flushed before retrieving the frame.
         339                 :   nsIFrame* GetFrameOfTypeForContent(nsIContent* aContent,
         340                 :                                      nsIAtom* aFrameType,
         341                 :                                      bool aShouldFlush);
         342                 :
         343                 :   // given a menu frame, find the prevous or next menu frame. If aPopup is
         344                 :   // true then navigate a menupopup, from one item on the menu to the previous
         345                 :   // or next one. This is used for cursor navigation between items in a popup
         346                 :   // menu. If aIsPopup is false, the navigation is on a menubar, so navigate
         347                 :   // between menus on the menubar. This is used for left/right cursor navigation.
         348                 :   //
         349                 :   // Items that are not valid, such as non-menu or non-menuitem elements are
         350                 :   // skipped, and the next or previous item after that is checked.
         351                 :   //
         352                 :   // If aStart is null, the first valid item is retrieved by GetNextMenuItem
         353                 :   // and the last valid item is retrieved by GetPreviousMenuItem.
         354                 :   //
         355                 :   // Both methods will loop around the beginning or end if needed.
         356                 :   //
         357                 :   // aParent - the parent menubar or menupopup
         358                 :   // aStart - the menu/menuitem to start navigation from. GetPreviousMenuItem
         359                 :   //          returns the item before it, while GetNextMenuItem returns the
         360                 :   //          item after it.
         361                 :   // aIsPopup - true for menupopups, false for menubars
         362                 :   static nsMenuFrame* GetPreviousMenuItem(nsIFrame* aParent,
         363                 :                                           nsMenuFrame* aStart,
         364                 :                                           bool aIsPopup);
         365                 :   static nsMenuFrame* GetNextMenuItem(nsIFrame* aParent,
         366                 :                                       nsMenuFrame* aStart,
         367                 :                                       bool aIsPopup);
         368                 :
         369                 :   // returns true if the menu item aContent is a valid menuitem which may
         370                 :   // be navigated to. aIsPopup should be true for items on a popup, or false
         371                 :   // for items on a menubar.
         372                 :   static bool IsValidMenuItem(nsPresContext* aPresContext,
         373                 :                                 nsIContent* aContent,
         374                 :                                 bool aOnPopup);
         375                 :
         376                 :   // inform the popup manager that a menu bar has been activated or deactivated,
         377                 :   // either because one of its menus has opened or closed, or that the menubar
         378                 :   // has been focused such that its menus may be navigated with the keyboard.
         379                 :   // aActivate should be true when the menubar should be focused, and false
         380                 :   // when the active menu bar should be defocused. In the latter case, if
         381                 :   // aMenuBar isn't currently active, yet another menu bar is, that menu bar
         382                 :   // will remain active.
         383                 :   void SetActiveMenuBar(nsMenuBarFrame* aMenuBar, bool aActivate);
         384                 :
         385                 :   // retrieve the node and offset of the last mouse event used to open a
         386                 :   // context menu. This information is determined from the rangeParent and
         387                 :   // the rangeOffset of the event supplied to ShowPopup or ShowPopupAtScreen.
         388                 :   // This is used by the implementation of nsIDOMXULDocument::GetPopupRangeParent
         389                 :   // and nsIDOMXULDocument::GetPopupRangeOffset.
         390                 :   void GetMouseLocation(nsIDOMNode** aNode, PRInt32* aOffset);
         391                 :
         392                 :   /**
         393                 :    * Open a <menu> given its content node. If aSelectFirstItem is
         394                 :    * set to true, the first item on the menu will automatically be
         395                 :    * selected. If aAsynchronous is true, the event will be dispatched
         396                 :    * asynchronously. This should be true when called from frame code.
         397                 :    */
         398                 :   void ShowMenu(nsIContent *aMenu, bool aSelectFirstItem, bool aAsynchronous);
         399                 :
         400                 :   /**
         401                 :    * Open a popup, either anchored or unanchored. If aSelectFirstItem is
         402                 :    * true, then the first item in the menu is selected. The arguments are
         403                 :    * similar to those for nsIPopupBoxObject::OpenPopup.
         404                 :    *
         405                 :    * aTriggerEvent should be the event that triggered the event. This is used
         406                 :    * to determine the coordinates and trigger node for the popup. This may be
         407                 :    * null if the popup was not triggered by an event.
         408                 :    *
         409                 :    * This fires the popupshowing event synchronously.
         410                 :    */
         411                 :   void ShowPopup(nsIContent* aPopup,
         412                 :                  nsIContent* aAnchorContent,
         413                 :                  const nsAString& aPosition,
         414                 :                  PRInt32 aXPos, PRInt32 aYPos,
         415                 :                  bool aIsContextMenu,
         416                 :                  bool aAttributesOverride,
         417                 :                  bool aSelectFirstItem,
         418                 :                  nsIDOMEvent* aTriggerEvent);
         419                 :
         420                 :   /**
         421                 :    * Open a popup at a specific screen position specified by aXPos and aYPos,
         422                 :    * measured in CSS pixels.
         423                 :    *
         424                 :    * This fires the popupshowing event synchronously.
         425                 :    *
         426                 :    * If aIsContextMenu is true, the popup is positioned at a slight
         427                 :    * offset from aXPos/aYPos to ensure that it is not under the mouse
         428                 :    * cursor.
         429                 :    */
         430                 :   void ShowPopupAtScreen(nsIContent* aPopup,
         431                 :                          PRInt32 aXPos, PRInt32 aYPos,
         432                 :                          bool aIsContextMenu,
         433                 :                          nsIDOMEvent* aTriggerEvent);
         434                 :
         435                 :   /**
         436                 :    * Open a tooltip at a specific screen position specified by aXPos and aYPos,
         437                 :    * measured in CSS pixels.
         438                 :    *
         439                 :    * This fires the popupshowing event synchronously.
         440                 :    */
         441                 :   void ShowTooltipAtScreen(nsIContent* aPopup,
         442                 :                            nsIContent* aTriggerContent,
         443                 :                            PRInt32 aXPos, PRInt32 aYPos);
         444                 :
         445                 :   /**
         446                 :    * This method is provided only for compatibility with an older popup API.
         447                 :    * New code should not call this function and should call ShowPopup instead.
         448                 :    *
         449                 :    * This fires the popupshowing event synchronously.
         450                 :    */
         451                 :   void ShowPopupWithAnchorAlign(nsIContent* aPopup,
         452                 :                                 nsIContent* aAnchorContent,
         453                 :                                 nsAString& aAnchor,
         454                 :                                 nsAString& aAlign,
         455                 :                                 PRInt32 aXPos, PRInt32 aYPos,
         456                 :                                 bool aIsContextMenu);
         457                 :
         458                 :   /*
         459                 :    * Hide a popup aPopup. If the popup is in a <menu>, then also inform the
         460                 :    * menu that the popup is being hidden.
         461                 :    *
         462                 :    * aHideChain - true if the entire chain of menus should be closed. If false,
         463                 :    *              only this popup is closed.
         464                 :    * aDeselectMenu - true if the parent <menu> of the popup should be deselected.
         465                 :    *                 This will be false when the menu is closed by pressing the
         466                 :    *                 Escape key.
         467                 :    * aAsynchronous - true if the first popuphiding event should be sent
         468                 :    *                 asynchrously. This should be true if HidePopup is called
         469                 :    *                 from a frame.
         470                 :    * aLastPopup - optional popup to close last when hiding a chain of menus.
         471                 :    *              If null, then all popups will be closed.
         472                 :    */
         473                 :   void HidePopup(nsIContent* aPopup,
         474                 :                  bool aHideChain,
         475                 :                  bool aDeselectMenu,
         476                 :                  bool aAsynchronous,
         477                 :                  nsIContent* aLastPopup = nsnull);
         478                 :
         479                 :   /**
         480                 :    * Hide the popup aFrame. This method is called by the view manager when the
         481                 :    * close button is pressed.
         482                 :    */
         483                 :   void HidePopup(nsIFrame* aFrame);
         484                 :
         485                 :   /**
         486                 :    * Hide a popup after a short delay. This is used when rolling over menu items.
         487                 :    * This timer is stored in mCloseTimer. The timer may be cancelled and the popup
         488                 :    * closed by calling KillMenuTimer.
         489                 :    */
         490                 :   void HidePopupAfterDelay(nsMenuPopupFrame* aPopup);
         491                 :
         492                 :   /**
         493                 :    * Hide all of the popups from a given docshell. This should be called when the
         494                 :    * document is hidden.
         495                 :    */
         496                 :   void HidePopupsInDocShell(nsIDocShellTreeItem* aDocShellToHide);
         497                 :
         498                 :   /**
         499                 :    * Execute a menu command from the triggering event aEvent.
         500                 :    *
         501                 :    * aMenu - a menuitem to execute
         502                 :    * aEvent - an nsXULMenuCommandEvent that contains all the info from the mouse
         503                 :    *          event which triggered the menu to be executed, may not be null
         504                 :    */
         505                 :   void ExecuteMenu(nsIContent* aMenu, nsXULMenuCommandEvent* aEvent);
         506                 :
         507                 :   /**
         508                 :    * Return true if the popup for the supplied content node is open.
         509                 :    */
         510                 :   bool IsPopupOpen(nsIContent* aPopup);
         511                 :
         512                 :   /**
         513                 :    * Return true if the popup for the supplied menu parent is open.
         514                 :    */
         515                 :   bool IsPopupOpenForMenuParent(nsMenuParent* aMenuParent);
         516                 :
         517                 :   /**
         518                 :    * Return the frame for the topmost open popup of a given type, or null if
         519                 :    * no popup of that type is open. If aType is ePopupTypeAny, a menu of any
         520                 :    * type is returned, except for popups in the mNoHidePanels list.
         521                 :    */
         522                 :   nsIFrame* GetTopPopup(nsPopupType aType);
         523                 :
         524                 :   /**
         525                 :    * Return an array of all the open and visible popup frames for
         526                 :    * menus, in order from top to bottom.
         527                 :    */
         528                 :   nsTArray<nsIFrame *> GetVisiblePopups();
         529                 :
         530                 :   /**
         531                 :    * Get the node that last triggered a popup or tooltip in the document
         532                 :    * aDocument. aDocument must be non-null and be a document contained within
         533                 :    * the same window hierarchy as the popup to retrieve.
         534                 :    */
         535               0 :   already_AddRefed<nsIDOMNode> GetLastTriggerPopupNode(nsIDocument* aDocument)
         536                 :   {
         537               0 :     return GetLastTriggerNode(aDocument, false);
         538                 :   }
         539                 :
         540               0 :   already_AddRefed<nsIDOMNode> GetLastTriggerTooltipNode(nsIDocument* aDocument)
         541                 :   {
         542               0 :     return GetLastTriggerNode(aDocument, true);
         543                 :   }
         544                 :
         545                 :   /**
         546                 :    * Return false if a popup may not be opened. This will return false if the
         547                 :    * popup is already open, if the popup is in a content shell that is not
         548                 :    * focused, or if it is a submenu of another menu that isn't open.
         549                 :    */
         550                 :   bool MayShowPopup(nsMenuPopupFrame* aFrame);
         551                 :
         552                 :   /**
         553                 :    * Indicate that the popup associated with aView has been moved to the
         554                 :    * specified screen coordiates.
         555                 :    */
         556                 :   void PopupMoved(nsIFrame* aFrame, nsIntPoint aPoint);
         557                 :
         558                 :   /**
         559                 :    * Indicate that the popup associated with aView has been resized to the
         560                 :    * specified screen width and height.
         561                 :    */
         562                 :   void PopupResized(nsIFrame* aFrame, nsIntSize ASize);
         563                 :
         564                 :   /**
         565                 :    * Called when a popup frame is destroyed. In this case, just remove the
         566                 :    * item and later popups from the list. No point going through HidePopup as
         567                 :    * the frames have gone away.
         568                 :    */
         569                 :   void PopupDestroyed(nsMenuPopupFrame* aFrame);
         570                 :
         571                 :   /**
         572                 :    * Returns true if there is a context menu open. If aPopup is specified,
         573                 :    * then the context menu must be later in the chain than aPopup. If aPopup
         574                 :    * is null, returns true if any context menu at all is open.
         575                 :    */
         576                 :   bool HasContextMenu(nsMenuPopupFrame* aPopup);
         577                 :
         578                 :   /**
         579                 :    * Update the commands for the menus within the menu popup for a given
         580                 :    * content node. aPopup should be a XUL menupopup element. This method
         581                 :    * changes attributes on the children of aPopup, and deals only with the
         582                 :    * content of the popup, not the frames.
         583                 :    */
         584                 :   void UpdateMenuItems(nsIContent* aPopup);
         585                 :
         586                 :   /**
         587                 :    * Stop the timer which hides a popup after a delay, started by a previous
         588                 :    * call to HidePopupAfterDelay. In addition, the popup awaiting to be hidden
         589                 :    * is closed asynchronously.
         590                 :    */
         591                 :   void KillMenuTimer();
         592                 :
         593                 :   /**
         594                 :    * Cancel the timer which closes menus after delay, but only if the menu to
         595                 :    * close is aMenuParent. When a submenu is opened, the user might move the
         596                 :    * mouse over a sibling menuitem which would normally close the menu. This
         597                 :    * menu is closed via a timer. However, if the user moves the mouse over the
         598                 :    * submenu before the timer fires, we should instead cancel the timer. This
         599                 :    * ensures that the user can move the mouse diagonally over a menu.
         600                 :    */
         601                 :   void CancelMenuTimer(nsMenuParent* aMenuParent);
         602                 :
         603                 :   /**
         604                 :    * Handles navigation for menu accelkeys. Returns true if the key has
         605                 :    * been handled. If aFrame is specified, then the key is handled by that
         606                 :    * popup, otherwise if aFrame is null, the key is handled by the active
         607                 :    * popup or menubar.
         608                 :    */
         609                 :   bool HandleShortcutNavigation(nsIDOMKeyEvent* aKeyEvent,
         610                 :                                   nsMenuPopupFrame* aFrame);
         611                 :
         612                 :   /**
         613                 :    * Handles cursor navigation within a menu. Returns true if the key has
         614                 :    * been handled.
         615                 :    */
         616                 :   bool HandleKeyboardNavigation(PRUint32 aKeyCode);
         617                 :
         618                 :   /**
         619                 :    * Handle keyboard navigation within a menu popup specified by aFrame.
         620                 :    * Returns true if the key was handled and other default handling
         621                 :    * should not occur.
         622                 :    */
         623               0 :   bool HandleKeyboardNavigationInPopup(nsMenuPopupFrame* aFrame,
         624                 :                                          nsNavigationDirection aDir)
         625                 :   {
         626               0 :     return HandleKeyboardNavigationInPopup(nsnull, aFrame, aDir);
         627                 :   }
         628                 :
         629                 :   nsresult KeyUp(nsIDOMKeyEvent* aKeyEvent);
         630                 :   nsresult KeyDown(nsIDOMKeyEvent* aKeyEvent);
         631                 :   nsresult KeyPress(nsIDOMKeyEvent* aKeyEvent);
         632                 :
         633                 : protected:
         634                 :   nsXULPopupManager();
         635                 :   ~nsXULPopupManager();
         636                 :
         637                 :   // get the nsMenuFrame, if any, for the given content node
         638                 :   nsMenuFrame* GetMenuFrameForContent(nsIContent* aContent);
         639                 :
         640                 :   // get the nsMenuPopupFrame, if any, for the given content node
         641                 :   nsMenuPopupFrame* GetPopupFrameForContent(nsIContent* aContent, bool aShouldFlush);
         642                 :
         643                 :   // return the topmost menu, skipping over invisible popups
         644                 :   nsMenuChainItem* GetTopVisibleMenu();
         645                 :
         646                 :   // Hide all of the visible popups from the given list. aDeselectMenu
         647                 :   // indicates whether to deselect the menu of popups when hiding; this
         648                 :   // flag is passed as the first argument to HidePopup. This function
         649                 :   // can cause style changes and frame destruction.
         650                 :   void HidePopupsInList(const nsTArray<nsMenuPopupFrame *> &aFrames,
         651                 :                         bool aDeselectMenu);
         652                 :
         653                 :   // set the event that was used to trigger the popup, or null to clear the
         654                 :   // event details. aTriggerContent will be set to the target of the event.
         655                 :   void InitTriggerEvent(nsIDOMEvent* aEvent, nsIContent* aPopup, nsIContent** aTriggerContent);
         656                 :
         657                 :   // callbacks for ShowPopup and HidePopup as events may be done asynchronously
         658                 :   void ShowPopupCallback(nsIContent* aPopup,
         659                 :                          nsMenuPopupFrame* aPopupFrame,
         660                 :                          bool aIsContextMenu,
         661                 :                          bool aSelectFirstItem);
         662                 :   void HidePopupCallback(nsIContent* aPopup,
         663                 :                          nsMenuPopupFrame* aPopupFrame,
         664                 :                          nsIContent* aNextPopup,
         665                 :                          nsIContent* aLastPopup,
         666                 :                          nsPopupType aPopupType,
         667                 :                          bool aDeselectMenu);
         668                 :
         669                 :   /**
         670                 :    * Fire a popupshowing event on the popup and then open the popup.
         671                 :    *
         672                 :    * aPopup - the popup to open
         673                 :    * aIsContextMenu - true for context menus
         674                 :    * aSelectFirstItem - true to select the first item in the menu
         675                 :    */
         676                 :   void FirePopupShowingEvent(nsIContent* aPopup,
         677                 :                              bool aIsContextMenu,
         678                 :                              bool aSelectFirstItem);
         679                 :
         680                 :   /**
         681                 :    * Fire a popuphiding event and then hide the popup. This will be called
         682                 :    * recursively if aNextPopup and aLastPopup are set in order to hide a chain
         683                 :    * of open menus. If these are not set, only one popup is closed. However,
         684                 :    * if the popup type indicates a menu, yet the next popup is not a menu,
         685                 :    * then this ends the closing of popups. This allows a menulist inside a
         686                 :    * non-menu to close up the menu but not close up the panel it is contained
         687                 :    * within.
         688                 :    *
         689                 :    * The caller must keep a strong reference to aPopup, aNextPopup and aLastPopup.
         690                 :    *
         691                 :    * aPopup - the popup to hide
         692                 :    * aNextPopup - the next popup to hide
         693                 :    * aLastPopup - the last popup in the chain to hide
         694                 :    * aPresContext - nsPresContext for the popup's frame
         695                 :    * aPopupType - the PopupType of the frame.
         696                 :    * aDeselectMenu - true to unhighlight the menu when hiding it
         697                 :    */
         698                 :   void FirePopupHidingEvent(nsIContent* aPopup,
         699                 :                             nsIContent* aNextPopup,
         700                 :                             nsIContent* aLastPopup,
         701                 :                             nsPresContext *aPresContext,
         702                 :                             nsPopupType aPopupType,
         703                 :                             bool aDeselectMenu);
         704                 :
         705                 :   /**
         706                 :    * Handle keyboard navigation within a menu popup specified by aItem.
         707                 :    */
         708               0 :   bool HandleKeyboardNavigationInPopup(nsMenuChainItem* aItem,
         709                 :                                          nsNavigationDirection aDir)
         710                 :   {
         711               0 :     return HandleKeyboardNavigationInPopup(aItem, aItem->Frame(), aDir);
         712                 :   }
         713                 :
         714                 : private:
         715                 :   /**
         716                 :    * Handle keyboard navigation within a menu popup aFrame. If aItem is
         717                 :    * supplied, then it is expected to have a frame equal to aFrame.
         718                 :    * If aItem is non-null, then the navigation may be redirected to
         719                 :    * an open submenu if one exists. Returns true if the key was
         720                 :    * handled and other default handling should not occur.
         721                 :    */
         722                 :   bool HandleKeyboardNavigationInPopup(nsMenuChainItem* aItem,
         723                 :                                          nsMenuPopupFrame* aFrame,
         724                 :                                          nsNavigationDirection aDir);
         725                 :
         726                 : protected:
         727                 :
         728                 :   already_AddRefed<nsIDOMNode> GetLastTriggerNode(nsIDocument* aDocument, bool aIsTooltip);
         729                 :
         730                 :   /**
         731                 :    * Set mouse capturing for the current popup. This traps mouse clicks that
         732                 :    * occur outside the popup so that it can be closed up. aOldPopup should be
         733                 :    * set to the popup that was previously the current popup.
         734                 :    */
         735                 :   void SetCaptureState(nsIContent *aOldPopup);
         736                 :
         737                 :   /**
         738                 :    * Key event listeners are attached to the document containing the current
         739                 :    * menu for menu and shortcut navigation. Only one listener is needed at a
         740                 :    * time, stored in mKeyListener, so switch it only if the document changes.
         741                 :    * Having menus in different documents is very rare, so the listeners will
         742                 :    * usually only be attached when the first menu opens and removed when all
         743                 :    * menus have closed.
         744                 :    *
         745                 :    * This is also used when only a menubar is active without any open menus,
         746                 :    * so that keyboard navigation between menus on the menubar may be done.
         747                 :    */
         748                 :   void UpdateKeyboardListeners();
         749                 :
         750                 :   /*
         751                 :    * Returns true if the docshell for aDoc is aExpected or a child of aExpected.
         752                 :    */
         753                 :   bool IsChildOfDocShell(nsIDocument* aDoc, nsIDocShellTreeItem* aExpected);
         754                 :
         755                 :   // the document the key event listener is attached to
         756                 :   nsCOMPtr<nsIDOMEventTarget> mKeyListener;
         757                 :
         758                 :   // widget that is currently listening to rollup events
         759                 :   nsCOMPtr<nsIWidget> mWidget;
         760                 :
         761                 :   // range parent and offset set in SetTriggerEvent
         762                 :   nsCOMPtr<nsIDOMNode> mRangeParent;
         763                 :   PRInt32 mRangeOffset;
         764                 :   // Device pixels relative to the showing popup's presshell's
         765                 :   // root prescontext's root frame.
         766                 :   nsIntPoint mCachedMousePoint;
         767                 :
         768                 :   // cached modifiers
         769                 :   PRInt8 mCachedModifiers;
         770                 :
         771                 :   // set to the currently active menu bar, if any
         772                 :   nsMenuBarFrame* mActiveMenuBar;
         773                 :
         774                 :   // linked list of normal menus and panels.
         775                 :   nsMenuChainItem* mPopups;
         776                 :
         777                 :   // linked list of noautohide panels and tooltips.
         778                 :   nsMenuChainItem* mNoHidePanels;
         779                 :
         780                 :   // timer used for HidePopupAfterDelay
         781                 :   nsCOMPtr<nsITimer> mCloseTimer;
         782                 :
         783                 :   // a popup that is waiting on the timer
         784                 :   nsMenuPopupFrame* mTimerMenu;
         785                 :
         786                 :   // the popup that is currently being opened, stored only during the
         787                 :   // popupshowing event
         788                 :   nsCOMPtr<nsIContent> mOpeningPopup;
         789                 : };
         790                 :
         791                 : #endif

Generated by: LCOV version 1.7