embedding/components/commandhandler/src/nsCommandManager.cpp

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 "nsString.h"
     8 #include "nsIController.h"
     9 #include "nsIControllers.h"
    10 #include "nsIObserver.h"
    12 #include "nsIComponentManager.h"
    14 #include "nsServiceManagerUtils.h"
    15 #include "nsIScriptSecurityManager.h"
    17 #include "nsIDOMWindow.h"
    18 #include "nsPIDOMWindow.h"
    19 #include "nsPIWindowRoot.h"
    20 #include "nsIFocusManager.h"
    22 #include "nsCOMArray.h"
    24 #include "nsCommandManager.h"
    27 nsCommandManager::nsCommandManager()
    28 : mWindow(nullptr)
    29 {
    30   /* member initializers and constructor code */
    31 }
    33 nsCommandManager::~nsCommandManager()
    34 {
    35   /* destructor code */
    36 }
    39 static PLDHashOperator
    40 TraverseCommandObservers(const char* aKey,
    41                          nsCommandManager::ObserverList* aObservers,
    42                          void* aClosure)
    43 {
    44   nsCycleCollectionTraversalCallback *cb = 
    45     static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
    47   int32_t i, numItems = aObservers->Length();
    48   for (i = 0; i < numItems; ++i) {
    49     cb->NoteXPCOMChild(aObservers->ElementAt(i));
    50   }
    52   return PL_DHASH_NEXT;
    53 }
    55 NS_IMPL_CYCLE_COLLECTION_CLASS(nsCommandManager)
    57 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCommandManager)
    58   tmp->mObserversTable.Clear();
    59 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
    60 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCommandManager)
    61   tmp->mObserversTable.EnumerateRead(TraverseCommandObservers, &cb);
    62 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
    64 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCommandManager)
    65 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCommandManager)
    67 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCommandManager)
    68    NS_INTERFACE_MAP_ENTRY(nsICommandManager)
    69    NS_INTERFACE_MAP_ENTRY(nsPICommandUpdater)
    70    NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
    71    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICommandManager)
    72 NS_INTERFACE_MAP_END
    74 #if 0
    75 #pragma mark -
    76 #endif
    78 /* void init (in nsIDOMWindow aWindow); */
    79 NS_IMETHODIMP
    80 nsCommandManager::Init(nsIDOMWindow *aWindow)
    81 {
    82   NS_ENSURE_ARG_POINTER(aWindow);
    84   NS_ASSERTION(aWindow, "Need non-null window here");
    85   mWindow = aWindow;      // weak ptr
    86   return NS_OK;
    87 }
    89 /* void commandStatusChanged (in DOMString aCommandName, in long aChangeFlags); */
    90 NS_IMETHODIMP
    91 nsCommandManager::CommandStatusChanged(const char * aCommandName)
    92 {
    93   ObserverList* commandObservers;
    94   mObserversTable.Get(aCommandName, &commandObservers);
    96   if (commandObservers)
    97   {
    98     // XXX Should we worry about observers removing themselves from Observe()?
    99     int32_t i, numItems = commandObservers->Length();
   100     for (i = 0; i < numItems;  ++i)
   101     {
   102       nsCOMPtr<nsIObserver> observer = commandObservers->ElementAt(i);
   103       // should we get the command state to pass here? This might be expensive.
   104       observer->Observe(NS_ISUPPORTS_CAST(nsICommandManager*, this),
   105                         aCommandName,
   106                         MOZ_UTF16("command_status_changed"));
   107     }
   108   }
   110   return NS_OK;
   111 }
   113 #if 0
   114 #pragma mark -
   115 #endif
   117 /* void addCommandObserver (in nsIObserver aCommandObserver, in wstring aCommandToObserve); */
   118 NS_IMETHODIMP
   119 nsCommandManager::AddCommandObserver(nsIObserver *aCommandObserver, const char *aCommandToObserve)
   120 {
   121   NS_ENSURE_ARG(aCommandObserver);
   123   // XXX todo: handle special cases of aCommandToObserve being null, or empty
   125   // for each command in the table, we make a list of observers for that command
   126   ObserverList* commandObservers;
   127   if (!mObserversTable.Get(aCommandToObserve, &commandObservers))
   128   {
   129     commandObservers = new ObserverList;
   130     mObserversTable.Put(aCommandToObserve, commandObservers);
   131   }
   133   // need to check that this command observer hasn't already been registered
   134   int32_t existingIndex = commandObservers->IndexOf(aCommandObserver);
   135   if (existingIndex == -1)
   136     commandObservers->AppendElement(aCommandObserver);
   137   else
   138     NS_WARNING("Registering command observer twice on the same command");
   140   return NS_OK;
   141 }
   143 /* void removeCommandObserver (in nsIObserver aCommandObserver, in wstring aCommandObserved); */
   144 NS_IMETHODIMP
   145 nsCommandManager::RemoveCommandObserver(nsIObserver *aCommandObserver, const char *aCommandObserved)
   146 {
   147   NS_ENSURE_ARG(aCommandObserver);
   149   // XXX todo: handle special cases of aCommandToObserve being null, or empty
   151   ObserverList* commandObservers;
   152   if (!mObserversTable.Get(aCommandObserved, &commandObservers))
   153     return NS_ERROR_UNEXPECTED;
   155   commandObservers->RemoveElement(aCommandObserver);
   157   return NS_OK;
   158 }
   160 /* boolean isCommandSupported(in string aCommandName,
   161                               in nsIDOMWindow aTargetWindow); */
   162 NS_IMETHODIMP
   163 nsCommandManager::IsCommandSupported(const char *aCommandName,
   164                                      nsIDOMWindow *aTargetWindow,
   165                                      bool *outCommandSupported)
   166 {
   167   NS_ENSURE_ARG_POINTER(outCommandSupported);
   169   nsCOMPtr<nsIController> controller;
   170   GetControllerForCommand(aCommandName, aTargetWindow, getter_AddRefs(controller)); 
   171   *outCommandSupported = (controller.get() != nullptr);
   172   return NS_OK;
   173 }
   175 /* boolean isCommandEnabled(in string aCommandName,
   176                             in nsIDOMWindow aTargetWindow); */
   177 NS_IMETHODIMP
   178 nsCommandManager::IsCommandEnabled(const char *aCommandName,
   179                                    nsIDOMWindow *aTargetWindow,
   180                                    bool *outCommandEnabled)
   181 {
   182   NS_ENSURE_ARG_POINTER(outCommandEnabled);
   184   bool    commandEnabled = false;
   186   nsCOMPtr<nsIController> controller;
   187   GetControllerForCommand(aCommandName, aTargetWindow, getter_AddRefs(controller)); 
   188   if (controller)
   189   {
   190     controller->IsCommandEnabled(aCommandName, &commandEnabled);
   191   }
   192   *outCommandEnabled = commandEnabled;
   193   return NS_OK;
   194 }
   196 /* void getCommandState (in DOMString aCommandName,
   197                          in nsIDOMWindow aTargetWindow,
   198                          inout nsICommandParams aCommandParams); */
   199 NS_IMETHODIMP
   200 nsCommandManager::GetCommandState(const char *aCommandName,
   201                                   nsIDOMWindow *aTargetWindow,
   202                                   nsICommandParams *aCommandParams)
   203 {
   204   nsCOMPtr<nsIController> controller;
   205   nsAutoString tValue;
   206   nsresult rv = GetControllerForCommand(aCommandName, aTargetWindow, getter_AddRefs(controller)); 
   207   if (!controller)
   208     return NS_ERROR_FAILURE;
   210   nsCOMPtr<nsICommandController>  commandController = do_QueryInterface(controller);
   211   if (commandController)
   212     rv = commandController->GetCommandStateWithParams(aCommandName, aCommandParams);
   213   else
   214     rv = NS_ERROR_NOT_IMPLEMENTED;
   215   return rv;
   216 }
   218 /* void doCommand(in string aCommandName,
   219                   in nsICommandParams aCommandParams,
   220                   in nsIDOMWindow aTargetWindow); */
   221 NS_IMETHODIMP
   222 nsCommandManager::DoCommand(const char *aCommandName,
   223                             nsICommandParams *aCommandParams,
   224                             nsIDOMWindow *aTargetWindow)
   225 {
   226   nsCOMPtr<nsIController> controller;
   227   nsresult rv = GetControllerForCommand(aCommandName, aTargetWindow, getter_AddRefs(controller)); 
   228   if (!controller)
   229 	  return NS_ERROR_FAILURE;
   231   nsCOMPtr<nsICommandController>  commandController = do_QueryInterface(controller);
   232   if (commandController && aCommandParams)
   233     rv = commandController->DoCommandWithParams(aCommandName, aCommandParams);
   234   else
   235     rv = controller->DoCommand(aCommandName);
   236   return rv;
   237 }
   239 nsresult
   240 nsCommandManager::IsCallerChrome(bool *is_caller_chrome)
   241 {
   242   *is_caller_chrome = false;
   243   nsresult rv = NS_OK;
   244   nsCOMPtr<nsIScriptSecurityManager> secMan = 
   245       do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
   246   if (NS_FAILED(rv))
   247     return rv;
   248   if (!secMan)
   249     return NS_ERROR_FAILURE;
   251   rv = secMan->SubjectPrincipalIsSystem(is_caller_chrome);
   252   return rv;
   253 }
   255 nsresult
   256 nsCommandManager::GetControllerForCommand(const char *aCommand, 
   257                                           nsIDOMWindow *aTargetWindow,
   258                                           nsIController** outController)
   259 {
   260   nsresult rv = NS_ERROR_FAILURE;
   261   *outController = nullptr;
   263   // check if we're in content or chrome
   264   // if we're not chrome we must have a target window or we bail
   265   bool isChrome = false;
   266   rv = IsCallerChrome(&isChrome);
   267   if (NS_FAILED(rv))
   268     return rv;
   270   if (!isChrome) {
   271     if (!aTargetWindow)
   272       return rv;
   274     // if a target window is specified, it must be the window we expect
   275     if (aTargetWindow != mWindow)
   276         return NS_ERROR_FAILURE;
   277   }
   279   if (aTargetWindow) {
   280     // get the controller for this particular window
   281     nsCOMPtr<nsIControllers> controllers;
   282     rv = aTargetWindow->GetControllers(getter_AddRefs(controllers));
   283     if (NS_FAILED(rv))
   284       return rv;
   285     if (!controllers)
   286       return NS_ERROR_FAILURE;
   288     // dispatch the command
   289     return controllers->GetControllerForCommand(aCommand, outController);
   290   }
   292   nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(mWindow));
   293   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
   294   nsCOMPtr<nsPIWindowRoot> root = window->GetTopWindowRoot();
   295   NS_ENSURE_TRUE(root, NS_ERROR_FAILURE);
   297   // no target window; send command to focus controller
   298   return root->GetControllerForCommand(aCommand, outController);
   299 }

mercurial