Bug 1154183 part.4 Implement nsXBLWindowKeyHandler::GetElementForHandler() r=smaug
MozReview-Commit-ID: 9qsOLU3QCnr
--- a/dom/xbl/nsXBLWindowKeyHandler.cpp
+++ b/dom/xbl/nsXBLWindowKeyHandler.cpp
@@ -592,45 +592,19 @@ nsXBLWindowKeyHandler::WalkHandlersAndEx
if (!EventMatched(handler, aEventType, aKeyEvent,
aCharCode, aIgnoreModifierState)) {
continue; // try the next one
}
// Before executing this handler, check that it's not disabled,
// and that it has something to do (oncommand of the <key> or its
// <command> is non-empty).
- nsCOMPtr<nsIContent> keyContent = handler->GetHandlerElement();
nsCOMPtr<Element> commandElement;
-
- // See if we're in a XUL doc.
- nsCOMPtr<Element> chromeHandlerElement = GetElement();
- if (chromeHandlerElement && keyContent) {
- // We are. Obtain our command attribute.
- nsAutoString command;
- keyContent->GetAttr(kNameSpaceID_None, nsGkAtoms::command, command);
- if (!command.IsEmpty()) {
- // Locate the command element in question. Note that we
- // know "keyContent" is in a doc if we're dealing with it here.
- NS_ASSERTION(keyContent->IsInDoc(),
- "the key element must be in document");
- nsIDocument* doc = keyContent->GetCurrentDoc();
- if (doc) {
- commandElement = do_QueryInterface(doc->GetElementById(command));
- }
-
- if (!commandElement) {
- NS_ERROR("A XUL <key> is observing a command that doesn't exist. "
- "Unable to execute key binding!");
- continue;
- }
- }
- }
-
- if (!commandElement) {
- commandElement = do_QueryInterface(keyContent);
+ if (!GetElementForHandler(handler, getter_AddRefs(commandElement))) {
+ continue;
}
if (commandElement) {
nsAutoString value;
commandElement->GetAttribute(NS_LITERAL_STRING("disabled"), value);
if (value.EqualsLiteral("true")) {
continue; // this handler is disabled, try the next one
}
@@ -648,16 +622,17 @@ nsXBLWindowKeyHandler::WalkHandlersAndEx
}
}
if (!aExecute) {
return true;
}
nsCOMPtr<EventTarget> target;
+ nsCOMPtr<Element> chromeHandlerElement = GetElement();
if (chromeHandlerElement) {
target = commandElement;
} else {
target = mTarget;
}
nsresult rv = handler->ExecuteHandler(target, aKeyEvent->AsEvent());
if (NS_SUCCEEDED(rv)) {
@@ -717,16 +692,59 @@ nsXBLWindowKeyHandler::GetElement(bool*
nsCOMPtr<Element> element = do_QueryReferent(mWeakPtrForElement);
if (element && aIsDisabled) {
*aIsDisabled = element->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
nsGkAtoms::_true, eCaseMatters);
}
return element.forget();
}
+bool
+nsXBLWindowKeyHandler::GetElementForHandler(nsXBLPrototypeHandler* aHandler,
+ Element** aElementForHandler)
+{
+ MOZ_ASSERT(aElementForHandler);
+ *aElementForHandler = nullptr;
+
+ nsCOMPtr<nsIContent> keyContent = aHandler->GetHandlerElement();
+
+ // See if we're in a XUL doc.
+ nsCOMPtr<Element> chromeHandlerElement = GetElement();
+ if (chromeHandlerElement && keyContent) {
+ // We are. Obtain our command attribute.
+ nsAutoString command;
+ keyContent->GetAttr(kNameSpaceID_None, nsGkAtoms::command, command);
+ if (!command.IsEmpty()) {
+ // Locate the command element in question. Note that we
+ // know "keyContent" is in a doc if we're dealing with it here.
+ NS_ASSERTION(keyContent->IsInDoc(),
+ "the key element must be in document");
+ nsIDocument* doc = keyContent->GetCurrentDoc();
+ if (NS_WARN_IF(!doc)) {
+ return false;
+ }
+ nsCOMPtr<Element> commandElement =
+ do_QueryInterface(doc->GetElementById(command));
+ if (!commandElement) {
+ NS_ERROR("A XUL <key> is observing a command that doesn't exist. "
+ "Unable to execute key binding!");
+ return false;
+ }
+ commandElement.swap(*aElementForHandler);
+ }
+ }
+
+ if (!*aElementForHandler) {
+ nsCOMPtr<Element> keyElement = do_QueryInterface(keyContent);
+ keyElement.swap(*aElementForHandler);
+ }
+
+ return true;
+}
+
///////////////////////////////////////////////////////////////////////////////////
already_AddRefed<nsXBLWindowKeyHandler>
NS_NewXBLWindowKeyHandler(nsIDOMElement* aElement, EventTarget* aTarget)
{
RefPtr<nsXBLWindowKeyHandler> result =
new nsXBLWindowKeyHandler(aElement, aTarget);
return result.forget();
--- a/dom/xbl/nsXBLWindowKeyHandler.h
+++ b/dom/xbl/nsXBLWindowKeyHandler.h
@@ -85,16 +85,29 @@ protected:
// Is an HTML editable element focused
bool IsHTMLEditableFieldFocused();
// Returns the element which was passed as a parameter to the constructor,
// unless the element has been removed from the document. Optionally returns
// whether the disabled attribute is set on the element (assuming the element
// is non-null).
already_AddRefed<mozilla::dom::Element> GetElement(bool* aIsDisabled = nullptr);
+
+ /**
+ * GetElementForHandler() retrieves an element for the handler. The element
+ * may be a command element or a key element.
+ *
+ * @param aHandler The handler.
+ * @param aElementForHandler Must not be nullptr. The element is returned to
+ * this.
+ * @return true if the handler is valid. Otherwise, false.
+ */
+ bool GetElementForHandler(nsXBLPrototypeHandler* aHandler,
+ mozilla::dom::Element** aElementForHandler);
+
// Using weak pointer to the DOM Element.
nsWeakPtr mWeakPtrForElement;
mozilla::dom::EventTarget* mTarget; // weak ref
// these are not owning references; the prototype handlers are owned
// by the prototype bindings which are owned by the docinfo.
nsXBLPrototypeHandler* mHandler; // platform bindings
nsXBLPrototypeHandler* mUserHandler; // user-specific bindings