mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-03 10:33:33 +00:00
Invoke <key> element commands using command events rather than compiling and executing the script directly, for consistency with click-invoked commands (bug 331290). r+sr=bzbarsky.
This commit is contained in:
parent
6241ecf3e0
commit
9c0686cc5d
@ -229,6 +229,8 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver,
|
||||
// See if our event receiver is a content node (and not us).
|
||||
PRBool isXULKey = (mType & NS_HANDLER_TYPE_XUL);
|
||||
PRBool isXBLCommand = (mType & NS_HANDLER_TYPE_XBL_COMMAND);
|
||||
NS_ASSERTION(!(isXULKey && isXBLCommand),
|
||||
"can't be both a key and xbl command handler");
|
||||
|
||||
// XUL handlers and commands shouldn't be triggered by non-trusted
|
||||
// events.
|
||||
@ -243,14 +245,10 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool isReceiverCommandElement = PR_FALSE;
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aReceiver));
|
||||
if (isXULKey && content && content.get() != mHandlerElement)
|
||||
isReceiverCommandElement = PR_TRUE;
|
||||
if (isXBLCommand) {
|
||||
// This is a special-case optimization to make command handling fast.
|
||||
// It isn't really a part of XBL, but it helps speed things up.
|
||||
|
||||
// This is a special-case optimization to make command handling fast.
|
||||
// It isn't really a part of XBL, but it helps speed things up.
|
||||
if (isXBLCommand && !isReceiverCommandElement) {
|
||||
// See if preventDefault has been set. If so, don't execute.
|
||||
PRBool preventDefault = PR_FALSE;
|
||||
nsCOMPtr<nsIDOMNSUIEvent> nsUIEvent(do_QueryInterface(aEvent));
|
||||
@ -319,8 +317,8 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver,
|
||||
nsCOMPtr<nsIContent> focusedContent = do_QueryInterface(focusedElement);
|
||||
nsIContent *content = focusedContent;
|
||||
|
||||
// if the focused element is a link then we do want space to
|
||||
// scroll down. focused element may be an element in a link,
|
||||
// if the focused element is a link then we do want space to
|
||||
// scroll down. focused element may be an element in a link,
|
||||
// we need to check the parent node too.
|
||||
if (focusedContent) {
|
||||
while (content) {
|
||||
@ -357,6 +355,20 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If we're executing on a XUL key element, just dispatch a command
|
||||
// event at the element. It will take care of retargeting it to its
|
||||
// command element, if applicable, and executing the event handler.
|
||||
if (isXULKey) {
|
||||
nsCOMPtr<nsIDOMXULElement> xulElement = do_QueryInterface(mHandlerElement);
|
||||
if (xulElement) {
|
||||
aEvent->PreventDefault();
|
||||
xulElement->DoCommand();
|
||||
} else {
|
||||
NS_WARNING("command target is not a XUL element");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Look for a compiled handler on the element.
|
||||
// Should be compiled and bound with "on" in front of the name.
|
||||
nsAutoString onEvent(NS_LITERAL_STRING("onxbl"));
|
||||
@ -367,31 +379,8 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver,
|
||||
|
||||
void* handler = nsnull;
|
||||
|
||||
// Compile the event handler.
|
||||
nsAutoString xulText;
|
||||
nsIContent* keyCommandContent = nsnull;
|
||||
if (isXULKey) {
|
||||
// Try an oncommand attribute (used by XUL <key> elements, which
|
||||
// are implemented using this code).
|
||||
mHandlerElement->GetAttr(kNameSpaceID_None, nsLayoutAtoms::oncommand, xulText);
|
||||
keyCommandContent = mHandlerElement;
|
||||
if (xulText.IsEmpty()) {
|
||||
// Maybe the receiver is a <command> elt.
|
||||
if (isReceiverCommandElement) {
|
||||
// It is! See if it has an oncommand attribute.
|
||||
content->GetAttr(kNameSpaceID_None, nsLayoutAtoms::oncommand, xulText);
|
||||
keyCommandContent = content;
|
||||
}
|
||||
|
||||
if (xulText.IsEmpty())
|
||||
return NS_ERROR_FAILURE; // For whatever reason, they didn't give us anything to do.
|
||||
}
|
||||
}
|
||||
|
||||
if (isXULKey)
|
||||
aEvent->PreventDefault(); // Preventing default for XUL key handlers
|
||||
|
||||
// Compile the handler and bind it to the element.
|
||||
nsAutoString xulText;
|
||||
nsCOMPtr<nsIScriptGlobalObject> boundGlobal;
|
||||
nsCOMPtr<nsPIWindowRoot> winRoot(do_QueryInterface(aReceiver));
|
||||
nsCOMPtr<nsIDOMWindowInternal> focusedWin;
|
||||
@ -465,25 +454,16 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver,
|
||||
|
||||
const char *eventName = nsContentUtils::GetEventArgName(kNameSpaceID_XBL);
|
||||
|
||||
if (isXULKey) {
|
||||
nsCAutoString documentURI;
|
||||
keyCommandContent->GetOwnerDoc()->GetDocumentURI()->GetSpec(documentURI);
|
||||
rv = boundContext->CompileEventHandler(scriptObject, onEventAtom, eventName,
|
||||
xulText, documentURI.get(), 0,
|
||||
PR_TRUE, &handler);
|
||||
}
|
||||
else {
|
||||
nsDependentString handlerText(mHandlerText);
|
||||
if (handlerText.IsEmpty())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCAutoString bindingURI;
|
||||
mPrototypeBinding->DocURI()->GetSpec(bindingURI);
|
||||
|
||||
rv = boundContext->CompileEventHandler(scriptObject, onEventAtom, eventName,
|
||||
handlerText, bindingURI.get(),
|
||||
mLineNumber, PR_TRUE, &handler);
|
||||
}
|
||||
nsDependentString handlerText(mHandlerText);
|
||||
if (handlerText.IsEmpty())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCAutoString bindingURI;
|
||||
mPrototypeBinding->DocURI()->GetSpec(bindingURI);
|
||||
|
||||
rv = boundContext->CompileEventHandler(scriptObject, onEventAtom, eventName,
|
||||
handlerText, bindingURI.get(),
|
||||
mLineNumber, PR_TRUE, &handler);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoGCRoot root(&handler, &rv);
|
||||
|
Loading…
Reference in New Issue
Block a user