Fix for 71740. r=jag, sr=shaver.

This commit is contained in:
hyatt%netscape.com 2001-03-21 08:15:12 +00:00
Родитель 7eb8765948
Коммит 6fe6375fc9
4 изменённых файлов: 70 добавлений и 9 удалений

Просмотреть файл

@ -189,12 +189,18 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver, nsIDOMEven
if (!mHandlerElement)
return NS_ERROR_FAILURE;
// See if our event receiver is a content node (and not us).
PRBool isReceiverCommandElement = PR_FALSE;
nsCOMPtr<nsIContent> content(do_QueryInterface(aReceiver));
if (content && content.get() != mHandlerElement)
isReceiverCommandElement = PR_TRUE;
// 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.
nsAutoString command;
mHandlerElement->GetAttribute(kNameSpaceID_None, kCommandAtom, command);
if (!command.IsEmpty()) {
if (!command.IsEmpty() && !isReceiverCommandElement) {
// Make sure the XBL doc is chrome or resource
// Fix for bug #45989
nsCOMPtr<nsIDocument> document;
@ -209,6 +215,15 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver, nsIDOMEven
if (!isChrome && !isRes)
return NS_OK;
// See if preventDefault has been set. If so, don't execute.
PRBool preventDefault;
nsCOMPtr<nsIDOMNSUIEvent> nsUIEvent(do_QueryInterface(aEvent));
if (nsUIEvent)
nsUIEvent->GetPreventDefault(&preventDefault);
if (preventDefault)
return NS_OK;
// We are the default action for this command.
// Stop any other default action from executing.
aEvent->PreventDefault();
@ -282,8 +297,15 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver, nsIDOMEven
// Try an oncommand attribute (used by XUL <key> elements, which
// are implemented using this code).
mHandlerElement->GetAttribute(kNameSpaceID_None, kOnCommandAtom, handlerText);
if (handlerText.IsEmpty())
return NS_ERROR_FAILURE; // For whatever reason, they didn't give us anything to do.
if (handlerText.IsEmpty()) {
// Maybe the receiver is a <command> elt.
if (isReceiverCommandElement) {
// It is! See if it has an oncommand attribute.
content->GetAttribute(kNameSpaceID_None, kOnCommandAtom, handlerText);
if (handlerText.IsEmpty())
return NS_ERROR_FAILURE; // For whatever reason, they didn't give us anything to do.
}
}
aEvent->PreventDefault(); // Preventing default for XUL key handlers
}
}

Просмотреть файл

@ -46,6 +46,10 @@
#include "nsIDocument.h"
#include "nsIXBLService.h"
#include "nsIServiceManager.h"
#include "nsIDOMDocument.h"
#ifdef INCLUDE_XUL
#include "nsXULAtoms.h"
#endif
class nsXBLSpecialDocInfo
{
@ -268,17 +272,35 @@ nsXBLWindowHandler::WalkHandlersInternal(nsIDOMEvent* aEvent, nsIAtom* aEventTyp
// if the handler says it wants the event, execute it
if ( EventMatched(currHandler, aEventType, aEvent) ) {
// ...but don't exectute if it is disabled.
// ...but don't execute if it is disabled.
nsAutoString disabled;
nsCOMPtr<nsIContent> elt;
currHandler->GetHandlerElement(getter_AddRefs(elt));
elt->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::disabled, disabled);
nsCOMPtr<nsIDOMElement> commandElt(do_QueryInterface(elt));
// See if we're in a XUL doc.
if (mElement) {
// We are. Obtain our command attribute.
nsAutoString command;
elt->GetAttribute(kNameSpaceID_None, nsXULAtoms::command, command);
if (!command.IsEmpty()) {
// Locate the command element in question.
nsCOMPtr<nsIDocument> doc;
elt->GetDocument(*getter_AddRefs(doc));
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
domDoc->GetElementById(command, getter_AddRefs(commandElt));
if (!commandElt)
continue;
}
}
commandElt->GetAttribute(NS_LITERAL_STRING("disabled"), disabled);
if (!disabled.Equals(NS_LITERAL_STRING("true"))) {
nsCOMPtr<nsIDOMEventReceiver> rec = mReceiver;
if (mElement)
rec = do_QueryInterface(elt);
rec = do_QueryInterface(commandElt);
rv = currHandler->ExecuteHandler(rec, aEvent);
if (NS_SUCCEEDED(rv))
return NS_OK;

Просмотреть файл

@ -3297,7 +3297,7 @@ nsXULElement::UnsetAttribute(PRInt32 aNameSpaceID,
// need to remove ourselves completely.
if (mDocument &&
(aNameSpaceID == kNameSpaceID_None) &&
(aName == nsXULAtoms::observes))
(aName == nsXULAtoms::observes || aName == nsXULAtoms::command))
{
// Do a getElementById to retrieve the broadcaster.
nsCOMPtr<nsIDOMElement> broadcaster;

Просмотреть файл

@ -6224,8 +6224,25 @@ nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
// Bail if there's no broadcasterID
if ((rv != NS_CONTENT_ATTR_HAS_VALUE) || (broadcasterID.Length() == 0)) {
*aNeedsHookup = PR_FALSE;
return NS_OK;
// Try the command attribute next.
nsAutoString commandID;
rv = aElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::command, commandID);
if (NS_FAILED(rv)) return rv;
if (rv == NS_CONTENT_ATTR_HAS_VALUE && commandID.Length() > 0) {
// We've got something in the command attribute. We only treat this as
// a normal broadcaster if we are not a menuitem or a key.
nsCOMPtr<nsIAtom> tag;
aElement->GetTag(*getter_AddRefs(tag));
if (tag.get() == nsXULAtoms::menuitem || tag.get() == nsXULAtoms::key) {
*aNeedsHookup = PR_FALSE;
return NS_OK;
}
}
else {
*aNeedsHookup = PR_FALSE;
return NS_OK;
}
}
listener = do_QueryInterface(aElement);