1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/xbl/nsXBLWindowKeyHandler.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,583 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsCOMPtr.h" 1.10 +#include "nsXBLPrototypeHandler.h" 1.11 +#include "nsXBLWindowKeyHandler.h" 1.12 +#include "nsIContent.h" 1.13 +#include "nsIAtom.h" 1.14 +#include "nsIDOMKeyEvent.h" 1.15 +#include "nsXBLService.h" 1.16 +#include "nsIServiceManager.h" 1.17 +#include "nsGkAtoms.h" 1.18 +#include "nsXBLDocumentInfo.h" 1.19 +#include "nsIDOMElement.h" 1.20 +#include "nsFocusManager.h" 1.21 +#include "nsIURI.h" 1.22 +#include "nsNetUtil.h" 1.23 +#include "nsContentUtils.h" 1.24 +#include "nsXBLPrototypeBinding.h" 1.25 +#include "nsPIDOMWindow.h" 1.26 +#include "nsIDocShell.h" 1.27 +#include "nsIPresShell.h" 1.28 +#include "mozilla/EventStateManager.h" 1.29 +#include "nsISelectionController.h" 1.30 +#include "mozilla/Preferences.h" 1.31 +#include "mozilla/TextEvents.h" 1.32 +#include "mozilla/dom/Element.h" 1.33 +#include "mozilla/dom/Event.h" 1.34 +#include "nsIEditor.h" 1.35 +#include "nsIHTMLEditor.h" 1.36 +#include "nsIDOMDocument.h" 1.37 + 1.38 +using namespace mozilla; 1.39 +using namespace mozilla::dom; 1.40 + 1.41 +class nsXBLSpecialDocInfo : public nsIObserver 1.42 +{ 1.43 +public: 1.44 + nsRefPtr<nsXBLDocumentInfo> mHTMLBindings; 1.45 + nsRefPtr<nsXBLDocumentInfo> mUserHTMLBindings; 1.46 + 1.47 + static const char sHTMLBindingStr[]; 1.48 + static const char sUserHTMLBindingStr[]; 1.49 + 1.50 + bool mInitialized; 1.51 + 1.52 +public: 1.53 + NS_DECL_ISUPPORTS 1.54 + NS_DECL_NSIOBSERVER 1.55 + 1.56 + void LoadDocInfo(); 1.57 + void GetAllHandlers(const char* aType, 1.58 + nsXBLPrototypeHandler** handler, 1.59 + nsXBLPrototypeHandler** userHandler); 1.60 + void GetHandlers(nsXBLDocumentInfo* aInfo, 1.61 + const nsACString& aRef, 1.62 + nsXBLPrototypeHandler** aResult); 1.63 + 1.64 + nsXBLSpecialDocInfo() : mInitialized(false) {} 1.65 + 1.66 + virtual ~nsXBLSpecialDocInfo() {} 1.67 + 1.68 +}; 1.69 + 1.70 +const char nsXBLSpecialDocInfo::sHTMLBindingStr[] = 1.71 + "chrome://global/content/platformHTMLBindings.xml"; 1.72 + 1.73 +NS_IMPL_ISUPPORTS(nsXBLSpecialDocInfo, nsIObserver) 1.74 + 1.75 +NS_IMETHODIMP 1.76 +nsXBLSpecialDocInfo::Observe(nsISupports* aSubject, 1.77 + const char* aTopic, 1.78 + const char16_t* aData) 1.79 +{ 1.80 + MOZ_ASSERT(!strcmp(aTopic, "xpcom-shutdown"), "wrong topic"); 1.81 + 1.82 + // On shutdown, clear our fields to avoid an extra cycle collection. 1.83 + mHTMLBindings = nullptr; 1.84 + mUserHTMLBindings = nullptr; 1.85 + mInitialized = false; 1.86 + nsContentUtils::UnregisterShutdownObserver(this); 1.87 + 1.88 + return NS_OK; 1.89 +} 1.90 + 1.91 +void nsXBLSpecialDocInfo::LoadDocInfo() 1.92 +{ 1.93 + if (mInitialized) 1.94 + return; 1.95 + mInitialized = true; 1.96 + nsContentUtils::RegisterShutdownObserver(this); 1.97 + 1.98 + nsXBLService* xblService = nsXBLService::GetInstance(); 1.99 + if (!xblService) 1.100 + return; 1.101 + 1.102 + // Obtain the platform doc info 1.103 + nsCOMPtr<nsIURI> bindingURI; 1.104 + NS_NewURI(getter_AddRefs(bindingURI), sHTMLBindingStr); 1.105 + if (!bindingURI) { 1.106 + return; 1.107 + } 1.108 + xblService->LoadBindingDocumentInfo(nullptr, nullptr, 1.109 + bindingURI, 1.110 + nullptr, 1.111 + true, 1.112 + getter_AddRefs(mHTMLBindings)); 1.113 + 1.114 + const nsAdoptingCString& userHTMLBindingStr = 1.115 + Preferences::GetCString("dom.userHTMLBindings.uri"); 1.116 + if (!userHTMLBindingStr.IsEmpty()) { 1.117 + NS_NewURI(getter_AddRefs(bindingURI), userHTMLBindingStr); 1.118 + if (!bindingURI) { 1.119 + return; 1.120 + } 1.121 + 1.122 + xblService->LoadBindingDocumentInfo(nullptr, nullptr, 1.123 + bindingURI, 1.124 + nullptr, 1.125 + true, 1.126 + getter_AddRefs(mUserHTMLBindings)); 1.127 + } 1.128 +} 1.129 + 1.130 +// 1.131 +// GetHandlers 1.132 +// 1.133 +// 1.134 +void 1.135 +nsXBLSpecialDocInfo::GetHandlers(nsXBLDocumentInfo* aInfo, 1.136 + const nsACString& aRef, 1.137 + nsXBLPrototypeHandler** aResult) 1.138 +{ 1.139 + nsXBLPrototypeBinding* binding = aInfo->GetPrototypeBinding(aRef); 1.140 + 1.141 + NS_ASSERTION(binding, "No binding found for the XBL window key handler."); 1.142 + if (!binding) 1.143 + return; 1.144 + 1.145 + *aResult = binding->GetPrototypeHandlers(); 1.146 +} 1.147 + 1.148 +void 1.149 +nsXBLSpecialDocInfo::GetAllHandlers(const char* aType, 1.150 + nsXBLPrototypeHandler** aHandler, 1.151 + nsXBLPrototypeHandler** aUserHandler) 1.152 +{ 1.153 + if (mUserHTMLBindings) { 1.154 + nsAutoCString type(aType); 1.155 + type.Append("User"); 1.156 + GetHandlers(mUserHTMLBindings, type, aUserHandler); 1.157 + } 1.158 + if (mHTMLBindings) { 1.159 + GetHandlers(mHTMLBindings, nsDependentCString(aType), aHandler); 1.160 + } 1.161 +} 1.162 + 1.163 +// Init statics 1.164 +nsXBLSpecialDocInfo* nsXBLWindowKeyHandler::sXBLSpecialDocInfo = nullptr; 1.165 +uint32_t nsXBLWindowKeyHandler::sRefCnt = 0; 1.166 + 1.167 +nsXBLWindowKeyHandler::nsXBLWindowKeyHandler(nsIDOMElement* aElement, 1.168 + EventTarget* aTarget) 1.169 + : mTarget(aTarget), 1.170 + mHandler(nullptr), 1.171 + mUserHandler(nullptr) 1.172 +{ 1.173 + mWeakPtrForElement = do_GetWeakReference(aElement); 1.174 + ++sRefCnt; 1.175 +} 1.176 + 1.177 +nsXBLWindowKeyHandler::~nsXBLWindowKeyHandler() 1.178 +{ 1.179 + // If mWeakPtrForElement is non-null, we created a prototype handler. 1.180 + if (mWeakPtrForElement) 1.181 + delete mHandler; 1.182 + 1.183 + --sRefCnt; 1.184 + if (!sRefCnt) { 1.185 + NS_IF_RELEASE(sXBLSpecialDocInfo); 1.186 + } 1.187 +} 1.188 + 1.189 +NS_IMPL_ISUPPORTS(nsXBLWindowKeyHandler, 1.190 + nsIDOMEventListener) 1.191 + 1.192 +static void 1.193 +BuildHandlerChain(nsIContent* aContent, nsXBLPrototypeHandler** aResult) 1.194 +{ 1.195 + *aResult = nullptr; 1.196 + 1.197 + // Since we chain each handler onto the next handler, 1.198 + // we'll enumerate them here in reverse so that when we 1.199 + // walk the chain they'll come out in the original order 1.200 + for (nsIContent* key = aContent->GetLastChild(); 1.201 + key; 1.202 + key = key->GetPreviousSibling()) { 1.203 + 1.204 + if (key->NodeInfo()->Equals(nsGkAtoms::key, kNameSpaceID_XUL)) { 1.205 + // Check whether the key element has empty value at key/char attribute. 1.206 + // Such element is used by localizers for alternative shortcut key 1.207 + // definition on the locale. See bug 426501. 1.208 + nsAutoString valKey, valCharCode, valKeyCode; 1.209 + bool attrExists = 1.210 + key->GetAttr(kNameSpaceID_None, nsGkAtoms::key, valKey) || 1.211 + key->GetAttr(kNameSpaceID_None, nsGkAtoms::charcode, valCharCode) || 1.212 + key->GetAttr(kNameSpaceID_None, nsGkAtoms::keycode, valKeyCode); 1.213 + if (attrExists && 1.214 + valKey.IsEmpty() && valCharCode.IsEmpty() && valKeyCode.IsEmpty()) 1.215 + continue; 1.216 + 1.217 + nsXBLPrototypeHandler* handler = new nsXBLPrototypeHandler(key); 1.218 + 1.219 + if (!handler) 1.220 + return; 1.221 + 1.222 + handler->SetNextHandler(*aResult); 1.223 + *aResult = handler; 1.224 + } 1.225 + } 1.226 +} 1.227 + 1.228 +// 1.229 +// EnsureHandlers 1.230 +// 1.231 +// Lazily load the XBL handlers. Overridden to handle being attached 1.232 +// to a particular element rather than the document 1.233 +// 1.234 +nsresult 1.235 +nsXBLWindowKeyHandler::EnsureHandlers() 1.236 +{ 1.237 + nsCOMPtr<Element> el = GetElement(); 1.238 + NS_ENSURE_STATE(!mWeakPtrForElement || el); 1.239 + if (el) { 1.240 + // We are actually a XUL <keyset>. 1.241 + if (mHandler) 1.242 + return NS_OK; 1.243 + 1.244 + nsCOMPtr<nsIContent> content(do_QueryInterface(el)); 1.245 + BuildHandlerChain(content, &mHandler); 1.246 + } else { // We are an XBL file of handlers. 1.247 + if (!sXBLSpecialDocInfo) { 1.248 + sXBLSpecialDocInfo = new nsXBLSpecialDocInfo(); 1.249 + NS_ADDREF(sXBLSpecialDocInfo); 1.250 + } 1.251 + sXBLSpecialDocInfo->LoadDocInfo(); 1.252 + 1.253 + // Now determine which handlers we should be using. 1.254 + if (IsHTMLEditableFieldFocused()) { 1.255 + sXBLSpecialDocInfo->GetAllHandlers("editor", &mHandler, &mUserHandler); 1.256 + } 1.257 + else { 1.258 + sXBLSpecialDocInfo->GetAllHandlers("browser", &mHandler, &mUserHandler); 1.259 + } 1.260 + } 1.261 + 1.262 + return NS_OK; 1.263 +} 1.264 + 1.265 +nsresult 1.266 +nsXBLWindowKeyHandler::WalkHandlers(nsIDOMKeyEvent* aKeyEvent, nsIAtom* aEventType) 1.267 +{ 1.268 + bool prevent; 1.269 + aKeyEvent->GetDefaultPrevented(&prevent); 1.270 + if (prevent) 1.271 + return NS_OK; 1.272 + 1.273 + bool trustedEvent = false; 1.274 + // Don't process the event if it was not dispatched from a trusted source 1.275 + aKeyEvent->GetIsTrusted(&trustedEvent); 1.276 + 1.277 + if (!trustedEvent) 1.278 + return NS_OK; 1.279 + 1.280 + nsresult rv = EnsureHandlers(); 1.281 + NS_ENSURE_SUCCESS(rv, rv); 1.282 + 1.283 + bool isDisabled; 1.284 + nsCOMPtr<Element> el = GetElement(&isDisabled); 1.285 + if (!el) { 1.286 + if (mUserHandler) { 1.287 + WalkHandlersInternal(aKeyEvent, aEventType, mUserHandler, true); 1.288 + aKeyEvent->GetDefaultPrevented(&prevent); 1.289 + if (prevent) 1.290 + return NS_OK; // Handled by the user bindings. Our work here is done. 1.291 + } 1.292 + } 1.293 + 1.294 + // skip keysets that are disabled 1.295 + if (el && isDisabled) { 1.296 + return NS_OK; 1.297 + } 1.298 + 1.299 + WalkHandlersInternal(aKeyEvent, aEventType, mHandler, true); 1.300 + 1.301 + return NS_OK; 1.302 +} 1.303 + 1.304 +NS_IMETHODIMP 1.305 +nsXBLWindowKeyHandler::HandleEvent(nsIDOMEvent* aEvent) 1.306 +{ 1.307 + nsCOMPtr<nsIDOMKeyEvent> keyEvent(do_QueryInterface(aEvent)); 1.308 + NS_ENSURE_TRUE(keyEvent, NS_ERROR_INVALID_ARG); 1.309 + 1.310 + uint16_t eventPhase; 1.311 + aEvent->GetEventPhase(&eventPhase); 1.312 + if (eventPhase == nsIDOMEvent::CAPTURING_PHASE) { 1.313 + HandleEventOnCapture(keyEvent); 1.314 + return NS_OK; 1.315 + } 1.316 + 1.317 + nsAutoString eventType; 1.318 + aEvent->GetType(eventType); 1.319 + nsCOMPtr<nsIAtom> eventTypeAtom = do_GetAtom(eventType); 1.320 + NS_ENSURE_TRUE(eventTypeAtom, NS_ERROR_OUT_OF_MEMORY); 1.321 + 1.322 + return WalkHandlers(keyEvent, eventTypeAtom); 1.323 +} 1.324 + 1.325 +void 1.326 +nsXBLWindowKeyHandler::HandleEventOnCapture(nsIDOMKeyEvent* aEvent) 1.327 +{ 1.328 + WidgetKeyboardEvent* widgetEvent = 1.329 + aEvent->GetInternalNSEvent()->AsKeyboardEvent(); 1.330 + 1.331 + if (widgetEvent->mFlags.mNoCrossProcessBoundaryForwarding) { 1.332 + return; 1.333 + } 1.334 + 1.335 + nsCOMPtr<mozilla::dom::Element> originalTarget = 1.336 + do_QueryInterface(aEvent->GetInternalNSEvent()->originalTarget); 1.337 + if (!EventStateManager::IsRemoteTarget(originalTarget)) { 1.338 + return; 1.339 + } 1.340 + 1.341 + if (!HasHandlerForEvent(aEvent)) { 1.342 + return; 1.343 + } 1.344 + 1.345 + // If this event hasn't been marked as mNoCrossProcessBoundaryForwarding 1.346 + // yet, it means it wasn't processed by content. We'll not call any 1.347 + // of the handlers at this moment, and will wait for the event to be 1.348 + // redispatched with mNoCrossProcessBoundaryForwarding = 1 to process it. 1.349 + 1.350 + // Inform the child process that this is a event that we want a reply 1.351 + // from. 1.352 + widgetEvent->mFlags.mWantReplyFromContentProcess = 1; 1.353 + aEvent->StopPropagation(); 1.354 +} 1.355 + 1.356 +// 1.357 +// EventMatched 1.358 +// 1.359 +// See if the given handler cares about this particular key event 1.360 +// 1.361 +bool 1.362 +nsXBLWindowKeyHandler::EventMatched(nsXBLPrototypeHandler* inHandler, 1.363 + nsIAtom* inEventType, 1.364 + nsIDOMKeyEvent* inEvent, 1.365 + uint32_t aCharCode, bool aIgnoreShiftKey) 1.366 +{ 1.367 + return inHandler->KeyEventMatched(inEventType, inEvent, aCharCode, 1.368 + aIgnoreShiftKey); 1.369 +} 1.370 + 1.371 +bool 1.372 +nsXBLWindowKeyHandler::IsHTMLEditableFieldFocused() 1.373 +{ 1.374 + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); 1.375 + if (!fm) 1.376 + return false; 1.377 + 1.378 + nsCOMPtr<nsIDOMWindow> focusedWindow; 1.379 + fm->GetFocusedWindow(getter_AddRefs(focusedWindow)); 1.380 + if (!focusedWindow) 1.381 + return false; 1.382 + 1.383 + nsCOMPtr<nsPIDOMWindow> piwin(do_QueryInterface(focusedWindow)); 1.384 + nsIDocShell *docShell = piwin->GetDocShell(); 1.385 + if (!docShell) { 1.386 + return false; 1.387 + } 1.388 + 1.389 + nsCOMPtr<nsIEditor> editor; 1.390 + docShell->GetEditor(getter_AddRefs(editor)); 1.391 + nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(editor); 1.392 + if (!htmlEditor) { 1.393 + return false; 1.394 + } 1.395 + 1.396 + nsCOMPtr<nsIDOMDocument> domDocument; 1.397 + editor->GetDocument(getter_AddRefs(domDocument)); 1.398 + nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDocument); 1.399 + if (doc->HasFlag(NODE_IS_EDITABLE)) { 1.400 + // Don't need to perform any checks in designMode documents. 1.401 + return true; 1.402 + } 1.403 + 1.404 + nsCOMPtr<nsIDOMElement> focusedElement; 1.405 + fm->GetFocusedElement(getter_AddRefs(focusedElement)); 1.406 + nsCOMPtr<nsINode> focusedNode = do_QueryInterface(focusedElement); 1.407 + if (focusedNode) { 1.408 + // If there is a focused element, make sure it's in the active editing host. 1.409 + // Note that GetActiveEditingHost finds the current editing host based on 1.410 + // the document's selection. Even though the document selection is usually 1.411 + // collapsed to where the focus is, but the page may modify the selection 1.412 + // without our knowledge, in which case this check will do something useful. 1.413 + nsCOMPtr<Element> activeEditingHost = htmlEditor->GetActiveEditingHost(); 1.414 + if (!activeEditingHost) { 1.415 + return false; 1.416 + } 1.417 + return nsContentUtils::ContentIsDescendantOf(focusedNode, activeEditingHost); 1.418 + } 1.419 + 1.420 + return false; 1.421 +} 1.422 + 1.423 +// 1.424 +// WalkHandlersInternal and WalkHandlersAndExecute 1.425 +// 1.426 +// Given a particular DOM event and a pointer to the first handler in the list, 1.427 +// scan through the list to find something to handle the event. If aExecute = true, 1.428 +// the handler will be executed; otherwise just return an answer telling if a handler 1.429 +// for that event was found. 1.430 +// 1.431 +bool 1.432 +nsXBLWindowKeyHandler::WalkHandlersInternal(nsIDOMKeyEvent* aKeyEvent, 1.433 + nsIAtom* aEventType, 1.434 + nsXBLPrototypeHandler* aHandler, 1.435 + bool aExecute) 1.436 +{ 1.437 + nsAutoTArray<nsShortcutCandidate, 10> accessKeys; 1.438 + nsContentUtils::GetAccelKeyCandidates(aKeyEvent, accessKeys); 1.439 + 1.440 + if (accessKeys.IsEmpty()) { 1.441 + return WalkHandlersAndExecute(aKeyEvent, aEventType, aHandler, 1.442 + 0, false, aExecute); 1.443 + } 1.444 + 1.445 + for (uint32_t i = 0; i < accessKeys.Length(); ++i) { 1.446 + nsShortcutCandidate &key = accessKeys[i]; 1.447 + if (WalkHandlersAndExecute(aKeyEvent, aEventType, aHandler, 1.448 + key.mCharCode, key.mIgnoreShift, aExecute)) 1.449 + return true; 1.450 + } 1.451 + return false; 1.452 +} 1.453 + 1.454 +bool 1.455 +nsXBLWindowKeyHandler::WalkHandlersAndExecute(nsIDOMKeyEvent* aKeyEvent, 1.456 + nsIAtom* aEventType, 1.457 + nsXBLPrototypeHandler* aHandler, 1.458 + uint32_t aCharCode, 1.459 + bool aIgnoreShiftKey, 1.460 + bool aExecute) 1.461 +{ 1.462 + nsresult rv; 1.463 + 1.464 + // Try all of the handlers until we find one that matches the event. 1.465 + for (nsXBLPrototypeHandler *currHandler = aHandler; currHandler; 1.466 + currHandler = currHandler->GetNextHandler()) { 1.467 + bool stopped = aKeyEvent->IsDispatchStopped(); 1.468 + if (stopped) { 1.469 + // The event is finished, don't execute any more handlers 1.470 + return false; 1.471 + } 1.472 + 1.473 + if (!EventMatched(currHandler, aEventType, aKeyEvent, 1.474 + aCharCode, aIgnoreShiftKey)) 1.475 + continue; // try the next one 1.476 + 1.477 + // Before executing this handler, check that it's not disabled, 1.478 + // and that it has something to do (oncommand of the <key> or its 1.479 + // <command> is non-empty). 1.480 + nsCOMPtr<nsIContent> elt = currHandler->GetHandlerElement(); 1.481 + nsCOMPtr<Element> commandElt; 1.482 + 1.483 + // See if we're in a XUL doc. 1.484 + nsCOMPtr<Element> el = GetElement(); 1.485 + if (el && elt) { 1.486 + // We are. Obtain our command attribute. 1.487 + nsAutoString command; 1.488 + elt->GetAttr(kNameSpaceID_None, nsGkAtoms::command, command); 1.489 + if (!command.IsEmpty()) { 1.490 + // Locate the command element in question. Note that we 1.491 + // know "elt" is in a doc if we're dealing with it here. 1.492 + NS_ASSERTION(elt->IsInDoc(), "elt must be in document"); 1.493 + nsIDocument *doc = elt->GetCurrentDoc(); 1.494 + if (doc) 1.495 + commandElt = do_QueryInterface(doc->GetElementById(command)); 1.496 + 1.497 + if (!commandElt) { 1.498 + NS_ERROR("A XUL <key> is observing a command that doesn't exist. Unable to execute key binding!"); 1.499 + continue; 1.500 + } 1.501 + } 1.502 + } 1.503 + 1.504 + if (!commandElt) { 1.505 + commandElt = do_QueryInterface(elt); 1.506 + } 1.507 + 1.508 + if (commandElt) { 1.509 + nsAutoString value; 1.510 + commandElt->GetAttribute(NS_LITERAL_STRING("disabled"), value); 1.511 + if (value.EqualsLiteral("true")) { 1.512 + continue; // this handler is disabled, try the next one 1.513 + } 1.514 + 1.515 + // Check that there is an oncommand handler 1.516 + commandElt->GetAttribute(NS_LITERAL_STRING("oncommand"), value); 1.517 + if (value.IsEmpty()) { 1.518 + continue; // nothing to do 1.519 + } 1.520 + } 1.521 + 1.522 + nsCOMPtr<EventTarget> piTarget; 1.523 + nsCOMPtr<Element> element = GetElement(); 1.524 + if (element) { 1.525 + piTarget = commandElt; 1.526 + } else { 1.527 + piTarget = mTarget; 1.528 + } 1.529 + 1.530 + if (!aExecute) { 1.531 + return true; 1.532 + } 1.533 + 1.534 + rv = currHandler->ExecuteHandler(piTarget, aKeyEvent); 1.535 + if (NS_SUCCEEDED(rv)) { 1.536 + return true; 1.537 + } 1.538 + } 1.539 + 1.540 + return false; 1.541 +} 1.542 + 1.543 +bool 1.544 +nsXBLWindowKeyHandler::HasHandlerForEvent(nsIDOMKeyEvent* aEvent) 1.545 +{ 1.546 + if (!aEvent->InternalDOMEvent()->IsTrusted()) { 1.547 + return false; 1.548 + } 1.549 + 1.550 + nsresult rv = EnsureHandlers(); 1.551 + NS_ENSURE_SUCCESS(rv, false); 1.552 + 1.553 + bool isDisabled; 1.554 + nsCOMPtr<Element> el = GetElement(&isDisabled); 1.555 + if (el && isDisabled) { 1.556 + return false; 1.557 + } 1.558 + 1.559 + nsAutoString eventType; 1.560 + aEvent->GetType(eventType); 1.561 + nsCOMPtr<nsIAtom> eventTypeAtom = do_GetAtom(eventType); 1.562 + NS_ENSURE_TRUE(eventTypeAtom, false); 1.563 + 1.564 + return WalkHandlersInternal(aEvent, eventTypeAtom, mHandler, false); 1.565 +} 1.566 + 1.567 +already_AddRefed<Element> 1.568 +nsXBLWindowKeyHandler::GetElement(bool* aIsDisabled) 1.569 +{ 1.570 + nsCOMPtr<Element> element = do_QueryReferent(mWeakPtrForElement); 1.571 + if (element && aIsDisabled) { 1.572 + *aIsDisabled = element->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled, 1.573 + nsGkAtoms::_true, eCaseMatters); 1.574 + } 1.575 + return element.forget(); 1.576 +} 1.577 + 1.578 +/////////////////////////////////////////////////////////////////////////////////// 1.579 + 1.580 +already_AddRefed<nsXBLWindowKeyHandler> 1.581 +NS_NewXBLWindowKeyHandler(nsIDOMElement* aElement, EventTarget* aTarget) 1.582 +{ 1.583 + nsRefPtr<nsXBLWindowKeyHandler> result = 1.584 + new nsXBLWindowKeyHandler(aElement, aTarget); 1.585 + return result.forget(); 1.586 +}