LCOV - code coverage report
Current view: directory - content/xbl/src - nsXBLWindowKeyHandler.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 237 3 1.3 %
Date: 2012-06-02 Functions: 24 1 4.2 %

       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 Communicator client code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Original Author: David W. Hyatt (hyatt@netscape.com)
      24                 :  *   - Mike Pinkerton (pinkerton@netscape.com)
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #include "nsCOMPtr.h"
      41                 : #include "nsXBLPrototypeHandler.h"
      42                 : #include "nsXBLWindowKeyHandler.h"
      43                 : #include "nsIContent.h"
      44                 : #include "nsIAtom.h"
      45                 : #include "nsIDOMKeyEvent.h"
      46                 : #include "nsIDOMEventTarget.h"
      47                 : #include "nsIDOMNSEvent.h"
      48                 : #include "nsXBLService.h"
      49                 : #include "nsIServiceManager.h"
      50                 : #include "nsGkAtoms.h"
      51                 : #include "nsXBLDocumentInfo.h"
      52                 : #include "nsIDOMElement.h"
      53                 : #include "nsINativeKeyBindings.h"
      54                 : #include "nsIController.h"
      55                 : #include "nsIControllers.h"
      56                 : #include "nsFocusManager.h"
      57                 : #include "nsPIWindowRoot.h"
      58                 : #include "nsIURI.h"
      59                 : #include "nsNetUtil.h"
      60                 : #include "nsContentUtils.h"
      61                 : #include "nsXBLPrototypeBinding.h"
      62                 : #include "nsIDOMDocument.h"
      63                 : #include "nsPIWindowRoot.h"
      64                 : #include "nsPIDOMWindow.h"
      65                 : #include "nsIDocShell.h"
      66                 : #include "nsIPresShell.h"
      67                 : #include "nsIPrivateDOMEvent.h"
      68                 : #include "nsISelectionController.h"
      69                 : #include "nsGUIEvent.h"
      70                 : #include "mozilla/Preferences.h"
      71                 : #include "mozilla/dom/Element.h"
      72                 : 
      73                 : using namespace mozilla;
      74                 : 
      75                 : static nsINativeKeyBindings *sNativeEditorBindings = nsnull;
      76                 : 
      77                 : class nsXBLSpecialDocInfo
      78               0 : {
      79                 : public:
      80                 :   nsRefPtr<nsXBLDocumentInfo> mHTMLBindings;
      81                 :   nsRefPtr<nsXBLDocumentInfo> mUserHTMLBindings;
      82                 : 
      83                 :   static const char sHTMLBindingStr[];
      84                 :   static const char sUserHTMLBindingStr[];
      85                 : 
      86                 :   bool mInitialized;
      87                 : 
      88                 : public:
      89                 :   void LoadDocInfo();
      90                 :   void GetAllHandlers(const char* aType,
      91                 :                       nsXBLPrototypeHandler** handler,
      92                 :                       nsXBLPrototypeHandler** userHandler);
      93                 :   void GetHandlers(nsXBLDocumentInfo* aInfo,
      94                 :                    const nsACString& aRef,
      95                 :                    nsXBLPrototypeHandler** aResult);
      96                 : 
      97               0 :   nsXBLSpecialDocInfo() : mInitialized(false) {}
      98                 : };
      99                 : 
     100                 : const char nsXBLSpecialDocInfo::sHTMLBindingStr[] =
     101                 :   "chrome://global/content/platformHTMLBindings.xml";
     102                 : 
     103               0 : void nsXBLSpecialDocInfo::LoadDocInfo()
     104                 : {
     105               0 :   if (mInitialized)
     106               0 :     return;
     107               0 :   mInitialized = true;
     108                 : 
     109                 :   nsresult rv;
     110                 :   nsCOMPtr<nsIXBLService> xblService = 
     111               0 :            do_GetService("@mozilla.org/xbl;1", &rv);
     112               0 :   if (NS_FAILED(rv) || !xblService)
     113                 :     return;
     114                 : 
     115                 :   // Obtain the platform doc info
     116               0 :   nsCOMPtr<nsIURI> bindingURI;
     117               0 :   NS_NewURI(getter_AddRefs(bindingURI), sHTMLBindingStr);
     118               0 :   if (!bindingURI) {
     119                 :     return;
     120                 :   }
     121               0 :   xblService->LoadBindingDocumentInfo(nsnull, nsnull,
     122                 :                                       bindingURI,
     123                 :                                       nsnull,
     124                 :                                       true, 
     125               0 :                                       getter_AddRefs(mHTMLBindings));
     126                 : 
     127                 :   const nsAdoptingCString& userHTMLBindingStr =
     128               0 :     Preferences::GetCString("dom.userHTMLBindings.uri");
     129               0 :   if (!userHTMLBindingStr.IsEmpty()) {
     130               0 :     NS_NewURI(getter_AddRefs(bindingURI), userHTMLBindingStr);
     131               0 :     if (!bindingURI) {
     132                 :       return;
     133                 :     }
     134                 : 
     135               0 :     xblService->LoadBindingDocumentInfo(nsnull, nsnull,
     136                 :                                         bindingURI,
     137                 :                                         nsnull,
     138                 :                                         true, 
     139               0 :                                         getter_AddRefs(mUserHTMLBindings));
     140                 :   }
     141                 : }
     142                 : 
     143                 : //
     144                 : // GetHandlers
     145                 : //
     146                 : // 
     147                 : void
     148               0 : nsXBLSpecialDocInfo::GetHandlers(nsXBLDocumentInfo* aInfo,
     149                 :                                  const nsACString& aRef,
     150                 :                                  nsXBLPrototypeHandler** aResult)
     151                 : {
     152               0 :   nsXBLPrototypeBinding* binding = aInfo->GetPrototypeBinding(aRef);
     153                 :   
     154               0 :   NS_ASSERTION(binding, "No binding found for the XBL window key handler.");
     155               0 :   if (!binding)
     156               0 :     return;
     157                 : 
     158               0 :   *aResult = binding->GetPrototypeHandlers();
     159                 : }
     160                 : 
     161                 : void
     162               0 : nsXBLSpecialDocInfo::GetAllHandlers(const char* aType,
     163                 :                                     nsXBLPrototypeHandler** aHandler,
     164                 :                                     nsXBLPrototypeHandler** aUserHandler)
     165                 : {
     166               0 :   if (mUserHTMLBindings) {
     167               0 :     nsCAutoString type(aType);
     168               0 :     type.Append("User");
     169               0 :     GetHandlers(mUserHTMLBindings, type, aUserHandler);
     170                 :   }
     171               0 :   if (mHTMLBindings) {
     172               0 :     GetHandlers(mHTMLBindings, nsDependentCString(aType), aHandler);
     173                 :   }
     174               0 : }
     175                 : 
     176                 : // Init statics
     177                 : nsXBLSpecialDocInfo* nsXBLWindowKeyHandler::sXBLSpecialDocInfo = nsnull;
     178                 : PRUint32 nsXBLWindowKeyHandler::sRefCnt = 0;
     179                 : 
     180               0 : nsXBLWindowKeyHandler::nsXBLWindowKeyHandler(nsIDOMElement* aElement,
     181                 :                                              nsIDOMEventTarget* aTarget)
     182                 :   : mTarget(aTarget),
     183                 :     mHandler(nsnull),
     184               0 :     mUserHandler(nsnull)
     185                 : {
     186               0 :   mWeakPtrForElement = do_GetWeakReference(aElement);
     187               0 :   ++sRefCnt;
     188               0 : }
     189                 : 
     190               0 : nsXBLWindowKeyHandler::~nsXBLWindowKeyHandler()
     191                 : {
     192                 :   // If mWeakPtrForElement is non-null, we created a prototype handler.
     193               0 :   if (mWeakPtrForElement)
     194               0 :     delete mHandler;
     195                 : 
     196               0 :   --sRefCnt;
     197               0 :   if (!sRefCnt) {
     198               0 :     delete sXBLSpecialDocInfo;
     199               0 :     sXBLSpecialDocInfo = nsnull;
     200                 :   }
     201               0 : }
     202                 : 
     203               0 : NS_IMPL_ISUPPORTS1(nsXBLWindowKeyHandler,
     204                 :                    nsIDOMEventListener)
     205                 : 
     206                 : static void
     207               0 : BuildHandlerChain(nsIContent* aContent, nsXBLPrototypeHandler** aResult)
     208                 : {
     209               0 :   *aResult = nsnull;
     210                 : 
     211                 :   // Since we chain each handler onto the next handler,
     212                 :   // we'll enumerate them here in reverse so that when we
     213                 :   // walk the chain they'll come out in the original order
     214               0 :   for (nsIContent* key = aContent->GetLastChild();
     215                 :        key;
     216               0 :        key = key->GetPreviousSibling()) {
     217                 : 
     218               0 :     if (key->NodeInfo()->Equals(nsGkAtoms::key, kNameSpaceID_XUL)) {
     219                 :       // Check whether the key element has empty value at key/char attribute.
     220                 :       // Such element is used by localizers for alternative shortcut key
     221                 :       // definition on the locale. See bug 426501.
     222               0 :       nsAutoString valKey, valCharCode, valKeyCode;
     223                 :       bool attrExists =
     224               0 :         key->GetAttr(kNameSpaceID_None, nsGkAtoms::key, valKey) ||
     225               0 :         key->GetAttr(kNameSpaceID_None, nsGkAtoms::charcode, valCharCode) ||
     226               0 :         key->GetAttr(kNameSpaceID_None, nsGkAtoms::keycode, valKeyCode);
     227               0 :       if (attrExists &&
     228               0 :           valKey.IsEmpty() && valCharCode.IsEmpty() && valKeyCode.IsEmpty())
     229               0 :         continue;
     230                 : 
     231               0 :       nsXBLPrototypeHandler* handler = new nsXBLPrototypeHandler(key);
     232                 : 
     233               0 :       if (!handler)
     234                 :         return;
     235                 : 
     236               0 :       handler->SetNextHandler(*aResult);
     237               0 :       *aResult = handler;
     238                 :     }
     239                 :   }
     240                 : }
     241                 : 
     242                 : //
     243                 : // EnsureHandlers
     244                 : //    
     245                 : // Lazily load the XBL handlers. Overridden to handle being attached
     246                 : // to a particular element rather than the document
     247                 : //
     248                 : nsresult
     249               0 : nsXBLWindowKeyHandler::EnsureHandlers(bool *aIsEditor)
     250                 : {
     251               0 :   nsCOMPtr<nsIDOMElement> el = GetElement();
     252               0 :   NS_ENSURE_STATE(!mWeakPtrForElement || el);
     253               0 :   if (el) {
     254                 :     // We are actually a XUL <keyset>.
     255               0 :     if (aIsEditor)
     256               0 :       *aIsEditor = false;
     257                 : 
     258               0 :     if (mHandler)
     259               0 :       return NS_OK;
     260                 : 
     261               0 :     nsCOMPtr<nsIContent> content(do_QueryInterface(el));
     262               0 :     BuildHandlerChain(content, &mHandler);
     263                 :   } else { // We are an XBL file of handlers.
     264               0 :     if (!sXBLSpecialDocInfo)
     265               0 :       sXBLSpecialDocInfo = new nsXBLSpecialDocInfo();
     266               0 :     if (!sXBLSpecialDocInfo) {
     267               0 :       if (aIsEditor) {
     268               0 :         *aIsEditor = false;
     269                 :       }
     270               0 :       return NS_ERROR_OUT_OF_MEMORY;
     271                 :     }
     272               0 :     sXBLSpecialDocInfo->LoadDocInfo();
     273                 : 
     274                 :     // Now determine which handlers we should be using.
     275               0 :     bool isEditor = IsEditor();
     276               0 :     if (isEditor) {
     277               0 :       sXBLSpecialDocInfo->GetAllHandlers("editor", &mHandler, &mUserHandler);
     278                 :     }
     279                 :     else {
     280               0 :       sXBLSpecialDocInfo->GetAllHandlers("browser", &mHandler, &mUserHandler);
     281                 :     }
     282                 : 
     283               0 :     if (aIsEditor)
     284               0 :       *aIsEditor = isEditor;
     285                 :   }
     286                 : 
     287               0 :   return NS_OK;
     288                 : }
     289                 : 
     290                 : static nsINativeKeyBindings*
     291               0 : GetEditorKeyBindings()
     292                 : {
     293                 :   static bool noBindings = false;
     294               0 :   if (!sNativeEditorBindings && !noBindings) {
     295                 :     CallGetService(NS_NATIVEKEYBINDINGS_CONTRACTID_PREFIX "editor",
     296               0 :                    &sNativeEditorBindings);
     297                 : 
     298               0 :     if (!sNativeEditorBindings) {
     299               0 :       noBindings = true;
     300                 :     }
     301                 :   }
     302                 : 
     303               0 :   return sNativeEditorBindings;
     304                 : }
     305                 : 
     306                 : static void
     307               0 : DoCommandCallback(const char *aCommand, void *aData)
     308                 : {
     309               0 :   nsIControllers *controllers = static_cast<nsIControllers*>(aData);
     310               0 :   if (controllers) {
     311               0 :     nsCOMPtr<nsIController> controller;
     312               0 :     controllers->GetControllerForCommand(aCommand, getter_AddRefs(controller));
     313               0 :     if (controller) {
     314               0 :       controller->DoCommand(aCommand);
     315                 :     }
     316                 :   }
     317               0 : }
     318                 : 
     319                 : nsresult
     320               0 : nsXBLWindowKeyHandler::WalkHandlers(nsIDOMKeyEvent* aKeyEvent, nsIAtom* aEventType)
     321                 : {
     322               0 :   nsCOMPtr<nsIDOMNSEvent> domNSEvent = do_QueryInterface(aKeyEvent);
     323                 :   bool prevent;
     324               0 :   domNSEvent->GetPreventDefault(&prevent);
     325               0 :   if (prevent)
     326               0 :     return NS_OK;
     327                 : 
     328               0 :   bool trustedEvent = false;
     329               0 :   if (domNSEvent) {
     330                 :     //Don't process the event if it was not dispatched from a trusted source
     331               0 :     domNSEvent->GetIsTrusted(&trustedEvent);
     332                 :   }
     333                 : 
     334               0 :   if (!trustedEvent)
     335               0 :     return NS_OK;
     336                 : 
     337                 :   bool isEditor;
     338               0 :   nsresult rv = EnsureHandlers(&isEditor);
     339               0 :   NS_ENSURE_SUCCESS(rv, rv);
     340                 :   
     341               0 :   nsCOMPtr<nsIDOMElement> el = GetElement();
     342               0 :   if (!el) {
     343               0 :     if (mUserHandler) {
     344               0 :       WalkHandlersInternal(aKeyEvent, aEventType, mUserHandler);
     345               0 :       domNSEvent->GetPreventDefault(&prevent);
     346               0 :       if (prevent)
     347               0 :         return NS_OK; // Handled by the user bindings. Our work here is done.
     348                 :     }
     349                 :   }
     350                 : 
     351               0 :   nsCOMPtr<nsIContent> content = do_QueryInterface(el);
     352                 :   // skip keysets that are disabled
     353               0 :   if (content && content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
     354               0 :                                       nsGkAtoms::_true, eCaseMatters)) {
     355               0 :     return NS_OK;
     356                 :   }
     357                 : 
     358               0 :   WalkHandlersInternal(aKeyEvent, aEventType, mHandler);
     359                 : 
     360               0 :   if (isEditor && GetEditorKeyBindings()) {
     361                 :     nsNativeKeyEvent nativeEvent;
     362                 :     // get the DOM window we're attached to
     363               0 :     nsCOMPtr<nsIControllers> controllers;
     364               0 :     nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(mTarget);
     365               0 :     if (root) {
     366               0 :       root->GetControllers(getter_AddRefs(controllers));
     367                 :     }
     368                 : 
     369               0 :     bool handled = false;
     370               0 :     if (aEventType == nsGkAtoms::keypress) {
     371               0 :       if (nsContentUtils::DOMEventToNativeKeyEvent(aKeyEvent, &nativeEvent, true))
     372                 :         handled = sNativeEditorBindings->KeyPress(nativeEvent,
     373               0 :                                                   DoCommandCallback, controllers);
     374               0 :     } else if (aEventType == nsGkAtoms::keyup) {
     375               0 :       if (nsContentUtils::DOMEventToNativeKeyEvent(aKeyEvent, &nativeEvent, false))
     376                 :         handled = sNativeEditorBindings->KeyUp(nativeEvent,
     377               0 :                                                DoCommandCallback, controllers);
     378                 :     } else {
     379               0 :       NS_ASSERTION(aEventType == nsGkAtoms::keydown, "unknown key event type");
     380               0 :       if (nsContentUtils::DOMEventToNativeKeyEvent(aKeyEvent, &nativeEvent, false))
     381                 :         handled = sNativeEditorBindings->KeyDown(nativeEvent,
     382               0 :                                                  DoCommandCallback, controllers);
     383                 :     }
     384                 : 
     385               0 :     if (handled)
     386               0 :       aKeyEvent->PreventDefault();
     387                 : 
     388                 :   }
     389                 :   
     390               0 :   return NS_OK;
     391                 : }
     392                 : 
     393                 : NS_IMETHODIMP
     394               0 : nsXBLWindowKeyHandler::HandleEvent(nsIDOMEvent* aEvent)
     395                 : {
     396               0 :   nsCOMPtr<nsIDOMKeyEvent> keyEvent(do_QueryInterface(aEvent));
     397               0 :   NS_ENSURE_TRUE(keyEvent, NS_ERROR_INVALID_ARG);
     398                 : 
     399               0 :   nsAutoString eventType;
     400               0 :   aEvent->GetType(eventType);
     401               0 :   nsCOMPtr<nsIAtom> eventTypeAtom = do_GetAtom(eventType);
     402               0 :   NS_ENSURE_TRUE(eventTypeAtom, NS_ERROR_OUT_OF_MEMORY);
     403                 : 
     404               0 :   return WalkHandlers(keyEvent, eventTypeAtom);
     405                 : }
     406                 : 
     407                 : //
     408                 : // EventMatched
     409                 : //
     410                 : // See if the given handler cares about this particular key event
     411                 : //
     412                 : bool
     413               0 : nsXBLWindowKeyHandler::EventMatched(nsXBLPrototypeHandler* inHandler,
     414                 :                                     nsIAtom* inEventType,
     415                 :                                     nsIDOMKeyEvent* inEvent,
     416                 :                                     PRUint32 aCharCode, bool aIgnoreShiftKey)
     417                 : {
     418                 :   return inHandler->KeyEventMatched(inEventType, inEvent, aCharCode,
     419               0 :                                     aIgnoreShiftKey);
     420                 : }
     421                 : 
     422                 : /* static */ void
     423            1403 : nsXBLWindowKeyHandler::ShutDown()
     424                 : {
     425            1403 :   NS_IF_RELEASE(sNativeEditorBindings);
     426            1403 : }
     427                 : 
     428                 : //
     429                 : // IsEditor
     430                 : //
     431                 : // Determine if the document we're working with is Editor or Browser
     432                 : //
     433                 : bool
     434               0 : nsXBLWindowKeyHandler::IsEditor()
     435                 : {
     436                 :   // XXXndeakin even though this is only used for key events which should be
     437                 :   // going to the focused frame anyway, this doesn't seem like the right way
     438                 :   // to determine if something is an editor.
     439               0 :   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
     440               0 :   if (!fm)
     441               0 :     return false;
     442                 : 
     443               0 :   nsCOMPtr<nsIDOMWindow> focusedWindow;
     444               0 :   fm->GetFocusedWindow(getter_AddRefs(focusedWindow));
     445               0 :   if (!focusedWindow)
     446               0 :     return false;
     447                 : 
     448               0 :   nsCOMPtr<nsPIDOMWindow> piwin(do_QueryInterface(focusedWindow));
     449               0 :   nsIDocShell *docShell = piwin->GetDocShell();
     450               0 :   nsCOMPtr<nsIPresShell> presShell;
     451               0 :   if (docShell)
     452               0 :     docShell->GetPresShell(getter_AddRefs(presShell));
     453                 : 
     454               0 :   if (presShell) {
     455               0 :     return presShell->GetSelectionFlags() == nsISelectionDisplay::DISPLAY_ALL;
     456                 :   }
     457                 : 
     458               0 :   return false;
     459                 : }
     460                 : 
     461                 : //
     462                 : // WalkHandlersInternal and WalkHandlersAndExecute
     463                 : //
     464                 : // Given a particular DOM event and a pointer to the first handler in the list,
     465                 : // scan through the list to find something to handle the event and then make it
     466                 : // so.
     467                 : //
     468                 : nsresult
     469               0 : nsXBLWindowKeyHandler::WalkHandlersInternal(nsIDOMKeyEvent* aKeyEvent,
     470                 :                                             nsIAtom* aEventType, 
     471                 :                                             nsXBLPrototypeHandler* aHandler)
     472                 : {
     473               0 :   nsAutoTArray<nsShortcutCandidate, 10> accessKeys;
     474               0 :   nsContentUtils::GetAccelKeyCandidates(aKeyEvent, accessKeys);
     475                 : 
     476               0 :   if (accessKeys.IsEmpty()) {
     477               0 :     WalkHandlersAndExecute(aKeyEvent, aEventType, aHandler, 0, false);
     478               0 :     return NS_OK;
     479                 :   }
     480                 : 
     481               0 :   for (PRUint32 i = 0; i < accessKeys.Length(); ++i) {
     482               0 :     nsShortcutCandidate &key = accessKeys[i];
     483               0 :     if (WalkHandlersAndExecute(aKeyEvent, aEventType, aHandler,
     484               0 :                                key.mCharCode, key.mIgnoreShift))
     485               0 :       return NS_OK;
     486                 :   }
     487               0 :   return NS_OK;
     488                 : }
     489                 : 
     490                 : bool
     491               0 : nsXBLWindowKeyHandler::WalkHandlersAndExecute(nsIDOMKeyEvent* aKeyEvent,
     492                 :                                               nsIAtom* aEventType,
     493                 :                                               nsXBLPrototypeHandler* aHandler,
     494                 :                                               PRUint32 aCharCode,
     495                 :                                               bool aIgnoreShiftKey)
     496                 : {
     497                 :   nsresult rv;
     498               0 :   nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(aKeyEvent));
     499                 : 
     500                 :   // Try all of the handlers until we find one that matches the event.
     501               0 :   for (nsXBLPrototypeHandler *currHandler = aHandler; currHandler;
     502                 :        currHandler = currHandler->GetNextHandler()) {
     503               0 :     bool stopped = privateEvent->IsDispatchStopped();
     504               0 :     if (stopped) {
     505                 :       // The event is finished, don't execute any more handlers
     506               0 :       return NS_OK;
     507                 :     }
     508                 : 
     509               0 :     if (!EventMatched(currHandler, aEventType, aKeyEvent,
     510               0 :                       aCharCode, aIgnoreShiftKey))
     511               0 :       continue;  // try the next one
     512                 : 
     513                 :     // Before executing this handler, check that it's not disabled,
     514                 :     // and that it has something to do (oncommand of the <key> or its
     515                 :     // <command> is non-empty).
     516               0 :     nsCOMPtr<nsIContent> elt = currHandler->GetHandlerElement();
     517               0 :     nsCOMPtr<nsIDOMElement> commandElt;
     518                 : 
     519                 :     // See if we're in a XUL doc.
     520               0 :     nsCOMPtr<nsIDOMElement> el = GetElement();
     521               0 :     if (el && elt) {
     522                 :       // We are.  Obtain our command attribute.
     523               0 :       nsAutoString command;
     524               0 :       elt->GetAttr(kNameSpaceID_None, nsGkAtoms::command, command);
     525               0 :       if (!command.IsEmpty()) {
     526                 :         // Locate the command element in question.  Note that we
     527                 :         // know "elt" is in a doc if we're dealing with it here.
     528               0 :         NS_ASSERTION(elt->IsInDoc(), "elt must be in document");
     529               0 :         nsIDocument *doc = elt->GetCurrentDoc();
     530               0 :         if (doc)
     531               0 :           commandElt = do_QueryInterface(doc->GetElementById(command));
     532                 : 
     533               0 :         if (!commandElt) {
     534               0 :           NS_ERROR("A XUL <key> is observing a command that doesn't exist. Unable to execute key binding!");
     535               0 :           continue;
     536                 :         }
     537                 :       }
     538                 :     }
     539                 : 
     540               0 :     if (!commandElt) {
     541               0 :       commandElt = do_QueryInterface(elt);
     542                 :     }
     543                 : 
     544               0 :     if (commandElt) {
     545               0 :       nsAutoString value;
     546               0 :       commandElt->GetAttribute(NS_LITERAL_STRING("disabled"), value);
     547               0 :       if (value.EqualsLiteral("true")) {
     548               0 :         continue;  // this handler is disabled, try the next one
     549                 :       }
     550                 : 
     551                 :       // Check that there is an oncommand handler
     552               0 :       commandElt->GetAttribute(NS_LITERAL_STRING("oncommand"), value);
     553               0 :       if (value.IsEmpty()) {
     554               0 :         continue;  // nothing to do
     555                 :       }
     556                 :     }
     557                 : 
     558               0 :     nsCOMPtr<nsIDOMEventTarget> piTarget;
     559               0 :     nsCOMPtr<nsIDOMElement> element = GetElement();
     560               0 :     if (element) {
     561               0 :       piTarget = do_QueryInterface(commandElt);
     562                 :     } else {
     563               0 :       piTarget = mTarget;
     564                 :     }
     565                 : 
     566               0 :     rv = currHandler->ExecuteHandler(piTarget, aKeyEvent);
     567               0 :     if (NS_SUCCEEDED(rv)) {
     568               0 :       return true;
     569                 :     }
     570                 :   }
     571                 : 
     572               0 :   return false;
     573                 : }
     574                 : 
     575                 : already_AddRefed<nsIDOMElement>
     576               0 : nsXBLWindowKeyHandler::GetElement()
     577                 : {
     578               0 :   nsCOMPtr<nsIDOMElement> element = do_QueryReferent(mWeakPtrForElement);
     579               0 :   nsIDOMElement* el = nsnull;
     580               0 :   element.swap(el);
     581               0 :   return el;
     582                 : }
     583                 : 
     584                 : ///////////////////////////////////////////////////////////////////////////////////
     585                 : 
     586                 : nsresult
     587               0 : NS_NewXBLWindowKeyHandler(nsIDOMElement* aElement, nsIDOMEventTarget* aTarget,
     588                 :                           nsXBLWindowKeyHandler** aResult)
     589                 : {
     590               0 :   *aResult = new nsXBLWindowKeyHandler(aElement, aTarget);
     591               0 :   if (!*aResult)
     592               0 :     return NS_ERROR_OUT_OF_MEMORY;
     593               0 :   NS_ADDREF(*aResult);
     594               0 :   return NS_OK;
     595                 : }

Generated by: LCOV version 1.7