widget/cocoa/nsMenuGroupOwnerX.mm

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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 "nsMenuGroupOwnerX.h"
     7 #include "nsMenuBarX.h"
     8 #include "nsMenuX.h"
     9 #include "nsMenuItemX.h"
    10 #include "nsMenuUtilsX.h"
    11 #include "nsCocoaUtils.h"
    12 #include "nsCocoaWindow.h"
    14 #include "nsCOMPtr.h"
    15 #include "nsString.h"
    16 #include "nsObjCExceptions.h"
    17 #include "nsThreadUtils.h"
    19 #include "mozilla/dom/Element.h"
    20 #include "nsIWidget.h"
    21 #include "nsIDocument.h"
    22 #include "nsIDOMDocument.h"
    23 #include "nsIDOMElement.h"
    25 #include "nsINode.h"
    27 using namespace mozilla;
    29 NS_IMPL_ISUPPORTS(nsMenuGroupOwnerX, nsIMutationObserver)
    32 nsMenuGroupOwnerX::nsMenuGroupOwnerX()
    33 : mCurrentCommandID(eCommand_ID_Last),
    34   mDocument(nullptr)
    35 {
    36 }
    39 nsMenuGroupOwnerX::~nsMenuGroupOwnerX()
    40 {
    41   // make sure we unregister ourselves as a document observer
    42   if (mDocument)
    43     mDocument->RemoveMutationObserver(this);
    44 }
    47 nsresult nsMenuGroupOwnerX::Create(nsIContent* aContent)
    48 {
    49   if (!aContent)
    50     return NS_ERROR_INVALID_ARG;
    52   mContent = aContent;
    54   nsIDocument* doc = aContent->OwnerDoc();
    55   if (!doc)
    56     return NS_ERROR_FAILURE;
    57   doc->AddMutationObserver(this);
    58   mDocument = doc;
    60   return NS_OK;
    61 }
    64 //
    65 // nsIMutationObserver
    66 //
    69 void nsMenuGroupOwnerX::CharacterDataWillChange(nsIDocument* aDocument,
    70                                                 nsIContent* aContent,
    71                                                 CharacterDataChangeInfo* aInfo)
    72 {
    73 }
    76 void nsMenuGroupOwnerX::CharacterDataChanged(nsIDocument* aDocument,
    77                                              nsIContent* aContent,
    78                                              CharacterDataChangeInfo* aInfo)
    79 {
    80 }
    83 void nsMenuGroupOwnerX::ContentAppended(nsIDocument* aDocument,
    84                                         nsIContent* aContainer,
    85                                         nsIContent* aFirstNewContent,
    86                                         int32_t /* unused */)
    87 {
    88   for (nsIContent* cur = aFirstNewContent; cur; cur = cur->GetNextSibling()) {
    89     ContentInserted(aDocument, aContainer, cur, 0);
    90   }
    91 }
    94 void nsMenuGroupOwnerX::NodeWillBeDestroyed(const nsINode * aNode)
    95 {
    96   // our menu bar node is being destroyed
    97   mDocument = nullptr;
    98 }
   101 void nsMenuGroupOwnerX::AttributeWillChange(nsIDocument* aDocument,
   102                                             dom::Element* aContent,
   103                                             int32_t aNameSpaceID,
   104                                             nsIAtom* aAttribute,
   105                                             int32_t aModType)
   106 {
   107 }
   110 void nsMenuGroupOwnerX::AttributeChanged(nsIDocument* aDocument,
   111                                          dom::Element* aElement,
   112                                          int32_t aNameSpaceID,
   113                                          nsIAtom* aAttribute,
   114                                          int32_t aModType)
   115 {
   116   nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
   117   nsChangeObserver* obs = LookupContentChangeObserver(aElement);
   118   if (obs)
   119     obs->ObserveAttributeChanged(aDocument, aElement, aAttribute);
   120 }
   123 void nsMenuGroupOwnerX::ContentRemoved(nsIDocument * aDocument,
   124                                        nsIContent * aContainer,
   125                                        nsIContent * aChild,
   126                                        int32_t aIndexInContainer,
   127                                        nsIContent * aPreviousSibling)
   128 {
   129   if (!aContainer) {
   130     return;
   131   }
   133   nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
   134   nsChangeObserver* obs = LookupContentChangeObserver(aContainer);
   135   if (obs)
   136     obs->ObserveContentRemoved(aDocument, aChild, aIndexInContainer);
   137   else if (aContainer != mContent) {
   138     // We do a lookup on the parent container in case things were removed
   139     // under a "menupopup" item. That is basically a wrapper for the contents
   140     // of a "menu" node.
   141     nsCOMPtr<nsIContent> parent = aContainer->GetParent();
   142     if (parent) {
   143       obs = LookupContentChangeObserver(parent);
   144       if (obs)
   145         obs->ObserveContentRemoved(aDocument, aChild, aIndexInContainer);
   146     }
   147   }
   148 }
   151 void nsMenuGroupOwnerX::ContentInserted(nsIDocument * aDocument,
   152                                         nsIContent * aContainer,
   153                                         nsIContent * aChild,
   154                                         int32_t /* unused */)
   155 {
   156   if (!aContainer) {
   157     return;
   158   }
   160   nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
   161   nsChangeObserver* obs = LookupContentChangeObserver(aContainer);
   162   if (obs)
   163     obs->ObserveContentInserted(aDocument, aContainer, aChild);
   164   else if (aContainer != mContent) {
   165     // We do a lookup on the parent container in case things were removed
   166     // under a "menupopup" item. That is basically a wrapper for the contents
   167     // of a "menu" node.
   168     nsCOMPtr<nsIContent> parent = aContainer->GetParent();
   169     if (parent) {
   170       obs = LookupContentChangeObserver(parent);
   171       if (obs)
   172         obs->ObserveContentInserted(aDocument, aContainer, aChild);
   173     }
   174   }
   175 }
   178 void nsMenuGroupOwnerX::ParentChainChanged(nsIContent *aContent)
   179 {
   180 }
   183 // For change management, we don't use a |nsSupportsHashtable| because
   184 // we know that the lifetime of all these items is bounded by the
   185 // lifetime of the menubar. No need to add any more strong refs to the
   186 // picture because the containment hierarchy already uses strong refs.
   187 void nsMenuGroupOwnerX::RegisterForContentChanges(nsIContent *aContent,
   188                                                   nsChangeObserver *aMenuObject)
   189 {
   190   mContentToObserverTable.Put(aContent, aMenuObject);
   191 }
   194 void nsMenuGroupOwnerX::UnregisterForContentChanges(nsIContent *aContent)
   195 {
   196   mContentToObserverTable.Remove(aContent);
   197 }
   200 nsChangeObserver* nsMenuGroupOwnerX::LookupContentChangeObserver(nsIContent* aContent)
   201 {
   202   nsChangeObserver * result;
   203   if (mContentToObserverTable.Get(aContent, &result))
   204     return result;
   205   else
   206     return nullptr;
   207 }
   210 // Given a menu item, creates a unique 4-character command ID and
   211 // maps it to the item. Returns the id for use by the client.
   212 uint32_t nsMenuGroupOwnerX::RegisterForCommand(nsMenuItemX* inMenuItem)
   213 {
   214   // no real need to check for uniqueness. We always start afresh with each
   215   // window at 1. Even if we did get close to the reserved Apple command id's,
   216   // those don't start until at least '    ', which is integer 538976288. If
   217   // we have that many menu items in one window, I think we have other
   218   // problems.
   220   // make id unique
   221   ++mCurrentCommandID;
   223   mCommandToMenuObjectTable.Put(mCurrentCommandID, inMenuItem);
   225   return mCurrentCommandID;
   226 }
   229 // Removes the mapping between the given 4-character command ID
   230 // and its associated menu item.
   231 void nsMenuGroupOwnerX::UnregisterCommand(uint32_t inCommandID)
   232 {
   233   mCommandToMenuObjectTable.Remove(inCommandID);
   234 }
   237 nsMenuItemX* nsMenuGroupOwnerX::GetMenuItemForCommandID(uint32_t inCommandID)
   238 {
   239   nsMenuItemX * result;
   240   if (mCommandToMenuObjectTable.Get(inCommandID, &result))
   241     return result;
   242   else
   243     return nullptr;
   244 }

mercurial