LCOV - code coverage report
Current view: top level - dom/base - nsWindowRoot.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 136 188 72.3 %
Date: 2017-07-14 16:53:18 Functions: 24 40 60.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/BasicEvents.h"
       8             : #include "mozilla/EventDispatcher.h"
       9             : #include "mozilla/EventListenerManager.h"
      10             : #include "mozilla/dom/WindowRootBinding.h"
      11             : #include "nsCOMPtr.h"
      12             : #include "nsWindowRoot.h"
      13             : #include "nsPIDOMWindow.h"
      14             : #include "nsPresContext.h"
      15             : #include "nsLayoutCID.h"
      16             : #include "nsContentCID.h"
      17             : #include "nsString.h"
      18             : #include "nsGlobalWindow.h"
      19             : #include "nsFocusManager.h"
      20             : #include "nsIContent.h"
      21             : #include "nsIDOMHTMLInputElement.h"
      22             : #include "nsIDOMHTMLTextAreaElement.h"
      23             : #include "nsIControllers.h"
      24             : #include "nsIController.h"
      25             : #include "xpcpublic.h"
      26             : #include "nsCycleCollectionParticipant.h"
      27             : #include "mozilla/dom/TabParent.h"
      28             : 
      29             : #ifdef MOZ_XUL
      30             : #include "nsXULElement.h"
      31             : #endif
      32             : 
      33             : using namespace mozilla;
      34             : using namespace mozilla::dom;
      35             : 
      36           3 : nsWindowRoot::nsWindowRoot(nsPIDOMWindowOuter* aWindow)
      37             : {
      38           3 :   mWindow = aWindow;
      39           3 :   MOZ_ASSERT(mWindow->IsOuterWindow());
      40             : 
      41             :   // Keyboard indicators are not shown on Mac by default.
      42             : #if defined(XP_MACOSX)
      43             :   mShowAccelerators = false;
      44             :   mShowFocusRings = false;
      45             : #else
      46           3 :   mShowAccelerators = true;
      47           3 :   mShowFocusRings = true;
      48             : #endif
      49           3 : }
      50             : 
      51           0 : nsWindowRoot::~nsWindowRoot()
      52             : {
      53           0 :   if (mListenerManager) {
      54           0 :     mListenerManager->Disconnect();
      55             :   }
      56           0 : }
      57             : 
      58           0 : NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsWindowRoot,
      59             :                                       mWindow,
      60             :                                       mListenerManager,
      61             :                                       mParent)
      62             : 
      63         509 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWindowRoot)
      64         506 :   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
      65         506 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventTarget)
      66         506 :   NS_INTERFACE_MAP_ENTRY(nsPIWindowRoot)
      67         443 :   NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
      68         431 :   NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
      69         101 : NS_INTERFACE_MAP_END
      70             : 
      71         734 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsWindowRoot)
      72         718 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsWindowRoot)
      73             : 
      74         320 : NS_IMPL_DOMTARGET_DEFAULTS(nsWindowRoot)
      75             : 
      76             : NS_IMETHODIMP
      77           2 : nsWindowRoot::RemoveEventListener(const nsAString& aType, nsIDOMEventListener* aListener, bool aUseCapture)
      78             : {
      79           4 :   if (RefPtr<EventListenerManager> elm = GetExistingListenerManager()) {
      80           2 :     elm->RemoveEventListener(aType, aListener, aUseCapture);
      81             :   }
      82           2 :   return NS_OK;
      83             : }
      84             : 
      85           1 : NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsWindowRoot)
      86             : 
      87             : NS_IMETHODIMP
      88           0 : nsWindowRoot::DispatchEvent(nsIDOMEvent* aEvt, bool *aRetVal)
      89             : {
      90           0 :   nsEventStatus status = nsEventStatus_eIgnore;
      91           0 :   nsresult rv =  EventDispatcher::DispatchDOMEvent(
      92           0 :     static_cast<EventTarget*>(this), nullptr, aEvt, nullptr, &status);
      93           0 :   *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
      94           0 :   return rv;
      95             : }
      96             : 
      97             : nsresult
      98          19 : nsWindowRoot::DispatchDOMEvent(WidgetEvent* aEvent,
      99             :                                nsIDOMEvent* aDOMEvent,
     100             :                                nsPresContext* aPresContext,
     101             :                                nsEventStatus* aEventStatus)
     102             : {
     103          19 :   return EventDispatcher::DispatchDOMEvent(static_cast<EventTarget*>(this),
     104             :                                            aEvent, aDOMEvent,
     105          19 :                                            aPresContext, aEventStatus);
     106             : }
     107             : 
     108             : NS_IMETHODIMP
     109          14 : nsWindowRoot::AddEventListener(const nsAString& aType,
     110             :                                nsIDOMEventListener *aListener,
     111             :                                bool aUseCapture, bool aWantsUntrusted,
     112             :                                uint8_t aOptionalArgc)
     113             : {
     114          14 :   NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
     115             :                "Won't check if this is chrome, you want to set "
     116             :                "aWantsUntrusted to false or make the aWantsUntrusted "
     117             :                "explicit by making optional_argc non-zero.");
     118             : 
     119          14 :   EventListenerManager* elm = GetOrCreateListenerManager();
     120          14 :   NS_ENSURE_STATE(elm);
     121          14 :   elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
     122          14 :   return NS_OK;
     123             : }
     124             : 
     125             : void
     126           0 : nsWindowRoot::AddEventListener(const nsAString& aType,
     127             :                                 EventListener* aListener,
     128             :                                 const AddEventListenerOptionsOrBoolean& aOptions,
     129             :                                 const Nullable<bool>& aWantsUntrusted,
     130             :                                 ErrorResult& aRv)
     131             : {
     132           0 :   bool wantsUntrusted = !aWantsUntrusted.IsNull() && aWantsUntrusted.Value();
     133           0 :   EventListenerManager* elm = GetOrCreateListenerManager();
     134           0 :   if (!elm) {
     135           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
     136           0 :     return;
     137             :   }
     138           0 :   elm->AddEventListener(aType, aListener, aOptions, wantsUntrusted);
     139             : }
     140             : 
     141             : 
     142             : NS_IMETHODIMP
     143           7 : nsWindowRoot::AddSystemEventListener(const nsAString& aType,
     144             :                                      nsIDOMEventListener *aListener,
     145             :                                      bool aUseCapture,
     146             :                                      bool aWantsUntrusted,
     147             :                                      uint8_t aOptionalArgc)
     148             : {
     149           7 :   NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
     150             :                "Won't check if this is chrome, you want to set "
     151             :                "aWantsUntrusted to false or make the aWantsUntrusted "
     152             :                "explicit by making optional_argc non-zero.");
     153             : 
     154           7 :   return NS_AddSystemEventListener(this, aType, aListener, aUseCapture,
     155           7 :                                    aWantsUntrusted);
     156             : }
     157             : 
     158             : EventListenerManager*
     159          30 : nsWindowRoot::GetOrCreateListenerManager()
     160             : {
     161          30 :   if (!mListenerManager) {
     162             :     mListenerManager =
     163           3 :       new EventListenerManager(static_cast<EventTarget*>(this));
     164             :   }
     165             : 
     166          30 :   return mListenerManager;
     167             : }
     168             : 
     169             : EventListenerManager*
     170         233 : nsWindowRoot::GetExistingListenerManager() const
     171             : {
     172         233 :   return mListenerManager;
     173             : }
     174             : 
     175             : nsIScriptContext*
     176           0 : nsWindowRoot::GetContextForEventHandlers(nsresult* aRv)
     177             : {
     178           0 :   *aRv = NS_OK;
     179           0 :   return nullptr;
     180             : }
     181             : 
     182             : nsresult
     183         230 : nsWindowRoot::GetEventTargetParent(EventChainPreVisitor& aVisitor)
     184             : {
     185         230 :   aVisitor.mCanHandle = true;
     186         230 :   aVisitor.mForceContentDispatch = true; //FIXME! Bug 329119
     187             :   // To keep mWindow alive
     188         230 :   aVisitor.mItemData = static_cast<nsISupports *>(mWindow);
     189         230 :   aVisitor.mParentTarget = mParent;
     190         230 :   return NS_OK;
     191             : }
     192             : 
     193             : nsresult
     194         138 : nsWindowRoot::PostHandleEvent(EventChainPostVisitor& aVisitor)
     195             : {
     196         138 :   return NS_OK;
     197             : }
     198             : 
     199             : nsPIDOMWindowOuter*
     200           0 : nsWindowRoot::GetOwnerGlobalForBindings()
     201             : {
     202           0 :   return GetWindow();
     203             : }
     204             : 
     205             : nsIGlobalObject*
     206           0 : nsWindowRoot::GetOwnerGlobal() const
     207             : {
     208             :   nsCOMPtr<nsIGlobalObject> global =
     209           0 :     do_QueryInterface(mWindow->GetCurrentInnerWindow());
     210             :   // We're still holding a ref to it, so returning the raw pointer is ok...
     211           0 :   return global;
     212             : }
     213             : 
     214             : nsPIDOMWindowOuter*
     215           9 : nsWindowRoot::GetWindow()
     216             : {
     217           9 :   return mWindow;
     218             : }
     219             : 
     220             : nsresult
     221          13 : nsWindowRoot::GetControllers(nsIControllers** aResult)
     222             : {
     223          13 :   *aResult = nullptr;
     224             : 
     225             :   // XXX: we should fix this so there's a generic interface that
     226             :   // describes controllers, so this code would have no special
     227             :   // knowledge of what object might have controllers.
     228             : 
     229          26 :   nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
     230             :   nsIContent* focusedContent =
     231          13 :     nsFocusManager::GetFocusedDescendant(mWindow, true, getter_AddRefs(focusedWindow));
     232          13 :   if (focusedContent) {
     233             : #ifdef MOZ_XUL
     234          11 :     RefPtr<nsXULElement> xulElement = nsXULElement::FromContent(focusedContent);
     235          11 :     if (xulElement) {
     236          22 :       ErrorResult rv;
     237          11 :       *aResult = xulElement->GetControllers(rv);
     238          11 :       NS_IF_ADDREF(*aResult);
     239          11 :       return rv.StealNSResult();
     240             :     }
     241             : #endif
     242             : 
     243             :     nsCOMPtr<nsIDOMHTMLTextAreaElement> htmlTextArea =
     244           0 :       do_QueryInterface(focusedContent);
     245           0 :     if (htmlTextArea)
     246           0 :       return htmlTextArea->GetControllers(aResult);
     247             : 
     248             :     nsCOMPtr<nsIDOMHTMLInputElement> htmlInputElement =
     249           0 :       do_QueryInterface(focusedContent);
     250           0 :     if (htmlInputElement)
     251           0 :       return htmlInputElement->GetControllers(aResult);
     252             : 
     253           0 :     if (focusedContent->IsEditable() && focusedWindow)
     254           0 :       return focusedWindow->GetControllers(aResult);
     255             :   }
     256             :   else {
     257           2 :     return focusedWindow->GetControllers(aResult);
     258             :   }
     259             : 
     260           0 :   return NS_OK;
     261             : }
     262             : 
     263             : nsresult
     264          11 : nsWindowRoot::GetControllerForCommand(const char * aCommand,
     265             :                                       nsIController** _retval)
     266             : {
     267          11 :   NS_ENSURE_ARG_POINTER(_retval);
     268          11 :   *_retval = nullptr;
     269             : 
     270             :   {
     271          22 :     nsCOMPtr<nsIControllers> controllers;
     272          11 :     GetControllers(getter_AddRefs(controllers));
     273          11 :     if (controllers) {
     274          22 :       nsCOMPtr<nsIController> controller;
     275          11 :       controllers->GetControllerForCommand(aCommand, getter_AddRefs(controller));
     276          11 :       if (controller) {
     277           0 :         controller.forget(_retval);
     278           0 :         return NS_OK;
     279             :       }
     280             :     }
     281             :   }
     282             : 
     283          22 :   nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
     284          11 :   nsFocusManager::GetFocusedDescendant(mWindow, true, getter_AddRefs(focusedWindow));
     285          25 :   while (focusedWindow) {
     286          18 :     nsCOMPtr<nsIControllers> controllers;
     287          11 :     focusedWindow->GetControllers(getter_AddRefs(controllers));
     288          11 :     if (controllers) {
     289          18 :       nsCOMPtr<nsIController> controller;
     290          22 :       controllers->GetControllerForCommand(aCommand,
     291          22 :                                            getter_AddRefs(controller));
     292          11 :       if (controller) {
     293           4 :         controller.forget(_retval);
     294           4 :         return NS_OK;
     295             :       }
     296             :     }
     297             : 
     298             :     // XXXndeakin P3 is this casting safe?
     299           7 :     nsGlobalWindow *win = nsGlobalWindow::Cast(focusedWindow);
     300           7 :     focusedWindow = win->GetPrivateParent();
     301             :   }
     302             : 
     303           7 :   return NS_OK;
     304             : }
     305             : 
     306             : void
     307           4 : nsWindowRoot::GetEnabledDisabledCommandsForControllers(nsIControllers* aControllers,
     308             :                                                        nsTHashtable<nsCharPtrHashKey>& aCommandsHandled,
     309             :                                                        nsTArray<nsCString>& aEnabledCommands,
     310             :                                                        nsTArray<nsCString>& aDisabledCommands)
     311             : {
     312             :   uint32_t controllerCount;
     313           4 :   aControllers->GetControllerCount(&controllerCount);
     314           8 :   for (uint32_t c = 0; c < controllerCount; c++) {
     315           8 :     nsCOMPtr<nsIController> controller;
     316           4 :     aControllers->GetControllerAt(c, getter_AddRefs(controller));
     317             : 
     318           8 :     nsCOMPtr<nsICommandController> commandController(do_QueryInterface(controller));
     319           4 :     if (commandController) {
     320             :       uint32_t commandsCount;
     321             :       char** commands;
     322           4 :       if (NS_SUCCEEDED(commandController->GetSupportedCommands(&commandsCount, &commands))) {
     323         248 :         for (uint32_t e = 0; e < commandsCount; e++) {
     324             :           // Use a hash to determine which commands have already been handled by
     325             :           // earlier controllers, as the earlier controller's result should get
     326             :           // priority.
     327         244 :           if (aCommandsHandled.EnsureInserted(commands[e])) {
     328             :             // We inserted a new entry into aCommandsHandled.
     329         122 :             bool enabled = false;
     330         122 :             controller->IsCommandEnabled(commands[e], &enabled);
     331             : 
     332         244 :             const nsDependentCSubstring commandStr(commands[e], strlen(commands[e]));
     333         122 :             if (enabled) {
     334         112 :               aEnabledCommands.AppendElement(commandStr);
     335             :             } else {
     336          10 :               aDisabledCommands.AppendElement(commandStr);
     337             :             }
     338             :           }
     339             :         }
     340             : 
     341           4 :         NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(commandsCount, commands);
     342             :       }
     343             :     }
     344             :   }
     345           4 : }
     346             : 
     347             : void
     348           2 : nsWindowRoot::GetEnabledDisabledCommands(nsTArray<nsCString>& aEnabledCommands,
     349             :                                          nsTArray<nsCString>& aDisabledCommands)
     350             : {
     351           4 :   nsTHashtable<nsCharPtrHashKey> commandsHandled;
     352             : 
     353           4 :   nsCOMPtr<nsIControllers> controllers;
     354           2 :   GetControllers(getter_AddRefs(controllers));
     355           2 :   if (controllers) {
     356           2 :     GetEnabledDisabledCommandsForControllers(controllers, commandsHandled,
     357           2 :                                              aEnabledCommands, aDisabledCommands);
     358             :   }
     359             : 
     360           4 :   nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
     361           2 :   nsFocusManager::GetFocusedDescendant(mWindow, true, getter_AddRefs(focusedWindow));
     362           6 :   while (focusedWindow) {
     363           2 :     focusedWindow->GetControllers(getter_AddRefs(controllers));
     364           2 :     if (controllers) {
     365           2 :       GetEnabledDisabledCommandsForControllers(controllers, commandsHandled,
     366           2 :                                                aEnabledCommands, aDisabledCommands);
     367             :     }
     368             : 
     369           2 :     nsGlobalWindow* win = nsGlobalWindow::Cast(focusedWindow);
     370           2 :     focusedWindow = win->GetPrivateParent();
     371             :   }
     372           2 : }
     373             : 
     374             : nsIDOMNode*
     375          11 : nsWindowRoot::GetPopupNode()
     376             : {
     377          22 :   nsCOMPtr<nsIDOMNode> popupNode = do_QueryReferent(mPopupNode);
     378          22 :   return popupNode;
     379             : }
     380             : 
     381             : void
     382           0 : nsWindowRoot::SetPopupNode(nsIDOMNode* aNode)
     383             : {
     384           0 :   mPopupNode = do_GetWeakReference(aNode);
     385           0 : }
     386             : 
     387             : nsIGlobalObject*
     388           0 : nsWindowRoot::GetParentObject()
     389             : {
     390           0 :   return xpc::NativeGlobal(xpc::PrivilegedJunkScope());
     391             : }
     392             : 
     393             : JSObject*
     394           0 : nsWindowRoot::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     395             : {
     396           0 :   return mozilla::dom::WindowRootBinding::Wrap(aCx, this, aGivenProto);
     397             : }
     398             : 
     399             : void
     400           1 : nsWindowRoot::AddBrowser(mozilla::dom::TabParent* aBrowser)
     401             : {
     402           2 :   nsWeakPtr weakBrowser = do_GetWeakReference(static_cast<nsITabParent*>(aBrowser));
     403           1 :   mWeakBrowsers.PutEntry(weakBrowser);
     404           1 : }
     405             : 
     406             : void
     407           0 : nsWindowRoot::RemoveBrowser(mozilla::dom::TabParent* aBrowser)
     408             : {
     409           0 :   nsWeakPtr weakBrowser = do_GetWeakReference(static_cast<nsITabParent*>(aBrowser));
     410           0 :   mWeakBrowsers.RemoveEntry(weakBrowser);
     411           0 : }
     412             : 
     413             : void
     414           1 : nsWindowRoot::EnumerateBrowsers(BrowserEnumerator aEnumFunc, void* aArg)
     415             : {
     416             :   // Collect strong references to all browsers in a separate array in
     417             :   // case aEnumFunc alters mWeakBrowsers.
     418           2 :   nsTArray<RefPtr<TabParent>> tabParents;
     419           1 :   for (auto iter = mWeakBrowsers.ConstIter(); !iter.Done(); iter.Next()) {
     420           0 :     nsCOMPtr<nsITabParent> tabParent(do_QueryReferent(iter.Get()->GetKey()));
     421           0 :     if (TabParent* tab = TabParent::GetFrom(tabParent)) {
     422           0 :       tabParents.AppendElement(tab);
     423             :     }
     424             :   }
     425             : 
     426           1 :   for (uint32_t i = 0; i < tabParents.Length(); ++i) {
     427           0 :     aEnumFunc(tabParents[i], aArg);
     428             :   }
     429           1 : }
     430             : 
     431             : ///////////////////////////////////////////////////////////////////////////////////
     432             : 
     433             : already_AddRefed<EventTarget>
     434           3 : NS_NewWindowRoot(nsPIDOMWindowOuter* aWindow)
     435             : {
     436           6 :   nsCOMPtr<EventTarget> result = new nsWindowRoot(aWindow);
     437           6 :   return result.forget();
     438             : }

Generated by: LCOV version 1.13