зеркало из https://github.com/mozilla/gecko-dev.git
Improve typing speed. r=ben
This commit is contained in:
Родитель
b98c866d6f
Коммит
2909098718
|
@ -33,6 +33,7 @@ EXPORTS = \
|
|||
nsIXBLBinding.h \
|
||||
nsIXBLBindingAttachedHandler.h \
|
||||
nsIXBLDocumentInfo.h \
|
||||
nsIXBLPrototypeHandler.h \
|
||||
nsIXBLService.h \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -2,5 +2,6 @@ nsIBindingManager.h
|
|||
nsIXBLBinding.h
|
||||
nsIXBLBindingAttachedHandler.h
|
||||
nsIXBLDocumentInfo.h
|
||||
nsIXBLPrototypeHandler.h
|
||||
nsIXBLService.h
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ EXPORTS = \
|
|||
nsIXBLBinding.h \
|
||||
nsIXBLBindingAttachedHandler.h \
|
||||
nsIXBLDocumentInfo.h \
|
||||
nsIXBLPrototypeHandler.h \
|
||||
nsIXBLService.h \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
class nsIContent;
|
||||
class nsIDocument;
|
||||
class nsIScriptContext;
|
||||
class nsIXBLPrototypeHandler;
|
||||
|
||||
// {5C4D9674-A2CF-4ddf-9F65-E1806C34D28D}
|
||||
#define NS_IXBLDOCUMENTINFO_IID \
|
||||
|
@ -54,6 +55,8 @@ public:
|
|||
NS_IMETHOD GetScriptAccess(PRBool* aResult)=0;
|
||||
NS_IMETHOD SetScriptAccess(PRBool aAccess)=0;
|
||||
|
||||
NS_IMETHOD GetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler** aResult)=0;
|
||||
NS_IMETHOD SetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler* aHandler)=0;
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Private interface to the XBL PrototypeHandler
|
||||
|
||||
*/
|
||||
|
||||
#ifndef nsIXBLPrototypeHandler_h__
|
||||
#define nsIXBLPrototypeHandler_h__
|
||||
|
||||
class nsIContent;
|
||||
class nsIDOMEvent;
|
||||
|
||||
// {921812E7-A044-4bd8-B49E-69BB0A607202}
|
||||
#define NS_IXBLPROTOTYPEHANDLER_IID \
|
||||
{ 0x921812e7, 0xa044, 0x4bd8, { 0xb4, 0x9e, 0x69, 0xbb, 0xa, 0x60, 0x72, 0x2 } }
|
||||
|
||||
class nsIXBLPrototypeHandler : public nsISupports
|
||||
{
|
||||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_IXBLPROTOTYPEHANDLER_IID; return iid; }
|
||||
|
||||
NS_IMETHOD EventMatched(nsIDOMEvent* aEvent, PRBool* aResult) = 0;
|
||||
NS_IMETHOD GetHandlerElement(nsIContent** aResult) = 0;
|
||||
|
||||
NS_IMETHOD GetNextHandler(nsIXBLPrototypeHandler** aResult) = 0;
|
||||
NS_IMETHOD SetNextHandler(nsIXBLPrototypeHandler* aHandler) = 0;
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
NS_NewXBLPrototypeHandler(nsIContent* aHandlerElement, nsIXBLPrototypeHandler** aResult);
|
||||
|
||||
#endif // nsIXBLPrototypeHandler_h__
|
|
@ -32,6 +32,7 @@ LIBRARY_NAME = gkxbl_s
|
|||
CPPSRCS = \
|
||||
nsXBLBinding.cpp \
|
||||
nsXBLEventHandler.cpp \
|
||||
nsXBLPrototypeHandler.cpp \
|
||||
nsXBLService.cpp \
|
||||
nsBindingManager.cpp \
|
||||
$(NULL)
|
||||
|
|
|
@ -30,12 +30,14 @@ CPPSRCS= \
|
|||
nsXBLBinding.cpp \
|
||||
nsXBLService.cpp \
|
||||
nsXBLEventHandler.cpp \
|
||||
nsXBLPrototypeHandler.cpp \
|
||||
nsBindingManager.cpp \
|
||||
$(NULL)
|
||||
|
||||
CPP_OBJS= \
|
||||
.\$(OBJDIR)\nsXBLBinding.obj \
|
||||
.\$(OBJDIR)\nsXBLEventHandler.obj \
|
||||
.\$(OBJDIR)\nsXBLPrototypeHandler.obj \
|
||||
.\$(OBJDIR)\nsXBLService.obj \
|
||||
.\$(OBJDIR)\nsBindingManager.obj \
|
||||
$(NULL)
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
|
||||
#include "nsIStyleRuleProcessor.h"
|
||||
#include "nsIStyleSet.h"
|
||||
#include "nsIXBLPrototypeHandler.h"
|
||||
|
||||
// Static IIDs/CIDs. Try to minimize these.
|
||||
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
|
||||
|
@ -78,10 +79,14 @@ public:
|
|||
NS_IMETHOD GetScriptAccess(PRBool* aResult) { *aResult = mScriptAccess; return NS_OK; };
|
||||
NS_IMETHOD SetScriptAccess(PRBool aAccess) { mScriptAccess = aAccess; return NS_OK; };
|
||||
|
||||
NS_IMETHOD GetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler** aResult);
|
||||
NS_IMETHOD SetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler* aHandler);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
nsCOMPtr<nsISupportsArray> mRuleProcessors;
|
||||
PRBool mScriptAccess;
|
||||
nsSupportsHashtable* mHandlerTable;
|
||||
};
|
||||
|
||||
/* Implementation file */
|
||||
|
@ -93,12 +98,13 @@ nsXBLDocumentInfo::nsXBLDocumentInfo(nsIDocument* aDocument)
|
|||
/* member initializers and constructor code */
|
||||
mDocument = aDocument;
|
||||
mScriptAccess = PR_TRUE;
|
||||
mHandlerTable = nsnull;
|
||||
}
|
||||
|
||||
nsXBLDocumentInfo::~nsXBLDocumentInfo()
|
||||
{
|
||||
/* destructor code */
|
||||
|
||||
delete mHandlerTable;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -136,7 +142,32 @@ nsXBLDocumentInfo::GetRuleProcessors(nsISupportsArray** aResult)
|
|||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLDocumentInfo::GetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
if (!mHandlerTable)
|
||||
return NS_OK;
|
||||
|
||||
nsCStringKey key(aRef);
|
||||
*aResult = NS_STATIC_CAST(nsIXBLPrototypeHandler*, mHandlerTable->Get(&key)); // Addref happens here.
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLDocumentInfo::SetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler* aHandler)
|
||||
{
|
||||
if (!mHandlerTable)
|
||||
mHandlerTable = new nsSupportsHashtable();
|
||||
|
||||
nsCStringKey key(aRef);
|
||||
mHandlerTable->Put(&key, aHandler);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NS_NewXBLDocumentInfo(nsIDocument* aDocument, nsIXBLDocumentInfo** aResult)
|
||||
{
|
||||
*aResult = new nsXBLDocumentInfo(aDocument);
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
#include "nsIDOMAttr.h"
|
||||
#include "nsIDOMNamedNodeMap.h"
|
||||
|
||||
#include "nsIXBLPrototypeHandler.h"
|
||||
#include "nsXBLEventHandler.h"
|
||||
#include "nsXBLBinding.h"
|
||||
|
||||
|
@ -573,112 +574,123 @@ nsXBLBinding::GenerateAnonymousContent(nsIContent* aBoundElement)
|
|||
NS_IMETHODIMP
|
||||
nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement, nsIXBLBinding** aBinding)
|
||||
{
|
||||
// Fetch the handlers element for this binding.
|
||||
nsCOMPtr<nsIContent> handlers;
|
||||
GetImmediateChild(kHandlersAtom, getter_AddRefs(handlers));
|
||||
// Don't install handlers if scripts aren't allowed.
|
||||
if (!AllowScripts())
|
||||
return NS_OK;
|
||||
|
||||
// Fetch the handlers prototypes for this binding.
|
||||
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||
gXBLService->GetXBLDocumentInfo(mDocURI, mBoundElement, getter_AddRefs(info));
|
||||
if (!info)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> handlerChain;
|
||||
info->GetPrototypeHandler(mID, getter_AddRefs(handlerChain));
|
||||
if (!handlerChain)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> curr = handlerChain;
|
||||
nsXBLEventHandler* currHandler = nsnull;
|
||||
if (handlers && AllowScripts()) {
|
||||
// Now walk the handlers and add event listeners to the bound
|
||||
// element.
|
||||
PRInt32 childCount;
|
||||
handlers->ChildCount(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
handlers->ChildAt(i, *getter_AddRefs(child));
|
||||
|
||||
// Fetch the type attribute.
|
||||
// XXX Deal with a comma-separated list of types
|
||||
nsAutoString type;
|
||||
child->GetAttribute(kNameSpaceID_None, kEventAtom, type);
|
||||
|
||||
if (!type.IsEmpty()) {
|
||||
nsIID iid;
|
||||
PRBool found = PR_FALSE;
|
||||
PRBool special = PR_FALSE;
|
||||
nsCOMPtr<nsIAtom> eventAtom = getter_AddRefs(NS_NewAtom(type));
|
||||
if (eventAtom.get() == kBindingAttachedAtom) {
|
||||
*aBinding = this;
|
||||
NS_ADDREF(*aBinding);
|
||||
special = PR_TRUE;
|
||||
while (curr) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
curr->GetHandlerElement(getter_AddRefs(child));
|
||||
|
||||
// Fetch the type attribute.
|
||||
// XXX Deal with a comma-separated list of types
|
||||
nsAutoString type;
|
||||
child->GetAttribute(kNameSpaceID_None, kEventAtom, type);
|
||||
|
||||
if (!type.IsEmpty()) {
|
||||
nsIID iid;
|
||||
PRBool found = PR_FALSE;
|
||||
PRBool special = PR_FALSE;
|
||||
nsCOMPtr<nsIAtom> eventAtom = getter_AddRefs(NS_NewAtom(type));
|
||||
if (eventAtom.get() == kBindingAttachedAtom) {
|
||||
*aBinding = this;
|
||||
NS_ADDREF(*aBinding);
|
||||
special = PR_TRUE;
|
||||
}
|
||||
else
|
||||
GetEventHandlerIID(eventAtom, &iid, &found);
|
||||
|
||||
if (found || special) {
|
||||
// Add an event listener for mouse and key events only.
|
||||
PRBool mouse = IsMouseHandler(type);
|
||||
PRBool key = IsKeyHandler(type);
|
||||
PRBool focus = IsFocusHandler(type);
|
||||
PRBool xul = IsXULHandler(type);
|
||||
PRBool scroll = IsScrollHandler(type);
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver = do_QueryInterface(mBoundElement);
|
||||
nsAutoString attachType;
|
||||
child->GetAttribute(kNameSpaceID_None, kAttachToAtom, attachType);
|
||||
if (attachType == NS_LITERAL_STRING("_document") ||
|
||||
attachType == NS_LITERAL_STRING("_window"))
|
||||
{
|
||||
nsCOMPtr<nsIDocument> boundDoc;
|
||||
mBoundElement->GetDocument(*getter_AddRefs(boundDoc));
|
||||
if (attachType == NS_LITERAL_STRING("_window")) {
|
||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||
boundDoc->GetScriptGlobalObject(getter_AddRefs(global));
|
||||
receiver = do_QueryInterface(global);
|
||||
}
|
||||
else receiver = do_QueryInterface(boundDoc);
|
||||
}
|
||||
else
|
||||
GetEventHandlerIID(eventAtom, &iid, &found);
|
||||
|
||||
if (found || special) {
|
||||
// Add an event listener for mouse and key events only.
|
||||
PRBool mouse = IsMouseHandler(type);
|
||||
PRBool key = IsKeyHandler(type);
|
||||
PRBool focus = IsFocusHandler(type);
|
||||
PRBool xul = IsXULHandler(type);
|
||||
PRBool scroll = IsScrollHandler(type);
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver = do_QueryInterface(mBoundElement);
|
||||
nsAutoString attachType;
|
||||
child->GetAttribute(kNameSpaceID_None, kAttachToAtom, attachType);
|
||||
if (attachType == NS_LITERAL_STRING("_document") ||
|
||||
attachType == NS_LITERAL_STRING("_window"))
|
||||
{
|
||||
nsCOMPtr<nsIDocument> boundDoc;
|
||||
mBoundElement->GetDocument(*getter_AddRefs(boundDoc));
|
||||
if (attachType == NS_LITERAL_STRING("_window")) {
|
||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||
boundDoc->GetScriptGlobalObject(getter_AddRefs(global));
|
||||
receiver = do_QueryInterface(global);
|
||||
}
|
||||
else receiver = do_QueryInterface(boundDoc);
|
||||
}
|
||||
if (mouse || key || focus || xul || scroll || special) {
|
||||
// Create a new nsXBLEventHandler.
|
||||
nsXBLEventHandler* handler;
|
||||
NS_NewXBLEventHandler(receiver, curr, type, &handler);
|
||||
|
||||
if (mouse || key || focus || xul || scroll || special) {
|
||||
// Create a new nsXBLEventHandler.
|
||||
nsXBLEventHandler* handler;
|
||||
NS_NewXBLEventHandler(receiver, child, type, &handler);
|
||||
// We chain all our event handlers together for easy
|
||||
// removal later (if/when the binding dies).
|
||||
if (!currHandler)
|
||||
mFirstHandler = handler;
|
||||
else
|
||||
currHandler->SetNextHandler(handler);
|
||||
|
||||
// We chain all our event handlers together for easy
|
||||
// removal later (if/when the binding dies).
|
||||
if (!currHandler)
|
||||
mFirstHandler = handler;
|
||||
else
|
||||
currHandler->SetNextHandler(handler);
|
||||
currHandler = handler;
|
||||
|
||||
currHandler = handler;
|
||||
// Figure out if we're using capturing or not.
|
||||
PRBool useCapture = PR_FALSE;
|
||||
nsAutoString capturer;
|
||||
child->GetAttribute(kNameSpaceID_None, kPhaseAtom, capturer);
|
||||
if (capturer == NS_LITERAL_STRING("capturing"))
|
||||
useCapture = PR_TRUE;
|
||||
|
||||
// Figure out if we're using capturing or not.
|
||||
PRBool useCapture = PR_FALSE;
|
||||
nsAutoString capturer;
|
||||
child->GetAttribute(kNameSpaceID_None, kPhaseAtom, capturer);
|
||||
if (capturer == NS_LITERAL_STRING("capturing"))
|
||||
useCapture = PR_TRUE;
|
||||
// Add the event listener.
|
||||
if (mouse)
|
||||
receiver->AddEventListener(type, (nsIDOMMouseListener*)handler, useCapture);
|
||||
else if(key)
|
||||
receiver->AddEventListener(type, (nsIDOMKeyListener*)handler, useCapture);
|
||||
else if(focus)
|
||||
receiver->AddEventListener(type, (nsIDOMFocusListener*)handler, useCapture);
|
||||
else if (xul)
|
||||
receiver->AddEventListener(type, (nsIDOMScrollListener*)handler, useCapture);
|
||||
else if (scroll)
|
||||
receiver->AddEventListener(type, (nsIDOMScrollListener*)handler, useCapture);
|
||||
|
||||
// Add the event listener.
|
||||
if (mouse)
|
||||
receiver->AddEventListener(type, (nsIDOMMouseListener*)handler, useCapture);
|
||||
else if(key)
|
||||
receiver->AddEventListener(type, (nsIDOMKeyListener*)handler, useCapture);
|
||||
else if(focus)
|
||||
receiver->AddEventListener(type, (nsIDOMFocusListener*)handler, useCapture);
|
||||
else if (xul)
|
||||
receiver->AddEventListener(type, (nsIDOMScrollListener*)handler, useCapture);
|
||||
else if (scroll)
|
||||
receiver->AddEventListener(type, (nsIDOMScrollListener*)handler, useCapture);
|
||||
if (!special) // Let the listener manager hold on to the handler.
|
||||
NS_RELEASE(handler);
|
||||
}
|
||||
else {
|
||||
// Call AddScriptEventListener for other IID types
|
||||
// XXX Want this to all go away!
|
||||
NS_WARNING("***** Non-compliant XBL event listener attached! *****");
|
||||
nsAutoString value;
|
||||
child->GetAttribute(kNameSpaceID_None, kActionAtom, value);
|
||||
if (value.IsEmpty())
|
||||
GetTextData(child, value);
|
||||
|
||||
if (!special) // Let the listener manager hold on to the handler.
|
||||
NS_RELEASE(handler);
|
||||
}
|
||||
else {
|
||||
// Call AddScriptEventListener for other IID types
|
||||
// XXX Want this to all go away!
|
||||
NS_WARNING("***** Non-compliant XBL event listener attached! *****");
|
||||
nsAutoString value;
|
||||
child->GetAttribute(kNameSpaceID_None, kActionAtom, value);
|
||||
if (value.IsEmpty())
|
||||
GetTextData(child, value);
|
||||
|
||||
AddScriptEventListener(mBoundElement, eventAtom, value, iid);
|
||||
}
|
||||
AddScriptEventListener(mBoundElement, eventAtom, value, iid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> next;
|
||||
curr->GetNextHandler(getter_AddRefs(next));
|
||||
curr = next;
|
||||
}
|
||||
|
||||
if (mNextBinding) {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIXBLPrototypeHandler.h"
|
||||
#include "nsXBLEventHandler.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIAtom.h"
|
||||
|
@ -63,19 +64,12 @@ nsIAtom* nsXBLEventHandler::kBindingAttachedAtom = nsnull;
|
|||
nsIAtom* nsXBLEventHandler::kBindingDetachedAtom = nsnull;
|
||||
nsIAtom* nsXBLEventHandler::kModifiersAtom = nsnull;
|
||||
|
||||
PRInt32 nsXBLEventHandler::kAccessKey = -1;
|
||||
|
||||
const PRInt32 nsXBLEventHandler::cShift = (1<<1);
|
||||
const PRInt32 nsXBLEventHandler::cAlt = (1<<2);
|
||||
const PRInt32 nsXBLEventHandler::cControl = (1<<3);
|
||||
const PRInt32 nsXBLEventHandler::cMeta = (1<<4);
|
||||
|
||||
nsXBLEventHandler::nsXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsIContent* aHandlerElement,
|
||||
nsXBLEventHandler::nsXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsIXBLPrototypeHandler* aHandler,
|
||||
const nsString& aEventName)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mEventReceiver = aEventReceiver;
|
||||
mHandlerElement = aHandlerElement;
|
||||
mProtoHandler = aHandler;
|
||||
mEventName.Assign(aEventName);
|
||||
mNextHandler = nsnull;
|
||||
gRefCnt++;
|
||||
|
@ -90,13 +84,7 @@ nsXBLEventHandler::nsXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsICon
|
|||
kButtonAtom = NS_NewAtom("button");
|
||||
kBindingAttachedAtom = NS_NewAtom("bindingattached");
|
||||
kBindingDetachedAtom = NS_NewAtom("bindingdetached");
|
||||
|
||||
// Get the primary accelerator key.
|
||||
InitAccessKey();
|
||||
}
|
||||
|
||||
// Make sure our mask is initialized.
|
||||
ConstructMask();
|
||||
}
|
||||
|
||||
nsXBLEventHandler::~nsXBLEventHandler()
|
||||
|
@ -166,6 +154,7 @@ nsXBLEventHandler::BindingAttached()
|
|||
NS_IMETHODIMP
|
||||
nsXBLEventHandler::BindingDetached()
|
||||
{
|
||||
// XXX Write me!!!!
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -180,8 +169,11 @@ nsresult nsXBLEventHandler::KeyUp(nsIDOMEvent* aKeyEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("keyup"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
|
||||
if (KeyEventMatched(keyEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aKeyEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("keyup"), aKeyEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -191,8 +183,11 @@ nsresult nsXBLEventHandler::KeyDown(nsIDOMEvent* aKeyEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("keydown"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
|
||||
if (KeyEventMatched(keyEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aKeyEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("keydown"), aKeyEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -202,8 +197,11 @@ nsresult nsXBLEventHandler::KeyPress(nsIDOMEvent* aKeyEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("keypress"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
|
||||
if (KeyEventMatched(keyEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aKeyEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("keypress"), aKeyEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -213,8 +211,11 @@ nsresult nsXBLEventHandler::MouseDown(nsIDOMEvent* aMouseEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("mousedown"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
if (MouseEventMatched(mouseEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aMouseEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("mousedown"), aMouseEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -224,8 +225,11 @@ nsresult nsXBLEventHandler::MouseUp(nsIDOMEvent* aMouseEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("mouseup"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
if (MouseEventMatched(mouseEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aMouseEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("mouseup"), aMouseEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -235,8 +239,11 @@ nsresult nsXBLEventHandler::MouseClick(nsIDOMEvent* aMouseEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("click"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
if (MouseEventMatched(mouseEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aMouseEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("click"), aMouseEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -246,8 +253,11 @@ nsresult nsXBLEventHandler::MouseDblClick(nsIDOMEvent* aMouseEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("dblclick"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
if (MouseEventMatched(mouseEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aMouseEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("dblclick"), aMouseEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -257,8 +267,11 @@ nsresult nsXBLEventHandler::MouseOver(nsIDOMEvent* aMouseEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("mouseover"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
if (MouseEventMatched(mouseEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aMouseEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("mouseover"), aMouseEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -268,8 +281,11 @@ nsresult nsXBLEventHandler::MouseOut(nsIDOMEvent* aMouseEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("mouseout"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
if (MouseEventMatched(mouseEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aMouseEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("mouseout"), aMouseEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -375,88 +391,22 @@ nsresult nsXBLEventHandler::Destroy(nsIDOMEvent* aEvent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Get the menu access key from prefs.
|
||||
// XXX Eventually pick up using CSS3 key-equivalent property or somesuch
|
||||
void
|
||||
nsXBLEventHandler::InitAccessKey()
|
||||
{
|
||||
if (kAccessKey >= 0)
|
||||
return;
|
||||
|
||||
// Compiled-in defaults, in case we can't get the pref --
|
||||
// mac doesn't have menu shortcuts, other platforms use alt.
|
||||
#ifndef XP_MAC
|
||||
kAccessKey = nsIDOMKeyEvent::DOM_VK_ALT;
|
||||
#else
|
||||
kAccessKey = 0;
|
||||
#endif
|
||||
|
||||
// Get the menu access key value from prefs, overriding the default:
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_PROGID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && prefs)
|
||||
{
|
||||
rv = prefs->GetIntPref("ui.key.menuAccessKey", &kAccessKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsXBLEventHandler::KeyEventMatched(nsIDOMKeyEvent* aKeyEvent)
|
||||
{
|
||||
if (!mHandlerElement)
|
||||
return PR_FALSE;
|
||||
|
||||
if (mDetail == 0 && mDetail2 == 0 && mKeyMask == 0)
|
||||
return PR_TRUE; // No filters set up. It's generic.
|
||||
|
||||
// Get the keycode and charcode of the key event.
|
||||
PRUint32 keyCode, charCode;
|
||||
aKeyEvent->GetKeyCode(&keyCode);
|
||||
aKeyEvent->GetCharCode(&charCode);
|
||||
|
||||
PRBool keyMatched = (mDetail == (mDetail2 ? charCode : keyCode));
|
||||
|
||||
if (!keyMatched)
|
||||
return PR_FALSE;
|
||||
|
||||
// Now check modifier keys
|
||||
return ModifiersMatchMask(aKeyEvent);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsXBLEventHandler::MouseEventMatched(nsIDOMMouseEvent* aMouseEvent)
|
||||
{
|
||||
if (!mHandlerElement)
|
||||
return PR_FALSE;
|
||||
|
||||
if (mDetail == 0 && mDetail2 == 0 && mKeyMask == 0)
|
||||
return PR_TRUE; // No filters set up. It's generic.
|
||||
|
||||
unsigned short button;
|
||||
aMouseEvent->GetButton(&button);
|
||||
if (mDetail != 0 && (button != mDetail))
|
||||
return PR_FALSE;
|
||||
|
||||
PRInt32 clickcount;
|
||||
aMouseEvent->GetDetail(&clickcount);
|
||||
if (mDetail2 != 0 && (clickcount != mDetail2))
|
||||
return PR_FALSE;
|
||||
|
||||
return ModifiersMatchMask(aMouseEvent);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLEventHandler::ExecuteHandler(const nsAReadableString & aEventName, nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mHandlerElement)
|
||||
if (!mProtoHandler)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIContent> handlerElement;
|
||||
mProtoHandler->GetHandlerElement(getter_AddRefs(handlerElement));
|
||||
if (!handlerElement)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// 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);
|
||||
handlerElement->GetAttribute(kNameSpaceID_None, kCommandAtom, command);
|
||||
if (!command.IsEmpty()) {
|
||||
// We are the default action for this command.
|
||||
// Stop any other default action from executing.
|
||||
|
@ -493,10 +443,10 @@ nsXBLEventHandler::ExecuteHandler(const nsAReadableString & aEventName, nsIDOMEv
|
|||
|
||||
// Compile the event handler.
|
||||
nsAutoString handlerText;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kActionAtom, handlerText);
|
||||
handlerElement->GetAttribute(kNameSpaceID_None, kActionAtom, handlerText);
|
||||
if (handlerText.IsEmpty()) {
|
||||
// look to see if action content is contained by the handler element
|
||||
GetTextData(mHandlerElement, handlerText);
|
||||
GetTextData(handlerElement, handlerText);
|
||||
if (handlerText.IsEmpty())
|
||||
return NS_OK; // For whatever reason, they didn't give us anything to do.
|
||||
}
|
||||
|
@ -598,15 +548,22 @@ nsXBLEventHandler::RemoveEventHandlers()
|
|||
}
|
||||
|
||||
// Figure out if we're using capturing or not.
|
||||
if (!mProtoHandler)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIContent> handlerElement;
|
||||
mProtoHandler->GetHandlerElement(getter_AddRefs(handlerElement));
|
||||
if (!handlerElement)
|
||||
return;
|
||||
|
||||
PRBool useCapture = PR_FALSE;
|
||||
nsAutoString capturer;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, nsXBLBinding::kPhaseAtom, capturer);
|
||||
handlerElement->GetAttribute(kNameSpaceID_None, nsXBLBinding::kPhaseAtom, capturer);
|
||||
if (capturer == NS_LITERAL_STRING("capturing"))
|
||||
useCapture = PR_TRUE;
|
||||
|
||||
// XXX Will potentially be comma-separated
|
||||
nsAutoString type;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, nsXBLBinding::kEventAtom, type);
|
||||
handlerElement->GetAttribute(kNameSpaceID_None, nsXBLBinding::kEventAtom, type);
|
||||
|
||||
// Figure out our type.
|
||||
PRBool mouse = nsXBLBinding::IsMouseHandler(type);
|
||||
|
@ -630,392 +587,6 @@ nsXBLEventHandler::RemoveEventHandlers()
|
|||
|
||||
/// Helpers that are relegated to the end of the file /////////////////////////////
|
||||
|
||||
enum {
|
||||
VK_CANCEL = 3,
|
||||
VK_BACK = 8,
|
||||
VK_TAB = 9,
|
||||
VK_CLEAR = 12,
|
||||
VK_RETURN = 13,
|
||||
VK_ENTER = 14,
|
||||
VK_SHIFT = 16,
|
||||
VK_CONTROL = 17,
|
||||
VK_ALT = 18,
|
||||
VK_PAUSE = 19,
|
||||
VK_CAPS_LOCK = 20,
|
||||
VK_ESCAPE = 27,
|
||||
VK_SPACE = 32,
|
||||
VK_PAGE_UP = 33,
|
||||
VK_PAGE_DOWN = 34,
|
||||
VK_END = 35,
|
||||
VK_HOME = 36,
|
||||
VK_LEFT = 37,
|
||||
VK_UP = 38,
|
||||
VK_RIGHT = 39,
|
||||
VK_DOWN = 40,
|
||||
VK_PRINTSCREEN = 44,
|
||||
VK_INSERT = 45,
|
||||
VK_DELETE = 46,
|
||||
VK_0 = 48,
|
||||
VK_1 = 49,
|
||||
VK_2 = 50,
|
||||
VK_3 = 51,
|
||||
VK_4 = 52,
|
||||
VK_5 = 53,
|
||||
VK_6 = 54,
|
||||
VK_7 = 55,
|
||||
VK_8 = 56,
|
||||
VK_9 = 57,
|
||||
VK_SEMICOLON = 59,
|
||||
VK_EQUALS = 61,
|
||||
VK_A = 65,
|
||||
VK_B = 66,
|
||||
VK_C = 67,
|
||||
VK_D = 68,
|
||||
VK_E = 69,
|
||||
VK_F = 70,
|
||||
VK_G = 71,
|
||||
VK_H = 72,
|
||||
VK_I = 73,
|
||||
VK_J = 74,
|
||||
VK_K = 75,
|
||||
VK_L = 76,
|
||||
VK_M = 77,
|
||||
VK_N = 78,
|
||||
VK_O = 79,
|
||||
VK_P = 80,
|
||||
VK_Q = 81,
|
||||
VK_R = 82,
|
||||
VK_S = 83,
|
||||
VK_T = 84,
|
||||
VK_U = 85,
|
||||
VK_V = 86,
|
||||
VK_W = 87,
|
||||
VK_X = 88,
|
||||
VK_Y = 89,
|
||||
VK_Z = 90,
|
||||
VK_NUMPAD0 = 96,
|
||||
VK_NUMPAD1 = 97,
|
||||
VK_NUMPAD2 = 98,
|
||||
VK_NUMPAD3 = 99,
|
||||
VK_NUMPAD4 = 100,
|
||||
VK_NUMPAD5 = 101,
|
||||
VK_NUMPAD6 = 102,
|
||||
VK_NUMPAD7 = 103,
|
||||
VK_NUMPAD8 = 104,
|
||||
VK_NUMPAD9 = 105,
|
||||
VK_MULTIPLY = 106,
|
||||
VK_ADD = 107,
|
||||
VK_SEPARATOR = 108,
|
||||
VK_SUBTRACT = 109,
|
||||
VK_DECIMAL = 110,
|
||||
VK_DIVIDE = 111,
|
||||
VK_F1 = 112,
|
||||
VK_F2 = 113,
|
||||
VK_F3 = 114,
|
||||
VK_F4 = 115,
|
||||
VK_F5 = 116,
|
||||
VK_F6 = 117,
|
||||
VK_F7 = 118,
|
||||
VK_F8 = 119,
|
||||
VK_F9 = 120,
|
||||
VK_F10 = 121,
|
||||
VK_F11 = 122,
|
||||
VK_F12 = 123,
|
||||
VK_F13 = 124,
|
||||
VK_F14 = 125,
|
||||
VK_F15 = 126,
|
||||
VK_F16 = 127,
|
||||
VK_F17 = 128,
|
||||
VK_F18 = 129,
|
||||
VK_F19 = 130,
|
||||
VK_F20 = 131,
|
||||
VK_F21 = 132,
|
||||
VK_F22 = 133,
|
||||
VK_F23 = 134,
|
||||
VK_F24 = 135,
|
||||
VK_NUM_LOCK = 144,
|
||||
VK_SCROLL_LOCK = 145,
|
||||
VK_COMMA = 188,
|
||||
VK_PERIOD = 190,
|
||||
VK_SLASH = 191,
|
||||
VK_BACK_QUOTE = 192,
|
||||
VK_OPEN_BRACKET = 219,
|
||||
VK_BACK_SLASH = 220,
|
||||
VK_CLOSE_BRACKET = 221,
|
||||
VK_QUOTE = 222
|
||||
};
|
||||
|
||||
PRUint32 nsXBLEventHandler::GetMatchingKeyCode(const nsString& aKeyName)
|
||||
{
|
||||
PRBool ret = PR_FALSE;
|
||||
|
||||
nsCAutoString keyName; keyName.AssignWithConversion(aKeyName);
|
||||
|
||||
if (keyName.EqualsIgnoreCase("VK_CANCEL"))
|
||||
return VK_CANCEL;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_BACK"))
|
||||
return VK_BACK;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_TAB"))
|
||||
return VK_TAB;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_CLEAR"))
|
||||
return VK_CLEAR;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_RETURN"))
|
||||
return VK_RETURN;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_ENTER"))
|
||||
return VK_ENTER;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_SHIFT"))
|
||||
return VK_SHIFT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_CONTROL"))
|
||||
return VK_CONTROL;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_ALT"))
|
||||
return VK_ALT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_PAUSE"))
|
||||
return VK_PAUSE;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_CAPS_LOCK"))
|
||||
return VK_CAPS_LOCK;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_ESCAPE"))
|
||||
return VK_ESCAPE;
|
||||
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_SPACE"))
|
||||
return VK_SPACE;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_PAGE_UP"))
|
||||
return VK_PAGE_UP;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_PAGE_DOWN"))
|
||||
return VK_PAGE_DOWN;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_END"))
|
||||
return VK_END;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_HOME"))
|
||||
return VK_HOME;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_LEFT"))
|
||||
return VK_LEFT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_UP"))
|
||||
return VK_UP;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_RIGHT"))
|
||||
return VK_RIGHT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_DOWN"))
|
||||
return VK_DOWN;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_PRINTSCREEN"))
|
||||
return VK_PRINTSCREEN;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_INSERT"))
|
||||
return VK_INSERT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_DELETE"))
|
||||
return VK_DELETE;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_0"))
|
||||
return VK_0;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_1"))
|
||||
return VK_1;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_2"))
|
||||
return VK_2;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_3"))
|
||||
return VK_3;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_4"))
|
||||
return VK_4;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_5"))
|
||||
return VK_5;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_6"))
|
||||
return VK_6;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_7"))
|
||||
return VK_7;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_8"))
|
||||
return VK_8;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_9"))
|
||||
return VK_9;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_SEMICOLON"))
|
||||
return VK_SEMICOLON;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_EQUALS"))
|
||||
return VK_EQUALS;
|
||||
if(keyName.EqualsIgnoreCase("VK_A"))
|
||||
return VK_A;
|
||||
if(keyName.EqualsIgnoreCase("VK_B"))
|
||||
return VK_B;
|
||||
if(keyName.EqualsIgnoreCase("VK_C"))
|
||||
return VK_C;
|
||||
if(keyName.EqualsIgnoreCase("VK_D"))
|
||||
return VK_D;
|
||||
if(keyName.EqualsIgnoreCase("VK_E"))
|
||||
return VK_E;
|
||||
if(keyName.EqualsIgnoreCase("VK_F"))
|
||||
return VK_F;
|
||||
if(keyName.EqualsIgnoreCase("VK_G"))
|
||||
return VK_G;
|
||||
if(keyName.EqualsIgnoreCase("VK_H"))
|
||||
return VK_H;
|
||||
if(keyName.EqualsIgnoreCase("VK_I"))
|
||||
return VK_I;
|
||||
if(keyName.EqualsIgnoreCase("VK_J"))
|
||||
return VK_J;
|
||||
if(keyName.EqualsIgnoreCase("VK_K"))
|
||||
return VK_K;
|
||||
if(keyName.EqualsIgnoreCase("VK_L"))
|
||||
return VK_L;
|
||||
if(keyName.EqualsIgnoreCase("VK_M"))
|
||||
return VK_M;
|
||||
if(keyName.EqualsIgnoreCase("VK_N"))
|
||||
return VK_N;
|
||||
if(keyName.EqualsIgnoreCase("VK_O"))
|
||||
return VK_O;
|
||||
if(keyName.EqualsIgnoreCase("VK_P"))
|
||||
return VK_P;
|
||||
if(keyName.EqualsIgnoreCase("VK_Q"))
|
||||
return VK_Q;
|
||||
if(keyName.EqualsIgnoreCase("VK_R"))
|
||||
return VK_R;
|
||||
if(keyName.EqualsIgnoreCase("VK_S"))
|
||||
return VK_S;
|
||||
if(keyName.EqualsIgnoreCase("VK_T"))
|
||||
return VK_T;
|
||||
if(keyName.EqualsIgnoreCase("VK_U"))
|
||||
return VK_U;
|
||||
if(keyName.EqualsIgnoreCase("VK_V"))
|
||||
return VK_V;
|
||||
if(keyName.EqualsIgnoreCase("VK_W"))
|
||||
return VK_W;
|
||||
if(keyName.EqualsIgnoreCase("VK_X"))
|
||||
return VK_X;
|
||||
if(keyName.EqualsIgnoreCase("VK_Y"))
|
||||
return VK_Y;
|
||||
if(keyName.EqualsIgnoreCase("VK_Z"))
|
||||
return VK_Z;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD0"))
|
||||
return VK_NUMPAD0;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD1"))
|
||||
return VK_NUMPAD1;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD2"))
|
||||
return VK_NUMPAD2;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD3"))
|
||||
return VK_NUMPAD3;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD4"))
|
||||
return VK_NUMPAD4;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD5"))
|
||||
return VK_NUMPAD5;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD6"))
|
||||
return VK_NUMPAD6;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD7"))
|
||||
return VK_NUMPAD7;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD8"))
|
||||
return VK_NUMPAD8;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD9"))
|
||||
return VK_NUMPAD9;
|
||||
if(keyName.EqualsIgnoreCase("VK_MULTIPLY"))
|
||||
return VK_MULTIPLY;
|
||||
if(keyName.EqualsIgnoreCase("VK_ADD"))
|
||||
return VK_ADD;
|
||||
if(keyName.EqualsIgnoreCase("VK_SEPARATOR"))
|
||||
return VK_SEPARATOR;
|
||||
if(keyName.EqualsIgnoreCase("VK_SUBTRACT"))
|
||||
return VK_SUBTRACT;
|
||||
if(keyName.EqualsIgnoreCase("VK_DECIMAL"))
|
||||
return VK_DECIMAL;
|
||||
if(keyName.EqualsIgnoreCase("VK_DIVIDE"))
|
||||
return VK_DIVIDE;
|
||||
if(keyName.EqualsIgnoreCase("VK_F1"))
|
||||
return VK_F1;
|
||||
if(keyName.EqualsIgnoreCase("VK_F2"))
|
||||
return VK_F2;
|
||||
if(keyName.EqualsIgnoreCase("VK_F3"))
|
||||
return VK_F3;
|
||||
if(keyName.EqualsIgnoreCase("VK_F4"))
|
||||
return VK_F4;
|
||||
if(keyName.EqualsIgnoreCase("VK_F5"))
|
||||
return VK_F5;
|
||||
if(keyName.EqualsIgnoreCase("VK_F6"))
|
||||
return VK_F6;
|
||||
if(keyName.EqualsIgnoreCase("VK_F7"))
|
||||
return VK_F7;
|
||||
if(keyName.EqualsIgnoreCase("VK_F8"))
|
||||
return VK_F8;
|
||||
if(keyName.EqualsIgnoreCase("VK_F9"))
|
||||
return VK_F9;
|
||||
if(keyName.EqualsIgnoreCase("VK_F10"))
|
||||
return VK_F10;
|
||||
if(keyName.EqualsIgnoreCase("VK_F11"))
|
||||
return VK_F11;
|
||||
if(keyName.EqualsIgnoreCase("VK_F12"))
|
||||
return VK_F12;
|
||||
if(keyName.EqualsIgnoreCase("VK_F13"))
|
||||
return VK_F13;
|
||||
if(keyName.EqualsIgnoreCase("VK_F14"))
|
||||
return VK_F14;
|
||||
if(keyName.EqualsIgnoreCase("VK_F15"))
|
||||
return VK_F15;
|
||||
if(keyName.EqualsIgnoreCase("VK_F16"))
|
||||
return VK_F16;
|
||||
if(keyName.EqualsIgnoreCase("VK_F17"))
|
||||
return VK_F17;
|
||||
if(keyName.EqualsIgnoreCase("VK_F18"))
|
||||
return VK_F18;
|
||||
if(keyName.EqualsIgnoreCase("VK_F19"))
|
||||
return VK_F19;
|
||||
if(keyName.EqualsIgnoreCase("VK_F20"))
|
||||
return VK_F20;
|
||||
if(keyName.EqualsIgnoreCase("VK_F21"))
|
||||
return VK_F21;
|
||||
if(keyName.EqualsIgnoreCase("VK_F22"))
|
||||
return VK_F22;
|
||||
if(keyName.EqualsIgnoreCase("VK_F23"))
|
||||
return VK_F23;
|
||||
if(keyName.EqualsIgnoreCase("VK_F24"))
|
||||
return VK_F24;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUM_LOCK"))
|
||||
return VK_NUM_LOCK;
|
||||
if(keyName.EqualsIgnoreCase("VK_SCROLL_LOCK"))
|
||||
return VK_SCROLL_LOCK;
|
||||
if(keyName.EqualsIgnoreCase("VK_COMMA"))
|
||||
return VK_COMMA;
|
||||
if(keyName.EqualsIgnoreCase("VK_PERIOD"))
|
||||
return VK_PERIOD;
|
||||
if(keyName.EqualsIgnoreCase("VK_SLASH"))
|
||||
return VK_SLASH;
|
||||
if(keyName.EqualsIgnoreCase("VK_BACK_QUOTE"))
|
||||
return VK_BACK_QUOTE;
|
||||
if(keyName.EqualsIgnoreCase("VK_OPEN_BRACKET"))
|
||||
return VK_OPEN_BRACKET;
|
||||
if(keyName.EqualsIgnoreCase("VK_BACK_SLASH"))
|
||||
return VK_BACK_SLASH;
|
||||
if(keyName.EqualsIgnoreCase("VK_CLOSE_BRACKET"))
|
||||
return VK_CLOSE_BRACKET;
|
||||
if(keyName.EqualsIgnoreCase("VK_QUOTE"))
|
||||
return VK_QUOTE;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXBLEventHandler::GetTextData(nsIContent *aParent, nsString& aResult)
|
||||
{
|
||||
|
@ -1038,117 +609,14 @@ nsXBLEventHandler::GetTextData(nsIContent *aParent, nsString& aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLEventHandler::ConstructMask()
|
||||
{
|
||||
mDetail = 0;
|
||||
mDetail2 = 0;
|
||||
mKeyMask = 0;
|
||||
|
||||
nsAutoString key;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kKeyAtom, key);
|
||||
if (key.IsEmpty())
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kCharCodeAtom, key);
|
||||
|
||||
if (!key.IsEmpty()) {
|
||||
// We have a charcode.
|
||||
mDetail2 = 1;
|
||||
mDetail = key[0];
|
||||
}
|
||||
else {
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kKeyCodeAtom, key);
|
||||
if (!key.IsEmpty())
|
||||
mDetail = GetMatchingKeyCode(key);
|
||||
}
|
||||
|
||||
nsAutoString buttonStr, clickCountStr;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kClickCountAtom, clickCountStr);
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kButtonAtom, buttonStr);
|
||||
|
||||
if (!buttonStr.IsEmpty()) {
|
||||
PRInt32 error;
|
||||
mDetail = buttonStr.ToInteger(&error);
|
||||
}
|
||||
|
||||
if (!clickCountStr.IsEmpty()) {
|
||||
PRInt32 error;
|
||||
mDetail2 = clickCountStr.ToInteger(&error);
|
||||
}
|
||||
|
||||
nsAutoString modifiers;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kModifiersAtom, modifiers);
|
||||
if (modifiers.IsEmpty())
|
||||
return;
|
||||
|
||||
char* str = modifiers.ToNewCString();
|
||||
char* newStr;
|
||||
char* token = nsCRT::strtok( str, ", ", &newStr );
|
||||
while( token != NULL ) {
|
||||
if (PL_strcmp(token, "shift") == 0)
|
||||
mKeyMask |= cShift;
|
||||
else if (PL_strcmp(token, "alt") == 0)
|
||||
mKeyMask |= cAlt;
|
||||
else if (PL_strcmp(token, "meta") == 0)
|
||||
mKeyMask |= cMeta;
|
||||
else if (PL_strcmp(token, "control") == 0)
|
||||
mKeyMask |= cControl;
|
||||
else if (PL_strcmp(token, "primary") == 0) {
|
||||
switch (kAccessKey)
|
||||
{
|
||||
case nsIDOMKeyEvent::DOM_VK_META:
|
||||
mKeyMask |= cMeta;
|
||||
break;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_ALT:
|
||||
mKeyMask |= cAlt;
|
||||
break;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_CONTROL:
|
||||
default:
|
||||
mKeyMask |= cControl;
|
||||
}
|
||||
}
|
||||
|
||||
token = nsCRT::strtok( newStr, ", ", &newStr );
|
||||
}
|
||||
|
||||
nsMemory::Free(str);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsXBLEventHandler::ModifiersMatchMask(nsIDOMUIEvent* aEvent)
|
||||
{
|
||||
nsCOMPtr<nsIDOMKeyEvent> key(do_QueryInterface(aEvent));
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouse(do_QueryInterface(aEvent));
|
||||
|
||||
PRBool keyPresent;
|
||||
key ? key->GetMetaKey(&keyPresent) : mouse->GetMetaKey(&keyPresent);
|
||||
if (keyPresent != ((mKeyMask & cMeta) != 0))
|
||||
return PR_FALSE;
|
||||
|
||||
key ? key->GetShiftKey(&keyPresent) : mouse->GetShiftKey(&keyPresent);
|
||||
if (keyPresent != ((mKeyMask & cShift) != 0))
|
||||
return PR_FALSE;
|
||||
|
||||
key ? key->GetAltKey(&keyPresent) : mouse->GetAltKey(&keyPresent);
|
||||
if (keyPresent != ((mKeyMask & cAlt) != 0))
|
||||
return PR_FALSE;
|
||||
|
||||
key ? key->GetCtrlKey(&keyPresent) : mouse->GetCtrlKey(&keyPresent);
|
||||
if (keyPresent != ((mKeyMask & cControl) != 0))
|
||||
return PR_FALSE;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
NS_NewXBLEventHandler(nsIDOMEventReceiver* aRec, nsIContent* aHandlerElement,
|
||||
NS_NewXBLEventHandler(nsIDOMEventReceiver* aRec, nsIXBLPrototypeHandler* aHandler,
|
||||
const nsString& aEventName,
|
||||
nsXBLEventHandler** aResult)
|
||||
{
|
||||
*aResult = new nsXBLEventHandler(aRec, aHandlerElement, aEventName);
|
||||
*aResult = new nsXBLEventHandler(aRec, aHandler, aEventName);
|
||||
if (!*aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aResult);
|
||||
|
|
|
@ -40,6 +40,7 @@ class nsIDOMKeyEvent;
|
|||
class nsIDOMMouseEvent;
|
||||
class nsIAtom;
|
||||
class nsIController;
|
||||
class nsIXBLPrototypeHandler;
|
||||
|
||||
class nsXBLEventHandler : public nsIDOMKeyListener,
|
||||
public nsIDOMMouseListener,
|
||||
|
@ -48,7 +49,7 @@ class nsXBLEventHandler : public nsIDOMKeyListener,
|
|||
public nsIDOMScrollListener
|
||||
{
|
||||
public:
|
||||
nsXBLEventHandler(nsIDOMEventReceiver* aReceiver, nsIContent* aHandlerElement, const nsString& aEventName);
|
||||
nsXBLEventHandler(nsIDOMEventReceiver* aReceiver, nsIXBLPrototypeHandler* aHandler, const nsString& aEventName);
|
||||
virtual ~nsXBLEventHandler();
|
||||
|
||||
NS_IMETHOD BindingAttached();
|
||||
|
@ -94,22 +95,13 @@ public:
|
|||
void RemoveEventHandlers();
|
||||
|
||||
void MarkForDeath() {
|
||||
if (mNextHandler) mNextHandler->MarkForDeath(); mHandlerElement = nsnull; mEventReceiver = nsnull;
|
||||
if (mNextHandler) mNextHandler->MarkForDeath(); mProtoHandler = nsnull; mEventReceiver = nsnull;
|
||||
}
|
||||
|
||||
protected:
|
||||
inline PRBool KeyEventMatched(nsIDOMKeyEvent* aKeyEvent);
|
||||
inline PRBool MouseEventMatched(nsIDOMMouseEvent* aMouseEvent);
|
||||
|
||||
inline PRUint32 GetMatchingKeyCode(const nsString& aKeyName);
|
||||
|
||||
NS_IMETHOD GetController(nsIController** aResult);
|
||||
|
||||
NS_IMETHOD ExecuteHandler(const nsAReadableString & aEventName, nsIDOMEvent* aEvent);
|
||||
|
||||
void ConstructMask();
|
||||
PRBool ModifiersMatchMask(nsIDOMUIEvent* aEvent);
|
||||
|
||||
static PRUint32 gRefCnt;
|
||||
static nsIAtom* kKeyAtom;
|
||||
static nsIAtom* kKeyCodeAtom;
|
||||
|
@ -122,36 +114,19 @@ protected:
|
|||
static nsIAtom* kBindingDetachedAtom;
|
||||
static nsIAtom* kModifiersAtom;
|
||||
|
||||
static PRInt32 kAccessKey;
|
||||
static void InitAccessKey();
|
||||
|
||||
static nsresult GetTextData(nsIContent *aParent, nsString& aResult);
|
||||
|
||||
static const PRInt32 cShift;
|
||||
static const PRInt32 cAlt;
|
||||
static const PRInt32 cControl;
|
||||
static const PRInt32 cMeta;
|
||||
|
||||
protected:
|
||||
nsIDOMEventReceiver* mEventReceiver; // Both of these refs are weak.
|
||||
nsIContent* mHandlerElement;
|
||||
nsIXBLPrototypeHandler* mProtoHandler;
|
||||
|
||||
nsAutoString mEventName;
|
||||
|
||||
PRInt32 mKeyMask; // Which modifier keys this event handler expects to have down
|
||||
// in order to be matched.
|
||||
|
||||
PRUint32 mDetail; // For key events, contains a charcode or keycode. For
|
||||
// mouse events, stores the button info.
|
||||
|
||||
PRInt32 mDetail2; // Miscellaneous extra information. For key events,
|
||||
// stores whether or not we're a key code or char code.
|
||||
// For mouse events, stores the clickCount.
|
||||
|
||||
nsXBLEventHandler* mNextHandler; // Handlers are chained for easy unloading later.
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
NS_NewXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsIContent* aHandlerElement,
|
||||
NS_NewXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsIXBLPrototypeHandler* aHandlerElement,
|
||||
const nsString& aEventName,
|
||||
nsXBLEventHandler** aResult);
|
||||
|
||||
|
|
|
@ -0,0 +1,719 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXBLPrototypeHandler.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIScriptObjectOwner.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIJSEventListener.h"
|
||||
#include "nsIController.h"
|
||||
#include "nsIControllers.h"
|
||||
#include "nsIDOMXULElement.h"
|
||||
#include "nsIDOMNSHTMLTextAreaElement.h"
|
||||
#include "nsIDOMNSHTMLInputElement.h"
|
||||
#include "nsIDOMText.h"
|
||||
#include "nsIEventListenerManager.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
||||
|
||||
PRUint32 nsXBLPrototypeHandler::gRefCnt = 0;
|
||||
nsIAtom* nsXBLPrototypeHandler::kKeyCodeAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kCharCodeAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kKeyAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kActionAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kCommandAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kClickCountAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kButtonAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kModifiersAtom = nsnull;
|
||||
|
||||
PRInt32 nsXBLPrototypeHandler::kAccessKey = -1;
|
||||
|
||||
const PRInt32 nsXBLPrototypeHandler::cShift = (1<<1);
|
||||
const PRInt32 nsXBLPrototypeHandler::cAlt = (1<<2);
|
||||
const PRInt32 nsXBLPrototypeHandler::cControl = (1<<3);
|
||||
const PRInt32 nsXBLPrototypeHandler::cMeta = (1<<4);
|
||||
|
||||
nsXBLPrototypeHandler::nsXBLPrototypeHandler(nsIContent* aHandlerElement)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mHandlerElement = aHandlerElement;
|
||||
gRefCnt++;
|
||||
if (gRefCnt == 1) {
|
||||
kKeyCodeAtom = NS_NewAtom("keycode");
|
||||
kKeyAtom = NS_NewAtom("key");
|
||||
kCharCodeAtom = NS_NewAtom("charcode");
|
||||
kModifiersAtom = NS_NewAtom("modifiers");
|
||||
kActionAtom = NS_NewAtom("action");
|
||||
kCommandAtom = NS_NewAtom("command");
|
||||
kClickCountAtom = NS_NewAtom("clickcount");
|
||||
kButtonAtom = NS_NewAtom("button");
|
||||
|
||||
// Get the primary accelerator key.
|
||||
InitAccessKey();
|
||||
}
|
||||
|
||||
// Make sure our mask is initialized.
|
||||
ConstructMask();
|
||||
}
|
||||
|
||||
nsXBLPrototypeHandler::~nsXBLPrototypeHandler()
|
||||
{
|
||||
gRefCnt--;
|
||||
if (gRefCnt == 0) {
|
||||
NS_RELEASE(kKeyAtom);
|
||||
NS_RELEASE(kKeyCodeAtom);
|
||||
NS_RELEASE(kCharCodeAtom);
|
||||
NS_RELEASE(kModifiersAtom);
|
||||
NS_RELEASE(kActionAtom);
|
||||
NS_RELEASE(kCommandAtom);
|
||||
NS_RELEASE(kButtonAtom);
|
||||
NS_RELEASE(kClickCountAtom);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXBLPrototypeHandler, nsIXBLPrototypeHandler)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeHandler::EventMatched(nsIDOMEvent* aEvent, PRBool* aResult)
|
||||
{
|
||||
nsCOMPtr<nsIDOMKeyEvent> key(do_QueryInterface(aEvent));
|
||||
if (key)
|
||||
*aResult = KeyEventMatched(key);
|
||||
else {
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouse(do_QueryInterface(aEvent));
|
||||
if (mouse)
|
||||
*aResult = MouseEventMatched(mouse);
|
||||
else *aResult = PR_TRUE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeHandler::GetHandlerElement(nsIContent** aResult)
|
||||
{
|
||||
*aResult = mHandlerElement;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeHandler::GetNextHandler(nsIXBLPrototypeHandler** aResult)
|
||||
{
|
||||
*aResult = mNextHandler;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeHandler::SetNextHandler(nsIXBLPrototypeHandler* aHandler)
|
||||
{
|
||||
mNextHandler = aHandler;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Get the menu access key from prefs.
|
||||
// XXX Eventually pick up using CSS3 key-equivalent property or somesuch
|
||||
void
|
||||
nsXBLPrototypeHandler::InitAccessKey()
|
||||
{
|
||||
if (kAccessKey >= 0)
|
||||
return;
|
||||
|
||||
// Compiled-in defaults, in case we can't get the pref --
|
||||
// mac doesn't have menu shortcuts, other platforms use alt.
|
||||
#ifndef XP_MAC
|
||||
kAccessKey = nsIDOMKeyEvent::DOM_VK_ALT;
|
||||
#else
|
||||
kAccessKey = 0;
|
||||
#endif
|
||||
|
||||
// Get the menu access key value from prefs, overriding the default:
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_PROGID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && prefs)
|
||||
{
|
||||
rv = prefs->GetIntPref("ui.key.menuAccessKey", &kAccessKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsXBLPrototypeHandler::KeyEventMatched(nsIDOMKeyEvent* aKeyEvent)
|
||||
{
|
||||
if (!mHandlerElement)
|
||||
return PR_FALSE;
|
||||
|
||||
if (mDetail == 0 && mDetail2 == 0 && mKeyMask == 0)
|
||||
return PR_TRUE; // No filters set up. It's generic.
|
||||
|
||||
// Get the keycode and charcode of the key event.
|
||||
PRUint32 keyCode, charCode;
|
||||
aKeyEvent->GetKeyCode(&keyCode);
|
||||
aKeyEvent->GetCharCode(&charCode);
|
||||
|
||||
PRBool keyMatched = (mDetail == (mDetail2 ? charCode : keyCode));
|
||||
|
||||
if (!keyMatched)
|
||||
return PR_FALSE;
|
||||
|
||||
// Now check modifier keys
|
||||
return ModifiersMatchMask(aKeyEvent);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsXBLPrototypeHandler::MouseEventMatched(nsIDOMMouseEvent* aMouseEvent)
|
||||
{
|
||||
if (!mHandlerElement)
|
||||
return PR_FALSE;
|
||||
|
||||
if (mDetail == 0 && mDetail2 == 0 && mKeyMask == 0)
|
||||
return PR_TRUE; // No filters set up. It's generic.
|
||||
|
||||
unsigned short button;
|
||||
aMouseEvent->GetButton(&button);
|
||||
if (mDetail != 0 && (button != mDetail))
|
||||
return PR_FALSE;
|
||||
|
||||
PRInt32 clickcount;
|
||||
aMouseEvent->GetDetail(&clickcount);
|
||||
if (mDetail2 != 0 && (clickcount != mDetail2))
|
||||
return PR_FALSE;
|
||||
|
||||
return ModifiersMatchMask(aMouseEvent);
|
||||
}
|
||||
|
||||
enum {
|
||||
VK_CANCEL = 3,
|
||||
VK_BACK = 8,
|
||||
VK_TAB = 9,
|
||||
VK_CLEAR = 12,
|
||||
VK_RETURN = 13,
|
||||
VK_ENTER = 14,
|
||||
VK_SHIFT = 16,
|
||||
VK_CONTROL = 17,
|
||||
VK_ALT = 18,
|
||||
VK_PAUSE = 19,
|
||||
VK_CAPS_LOCK = 20,
|
||||
VK_ESCAPE = 27,
|
||||
VK_SPACE = 32,
|
||||
VK_PAGE_UP = 33,
|
||||
VK_PAGE_DOWN = 34,
|
||||
VK_END = 35,
|
||||
VK_HOME = 36,
|
||||
VK_LEFT = 37,
|
||||
VK_UP = 38,
|
||||
VK_RIGHT = 39,
|
||||
VK_DOWN = 40,
|
||||
VK_PRINTSCREEN = 44,
|
||||
VK_INSERT = 45,
|
||||
VK_DELETE = 46,
|
||||
VK_0 = 48,
|
||||
VK_1 = 49,
|
||||
VK_2 = 50,
|
||||
VK_3 = 51,
|
||||
VK_4 = 52,
|
||||
VK_5 = 53,
|
||||
VK_6 = 54,
|
||||
VK_7 = 55,
|
||||
VK_8 = 56,
|
||||
VK_9 = 57,
|
||||
VK_SEMICOLON = 59,
|
||||
VK_EQUALS = 61,
|
||||
VK_A = 65,
|
||||
VK_B = 66,
|
||||
VK_C = 67,
|
||||
VK_D = 68,
|
||||
VK_E = 69,
|
||||
VK_F = 70,
|
||||
VK_G = 71,
|
||||
VK_H = 72,
|
||||
VK_I = 73,
|
||||
VK_J = 74,
|
||||
VK_K = 75,
|
||||
VK_L = 76,
|
||||
VK_M = 77,
|
||||
VK_N = 78,
|
||||
VK_O = 79,
|
||||
VK_P = 80,
|
||||
VK_Q = 81,
|
||||
VK_R = 82,
|
||||
VK_S = 83,
|
||||
VK_T = 84,
|
||||
VK_U = 85,
|
||||
VK_V = 86,
|
||||
VK_W = 87,
|
||||
VK_X = 88,
|
||||
VK_Y = 89,
|
||||
VK_Z = 90,
|
||||
VK_NUMPAD0 = 96,
|
||||
VK_NUMPAD1 = 97,
|
||||
VK_NUMPAD2 = 98,
|
||||
VK_NUMPAD3 = 99,
|
||||
VK_NUMPAD4 = 100,
|
||||
VK_NUMPAD5 = 101,
|
||||
VK_NUMPAD6 = 102,
|
||||
VK_NUMPAD7 = 103,
|
||||
VK_NUMPAD8 = 104,
|
||||
VK_NUMPAD9 = 105,
|
||||
VK_MULTIPLY = 106,
|
||||
VK_ADD = 107,
|
||||
VK_SEPARATOR = 108,
|
||||
VK_SUBTRACT = 109,
|
||||
VK_DECIMAL = 110,
|
||||
VK_DIVIDE = 111,
|
||||
VK_F1 = 112,
|
||||
VK_F2 = 113,
|
||||
VK_F3 = 114,
|
||||
VK_F4 = 115,
|
||||
VK_F5 = 116,
|
||||
VK_F6 = 117,
|
||||
VK_F7 = 118,
|
||||
VK_F8 = 119,
|
||||
VK_F9 = 120,
|
||||
VK_F10 = 121,
|
||||
VK_F11 = 122,
|
||||
VK_F12 = 123,
|
||||
VK_F13 = 124,
|
||||
VK_F14 = 125,
|
||||
VK_F15 = 126,
|
||||
VK_F16 = 127,
|
||||
VK_F17 = 128,
|
||||
VK_F18 = 129,
|
||||
VK_F19 = 130,
|
||||
VK_F20 = 131,
|
||||
VK_F21 = 132,
|
||||
VK_F22 = 133,
|
||||
VK_F23 = 134,
|
||||
VK_F24 = 135,
|
||||
VK_NUM_LOCK = 144,
|
||||
VK_SCROLL_LOCK = 145,
|
||||
VK_COMMA = 188,
|
||||
VK_PERIOD = 190,
|
||||
VK_SLASH = 191,
|
||||
VK_BACK_QUOTE = 192,
|
||||
VK_OPEN_BRACKET = 219,
|
||||
VK_BACK_SLASH = 220,
|
||||
VK_CLOSE_BRACKET = 221,
|
||||
VK_QUOTE = 222
|
||||
};
|
||||
|
||||
PRUint32 nsXBLPrototypeHandler::GetMatchingKeyCode(const nsString& aKeyName)
|
||||
{
|
||||
PRBool ret = PR_FALSE;
|
||||
|
||||
nsCAutoString keyName; keyName.AssignWithConversion(aKeyName);
|
||||
|
||||
if (keyName.EqualsIgnoreCase("VK_CANCEL"))
|
||||
return VK_CANCEL;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_BACK"))
|
||||
return VK_BACK;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_TAB"))
|
||||
return VK_TAB;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_CLEAR"))
|
||||
return VK_CLEAR;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_RETURN"))
|
||||
return VK_RETURN;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_ENTER"))
|
||||
return VK_ENTER;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_SHIFT"))
|
||||
return VK_SHIFT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_CONTROL"))
|
||||
return VK_CONTROL;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_ALT"))
|
||||
return VK_ALT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_PAUSE"))
|
||||
return VK_PAUSE;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_CAPS_LOCK"))
|
||||
return VK_CAPS_LOCK;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_ESCAPE"))
|
||||
return VK_ESCAPE;
|
||||
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_SPACE"))
|
||||
return VK_SPACE;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_PAGE_UP"))
|
||||
return VK_PAGE_UP;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_PAGE_DOWN"))
|
||||
return VK_PAGE_DOWN;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_END"))
|
||||
return VK_END;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_HOME"))
|
||||
return VK_HOME;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_LEFT"))
|
||||
return VK_LEFT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_UP"))
|
||||
return VK_UP;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_RIGHT"))
|
||||
return VK_RIGHT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_DOWN"))
|
||||
return VK_DOWN;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_PRINTSCREEN"))
|
||||
return VK_PRINTSCREEN;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_INSERT"))
|
||||
return VK_INSERT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_DELETE"))
|
||||
return VK_DELETE;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_0"))
|
||||
return VK_0;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_1"))
|
||||
return VK_1;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_2"))
|
||||
return VK_2;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_3"))
|
||||
return VK_3;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_4"))
|
||||
return VK_4;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_5"))
|
||||
return VK_5;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_6"))
|
||||
return VK_6;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_7"))
|
||||
return VK_7;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_8"))
|
||||
return VK_8;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_9"))
|
||||
return VK_9;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_SEMICOLON"))
|
||||
return VK_SEMICOLON;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_EQUALS"))
|
||||
return VK_EQUALS;
|
||||
if(keyName.EqualsIgnoreCase("VK_A"))
|
||||
return VK_A;
|
||||
if(keyName.EqualsIgnoreCase("VK_B"))
|
||||
return VK_B;
|
||||
if(keyName.EqualsIgnoreCase("VK_C"))
|
||||
return VK_C;
|
||||
if(keyName.EqualsIgnoreCase("VK_D"))
|
||||
return VK_D;
|
||||
if(keyName.EqualsIgnoreCase("VK_E"))
|
||||
return VK_E;
|
||||
if(keyName.EqualsIgnoreCase("VK_F"))
|
||||
return VK_F;
|
||||
if(keyName.EqualsIgnoreCase("VK_G"))
|
||||
return VK_G;
|
||||
if(keyName.EqualsIgnoreCase("VK_H"))
|
||||
return VK_H;
|
||||
if(keyName.EqualsIgnoreCase("VK_I"))
|
||||
return VK_I;
|
||||
if(keyName.EqualsIgnoreCase("VK_J"))
|
||||
return VK_J;
|
||||
if(keyName.EqualsIgnoreCase("VK_K"))
|
||||
return VK_K;
|
||||
if(keyName.EqualsIgnoreCase("VK_L"))
|
||||
return VK_L;
|
||||
if(keyName.EqualsIgnoreCase("VK_M"))
|
||||
return VK_M;
|
||||
if(keyName.EqualsIgnoreCase("VK_N"))
|
||||
return VK_N;
|
||||
if(keyName.EqualsIgnoreCase("VK_O"))
|
||||
return VK_O;
|
||||
if(keyName.EqualsIgnoreCase("VK_P"))
|
||||
return VK_P;
|
||||
if(keyName.EqualsIgnoreCase("VK_Q"))
|
||||
return VK_Q;
|
||||
if(keyName.EqualsIgnoreCase("VK_R"))
|
||||
return VK_R;
|
||||
if(keyName.EqualsIgnoreCase("VK_S"))
|
||||
return VK_S;
|
||||
if(keyName.EqualsIgnoreCase("VK_T"))
|
||||
return VK_T;
|
||||
if(keyName.EqualsIgnoreCase("VK_U"))
|
||||
return VK_U;
|
||||
if(keyName.EqualsIgnoreCase("VK_V"))
|
||||
return VK_V;
|
||||
if(keyName.EqualsIgnoreCase("VK_W"))
|
||||
return VK_W;
|
||||
if(keyName.EqualsIgnoreCase("VK_X"))
|
||||
return VK_X;
|
||||
if(keyName.EqualsIgnoreCase("VK_Y"))
|
||||
return VK_Y;
|
||||
if(keyName.EqualsIgnoreCase("VK_Z"))
|
||||
return VK_Z;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD0"))
|
||||
return VK_NUMPAD0;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD1"))
|
||||
return VK_NUMPAD1;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD2"))
|
||||
return VK_NUMPAD2;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD3"))
|
||||
return VK_NUMPAD3;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD4"))
|
||||
return VK_NUMPAD4;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD5"))
|
||||
return VK_NUMPAD5;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD6"))
|
||||
return VK_NUMPAD6;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD7"))
|
||||
return VK_NUMPAD7;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD8"))
|
||||
return VK_NUMPAD8;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD9"))
|
||||
return VK_NUMPAD9;
|
||||
if(keyName.EqualsIgnoreCase("VK_MULTIPLY"))
|
||||
return VK_MULTIPLY;
|
||||
if(keyName.EqualsIgnoreCase("VK_ADD"))
|
||||
return VK_ADD;
|
||||
if(keyName.EqualsIgnoreCase("VK_SEPARATOR"))
|
||||
return VK_SEPARATOR;
|
||||
if(keyName.EqualsIgnoreCase("VK_SUBTRACT"))
|
||||
return VK_SUBTRACT;
|
||||
if(keyName.EqualsIgnoreCase("VK_DECIMAL"))
|
||||
return VK_DECIMAL;
|
||||
if(keyName.EqualsIgnoreCase("VK_DIVIDE"))
|
||||
return VK_DIVIDE;
|
||||
if(keyName.EqualsIgnoreCase("VK_F1"))
|
||||
return VK_F1;
|
||||
if(keyName.EqualsIgnoreCase("VK_F2"))
|
||||
return VK_F2;
|
||||
if(keyName.EqualsIgnoreCase("VK_F3"))
|
||||
return VK_F3;
|
||||
if(keyName.EqualsIgnoreCase("VK_F4"))
|
||||
return VK_F4;
|
||||
if(keyName.EqualsIgnoreCase("VK_F5"))
|
||||
return VK_F5;
|
||||
if(keyName.EqualsIgnoreCase("VK_F6"))
|
||||
return VK_F6;
|
||||
if(keyName.EqualsIgnoreCase("VK_F7"))
|
||||
return VK_F7;
|
||||
if(keyName.EqualsIgnoreCase("VK_F8"))
|
||||
return VK_F8;
|
||||
if(keyName.EqualsIgnoreCase("VK_F9"))
|
||||
return VK_F9;
|
||||
if(keyName.EqualsIgnoreCase("VK_F10"))
|
||||
return VK_F10;
|
||||
if(keyName.EqualsIgnoreCase("VK_F11"))
|
||||
return VK_F11;
|
||||
if(keyName.EqualsIgnoreCase("VK_F12"))
|
||||
return VK_F12;
|
||||
if(keyName.EqualsIgnoreCase("VK_F13"))
|
||||
return VK_F13;
|
||||
if(keyName.EqualsIgnoreCase("VK_F14"))
|
||||
return VK_F14;
|
||||
if(keyName.EqualsIgnoreCase("VK_F15"))
|
||||
return VK_F15;
|
||||
if(keyName.EqualsIgnoreCase("VK_F16"))
|
||||
return VK_F16;
|
||||
if(keyName.EqualsIgnoreCase("VK_F17"))
|
||||
return VK_F17;
|
||||
if(keyName.EqualsIgnoreCase("VK_F18"))
|
||||
return VK_F18;
|
||||
if(keyName.EqualsIgnoreCase("VK_F19"))
|
||||
return VK_F19;
|
||||
if(keyName.EqualsIgnoreCase("VK_F20"))
|
||||
return VK_F20;
|
||||
if(keyName.EqualsIgnoreCase("VK_F21"))
|
||||
return VK_F21;
|
||||
if(keyName.EqualsIgnoreCase("VK_F22"))
|
||||
return VK_F22;
|
||||
if(keyName.EqualsIgnoreCase("VK_F23"))
|
||||
return VK_F23;
|
||||
if(keyName.EqualsIgnoreCase("VK_F24"))
|
||||
return VK_F24;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUM_LOCK"))
|
||||
return VK_NUM_LOCK;
|
||||
if(keyName.EqualsIgnoreCase("VK_SCROLL_LOCK"))
|
||||
return VK_SCROLL_LOCK;
|
||||
if(keyName.EqualsIgnoreCase("VK_COMMA"))
|
||||
return VK_COMMA;
|
||||
if(keyName.EqualsIgnoreCase("VK_PERIOD"))
|
||||
return VK_PERIOD;
|
||||
if(keyName.EqualsIgnoreCase("VK_SLASH"))
|
||||
return VK_SLASH;
|
||||
if(keyName.EqualsIgnoreCase("VK_BACK_QUOTE"))
|
||||
return VK_BACK_QUOTE;
|
||||
if(keyName.EqualsIgnoreCase("VK_OPEN_BRACKET"))
|
||||
return VK_OPEN_BRACKET;
|
||||
if(keyName.EqualsIgnoreCase("VK_BACK_SLASH"))
|
||||
return VK_BACK_SLASH;
|
||||
if(keyName.EqualsIgnoreCase("VK_CLOSE_BRACKET"))
|
||||
return VK_CLOSE_BRACKET;
|
||||
if(keyName.EqualsIgnoreCase("VK_QUOTE"))
|
||||
return VK_QUOTE;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLPrototypeHandler::ConstructMask()
|
||||
{
|
||||
mDetail = 0;
|
||||
mDetail2 = 0;
|
||||
mKeyMask = 0;
|
||||
|
||||
nsAutoString key;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kKeyAtom, key);
|
||||
if (key.IsEmpty())
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kCharCodeAtom, key);
|
||||
|
||||
if (!key.IsEmpty()) {
|
||||
// We have a charcode.
|
||||
mDetail2 = 1;
|
||||
mDetail = key[0];
|
||||
}
|
||||
else {
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kKeyCodeAtom, key);
|
||||
if (!key.IsEmpty())
|
||||
mDetail = GetMatchingKeyCode(key);
|
||||
}
|
||||
|
||||
nsAutoString buttonStr, clickCountStr;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kClickCountAtom, clickCountStr);
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kButtonAtom, buttonStr);
|
||||
|
||||
if (!buttonStr.IsEmpty()) {
|
||||
PRInt32 error;
|
||||
mDetail = buttonStr.ToInteger(&error);
|
||||
}
|
||||
|
||||
if (!clickCountStr.IsEmpty()) {
|
||||
PRInt32 error;
|
||||
mDetail2 = clickCountStr.ToInteger(&error);
|
||||
}
|
||||
|
||||
nsAutoString modifiers;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kModifiersAtom, modifiers);
|
||||
if (modifiers.IsEmpty())
|
||||
return;
|
||||
|
||||
char* str = modifiers.ToNewCString();
|
||||
char* newStr;
|
||||
char* token = nsCRT::strtok( str, ", ", &newStr );
|
||||
while( token != NULL ) {
|
||||
if (PL_strcmp(token, "shift") == 0)
|
||||
mKeyMask |= cShift;
|
||||
else if (PL_strcmp(token, "alt") == 0)
|
||||
mKeyMask |= cAlt;
|
||||
else if (PL_strcmp(token, "meta") == 0)
|
||||
mKeyMask |= cMeta;
|
||||
else if (PL_strcmp(token, "control") == 0)
|
||||
mKeyMask |= cControl;
|
||||
else if (PL_strcmp(token, "primary") == 0) {
|
||||
switch (kAccessKey)
|
||||
{
|
||||
case nsIDOMKeyEvent::DOM_VK_META:
|
||||
mKeyMask |= cMeta;
|
||||
break;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_ALT:
|
||||
mKeyMask |= cAlt;
|
||||
break;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_CONTROL:
|
||||
default:
|
||||
mKeyMask |= cControl;
|
||||
}
|
||||
}
|
||||
|
||||
token = nsCRT::strtok( newStr, ", ", &newStr );
|
||||
}
|
||||
|
||||
nsMemory::Free(str);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsXBLPrototypeHandler::ModifiersMatchMask(nsIDOMUIEvent* aEvent)
|
||||
{
|
||||
nsCOMPtr<nsIDOMKeyEvent> key(do_QueryInterface(aEvent));
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouse(do_QueryInterface(aEvent));
|
||||
|
||||
PRBool keyPresent;
|
||||
key ? key->GetMetaKey(&keyPresent) : mouse->GetMetaKey(&keyPresent);
|
||||
if (keyPresent != ((mKeyMask & cMeta) != 0))
|
||||
return PR_FALSE;
|
||||
|
||||
key ? key->GetShiftKey(&keyPresent) : mouse->GetShiftKey(&keyPresent);
|
||||
if (keyPresent != ((mKeyMask & cShift) != 0))
|
||||
return PR_FALSE;
|
||||
|
||||
key ? key->GetAltKey(&keyPresent) : mouse->GetAltKey(&keyPresent);
|
||||
if (keyPresent != ((mKeyMask & cAlt) != 0))
|
||||
return PR_FALSE;
|
||||
|
||||
key ? key->GetCtrlKey(&keyPresent) : mouse->GetCtrlKey(&keyPresent);
|
||||
if (keyPresent != ((mKeyMask & cControl) != 0))
|
||||
return PR_FALSE;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
NS_NewXBLPrototypeHandler(nsIContent* aHandlerElement, nsIXBLPrototypeHandler** aResult)
|
||||
{
|
||||
*aResult = new nsXBLPrototypeHandler(aHandlerElement);
|
||||
if (!*aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef nsXBLPrototypeHandler_h__
|
||||
#define nsXBLPrototypeHandler_h__
|
||||
|
||||
#include "nsIXBLPrototypeHandler.h"
|
||||
|
||||
class nsIXBLBinding;
|
||||
class nsIDOMEvent;
|
||||
class nsIContent;
|
||||
class nsIDOMUIEvent;
|
||||
class nsIDOMKeyEvent;
|
||||
class nsIDOMMouseEvent;
|
||||
class nsIAtom;
|
||||
class nsString;
|
||||
|
||||
class nsXBLPrototypeHandler : public nsIXBLPrototypeHandler
|
||||
{
|
||||
public:
|
||||
nsXBLPrototypeHandler(nsIContent* aHandlerElement);
|
||||
virtual ~nsXBLPrototypeHandler();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD EventMatched(nsIDOMEvent* aEvent, PRBool* aResult);
|
||||
NS_IMETHOD GetHandlerElement(nsIContent** aResult);
|
||||
|
||||
NS_IMETHOD GetNextHandler(nsIXBLPrototypeHandler** aResult);
|
||||
NS_IMETHOD SetNextHandler(nsIXBLPrototypeHandler* aHandler);
|
||||
|
||||
protected:
|
||||
inline PRUint32 GetMatchingKeyCode(const nsString& aKeyName);
|
||||
void ConstructMask();
|
||||
PRBool ModifiersMatchMask(nsIDOMUIEvent* aEvent);
|
||||
|
||||
inline PRBool KeyEventMatched(nsIDOMKeyEvent* aKeyEvent);
|
||||
inline PRBool MouseEventMatched(nsIDOMMouseEvent* aMouseEvent);
|
||||
|
||||
static PRUint32 gRefCnt;
|
||||
static nsIAtom* kKeyAtom;
|
||||
static nsIAtom* kKeyCodeAtom;
|
||||
static nsIAtom* kCharCodeAtom;
|
||||
static nsIAtom* kActionAtom;
|
||||
static nsIAtom* kCommandAtom;
|
||||
static nsIAtom* kClickCountAtom;
|
||||
static nsIAtom* kButtonAtom;
|
||||
static nsIAtom* kModifiersAtom;
|
||||
|
||||
static PRInt32 kAccessKey;
|
||||
static void InitAccessKey();
|
||||
|
||||
static const PRInt32 cShift;
|
||||
static const PRInt32 cAlt;
|
||||
static const PRInt32 cControl;
|
||||
static const PRInt32 cMeta;
|
||||
|
||||
protected:
|
||||
nsIContent* mHandlerElement; // This ref is weak.
|
||||
|
||||
PRInt32 mKeyMask; // Which modifier keys this event handler expects to have down
|
||||
// in order to be matched.
|
||||
|
||||
PRUint32 mDetail; // For key events, contains a charcode or keycode. For
|
||||
// mouse events, stores the button info.
|
||||
|
||||
PRInt32 mDetail2; // Miscellaneous extra information. For key events,
|
||||
// stores whether or not we're a key code or char code.
|
||||
// For mouse events, stores the clickCount.
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> mNextHandler; // Prototype handlers are chained. We own the next handler in the chain.
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
NS_NewXBLPrototypeHandler(nsIContent* aHandlerElement, nsIXBLPrototypeHandler** aResult);
|
||||
|
||||
#endif
|
|
@ -51,6 +51,8 @@
|
|||
#include "nsIXBLBinding.h"
|
||||
#include "nsIXBLDocumentInfo.h"
|
||||
|
||||
#include "nsIXBLPrototypeHandler.h"
|
||||
|
||||
#include "nsIChromeRegistry.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
|
@ -325,11 +327,18 @@ nsXBLStreamListener::Load(nsIDOMEvent* aEvent)
|
|||
nsCOMPtr<nsIContent> root = getter_AddRefs(mBindingDocument->GetRootContent());
|
||||
if (root)
|
||||
nsXBLService::StripWhitespaceNodes(root);
|
||||
else {
|
||||
NS_ERROR("*** XBL doc with no root element! Something went horribly wrong! ***");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Put our doc in the doc table.
|
||||
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||
NS_NewXBLDocumentInfo(mBindingDocument, getter_AddRefs(info));
|
||||
|
||||
// Construct our prototype handlers.
|
||||
nsXBLService::ConstructPrototypeHandlers(info);
|
||||
|
||||
// If the doc is a chrome URI, then we put it into the XUL cache.
|
||||
PRBool cached = PR_FALSE;
|
||||
if (IsChromeURI(uri) && gXULUtils->UseXULCache()) {
|
||||
|
@ -470,6 +479,7 @@ PRUint32 nsXBLService::gClassLRUListLength = 0;
|
|||
PRUint32 nsXBLService::gClassLRUListQuota = 64;
|
||||
|
||||
nsIAtom* nsXBLService::kExtendsAtom = nsnull;
|
||||
nsIAtom* nsXBLService::kHandlersAtom = nsnull;
|
||||
nsIAtom* nsXBLService::kScrollbarAtom = nsnull;
|
||||
nsIAtom* nsXBLService::kInputAtom = nsnull;
|
||||
|
||||
|
@ -509,6 +519,7 @@ nsXBLService::nsXBLService(void)
|
|||
|
||||
// Create our atoms
|
||||
kExtendsAtom = NS_NewAtom("extends");
|
||||
kHandlersAtom = NS_NewAtom("handlers");
|
||||
kScrollbarAtom = NS_NewAtom("scrollbar");
|
||||
kInputAtom = NS_NewAtom("input");
|
||||
|
||||
|
@ -544,6 +555,7 @@ nsXBLService::~nsXBLService(void)
|
|||
|
||||
// Release our atoms
|
||||
NS_RELEASE(kExtendsAtom);
|
||||
NS_RELEASE(kHandlersAtom);
|
||||
NS_RELEASE(kScrollbarAtom);
|
||||
NS_RELEASE(kInputAtom);
|
||||
|
||||
|
@ -999,6 +1011,9 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aB
|
|||
|
||||
if (document) {
|
||||
NS_NewXBLDocumentInfo(document, getter_AddRefs(info));
|
||||
|
||||
// Construct our prototype handlers.
|
||||
ConstructPrototypeHandlers(info);
|
||||
|
||||
// If the doc is a chrome URI, then we put it into the XUL cache.
|
||||
PRBool cached = PR_FALSE;
|
||||
|
@ -1183,6 +1198,74 @@ nsXBLService::StripWhitespaceNodes(nsIContent* aElement)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static void GetImmediateChild(nsIAtom* aTag, nsIContent* aParent, nsIContent** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
PRInt32 childCount;
|
||||
aParent->ChildCount(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
aParent->ChildAt(i, *getter_AddRefs(child));
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
child->GetTag(*getter_AddRefs(tag));
|
||||
if (aTag == tag.get()) {
|
||||
*aResult = child;
|
||||
NS_ADDREF(*aResult);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXBLService::ConstructPrototypeHandlers(nsIXBLDocumentInfo* aInfo)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aInfo->GetDocument(getter_AddRefs(doc));
|
||||
nsCOMPtr<nsIContent> bindings = getter_AddRefs(doc->GetRootContent());
|
||||
PRInt32 childCount;
|
||||
bindings->ChildCount(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIContent> binding;
|
||||
bindings->ChildAt(i, *getter_AddRefs(binding));
|
||||
|
||||
// See if this binding has a handler elt.
|
||||
nsCOMPtr<nsIContent> handlers;
|
||||
GetImmediateChild(kHandlersAtom, binding, getter_AddRefs(handlers));
|
||||
if (handlers) {
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> firstHandler;
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> currHandler;
|
||||
|
||||
PRInt32 handlerCount;
|
||||
handlers->ChildCount(handlerCount);
|
||||
for (PRInt32 j = 0; j < handlerCount; j++) {
|
||||
nsCOMPtr<nsIContent> handler;
|
||||
handlers->ChildAt(j, *getter_AddRefs(handler));
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> newHandler;
|
||||
NS_NewXBLPrototypeHandler(handler, getter_AddRefs(newHandler));
|
||||
if (newHandler) {
|
||||
if (currHandler)
|
||||
currHandler->SetNextHandler(newHandler);
|
||||
else firstHandler = newHandler;
|
||||
currHandler = newHandler;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstHandler) {
|
||||
nsAutoString ref;
|
||||
binding->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, ref);
|
||||
|
||||
nsCAutoString cref;
|
||||
cref.AssignWithConversion(ref);
|
||||
|
||||
aInfo->SetPrototypeHandler(cref, firstHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -96,6 +96,7 @@ public:
|
|||
// This method walks a binding document and removes any text nodes
|
||||
// that contain only whitespace.
|
||||
static nsresult StripWhitespaceNodes(nsIContent* aContent);
|
||||
static nsresult ConstructPrototypeHandlers(nsIXBLDocumentInfo* aInfo);
|
||||
|
||||
// MEMBER VARIABLES
|
||||
public:
|
||||
|
@ -117,7 +118,7 @@ public:
|
|||
|
||||
// XBL Atoms
|
||||
static nsIAtom* kExtendsAtom;
|
||||
|
||||
static nsIAtom* kHandlersAtom;
|
||||
static nsIAtom* kScrollbarAtom;
|
||||
static nsIAtom* kInputAtom;
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ EXPORTS = \
|
|||
nsIXBLBinding.h \
|
||||
nsIXBLBindingAttachedHandler.h \
|
||||
nsIXBLDocumentInfo.h \
|
||||
nsIXBLPrototypeHandler.h \
|
||||
nsIXBLService.h \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -2,5 +2,6 @@ nsIBindingManager.h
|
|||
nsIXBLBinding.h
|
||||
nsIXBLBindingAttachedHandler.h
|
||||
nsIXBLDocumentInfo.h
|
||||
nsIXBLPrototypeHandler.h
|
||||
nsIXBLService.h
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ EXPORTS = \
|
|||
nsIXBLBinding.h \
|
||||
nsIXBLBindingAttachedHandler.h \
|
||||
nsIXBLDocumentInfo.h \
|
||||
nsIXBLPrototypeHandler.h \
|
||||
nsIXBLService.h \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
class nsIContent;
|
||||
class nsIDocument;
|
||||
class nsIScriptContext;
|
||||
class nsIXBLPrototypeHandler;
|
||||
|
||||
// {5C4D9674-A2CF-4ddf-9F65-E1806C34D28D}
|
||||
#define NS_IXBLDOCUMENTINFO_IID \
|
||||
|
@ -54,6 +55,8 @@ public:
|
|||
NS_IMETHOD GetScriptAccess(PRBool* aResult)=0;
|
||||
NS_IMETHOD SetScriptAccess(PRBool aAccess)=0;
|
||||
|
||||
NS_IMETHOD GetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler** aResult)=0;
|
||||
NS_IMETHOD SetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler* aHandler)=0;
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Private interface to the XBL PrototypeHandler
|
||||
|
||||
*/
|
||||
|
||||
#ifndef nsIXBLPrototypeHandler_h__
|
||||
#define nsIXBLPrototypeHandler_h__
|
||||
|
||||
class nsIContent;
|
||||
class nsIDOMEvent;
|
||||
|
||||
// {921812E7-A044-4bd8-B49E-69BB0A607202}
|
||||
#define NS_IXBLPROTOTYPEHANDLER_IID \
|
||||
{ 0x921812e7, 0xa044, 0x4bd8, { 0xb4, 0x9e, 0x69, 0xbb, 0xa, 0x60, 0x72, 0x2 } }
|
||||
|
||||
class nsIXBLPrototypeHandler : public nsISupports
|
||||
{
|
||||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_IXBLPROTOTYPEHANDLER_IID; return iid; }
|
||||
|
||||
NS_IMETHOD EventMatched(nsIDOMEvent* aEvent, PRBool* aResult) = 0;
|
||||
NS_IMETHOD GetHandlerElement(nsIContent** aResult) = 0;
|
||||
|
||||
NS_IMETHOD GetNextHandler(nsIXBLPrototypeHandler** aResult) = 0;
|
||||
NS_IMETHOD SetNextHandler(nsIXBLPrototypeHandler* aHandler) = 0;
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
NS_NewXBLPrototypeHandler(nsIContent* aHandlerElement, nsIXBLPrototypeHandler** aResult);
|
||||
|
||||
#endif // nsIXBLPrototypeHandler_h__
|
|
@ -32,6 +32,7 @@ LIBRARY_NAME = gkxbl_s
|
|||
CPPSRCS = \
|
||||
nsXBLBinding.cpp \
|
||||
nsXBLEventHandler.cpp \
|
||||
nsXBLPrototypeHandler.cpp \
|
||||
nsXBLService.cpp \
|
||||
nsBindingManager.cpp \
|
||||
$(NULL)
|
||||
|
|
|
@ -30,12 +30,14 @@ CPPSRCS= \
|
|||
nsXBLBinding.cpp \
|
||||
nsXBLService.cpp \
|
||||
nsXBLEventHandler.cpp \
|
||||
nsXBLPrototypeHandler.cpp \
|
||||
nsBindingManager.cpp \
|
||||
$(NULL)
|
||||
|
||||
CPP_OBJS= \
|
||||
.\$(OBJDIR)\nsXBLBinding.obj \
|
||||
.\$(OBJDIR)\nsXBLEventHandler.obj \
|
||||
.\$(OBJDIR)\nsXBLPrototypeHandler.obj \
|
||||
.\$(OBJDIR)\nsXBLService.obj \
|
||||
.\$(OBJDIR)\nsBindingManager.obj \
|
||||
$(NULL)
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
|
||||
#include "nsIStyleRuleProcessor.h"
|
||||
#include "nsIStyleSet.h"
|
||||
#include "nsIXBLPrototypeHandler.h"
|
||||
|
||||
// Static IIDs/CIDs. Try to minimize these.
|
||||
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
|
||||
|
@ -78,10 +79,14 @@ public:
|
|||
NS_IMETHOD GetScriptAccess(PRBool* aResult) { *aResult = mScriptAccess; return NS_OK; };
|
||||
NS_IMETHOD SetScriptAccess(PRBool aAccess) { mScriptAccess = aAccess; return NS_OK; };
|
||||
|
||||
NS_IMETHOD GetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler** aResult);
|
||||
NS_IMETHOD SetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler* aHandler);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
nsCOMPtr<nsISupportsArray> mRuleProcessors;
|
||||
PRBool mScriptAccess;
|
||||
nsSupportsHashtable* mHandlerTable;
|
||||
};
|
||||
|
||||
/* Implementation file */
|
||||
|
@ -93,12 +98,13 @@ nsXBLDocumentInfo::nsXBLDocumentInfo(nsIDocument* aDocument)
|
|||
/* member initializers and constructor code */
|
||||
mDocument = aDocument;
|
||||
mScriptAccess = PR_TRUE;
|
||||
mHandlerTable = nsnull;
|
||||
}
|
||||
|
||||
nsXBLDocumentInfo::~nsXBLDocumentInfo()
|
||||
{
|
||||
/* destructor code */
|
||||
|
||||
delete mHandlerTable;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -136,7 +142,32 @@ nsXBLDocumentInfo::GetRuleProcessors(nsISupportsArray** aResult)
|
|||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLDocumentInfo::GetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
if (!mHandlerTable)
|
||||
return NS_OK;
|
||||
|
||||
nsCStringKey key(aRef);
|
||||
*aResult = NS_STATIC_CAST(nsIXBLPrototypeHandler*, mHandlerTable->Get(&key)); // Addref happens here.
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLDocumentInfo::SetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler* aHandler)
|
||||
{
|
||||
if (!mHandlerTable)
|
||||
mHandlerTable = new nsSupportsHashtable();
|
||||
|
||||
nsCStringKey key(aRef);
|
||||
mHandlerTable->Put(&key, aHandler);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NS_NewXBLDocumentInfo(nsIDocument* aDocument, nsIXBLDocumentInfo** aResult)
|
||||
{
|
||||
*aResult = new nsXBLDocumentInfo(aDocument);
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
#include "nsIDOMAttr.h"
|
||||
#include "nsIDOMNamedNodeMap.h"
|
||||
|
||||
#include "nsIXBLPrototypeHandler.h"
|
||||
#include "nsXBLEventHandler.h"
|
||||
#include "nsXBLBinding.h"
|
||||
|
||||
|
@ -573,112 +574,123 @@ nsXBLBinding::GenerateAnonymousContent(nsIContent* aBoundElement)
|
|||
NS_IMETHODIMP
|
||||
nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement, nsIXBLBinding** aBinding)
|
||||
{
|
||||
// Fetch the handlers element for this binding.
|
||||
nsCOMPtr<nsIContent> handlers;
|
||||
GetImmediateChild(kHandlersAtom, getter_AddRefs(handlers));
|
||||
// Don't install handlers if scripts aren't allowed.
|
||||
if (!AllowScripts())
|
||||
return NS_OK;
|
||||
|
||||
// Fetch the handlers prototypes for this binding.
|
||||
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||
gXBLService->GetXBLDocumentInfo(mDocURI, mBoundElement, getter_AddRefs(info));
|
||||
if (!info)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> handlerChain;
|
||||
info->GetPrototypeHandler(mID, getter_AddRefs(handlerChain));
|
||||
if (!handlerChain)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> curr = handlerChain;
|
||||
nsXBLEventHandler* currHandler = nsnull;
|
||||
if (handlers && AllowScripts()) {
|
||||
// Now walk the handlers and add event listeners to the bound
|
||||
// element.
|
||||
PRInt32 childCount;
|
||||
handlers->ChildCount(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
handlers->ChildAt(i, *getter_AddRefs(child));
|
||||
|
||||
// Fetch the type attribute.
|
||||
// XXX Deal with a comma-separated list of types
|
||||
nsAutoString type;
|
||||
child->GetAttribute(kNameSpaceID_None, kEventAtom, type);
|
||||
|
||||
if (!type.IsEmpty()) {
|
||||
nsIID iid;
|
||||
PRBool found = PR_FALSE;
|
||||
PRBool special = PR_FALSE;
|
||||
nsCOMPtr<nsIAtom> eventAtom = getter_AddRefs(NS_NewAtom(type));
|
||||
if (eventAtom.get() == kBindingAttachedAtom) {
|
||||
*aBinding = this;
|
||||
NS_ADDREF(*aBinding);
|
||||
special = PR_TRUE;
|
||||
while (curr) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
curr->GetHandlerElement(getter_AddRefs(child));
|
||||
|
||||
// Fetch the type attribute.
|
||||
// XXX Deal with a comma-separated list of types
|
||||
nsAutoString type;
|
||||
child->GetAttribute(kNameSpaceID_None, kEventAtom, type);
|
||||
|
||||
if (!type.IsEmpty()) {
|
||||
nsIID iid;
|
||||
PRBool found = PR_FALSE;
|
||||
PRBool special = PR_FALSE;
|
||||
nsCOMPtr<nsIAtom> eventAtom = getter_AddRefs(NS_NewAtom(type));
|
||||
if (eventAtom.get() == kBindingAttachedAtom) {
|
||||
*aBinding = this;
|
||||
NS_ADDREF(*aBinding);
|
||||
special = PR_TRUE;
|
||||
}
|
||||
else
|
||||
GetEventHandlerIID(eventAtom, &iid, &found);
|
||||
|
||||
if (found || special) {
|
||||
// Add an event listener for mouse and key events only.
|
||||
PRBool mouse = IsMouseHandler(type);
|
||||
PRBool key = IsKeyHandler(type);
|
||||
PRBool focus = IsFocusHandler(type);
|
||||
PRBool xul = IsXULHandler(type);
|
||||
PRBool scroll = IsScrollHandler(type);
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver = do_QueryInterface(mBoundElement);
|
||||
nsAutoString attachType;
|
||||
child->GetAttribute(kNameSpaceID_None, kAttachToAtom, attachType);
|
||||
if (attachType == NS_LITERAL_STRING("_document") ||
|
||||
attachType == NS_LITERAL_STRING("_window"))
|
||||
{
|
||||
nsCOMPtr<nsIDocument> boundDoc;
|
||||
mBoundElement->GetDocument(*getter_AddRefs(boundDoc));
|
||||
if (attachType == NS_LITERAL_STRING("_window")) {
|
||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||
boundDoc->GetScriptGlobalObject(getter_AddRefs(global));
|
||||
receiver = do_QueryInterface(global);
|
||||
}
|
||||
else receiver = do_QueryInterface(boundDoc);
|
||||
}
|
||||
else
|
||||
GetEventHandlerIID(eventAtom, &iid, &found);
|
||||
|
||||
if (found || special) {
|
||||
// Add an event listener for mouse and key events only.
|
||||
PRBool mouse = IsMouseHandler(type);
|
||||
PRBool key = IsKeyHandler(type);
|
||||
PRBool focus = IsFocusHandler(type);
|
||||
PRBool xul = IsXULHandler(type);
|
||||
PRBool scroll = IsScrollHandler(type);
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver = do_QueryInterface(mBoundElement);
|
||||
nsAutoString attachType;
|
||||
child->GetAttribute(kNameSpaceID_None, kAttachToAtom, attachType);
|
||||
if (attachType == NS_LITERAL_STRING("_document") ||
|
||||
attachType == NS_LITERAL_STRING("_window"))
|
||||
{
|
||||
nsCOMPtr<nsIDocument> boundDoc;
|
||||
mBoundElement->GetDocument(*getter_AddRefs(boundDoc));
|
||||
if (attachType == NS_LITERAL_STRING("_window")) {
|
||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||
boundDoc->GetScriptGlobalObject(getter_AddRefs(global));
|
||||
receiver = do_QueryInterface(global);
|
||||
}
|
||||
else receiver = do_QueryInterface(boundDoc);
|
||||
}
|
||||
if (mouse || key || focus || xul || scroll || special) {
|
||||
// Create a new nsXBLEventHandler.
|
||||
nsXBLEventHandler* handler;
|
||||
NS_NewXBLEventHandler(receiver, curr, type, &handler);
|
||||
|
||||
if (mouse || key || focus || xul || scroll || special) {
|
||||
// Create a new nsXBLEventHandler.
|
||||
nsXBLEventHandler* handler;
|
||||
NS_NewXBLEventHandler(receiver, child, type, &handler);
|
||||
// We chain all our event handlers together for easy
|
||||
// removal later (if/when the binding dies).
|
||||
if (!currHandler)
|
||||
mFirstHandler = handler;
|
||||
else
|
||||
currHandler->SetNextHandler(handler);
|
||||
|
||||
// We chain all our event handlers together for easy
|
||||
// removal later (if/when the binding dies).
|
||||
if (!currHandler)
|
||||
mFirstHandler = handler;
|
||||
else
|
||||
currHandler->SetNextHandler(handler);
|
||||
currHandler = handler;
|
||||
|
||||
currHandler = handler;
|
||||
// Figure out if we're using capturing or not.
|
||||
PRBool useCapture = PR_FALSE;
|
||||
nsAutoString capturer;
|
||||
child->GetAttribute(kNameSpaceID_None, kPhaseAtom, capturer);
|
||||
if (capturer == NS_LITERAL_STRING("capturing"))
|
||||
useCapture = PR_TRUE;
|
||||
|
||||
// Figure out if we're using capturing or not.
|
||||
PRBool useCapture = PR_FALSE;
|
||||
nsAutoString capturer;
|
||||
child->GetAttribute(kNameSpaceID_None, kPhaseAtom, capturer);
|
||||
if (capturer == NS_LITERAL_STRING("capturing"))
|
||||
useCapture = PR_TRUE;
|
||||
// Add the event listener.
|
||||
if (mouse)
|
||||
receiver->AddEventListener(type, (nsIDOMMouseListener*)handler, useCapture);
|
||||
else if(key)
|
||||
receiver->AddEventListener(type, (nsIDOMKeyListener*)handler, useCapture);
|
||||
else if(focus)
|
||||
receiver->AddEventListener(type, (nsIDOMFocusListener*)handler, useCapture);
|
||||
else if (xul)
|
||||
receiver->AddEventListener(type, (nsIDOMScrollListener*)handler, useCapture);
|
||||
else if (scroll)
|
||||
receiver->AddEventListener(type, (nsIDOMScrollListener*)handler, useCapture);
|
||||
|
||||
// Add the event listener.
|
||||
if (mouse)
|
||||
receiver->AddEventListener(type, (nsIDOMMouseListener*)handler, useCapture);
|
||||
else if(key)
|
||||
receiver->AddEventListener(type, (nsIDOMKeyListener*)handler, useCapture);
|
||||
else if(focus)
|
||||
receiver->AddEventListener(type, (nsIDOMFocusListener*)handler, useCapture);
|
||||
else if (xul)
|
||||
receiver->AddEventListener(type, (nsIDOMScrollListener*)handler, useCapture);
|
||||
else if (scroll)
|
||||
receiver->AddEventListener(type, (nsIDOMScrollListener*)handler, useCapture);
|
||||
if (!special) // Let the listener manager hold on to the handler.
|
||||
NS_RELEASE(handler);
|
||||
}
|
||||
else {
|
||||
// Call AddScriptEventListener for other IID types
|
||||
// XXX Want this to all go away!
|
||||
NS_WARNING("***** Non-compliant XBL event listener attached! *****");
|
||||
nsAutoString value;
|
||||
child->GetAttribute(kNameSpaceID_None, kActionAtom, value);
|
||||
if (value.IsEmpty())
|
||||
GetTextData(child, value);
|
||||
|
||||
if (!special) // Let the listener manager hold on to the handler.
|
||||
NS_RELEASE(handler);
|
||||
}
|
||||
else {
|
||||
// Call AddScriptEventListener for other IID types
|
||||
// XXX Want this to all go away!
|
||||
NS_WARNING("***** Non-compliant XBL event listener attached! *****");
|
||||
nsAutoString value;
|
||||
child->GetAttribute(kNameSpaceID_None, kActionAtom, value);
|
||||
if (value.IsEmpty())
|
||||
GetTextData(child, value);
|
||||
|
||||
AddScriptEventListener(mBoundElement, eventAtom, value, iid);
|
||||
}
|
||||
AddScriptEventListener(mBoundElement, eventAtom, value, iid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> next;
|
||||
curr->GetNextHandler(getter_AddRefs(next));
|
||||
curr = next;
|
||||
}
|
||||
|
||||
if (mNextBinding) {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIXBLPrototypeHandler.h"
|
||||
#include "nsXBLEventHandler.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIAtom.h"
|
||||
|
@ -63,19 +64,12 @@ nsIAtom* nsXBLEventHandler::kBindingAttachedAtom = nsnull;
|
|||
nsIAtom* nsXBLEventHandler::kBindingDetachedAtom = nsnull;
|
||||
nsIAtom* nsXBLEventHandler::kModifiersAtom = nsnull;
|
||||
|
||||
PRInt32 nsXBLEventHandler::kAccessKey = -1;
|
||||
|
||||
const PRInt32 nsXBLEventHandler::cShift = (1<<1);
|
||||
const PRInt32 nsXBLEventHandler::cAlt = (1<<2);
|
||||
const PRInt32 nsXBLEventHandler::cControl = (1<<3);
|
||||
const PRInt32 nsXBLEventHandler::cMeta = (1<<4);
|
||||
|
||||
nsXBLEventHandler::nsXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsIContent* aHandlerElement,
|
||||
nsXBLEventHandler::nsXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsIXBLPrototypeHandler* aHandler,
|
||||
const nsString& aEventName)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mEventReceiver = aEventReceiver;
|
||||
mHandlerElement = aHandlerElement;
|
||||
mProtoHandler = aHandler;
|
||||
mEventName.Assign(aEventName);
|
||||
mNextHandler = nsnull;
|
||||
gRefCnt++;
|
||||
|
@ -90,13 +84,7 @@ nsXBLEventHandler::nsXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsICon
|
|||
kButtonAtom = NS_NewAtom("button");
|
||||
kBindingAttachedAtom = NS_NewAtom("bindingattached");
|
||||
kBindingDetachedAtom = NS_NewAtom("bindingdetached");
|
||||
|
||||
// Get the primary accelerator key.
|
||||
InitAccessKey();
|
||||
}
|
||||
|
||||
// Make sure our mask is initialized.
|
||||
ConstructMask();
|
||||
}
|
||||
|
||||
nsXBLEventHandler::~nsXBLEventHandler()
|
||||
|
@ -166,6 +154,7 @@ nsXBLEventHandler::BindingAttached()
|
|||
NS_IMETHODIMP
|
||||
nsXBLEventHandler::BindingDetached()
|
||||
{
|
||||
// XXX Write me!!!!
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -180,8 +169,11 @@ nsresult nsXBLEventHandler::KeyUp(nsIDOMEvent* aKeyEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("keyup"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
|
||||
if (KeyEventMatched(keyEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aKeyEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("keyup"), aKeyEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -191,8 +183,11 @@ nsresult nsXBLEventHandler::KeyDown(nsIDOMEvent* aKeyEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("keydown"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
|
||||
if (KeyEventMatched(keyEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aKeyEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("keydown"), aKeyEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -202,8 +197,11 @@ nsresult nsXBLEventHandler::KeyPress(nsIDOMEvent* aKeyEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("keypress"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
|
||||
if (KeyEventMatched(keyEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aKeyEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("keypress"), aKeyEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -213,8 +211,11 @@ nsresult nsXBLEventHandler::MouseDown(nsIDOMEvent* aMouseEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("mousedown"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
if (MouseEventMatched(mouseEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aMouseEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("mousedown"), aMouseEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -224,8 +225,11 @@ nsresult nsXBLEventHandler::MouseUp(nsIDOMEvent* aMouseEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("mouseup"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
if (MouseEventMatched(mouseEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aMouseEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("mouseup"), aMouseEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -235,8 +239,11 @@ nsresult nsXBLEventHandler::MouseClick(nsIDOMEvent* aMouseEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("click"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
if (MouseEventMatched(mouseEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aMouseEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("click"), aMouseEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -246,8 +253,11 @@ nsresult nsXBLEventHandler::MouseDblClick(nsIDOMEvent* aMouseEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("dblclick"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
if (MouseEventMatched(mouseEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aMouseEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("dblclick"), aMouseEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -257,8 +267,11 @@ nsresult nsXBLEventHandler::MouseOver(nsIDOMEvent* aMouseEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("mouseover"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
if (MouseEventMatched(mouseEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aMouseEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("mouseover"), aMouseEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -268,8 +281,11 @@ nsresult nsXBLEventHandler::MouseOut(nsIDOMEvent* aMouseEvent)
|
|||
if (mEventName != NS_LITERAL_STRING("mouseout"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
if (MouseEventMatched(mouseEvent))
|
||||
PRBool matched = PR_FALSE;
|
||||
if (mProtoHandler)
|
||||
mProtoHandler->EventMatched(aMouseEvent, &matched);
|
||||
|
||||
if (matched)
|
||||
ExecuteHandler(NS_LITERAL_STRING("mouseout"), aMouseEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -375,88 +391,22 @@ nsresult nsXBLEventHandler::Destroy(nsIDOMEvent* aEvent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Get the menu access key from prefs.
|
||||
// XXX Eventually pick up using CSS3 key-equivalent property or somesuch
|
||||
void
|
||||
nsXBLEventHandler::InitAccessKey()
|
||||
{
|
||||
if (kAccessKey >= 0)
|
||||
return;
|
||||
|
||||
// Compiled-in defaults, in case we can't get the pref --
|
||||
// mac doesn't have menu shortcuts, other platforms use alt.
|
||||
#ifndef XP_MAC
|
||||
kAccessKey = nsIDOMKeyEvent::DOM_VK_ALT;
|
||||
#else
|
||||
kAccessKey = 0;
|
||||
#endif
|
||||
|
||||
// Get the menu access key value from prefs, overriding the default:
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_PROGID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && prefs)
|
||||
{
|
||||
rv = prefs->GetIntPref("ui.key.menuAccessKey", &kAccessKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsXBLEventHandler::KeyEventMatched(nsIDOMKeyEvent* aKeyEvent)
|
||||
{
|
||||
if (!mHandlerElement)
|
||||
return PR_FALSE;
|
||||
|
||||
if (mDetail == 0 && mDetail2 == 0 && mKeyMask == 0)
|
||||
return PR_TRUE; // No filters set up. It's generic.
|
||||
|
||||
// Get the keycode and charcode of the key event.
|
||||
PRUint32 keyCode, charCode;
|
||||
aKeyEvent->GetKeyCode(&keyCode);
|
||||
aKeyEvent->GetCharCode(&charCode);
|
||||
|
||||
PRBool keyMatched = (mDetail == (mDetail2 ? charCode : keyCode));
|
||||
|
||||
if (!keyMatched)
|
||||
return PR_FALSE;
|
||||
|
||||
// Now check modifier keys
|
||||
return ModifiersMatchMask(aKeyEvent);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsXBLEventHandler::MouseEventMatched(nsIDOMMouseEvent* aMouseEvent)
|
||||
{
|
||||
if (!mHandlerElement)
|
||||
return PR_FALSE;
|
||||
|
||||
if (mDetail == 0 && mDetail2 == 0 && mKeyMask == 0)
|
||||
return PR_TRUE; // No filters set up. It's generic.
|
||||
|
||||
unsigned short button;
|
||||
aMouseEvent->GetButton(&button);
|
||||
if (mDetail != 0 && (button != mDetail))
|
||||
return PR_FALSE;
|
||||
|
||||
PRInt32 clickcount;
|
||||
aMouseEvent->GetDetail(&clickcount);
|
||||
if (mDetail2 != 0 && (clickcount != mDetail2))
|
||||
return PR_FALSE;
|
||||
|
||||
return ModifiersMatchMask(aMouseEvent);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLEventHandler::ExecuteHandler(const nsAReadableString & aEventName, nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mHandlerElement)
|
||||
if (!mProtoHandler)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIContent> handlerElement;
|
||||
mProtoHandler->GetHandlerElement(getter_AddRefs(handlerElement));
|
||||
if (!handlerElement)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// 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);
|
||||
handlerElement->GetAttribute(kNameSpaceID_None, kCommandAtom, command);
|
||||
if (!command.IsEmpty()) {
|
||||
// We are the default action for this command.
|
||||
// Stop any other default action from executing.
|
||||
|
@ -493,10 +443,10 @@ nsXBLEventHandler::ExecuteHandler(const nsAReadableString & aEventName, nsIDOMEv
|
|||
|
||||
// Compile the event handler.
|
||||
nsAutoString handlerText;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kActionAtom, handlerText);
|
||||
handlerElement->GetAttribute(kNameSpaceID_None, kActionAtom, handlerText);
|
||||
if (handlerText.IsEmpty()) {
|
||||
// look to see if action content is contained by the handler element
|
||||
GetTextData(mHandlerElement, handlerText);
|
||||
GetTextData(handlerElement, handlerText);
|
||||
if (handlerText.IsEmpty())
|
||||
return NS_OK; // For whatever reason, they didn't give us anything to do.
|
||||
}
|
||||
|
@ -598,15 +548,22 @@ nsXBLEventHandler::RemoveEventHandlers()
|
|||
}
|
||||
|
||||
// Figure out if we're using capturing or not.
|
||||
if (!mProtoHandler)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIContent> handlerElement;
|
||||
mProtoHandler->GetHandlerElement(getter_AddRefs(handlerElement));
|
||||
if (!handlerElement)
|
||||
return;
|
||||
|
||||
PRBool useCapture = PR_FALSE;
|
||||
nsAutoString capturer;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, nsXBLBinding::kPhaseAtom, capturer);
|
||||
handlerElement->GetAttribute(kNameSpaceID_None, nsXBLBinding::kPhaseAtom, capturer);
|
||||
if (capturer == NS_LITERAL_STRING("capturing"))
|
||||
useCapture = PR_TRUE;
|
||||
|
||||
// XXX Will potentially be comma-separated
|
||||
nsAutoString type;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, nsXBLBinding::kEventAtom, type);
|
||||
handlerElement->GetAttribute(kNameSpaceID_None, nsXBLBinding::kEventAtom, type);
|
||||
|
||||
// Figure out our type.
|
||||
PRBool mouse = nsXBLBinding::IsMouseHandler(type);
|
||||
|
@ -630,392 +587,6 @@ nsXBLEventHandler::RemoveEventHandlers()
|
|||
|
||||
/// Helpers that are relegated to the end of the file /////////////////////////////
|
||||
|
||||
enum {
|
||||
VK_CANCEL = 3,
|
||||
VK_BACK = 8,
|
||||
VK_TAB = 9,
|
||||
VK_CLEAR = 12,
|
||||
VK_RETURN = 13,
|
||||
VK_ENTER = 14,
|
||||
VK_SHIFT = 16,
|
||||
VK_CONTROL = 17,
|
||||
VK_ALT = 18,
|
||||
VK_PAUSE = 19,
|
||||
VK_CAPS_LOCK = 20,
|
||||
VK_ESCAPE = 27,
|
||||
VK_SPACE = 32,
|
||||
VK_PAGE_UP = 33,
|
||||
VK_PAGE_DOWN = 34,
|
||||
VK_END = 35,
|
||||
VK_HOME = 36,
|
||||
VK_LEFT = 37,
|
||||
VK_UP = 38,
|
||||
VK_RIGHT = 39,
|
||||
VK_DOWN = 40,
|
||||
VK_PRINTSCREEN = 44,
|
||||
VK_INSERT = 45,
|
||||
VK_DELETE = 46,
|
||||
VK_0 = 48,
|
||||
VK_1 = 49,
|
||||
VK_2 = 50,
|
||||
VK_3 = 51,
|
||||
VK_4 = 52,
|
||||
VK_5 = 53,
|
||||
VK_6 = 54,
|
||||
VK_7 = 55,
|
||||
VK_8 = 56,
|
||||
VK_9 = 57,
|
||||
VK_SEMICOLON = 59,
|
||||
VK_EQUALS = 61,
|
||||
VK_A = 65,
|
||||
VK_B = 66,
|
||||
VK_C = 67,
|
||||
VK_D = 68,
|
||||
VK_E = 69,
|
||||
VK_F = 70,
|
||||
VK_G = 71,
|
||||
VK_H = 72,
|
||||
VK_I = 73,
|
||||
VK_J = 74,
|
||||
VK_K = 75,
|
||||
VK_L = 76,
|
||||
VK_M = 77,
|
||||
VK_N = 78,
|
||||
VK_O = 79,
|
||||
VK_P = 80,
|
||||
VK_Q = 81,
|
||||
VK_R = 82,
|
||||
VK_S = 83,
|
||||
VK_T = 84,
|
||||
VK_U = 85,
|
||||
VK_V = 86,
|
||||
VK_W = 87,
|
||||
VK_X = 88,
|
||||
VK_Y = 89,
|
||||
VK_Z = 90,
|
||||
VK_NUMPAD0 = 96,
|
||||
VK_NUMPAD1 = 97,
|
||||
VK_NUMPAD2 = 98,
|
||||
VK_NUMPAD3 = 99,
|
||||
VK_NUMPAD4 = 100,
|
||||
VK_NUMPAD5 = 101,
|
||||
VK_NUMPAD6 = 102,
|
||||
VK_NUMPAD7 = 103,
|
||||
VK_NUMPAD8 = 104,
|
||||
VK_NUMPAD9 = 105,
|
||||
VK_MULTIPLY = 106,
|
||||
VK_ADD = 107,
|
||||
VK_SEPARATOR = 108,
|
||||
VK_SUBTRACT = 109,
|
||||
VK_DECIMAL = 110,
|
||||
VK_DIVIDE = 111,
|
||||
VK_F1 = 112,
|
||||
VK_F2 = 113,
|
||||
VK_F3 = 114,
|
||||
VK_F4 = 115,
|
||||
VK_F5 = 116,
|
||||
VK_F6 = 117,
|
||||
VK_F7 = 118,
|
||||
VK_F8 = 119,
|
||||
VK_F9 = 120,
|
||||
VK_F10 = 121,
|
||||
VK_F11 = 122,
|
||||
VK_F12 = 123,
|
||||
VK_F13 = 124,
|
||||
VK_F14 = 125,
|
||||
VK_F15 = 126,
|
||||
VK_F16 = 127,
|
||||
VK_F17 = 128,
|
||||
VK_F18 = 129,
|
||||
VK_F19 = 130,
|
||||
VK_F20 = 131,
|
||||
VK_F21 = 132,
|
||||
VK_F22 = 133,
|
||||
VK_F23 = 134,
|
||||
VK_F24 = 135,
|
||||
VK_NUM_LOCK = 144,
|
||||
VK_SCROLL_LOCK = 145,
|
||||
VK_COMMA = 188,
|
||||
VK_PERIOD = 190,
|
||||
VK_SLASH = 191,
|
||||
VK_BACK_QUOTE = 192,
|
||||
VK_OPEN_BRACKET = 219,
|
||||
VK_BACK_SLASH = 220,
|
||||
VK_CLOSE_BRACKET = 221,
|
||||
VK_QUOTE = 222
|
||||
};
|
||||
|
||||
PRUint32 nsXBLEventHandler::GetMatchingKeyCode(const nsString& aKeyName)
|
||||
{
|
||||
PRBool ret = PR_FALSE;
|
||||
|
||||
nsCAutoString keyName; keyName.AssignWithConversion(aKeyName);
|
||||
|
||||
if (keyName.EqualsIgnoreCase("VK_CANCEL"))
|
||||
return VK_CANCEL;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_BACK"))
|
||||
return VK_BACK;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_TAB"))
|
||||
return VK_TAB;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_CLEAR"))
|
||||
return VK_CLEAR;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_RETURN"))
|
||||
return VK_RETURN;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_ENTER"))
|
||||
return VK_ENTER;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_SHIFT"))
|
||||
return VK_SHIFT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_CONTROL"))
|
||||
return VK_CONTROL;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_ALT"))
|
||||
return VK_ALT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_PAUSE"))
|
||||
return VK_PAUSE;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_CAPS_LOCK"))
|
||||
return VK_CAPS_LOCK;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_ESCAPE"))
|
||||
return VK_ESCAPE;
|
||||
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_SPACE"))
|
||||
return VK_SPACE;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_PAGE_UP"))
|
||||
return VK_PAGE_UP;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_PAGE_DOWN"))
|
||||
return VK_PAGE_DOWN;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_END"))
|
||||
return VK_END;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_HOME"))
|
||||
return VK_HOME;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_LEFT"))
|
||||
return VK_LEFT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_UP"))
|
||||
return VK_UP;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_RIGHT"))
|
||||
return VK_RIGHT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_DOWN"))
|
||||
return VK_DOWN;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_PRINTSCREEN"))
|
||||
return VK_PRINTSCREEN;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_INSERT"))
|
||||
return VK_INSERT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_DELETE"))
|
||||
return VK_DELETE;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_0"))
|
||||
return VK_0;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_1"))
|
||||
return VK_1;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_2"))
|
||||
return VK_2;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_3"))
|
||||
return VK_3;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_4"))
|
||||
return VK_4;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_5"))
|
||||
return VK_5;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_6"))
|
||||
return VK_6;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_7"))
|
||||
return VK_7;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_8"))
|
||||
return VK_8;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_9"))
|
||||
return VK_9;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_SEMICOLON"))
|
||||
return VK_SEMICOLON;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_EQUALS"))
|
||||
return VK_EQUALS;
|
||||
if(keyName.EqualsIgnoreCase("VK_A"))
|
||||
return VK_A;
|
||||
if(keyName.EqualsIgnoreCase("VK_B"))
|
||||
return VK_B;
|
||||
if(keyName.EqualsIgnoreCase("VK_C"))
|
||||
return VK_C;
|
||||
if(keyName.EqualsIgnoreCase("VK_D"))
|
||||
return VK_D;
|
||||
if(keyName.EqualsIgnoreCase("VK_E"))
|
||||
return VK_E;
|
||||
if(keyName.EqualsIgnoreCase("VK_F"))
|
||||
return VK_F;
|
||||
if(keyName.EqualsIgnoreCase("VK_G"))
|
||||
return VK_G;
|
||||
if(keyName.EqualsIgnoreCase("VK_H"))
|
||||
return VK_H;
|
||||
if(keyName.EqualsIgnoreCase("VK_I"))
|
||||
return VK_I;
|
||||
if(keyName.EqualsIgnoreCase("VK_J"))
|
||||
return VK_J;
|
||||
if(keyName.EqualsIgnoreCase("VK_K"))
|
||||
return VK_K;
|
||||
if(keyName.EqualsIgnoreCase("VK_L"))
|
||||
return VK_L;
|
||||
if(keyName.EqualsIgnoreCase("VK_M"))
|
||||
return VK_M;
|
||||
if(keyName.EqualsIgnoreCase("VK_N"))
|
||||
return VK_N;
|
||||
if(keyName.EqualsIgnoreCase("VK_O"))
|
||||
return VK_O;
|
||||
if(keyName.EqualsIgnoreCase("VK_P"))
|
||||
return VK_P;
|
||||
if(keyName.EqualsIgnoreCase("VK_Q"))
|
||||
return VK_Q;
|
||||
if(keyName.EqualsIgnoreCase("VK_R"))
|
||||
return VK_R;
|
||||
if(keyName.EqualsIgnoreCase("VK_S"))
|
||||
return VK_S;
|
||||
if(keyName.EqualsIgnoreCase("VK_T"))
|
||||
return VK_T;
|
||||
if(keyName.EqualsIgnoreCase("VK_U"))
|
||||
return VK_U;
|
||||
if(keyName.EqualsIgnoreCase("VK_V"))
|
||||
return VK_V;
|
||||
if(keyName.EqualsIgnoreCase("VK_W"))
|
||||
return VK_W;
|
||||
if(keyName.EqualsIgnoreCase("VK_X"))
|
||||
return VK_X;
|
||||
if(keyName.EqualsIgnoreCase("VK_Y"))
|
||||
return VK_Y;
|
||||
if(keyName.EqualsIgnoreCase("VK_Z"))
|
||||
return VK_Z;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD0"))
|
||||
return VK_NUMPAD0;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD1"))
|
||||
return VK_NUMPAD1;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD2"))
|
||||
return VK_NUMPAD2;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD3"))
|
||||
return VK_NUMPAD3;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD4"))
|
||||
return VK_NUMPAD4;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD5"))
|
||||
return VK_NUMPAD5;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD6"))
|
||||
return VK_NUMPAD6;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD7"))
|
||||
return VK_NUMPAD7;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD8"))
|
||||
return VK_NUMPAD8;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD9"))
|
||||
return VK_NUMPAD9;
|
||||
if(keyName.EqualsIgnoreCase("VK_MULTIPLY"))
|
||||
return VK_MULTIPLY;
|
||||
if(keyName.EqualsIgnoreCase("VK_ADD"))
|
||||
return VK_ADD;
|
||||
if(keyName.EqualsIgnoreCase("VK_SEPARATOR"))
|
||||
return VK_SEPARATOR;
|
||||
if(keyName.EqualsIgnoreCase("VK_SUBTRACT"))
|
||||
return VK_SUBTRACT;
|
||||
if(keyName.EqualsIgnoreCase("VK_DECIMAL"))
|
||||
return VK_DECIMAL;
|
||||
if(keyName.EqualsIgnoreCase("VK_DIVIDE"))
|
||||
return VK_DIVIDE;
|
||||
if(keyName.EqualsIgnoreCase("VK_F1"))
|
||||
return VK_F1;
|
||||
if(keyName.EqualsIgnoreCase("VK_F2"))
|
||||
return VK_F2;
|
||||
if(keyName.EqualsIgnoreCase("VK_F3"))
|
||||
return VK_F3;
|
||||
if(keyName.EqualsIgnoreCase("VK_F4"))
|
||||
return VK_F4;
|
||||
if(keyName.EqualsIgnoreCase("VK_F5"))
|
||||
return VK_F5;
|
||||
if(keyName.EqualsIgnoreCase("VK_F6"))
|
||||
return VK_F6;
|
||||
if(keyName.EqualsIgnoreCase("VK_F7"))
|
||||
return VK_F7;
|
||||
if(keyName.EqualsIgnoreCase("VK_F8"))
|
||||
return VK_F8;
|
||||
if(keyName.EqualsIgnoreCase("VK_F9"))
|
||||
return VK_F9;
|
||||
if(keyName.EqualsIgnoreCase("VK_F10"))
|
||||
return VK_F10;
|
||||
if(keyName.EqualsIgnoreCase("VK_F11"))
|
||||
return VK_F11;
|
||||
if(keyName.EqualsIgnoreCase("VK_F12"))
|
||||
return VK_F12;
|
||||
if(keyName.EqualsIgnoreCase("VK_F13"))
|
||||
return VK_F13;
|
||||
if(keyName.EqualsIgnoreCase("VK_F14"))
|
||||
return VK_F14;
|
||||
if(keyName.EqualsIgnoreCase("VK_F15"))
|
||||
return VK_F15;
|
||||
if(keyName.EqualsIgnoreCase("VK_F16"))
|
||||
return VK_F16;
|
||||
if(keyName.EqualsIgnoreCase("VK_F17"))
|
||||
return VK_F17;
|
||||
if(keyName.EqualsIgnoreCase("VK_F18"))
|
||||
return VK_F18;
|
||||
if(keyName.EqualsIgnoreCase("VK_F19"))
|
||||
return VK_F19;
|
||||
if(keyName.EqualsIgnoreCase("VK_F20"))
|
||||
return VK_F20;
|
||||
if(keyName.EqualsIgnoreCase("VK_F21"))
|
||||
return VK_F21;
|
||||
if(keyName.EqualsIgnoreCase("VK_F22"))
|
||||
return VK_F22;
|
||||
if(keyName.EqualsIgnoreCase("VK_F23"))
|
||||
return VK_F23;
|
||||
if(keyName.EqualsIgnoreCase("VK_F24"))
|
||||
return VK_F24;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUM_LOCK"))
|
||||
return VK_NUM_LOCK;
|
||||
if(keyName.EqualsIgnoreCase("VK_SCROLL_LOCK"))
|
||||
return VK_SCROLL_LOCK;
|
||||
if(keyName.EqualsIgnoreCase("VK_COMMA"))
|
||||
return VK_COMMA;
|
||||
if(keyName.EqualsIgnoreCase("VK_PERIOD"))
|
||||
return VK_PERIOD;
|
||||
if(keyName.EqualsIgnoreCase("VK_SLASH"))
|
||||
return VK_SLASH;
|
||||
if(keyName.EqualsIgnoreCase("VK_BACK_QUOTE"))
|
||||
return VK_BACK_QUOTE;
|
||||
if(keyName.EqualsIgnoreCase("VK_OPEN_BRACKET"))
|
||||
return VK_OPEN_BRACKET;
|
||||
if(keyName.EqualsIgnoreCase("VK_BACK_SLASH"))
|
||||
return VK_BACK_SLASH;
|
||||
if(keyName.EqualsIgnoreCase("VK_CLOSE_BRACKET"))
|
||||
return VK_CLOSE_BRACKET;
|
||||
if(keyName.EqualsIgnoreCase("VK_QUOTE"))
|
||||
return VK_QUOTE;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXBLEventHandler::GetTextData(nsIContent *aParent, nsString& aResult)
|
||||
{
|
||||
|
@ -1038,117 +609,14 @@ nsXBLEventHandler::GetTextData(nsIContent *aParent, nsString& aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLEventHandler::ConstructMask()
|
||||
{
|
||||
mDetail = 0;
|
||||
mDetail2 = 0;
|
||||
mKeyMask = 0;
|
||||
|
||||
nsAutoString key;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kKeyAtom, key);
|
||||
if (key.IsEmpty())
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kCharCodeAtom, key);
|
||||
|
||||
if (!key.IsEmpty()) {
|
||||
// We have a charcode.
|
||||
mDetail2 = 1;
|
||||
mDetail = key[0];
|
||||
}
|
||||
else {
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kKeyCodeAtom, key);
|
||||
if (!key.IsEmpty())
|
||||
mDetail = GetMatchingKeyCode(key);
|
||||
}
|
||||
|
||||
nsAutoString buttonStr, clickCountStr;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kClickCountAtom, clickCountStr);
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kButtonAtom, buttonStr);
|
||||
|
||||
if (!buttonStr.IsEmpty()) {
|
||||
PRInt32 error;
|
||||
mDetail = buttonStr.ToInteger(&error);
|
||||
}
|
||||
|
||||
if (!clickCountStr.IsEmpty()) {
|
||||
PRInt32 error;
|
||||
mDetail2 = clickCountStr.ToInteger(&error);
|
||||
}
|
||||
|
||||
nsAutoString modifiers;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kModifiersAtom, modifiers);
|
||||
if (modifiers.IsEmpty())
|
||||
return;
|
||||
|
||||
char* str = modifiers.ToNewCString();
|
||||
char* newStr;
|
||||
char* token = nsCRT::strtok( str, ", ", &newStr );
|
||||
while( token != NULL ) {
|
||||
if (PL_strcmp(token, "shift") == 0)
|
||||
mKeyMask |= cShift;
|
||||
else if (PL_strcmp(token, "alt") == 0)
|
||||
mKeyMask |= cAlt;
|
||||
else if (PL_strcmp(token, "meta") == 0)
|
||||
mKeyMask |= cMeta;
|
||||
else if (PL_strcmp(token, "control") == 0)
|
||||
mKeyMask |= cControl;
|
||||
else if (PL_strcmp(token, "primary") == 0) {
|
||||
switch (kAccessKey)
|
||||
{
|
||||
case nsIDOMKeyEvent::DOM_VK_META:
|
||||
mKeyMask |= cMeta;
|
||||
break;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_ALT:
|
||||
mKeyMask |= cAlt;
|
||||
break;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_CONTROL:
|
||||
default:
|
||||
mKeyMask |= cControl;
|
||||
}
|
||||
}
|
||||
|
||||
token = nsCRT::strtok( newStr, ", ", &newStr );
|
||||
}
|
||||
|
||||
nsMemory::Free(str);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsXBLEventHandler::ModifiersMatchMask(nsIDOMUIEvent* aEvent)
|
||||
{
|
||||
nsCOMPtr<nsIDOMKeyEvent> key(do_QueryInterface(aEvent));
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouse(do_QueryInterface(aEvent));
|
||||
|
||||
PRBool keyPresent;
|
||||
key ? key->GetMetaKey(&keyPresent) : mouse->GetMetaKey(&keyPresent);
|
||||
if (keyPresent != ((mKeyMask & cMeta) != 0))
|
||||
return PR_FALSE;
|
||||
|
||||
key ? key->GetShiftKey(&keyPresent) : mouse->GetShiftKey(&keyPresent);
|
||||
if (keyPresent != ((mKeyMask & cShift) != 0))
|
||||
return PR_FALSE;
|
||||
|
||||
key ? key->GetAltKey(&keyPresent) : mouse->GetAltKey(&keyPresent);
|
||||
if (keyPresent != ((mKeyMask & cAlt) != 0))
|
||||
return PR_FALSE;
|
||||
|
||||
key ? key->GetCtrlKey(&keyPresent) : mouse->GetCtrlKey(&keyPresent);
|
||||
if (keyPresent != ((mKeyMask & cControl) != 0))
|
||||
return PR_FALSE;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
NS_NewXBLEventHandler(nsIDOMEventReceiver* aRec, nsIContent* aHandlerElement,
|
||||
NS_NewXBLEventHandler(nsIDOMEventReceiver* aRec, nsIXBLPrototypeHandler* aHandler,
|
||||
const nsString& aEventName,
|
||||
nsXBLEventHandler** aResult)
|
||||
{
|
||||
*aResult = new nsXBLEventHandler(aRec, aHandlerElement, aEventName);
|
||||
*aResult = new nsXBLEventHandler(aRec, aHandler, aEventName);
|
||||
if (!*aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aResult);
|
||||
|
|
|
@ -40,6 +40,7 @@ class nsIDOMKeyEvent;
|
|||
class nsIDOMMouseEvent;
|
||||
class nsIAtom;
|
||||
class nsIController;
|
||||
class nsIXBLPrototypeHandler;
|
||||
|
||||
class nsXBLEventHandler : public nsIDOMKeyListener,
|
||||
public nsIDOMMouseListener,
|
||||
|
@ -48,7 +49,7 @@ class nsXBLEventHandler : public nsIDOMKeyListener,
|
|||
public nsIDOMScrollListener
|
||||
{
|
||||
public:
|
||||
nsXBLEventHandler(nsIDOMEventReceiver* aReceiver, nsIContent* aHandlerElement, const nsString& aEventName);
|
||||
nsXBLEventHandler(nsIDOMEventReceiver* aReceiver, nsIXBLPrototypeHandler* aHandler, const nsString& aEventName);
|
||||
virtual ~nsXBLEventHandler();
|
||||
|
||||
NS_IMETHOD BindingAttached();
|
||||
|
@ -94,22 +95,13 @@ public:
|
|||
void RemoveEventHandlers();
|
||||
|
||||
void MarkForDeath() {
|
||||
if (mNextHandler) mNextHandler->MarkForDeath(); mHandlerElement = nsnull; mEventReceiver = nsnull;
|
||||
if (mNextHandler) mNextHandler->MarkForDeath(); mProtoHandler = nsnull; mEventReceiver = nsnull;
|
||||
}
|
||||
|
||||
protected:
|
||||
inline PRBool KeyEventMatched(nsIDOMKeyEvent* aKeyEvent);
|
||||
inline PRBool MouseEventMatched(nsIDOMMouseEvent* aMouseEvent);
|
||||
|
||||
inline PRUint32 GetMatchingKeyCode(const nsString& aKeyName);
|
||||
|
||||
NS_IMETHOD GetController(nsIController** aResult);
|
||||
|
||||
NS_IMETHOD ExecuteHandler(const nsAReadableString & aEventName, nsIDOMEvent* aEvent);
|
||||
|
||||
void ConstructMask();
|
||||
PRBool ModifiersMatchMask(nsIDOMUIEvent* aEvent);
|
||||
|
||||
static PRUint32 gRefCnt;
|
||||
static nsIAtom* kKeyAtom;
|
||||
static nsIAtom* kKeyCodeAtom;
|
||||
|
@ -122,36 +114,19 @@ protected:
|
|||
static nsIAtom* kBindingDetachedAtom;
|
||||
static nsIAtom* kModifiersAtom;
|
||||
|
||||
static PRInt32 kAccessKey;
|
||||
static void InitAccessKey();
|
||||
|
||||
static nsresult GetTextData(nsIContent *aParent, nsString& aResult);
|
||||
|
||||
static const PRInt32 cShift;
|
||||
static const PRInt32 cAlt;
|
||||
static const PRInt32 cControl;
|
||||
static const PRInt32 cMeta;
|
||||
|
||||
protected:
|
||||
nsIDOMEventReceiver* mEventReceiver; // Both of these refs are weak.
|
||||
nsIContent* mHandlerElement;
|
||||
nsIXBLPrototypeHandler* mProtoHandler;
|
||||
|
||||
nsAutoString mEventName;
|
||||
|
||||
PRInt32 mKeyMask; // Which modifier keys this event handler expects to have down
|
||||
// in order to be matched.
|
||||
|
||||
PRUint32 mDetail; // For key events, contains a charcode or keycode. For
|
||||
// mouse events, stores the button info.
|
||||
|
||||
PRInt32 mDetail2; // Miscellaneous extra information. For key events,
|
||||
// stores whether or not we're a key code or char code.
|
||||
// For mouse events, stores the clickCount.
|
||||
|
||||
nsXBLEventHandler* mNextHandler; // Handlers are chained for easy unloading later.
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
NS_NewXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsIContent* aHandlerElement,
|
||||
NS_NewXBLEventHandler(nsIDOMEventReceiver* aEventReceiver, nsIXBLPrototypeHandler* aHandlerElement,
|
||||
const nsString& aEventName,
|
||||
nsXBLEventHandler** aResult);
|
||||
|
||||
|
|
|
@ -0,0 +1,719 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXBLPrototypeHandler.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIScriptObjectOwner.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIJSEventListener.h"
|
||||
#include "nsIController.h"
|
||||
#include "nsIControllers.h"
|
||||
#include "nsIDOMXULElement.h"
|
||||
#include "nsIDOMNSHTMLTextAreaElement.h"
|
||||
#include "nsIDOMNSHTMLInputElement.h"
|
||||
#include "nsIDOMText.h"
|
||||
#include "nsIEventListenerManager.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
||||
|
||||
PRUint32 nsXBLPrototypeHandler::gRefCnt = 0;
|
||||
nsIAtom* nsXBLPrototypeHandler::kKeyCodeAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kCharCodeAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kKeyAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kActionAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kCommandAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kClickCountAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kButtonAtom = nsnull;
|
||||
nsIAtom* nsXBLPrototypeHandler::kModifiersAtom = nsnull;
|
||||
|
||||
PRInt32 nsXBLPrototypeHandler::kAccessKey = -1;
|
||||
|
||||
const PRInt32 nsXBLPrototypeHandler::cShift = (1<<1);
|
||||
const PRInt32 nsXBLPrototypeHandler::cAlt = (1<<2);
|
||||
const PRInt32 nsXBLPrototypeHandler::cControl = (1<<3);
|
||||
const PRInt32 nsXBLPrototypeHandler::cMeta = (1<<4);
|
||||
|
||||
nsXBLPrototypeHandler::nsXBLPrototypeHandler(nsIContent* aHandlerElement)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mHandlerElement = aHandlerElement;
|
||||
gRefCnt++;
|
||||
if (gRefCnt == 1) {
|
||||
kKeyCodeAtom = NS_NewAtom("keycode");
|
||||
kKeyAtom = NS_NewAtom("key");
|
||||
kCharCodeAtom = NS_NewAtom("charcode");
|
||||
kModifiersAtom = NS_NewAtom("modifiers");
|
||||
kActionAtom = NS_NewAtom("action");
|
||||
kCommandAtom = NS_NewAtom("command");
|
||||
kClickCountAtom = NS_NewAtom("clickcount");
|
||||
kButtonAtom = NS_NewAtom("button");
|
||||
|
||||
// Get the primary accelerator key.
|
||||
InitAccessKey();
|
||||
}
|
||||
|
||||
// Make sure our mask is initialized.
|
||||
ConstructMask();
|
||||
}
|
||||
|
||||
nsXBLPrototypeHandler::~nsXBLPrototypeHandler()
|
||||
{
|
||||
gRefCnt--;
|
||||
if (gRefCnt == 0) {
|
||||
NS_RELEASE(kKeyAtom);
|
||||
NS_RELEASE(kKeyCodeAtom);
|
||||
NS_RELEASE(kCharCodeAtom);
|
||||
NS_RELEASE(kModifiersAtom);
|
||||
NS_RELEASE(kActionAtom);
|
||||
NS_RELEASE(kCommandAtom);
|
||||
NS_RELEASE(kButtonAtom);
|
||||
NS_RELEASE(kClickCountAtom);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXBLPrototypeHandler, nsIXBLPrototypeHandler)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeHandler::EventMatched(nsIDOMEvent* aEvent, PRBool* aResult)
|
||||
{
|
||||
nsCOMPtr<nsIDOMKeyEvent> key(do_QueryInterface(aEvent));
|
||||
if (key)
|
||||
*aResult = KeyEventMatched(key);
|
||||
else {
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouse(do_QueryInterface(aEvent));
|
||||
if (mouse)
|
||||
*aResult = MouseEventMatched(mouse);
|
||||
else *aResult = PR_TRUE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeHandler::GetHandlerElement(nsIContent** aResult)
|
||||
{
|
||||
*aResult = mHandlerElement;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeHandler::GetNextHandler(nsIXBLPrototypeHandler** aResult)
|
||||
{
|
||||
*aResult = mNextHandler;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeHandler::SetNextHandler(nsIXBLPrototypeHandler* aHandler)
|
||||
{
|
||||
mNextHandler = aHandler;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Get the menu access key from prefs.
|
||||
// XXX Eventually pick up using CSS3 key-equivalent property or somesuch
|
||||
void
|
||||
nsXBLPrototypeHandler::InitAccessKey()
|
||||
{
|
||||
if (kAccessKey >= 0)
|
||||
return;
|
||||
|
||||
// Compiled-in defaults, in case we can't get the pref --
|
||||
// mac doesn't have menu shortcuts, other platforms use alt.
|
||||
#ifndef XP_MAC
|
||||
kAccessKey = nsIDOMKeyEvent::DOM_VK_ALT;
|
||||
#else
|
||||
kAccessKey = 0;
|
||||
#endif
|
||||
|
||||
// Get the menu access key value from prefs, overriding the default:
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_PROGID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && prefs)
|
||||
{
|
||||
rv = prefs->GetIntPref("ui.key.menuAccessKey", &kAccessKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsXBLPrototypeHandler::KeyEventMatched(nsIDOMKeyEvent* aKeyEvent)
|
||||
{
|
||||
if (!mHandlerElement)
|
||||
return PR_FALSE;
|
||||
|
||||
if (mDetail == 0 && mDetail2 == 0 && mKeyMask == 0)
|
||||
return PR_TRUE; // No filters set up. It's generic.
|
||||
|
||||
// Get the keycode and charcode of the key event.
|
||||
PRUint32 keyCode, charCode;
|
||||
aKeyEvent->GetKeyCode(&keyCode);
|
||||
aKeyEvent->GetCharCode(&charCode);
|
||||
|
||||
PRBool keyMatched = (mDetail == (mDetail2 ? charCode : keyCode));
|
||||
|
||||
if (!keyMatched)
|
||||
return PR_FALSE;
|
||||
|
||||
// Now check modifier keys
|
||||
return ModifiersMatchMask(aKeyEvent);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsXBLPrototypeHandler::MouseEventMatched(nsIDOMMouseEvent* aMouseEvent)
|
||||
{
|
||||
if (!mHandlerElement)
|
||||
return PR_FALSE;
|
||||
|
||||
if (mDetail == 0 && mDetail2 == 0 && mKeyMask == 0)
|
||||
return PR_TRUE; // No filters set up. It's generic.
|
||||
|
||||
unsigned short button;
|
||||
aMouseEvent->GetButton(&button);
|
||||
if (mDetail != 0 && (button != mDetail))
|
||||
return PR_FALSE;
|
||||
|
||||
PRInt32 clickcount;
|
||||
aMouseEvent->GetDetail(&clickcount);
|
||||
if (mDetail2 != 0 && (clickcount != mDetail2))
|
||||
return PR_FALSE;
|
||||
|
||||
return ModifiersMatchMask(aMouseEvent);
|
||||
}
|
||||
|
||||
enum {
|
||||
VK_CANCEL = 3,
|
||||
VK_BACK = 8,
|
||||
VK_TAB = 9,
|
||||
VK_CLEAR = 12,
|
||||
VK_RETURN = 13,
|
||||
VK_ENTER = 14,
|
||||
VK_SHIFT = 16,
|
||||
VK_CONTROL = 17,
|
||||
VK_ALT = 18,
|
||||
VK_PAUSE = 19,
|
||||
VK_CAPS_LOCK = 20,
|
||||
VK_ESCAPE = 27,
|
||||
VK_SPACE = 32,
|
||||
VK_PAGE_UP = 33,
|
||||
VK_PAGE_DOWN = 34,
|
||||
VK_END = 35,
|
||||
VK_HOME = 36,
|
||||
VK_LEFT = 37,
|
||||
VK_UP = 38,
|
||||
VK_RIGHT = 39,
|
||||
VK_DOWN = 40,
|
||||
VK_PRINTSCREEN = 44,
|
||||
VK_INSERT = 45,
|
||||
VK_DELETE = 46,
|
||||
VK_0 = 48,
|
||||
VK_1 = 49,
|
||||
VK_2 = 50,
|
||||
VK_3 = 51,
|
||||
VK_4 = 52,
|
||||
VK_5 = 53,
|
||||
VK_6 = 54,
|
||||
VK_7 = 55,
|
||||
VK_8 = 56,
|
||||
VK_9 = 57,
|
||||
VK_SEMICOLON = 59,
|
||||
VK_EQUALS = 61,
|
||||
VK_A = 65,
|
||||
VK_B = 66,
|
||||
VK_C = 67,
|
||||
VK_D = 68,
|
||||
VK_E = 69,
|
||||
VK_F = 70,
|
||||
VK_G = 71,
|
||||
VK_H = 72,
|
||||
VK_I = 73,
|
||||
VK_J = 74,
|
||||
VK_K = 75,
|
||||
VK_L = 76,
|
||||
VK_M = 77,
|
||||
VK_N = 78,
|
||||
VK_O = 79,
|
||||
VK_P = 80,
|
||||
VK_Q = 81,
|
||||
VK_R = 82,
|
||||
VK_S = 83,
|
||||
VK_T = 84,
|
||||
VK_U = 85,
|
||||
VK_V = 86,
|
||||
VK_W = 87,
|
||||
VK_X = 88,
|
||||
VK_Y = 89,
|
||||
VK_Z = 90,
|
||||
VK_NUMPAD0 = 96,
|
||||
VK_NUMPAD1 = 97,
|
||||
VK_NUMPAD2 = 98,
|
||||
VK_NUMPAD3 = 99,
|
||||
VK_NUMPAD4 = 100,
|
||||
VK_NUMPAD5 = 101,
|
||||
VK_NUMPAD6 = 102,
|
||||
VK_NUMPAD7 = 103,
|
||||
VK_NUMPAD8 = 104,
|
||||
VK_NUMPAD9 = 105,
|
||||
VK_MULTIPLY = 106,
|
||||
VK_ADD = 107,
|
||||
VK_SEPARATOR = 108,
|
||||
VK_SUBTRACT = 109,
|
||||
VK_DECIMAL = 110,
|
||||
VK_DIVIDE = 111,
|
||||
VK_F1 = 112,
|
||||
VK_F2 = 113,
|
||||
VK_F3 = 114,
|
||||
VK_F4 = 115,
|
||||
VK_F5 = 116,
|
||||
VK_F6 = 117,
|
||||
VK_F7 = 118,
|
||||
VK_F8 = 119,
|
||||
VK_F9 = 120,
|
||||
VK_F10 = 121,
|
||||
VK_F11 = 122,
|
||||
VK_F12 = 123,
|
||||
VK_F13 = 124,
|
||||
VK_F14 = 125,
|
||||
VK_F15 = 126,
|
||||
VK_F16 = 127,
|
||||
VK_F17 = 128,
|
||||
VK_F18 = 129,
|
||||
VK_F19 = 130,
|
||||
VK_F20 = 131,
|
||||
VK_F21 = 132,
|
||||
VK_F22 = 133,
|
||||
VK_F23 = 134,
|
||||
VK_F24 = 135,
|
||||
VK_NUM_LOCK = 144,
|
||||
VK_SCROLL_LOCK = 145,
|
||||
VK_COMMA = 188,
|
||||
VK_PERIOD = 190,
|
||||
VK_SLASH = 191,
|
||||
VK_BACK_QUOTE = 192,
|
||||
VK_OPEN_BRACKET = 219,
|
||||
VK_BACK_SLASH = 220,
|
||||
VK_CLOSE_BRACKET = 221,
|
||||
VK_QUOTE = 222
|
||||
};
|
||||
|
||||
PRUint32 nsXBLPrototypeHandler::GetMatchingKeyCode(const nsString& aKeyName)
|
||||
{
|
||||
PRBool ret = PR_FALSE;
|
||||
|
||||
nsCAutoString keyName; keyName.AssignWithConversion(aKeyName);
|
||||
|
||||
if (keyName.EqualsIgnoreCase("VK_CANCEL"))
|
||||
return VK_CANCEL;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_BACK"))
|
||||
return VK_BACK;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_TAB"))
|
||||
return VK_TAB;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_CLEAR"))
|
||||
return VK_CLEAR;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_RETURN"))
|
||||
return VK_RETURN;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_ENTER"))
|
||||
return VK_ENTER;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_SHIFT"))
|
||||
return VK_SHIFT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_CONTROL"))
|
||||
return VK_CONTROL;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_ALT"))
|
||||
return VK_ALT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_PAUSE"))
|
||||
return VK_PAUSE;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_CAPS_LOCK"))
|
||||
return VK_CAPS_LOCK;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_ESCAPE"))
|
||||
return VK_ESCAPE;
|
||||
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_SPACE"))
|
||||
return VK_SPACE;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_PAGE_UP"))
|
||||
return VK_PAGE_UP;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_PAGE_DOWN"))
|
||||
return VK_PAGE_DOWN;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_END"))
|
||||
return VK_END;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_HOME"))
|
||||
return VK_HOME;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_LEFT"))
|
||||
return VK_LEFT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_UP"))
|
||||
return VK_UP;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_RIGHT"))
|
||||
return VK_RIGHT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_DOWN"))
|
||||
return VK_DOWN;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_PRINTSCREEN"))
|
||||
return VK_PRINTSCREEN;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_INSERT"))
|
||||
return VK_INSERT;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_DELETE"))
|
||||
return VK_DELETE;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_0"))
|
||||
return VK_0;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_1"))
|
||||
return VK_1;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_2"))
|
||||
return VK_2;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_3"))
|
||||
return VK_3;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_4"))
|
||||
return VK_4;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_5"))
|
||||
return VK_5;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_6"))
|
||||
return VK_6;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_7"))
|
||||
return VK_7;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_8"))
|
||||
return VK_8;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_9"))
|
||||
return VK_9;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_SEMICOLON"))
|
||||
return VK_SEMICOLON;
|
||||
|
||||
if(keyName.EqualsIgnoreCase("VK_EQUALS"))
|
||||
return VK_EQUALS;
|
||||
if(keyName.EqualsIgnoreCase("VK_A"))
|
||||
return VK_A;
|
||||
if(keyName.EqualsIgnoreCase("VK_B"))
|
||||
return VK_B;
|
||||
if(keyName.EqualsIgnoreCase("VK_C"))
|
||||
return VK_C;
|
||||
if(keyName.EqualsIgnoreCase("VK_D"))
|
||||
return VK_D;
|
||||
if(keyName.EqualsIgnoreCase("VK_E"))
|
||||
return VK_E;
|
||||
if(keyName.EqualsIgnoreCase("VK_F"))
|
||||
return VK_F;
|
||||
if(keyName.EqualsIgnoreCase("VK_G"))
|
||||
return VK_G;
|
||||
if(keyName.EqualsIgnoreCase("VK_H"))
|
||||
return VK_H;
|
||||
if(keyName.EqualsIgnoreCase("VK_I"))
|
||||
return VK_I;
|
||||
if(keyName.EqualsIgnoreCase("VK_J"))
|
||||
return VK_J;
|
||||
if(keyName.EqualsIgnoreCase("VK_K"))
|
||||
return VK_K;
|
||||
if(keyName.EqualsIgnoreCase("VK_L"))
|
||||
return VK_L;
|
||||
if(keyName.EqualsIgnoreCase("VK_M"))
|
||||
return VK_M;
|
||||
if(keyName.EqualsIgnoreCase("VK_N"))
|
||||
return VK_N;
|
||||
if(keyName.EqualsIgnoreCase("VK_O"))
|
||||
return VK_O;
|
||||
if(keyName.EqualsIgnoreCase("VK_P"))
|
||||
return VK_P;
|
||||
if(keyName.EqualsIgnoreCase("VK_Q"))
|
||||
return VK_Q;
|
||||
if(keyName.EqualsIgnoreCase("VK_R"))
|
||||
return VK_R;
|
||||
if(keyName.EqualsIgnoreCase("VK_S"))
|
||||
return VK_S;
|
||||
if(keyName.EqualsIgnoreCase("VK_T"))
|
||||
return VK_T;
|
||||
if(keyName.EqualsIgnoreCase("VK_U"))
|
||||
return VK_U;
|
||||
if(keyName.EqualsIgnoreCase("VK_V"))
|
||||
return VK_V;
|
||||
if(keyName.EqualsIgnoreCase("VK_W"))
|
||||
return VK_W;
|
||||
if(keyName.EqualsIgnoreCase("VK_X"))
|
||||
return VK_X;
|
||||
if(keyName.EqualsIgnoreCase("VK_Y"))
|
||||
return VK_Y;
|
||||
if(keyName.EqualsIgnoreCase("VK_Z"))
|
||||
return VK_Z;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD0"))
|
||||
return VK_NUMPAD0;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD1"))
|
||||
return VK_NUMPAD1;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD2"))
|
||||
return VK_NUMPAD2;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD3"))
|
||||
return VK_NUMPAD3;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD4"))
|
||||
return VK_NUMPAD4;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD5"))
|
||||
return VK_NUMPAD5;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD6"))
|
||||
return VK_NUMPAD6;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD7"))
|
||||
return VK_NUMPAD7;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD8"))
|
||||
return VK_NUMPAD8;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUMPAD9"))
|
||||
return VK_NUMPAD9;
|
||||
if(keyName.EqualsIgnoreCase("VK_MULTIPLY"))
|
||||
return VK_MULTIPLY;
|
||||
if(keyName.EqualsIgnoreCase("VK_ADD"))
|
||||
return VK_ADD;
|
||||
if(keyName.EqualsIgnoreCase("VK_SEPARATOR"))
|
||||
return VK_SEPARATOR;
|
||||
if(keyName.EqualsIgnoreCase("VK_SUBTRACT"))
|
||||
return VK_SUBTRACT;
|
||||
if(keyName.EqualsIgnoreCase("VK_DECIMAL"))
|
||||
return VK_DECIMAL;
|
||||
if(keyName.EqualsIgnoreCase("VK_DIVIDE"))
|
||||
return VK_DIVIDE;
|
||||
if(keyName.EqualsIgnoreCase("VK_F1"))
|
||||
return VK_F1;
|
||||
if(keyName.EqualsIgnoreCase("VK_F2"))
|
||||
return VK_F2;
|
||||
if(keyName.EqualsIgnoreCase("VK_F3"))
|
||||
return VK_F3;
|
||||
if(keyName.EqualsIgnoreCase("VK_F4"))
|
||||
return VK_F4;
|
||||
if(keyName.EqualsIgnoreCase("VK_F5"))
|
||||
return VK_F5;
|
||||
if(keyName.EqualsIgnoreCase("VK_F6"))
|
||||
return VK_F6;
|
||||
if(keyName.EqualsIgnoreCase("VK_F7"))
|
||||
return VK_F7;
|
||||
if(keyName.EqualsIgnoreCase("VK_F8"))
|
||||
return VK_F8;
|
||||
if(keyName.EqualsIgnoreCase("VK_F9"))
|
||||
return VK_F9;
|
||||
if(keyName.EqualsIgnoreCase("VK_F10"))
|
||||
return VK_F10;
|
||||
if(keyName.EqualsIgnoreCase("VK_F11"))
|
||||
return VK_F11;
|
||||
if(keyName.EqualsIgnoreCase("VK_F12"))
|
||||
return VK_F12;
|
||||
if(keyName.EqualsIgnoreCase("VK_F13"))
|
||||
return VK_F13;
|
||||
if(keyName.EqualsIgnoreCase("VK_F14"))
|
||||
return VK_F14;
|
||||
if(keyName.EqualsIgnoreCase("VK_F15"))
|
||||
return VK_F15;
|
||||
if(keyName.EqualsIgnoreCase("VK_F16"))
|
||||
return VK_F16;
|
||||
if(keyName.EqualsIgnoreCase("VK_F17"))
|
||||
return VK_F17;
|
||||
if(keyName.EqualsIgnoreCase("VK_F18"))
|
||||
return VK_F18;
|
||||
if(keyName.EqualsIgnoreCase("VK_F19"))
|
||||
return VK_F19;
|
||||
if(keyName.EqualsIgnoreCase("VK_F20"))
|
||||
return VK_F20;
|
||||
if(keyName.EqualsIgnoreCase("VK_F21"))
|
||||
return VK_F21;
|
||||
if(keyName.EqualsIgnoreCase("VK_F22"))
|
||||
return VK_F22;
|
||||
if(keyName.EqualsIgnoreCase("VK_F23"))
|
||||
return VK_F23;
|
||||
if(keyName.EqualsIgnoreCase("VK_F24"))
|
||||
return VK_F24;
|
||||
if(keyName.EqualsIgnoreCase("VK_NUM_LOCK"))
|
||||
return VK_NUM_LOCK;
|
||||
if(keyName.EqualsIgnoreCase("VK_SCROLL_LOCK"))
|
||||
return VK_SCROLL_LOCK;
|
||||
if(keyName.EqualsIgnoreCase("VK_COMMA"))
|
||||
return VK_COMMA;
|
||||
if(keyName.EqualsIgnoreCase("VK_PERIOD"))
|
||||
return VK_PERIOD;
|
||||
if(keyName.EqualsIgnoreCase("VK_SLASH"))
|
||||
return VK_SLASH;
|
||||
if(keyName.EqualsIgnoreCase("VK_BACK_QUOTE"))
|
||||
return VK_BACK_QUOTE;
|
||||
if(keyName.EqualsIgnoreCase("VK_OPEN_BRACKET"))
|
||||
return VK_OPEN_BRACKET;
|
||||
if(keyName.EqualsIgnoreCase("VK_BACK_SLASH"))
|
||||
return VK_BACK_SLASH;
|
||||
if(keyName.EqualsIgnoreCase("VK_CLOSE_BRACKET"))
|
||||
return VK_CLOSE_BRACKET;
|
||||
if(keyName.EqualsIgnoreCase("VK_QUOTE"))
|
||||
return VK_QUOTE;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLPrototypeHandler::ConstructMask()
|
||||
{
|
||||
mDetail = 0;
|
||||
mDetail2 = 0;
|
||||
mKeyMask = 0;
|
||||
|
||||
nsAutoString key;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kKeyAtom, key);
|
||||
if (key.IsEmpty())
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kCharCodeAtom, key);
|
||||
|
||||
if (!key.IsEmpty()) {
|
||||
// We have a charcode.
|
||||
mDetail2 = 1;
|
||||
mDetail = key[0];
|
||||
}
|
||||
else {
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kKeyCodeAtom, key);
|
||||
if (!key.IsEmpty())
|
||||
mDetail = GetMatchingKeyCode(key);
|
||||
}
|
||||
|
||||
nsAutoString buttonStr, clickCountStr;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kClickCountAtom, clickCountStr);
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kButtonAtom, buttonStr);
|
||||
|
||||
if (!buttonStr.IsEmpty()) {
|
||||
PRInt32 error;
|
||||
mDetail = buttonStr.ToInteger(&error);
|
||||
}
|
||||
|
||||
if (!clickCountStr.IsEmpty()) {
|
||||
PRInt32 error;
|
||||
mDetail2 = clickCountStr.ToInteger(&error);
|
||||
}
|
||||
|
||||
nsAutoString modifiers;
|
||||
mHandlerElement->GetAttribute(kNameSpaceID_None, kModifiersAtom, modifiers);
|
||||
if (modifiers.IsEmpty())
|
||||
return;
|
||||
|
||||
char* str = modifiers.ToNewCString();
|
||||
char* newStr;
|
||||
char* token = nsCRT::strtok( str, ", ", &newStr );
|
||||
while( token != NULL ) {
|
||||
if (PL_strcmp(token, "shift") == 0)
|
||||
mKeyMask |= cShift;
|
||||
else if (PL_strcmp(token, "alt") == 0)
|
||||
mKeyMask |= cAlt;
|
||||
else if (PL_strcmp(token, "meta") == 0)
|
||||
mKeyMask |= cMeta;
|
||||
else if (PL_strcmp(token, "control") == 0)
|
||||
mKeyMask |= cControl;
|
||||
else if (PL_strcmp(token, "primary") == 0) {
|
||||
switch (kAccessKey)
|
||||
{
|
||||
case nsIDOMKeyEvent::DOM_VK_META:
|
||||
mKeyMask |= cMeta;
|
||||
break;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_ALT:
|
||||
mKeyMask |= cAlt;
|
||||
break;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_CONTROL:
|
||||
default:
|
||||
mKeyMask |= cControl;
|
||||
}
|
||||
}
|
||||
|
||||
token = nsCRT::strtok( newStr, ", ", &newStr );
|
||||
}
|
||||
|
||||
nsMemory::Free(str);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsXBLPrototypeHandler::ModifiersMatchMask(nsIDOMUIEvent* aEvent)
|
||||
{
|
||||
nsCOMPtr<nsIDOMKeyEvent> key(do_QueryInterface(aEvent));
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouse(do_QueryInterface(aEvent));
|
||||
|
||||
PRBool keyPresent;
|
||||
key ? key->GetMetaKey(&keyPresent) : mouse->GetMetaKey(&keyPresent);
|
||||
if (keyPresent != ((mKeyMask & cMeta) != 0))
|
||||
return PR_FALSE;
|
||||
|
||||
key ? key->GetShiftKey(&keyPresent) : mouse->GetShiftKey(&keyPresent);
|
||||
if (keyPresent != ((mKeyMask & cShift) != 0))
|
||||
return PR_FALSE;
|
||||
|
||||
key ? key->GetAltKey(&keyPresent) : mouse->GetAltKey(&keyPresent);
|
||||
if (keyPresent != ((mKeyMask & cAlt) != 0))
|
||||
return PR_FALSE;
|
||||
|
||||
key ? key->GetCtrlKey(&keyPresent) : mouse->GetCtrlKey(&keyPresent);
|
||||
if (keyPresent != ((mKeyMask & cControl) != 0))
|
||||
return PR_FALSE;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
NS_NewXBLPrototypeHandler(nsIContent* aHandlerElement, nsIXBLPrototypeHandler** aResult)
|
||||
{
|
||||
*aResult = new nsXBLPrototypeHandler(aHandlerElement);
|
||||
if (!*aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef nsXBLPrototypeHandler_h__
|
||||
#define nsXBLPrototypeHandler_h__
|
||||
|
||||
#include "nsIXBLPrototypeHandler.h"
|
||||
|
||||
class nsIXBLBinding;
|
||||
class nsIDOMEvent;
|
||||
class nsIContent;
|
||||
class nsIDOMUIEvent;
|
||||
class nsIDOMKeyEvent;
|
||||
class nsIDOMMouseEvent;
|
||||
class nsIAtom;
|
||||
class nsString;
|
||||
|
||||
class nsXBLPrototypeHandler : public nsIXBLPrototypeHandler
|
||||
{
|
||||
public:
|
||||
nsXBLPrototypeHandler(nsIContent* aHandlerElement);
|
||||
virtual ~nsXBLPrototypeHandler();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD EventMatched(nsIDOMEvent* aEvent, PRBool* aResult);
|
||||
NS_IMETHOD GetHandlerElement(nsIContent** aResult);
|
||||
|
||||
NS_IMETHOD GetNextHandler(nsIXBLPrototypeHandler** aResult);
|
||||
NS_IMETHOD SetNextHandler(nsIXBLPrototypeHandler* aHandler);
|
||||
|
||||
protected:
|
||||
inline PRUint32 GetMatchingKeyCode(const nsString& aKeyName);
|
||||
void ConstructMask();
|
||||
PRBool ModifiersMatchMask(nsIDOMUIEvent* aEvent);
|
||||
|
||||
inline PRBool KeyEventMatched(nsIDOMKeyEvent* aKeyEvent);
|
||||
inline PRBool MouseEventMatched(nsIDOMMouseEvent* aMouseEvent);
|
||||
|
||||
static PRUint32 gRefCnt;
|
||||
static nsIAtom* kKeyAtom;
|
||||
static nsIAtom* kKeyCodeAtom;
|
||||
static nsIAtom* kCharCodeAtom;
|
||||
static nsIAtom* kActionAtom;
|
||||
static nsIAtom* kCommandAtom;
|
||||
static nsIAtom* kClickCountAtom;
|
||||
static nsIAtom* kButtonAtom;
|
||||
static nsIAtom* kModifiersAtom;
|
||||
|
||||
static PRInt32 kAccessKey;
|
||||
static void InitAccessKey();
|
||||
|
||||
static const PRInt32 cShift;
|
||||
static const PRInt32 cAlt;
|
||||
static const PRInt32 cControl;
|
||||
static const PRInt32 cMeta;
|
||||
|
||||
protected:
|
||||
nsIContent* mHandlerElement; // This ref is weak.
|
||||
|
||||
PRInt32 mKeyMask; // Which modifier keys this event handler expects to have down
|
||||
// in order to be matched.
|
||||
|
||||
PRUint32 mDetail; // For key events, contains a charcode or keycode. For
|
||||
// mouse events, stores the button info.
|
||||
|
||||
PRInt32 mDetail2; // Miscellaneous extra information. For key events,
|
||||
// stores whether or not we're a key code or char code.
|
||||
// For mouse events, stores the clickCount.
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> mNextHandler; // Prototype handlers are chained. We own the next handler in the chain.
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
NS_NewXBLPrototypeHandler(nsIContent* aHandlerElement, nsIXBLPrototypeHandler** aResult);
|
||||
|
||||
#endif
|
|
@ -51,6 +51,8 @@
|
|||
#include "nsIXBLBinding.h"
|
||||
#include "nsIXBLDocumentInfo.h"
|
||||
|
||||
#include "nsIXBLPrototypeHandler.h"
|
||||
|
||||
#include "nsIChromeRegistry.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
|
@ -325,11 +327,18 @@ nsXBLStreamListener::Load(nsIDOMEvent* aEvent)
|
|||
nsCOMPtr<nsIContent> root = getter_AddRefs(mBindingDocument->GetRootContent());
|
||||
if (root)
|
||||
nsXBLService::StripWhitespaceNodes(root);
|
||||
else {
|
||||
NS_ERROR("*** XBL doc with no root element! Something went horribly wrong! ***");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Put our doc in the doc table.
|
||||
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||
NS_NewXBLDocumentInfo(mBindingDocument, getter_AddRefs(info));
|
||||
|
||||
// Construct our prototype handlers.
|
||||
nsXBLService::ConstructPrototypeHandlers(info);
|
||||
|
||||
// If the doc is a chrome URI, then we put it into the XUL cache.
|
||||
PRBool cached = PR_FALSE;
|
||||
if (IsChromeURI(uri) && gXULUtils->UseXULCache()) {
|
||||
|
@ -470,6 +479,7 @@ PRUint32 nsXBLService::gClassLRUListLength = 0;
|
|||
PRUint32 nsXBLService::gClassLRUListQuota = 64;
|
||||
|
||||
nsIAtom* nsXBLService::kExtendsAtom = nsnull;
|
||||
nsIAtom* nsXBLService::kHandlersAtom = nsnull;
|
||||
nsIAtom* nsXBLService::kScrollbarAtom = nsnull;
|
||||
nsIAtom* nsXBLService::kInputAtom = nsnull;
|
||||
|
||||
|
@ -509,6 +519,7 @@ nsXBLService::nsXBLService(void)
|
|||
|
||||
// Create our atoms
|
||||
kExtendsAtom = NS_NewAtom("extends");
|
||||
kHandlersAtom = NS_NewAtom("handlers");
|
||||
kScrollbarAtom = NS_NewAtom("scrollbar");
|
||||
kInputAtom = NS_NewAtom("input");
|
||||
|
||||
|
@ -544,6 +555,7 @@ nsXBLService::~nsXBLService(void)
|
|||
|
||||
// Release our atoms
|
||||
NS_RELEASE(kExtendsAtom);
|
||||
NS_RELEASE(kHandlersAtom);
|
||||
NS_RELEASE(kScrollbarAtom);
|
||||
NS_RELEASE(kInputAtom);
|
||||
|
||||
|
@ -999,6 +1011,9 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aB
|
|||
|
||||
if (document) {
|
||||
NS_NewXBLDocumentInfo(document, getter_AddRefs(info));
|
||||
|
||||
// Construct our prototype handlers.
|
||||
ConstructPrototypeHandlers(info);
|
||||
|
||||
// If the doc is a chrome URI, then we put it into the XUL cache.
|
||||
PRBool cached = PR_FALSE;
|
||||
|
@ -1183,6 +1198,74 @@ nsXBLService::StripWhitespaceNodes(nsIContent* aElement)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static void GetImmediateChild(nsIAtom* aTag, nsIContent* aParent, nsIContent** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
PRInt32 childCount;
|
||||
aParent->ChildCount(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
aParent->ChildAt(i, *getter_AddRefs(child));
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
child->GetTag(*getter_AddRefs(tag));
|
||||
if (aTag == tag.get()) {
|
||||
*aResult = child;
|
||||
NS_ADDREF(*aResult);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXBLService::ConstructPrototypeHandlers(nsIXBLDocumentInfo* aInfo)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aInfo->GetDocument(getter_AddRefs(doc));
|
||||
nsCOMPtr<nsIContent> bindings = getter_AddRefs(doc->GetRootContent());
|
||||
PRInt32 childCount;
|
||||
bindings->ChildCount(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIContent> binding;
|
||||
bindings->ChildAt(i, *getter_AddRefs(binding));
|
||||
|
||||
// See if this binding has a handler elt.
|
||||
nsCOMPtr<nsIContent> handlers;
|
||||
GetImmediateChild(kHandlersAtom, binding, getter_AddRefs(handlers));
|
||||
if (handlers) {
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> firstHandler;
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> currHandler;
|
||||
|
||||
PRInt32 handlerCount;
|
||||
handlers->ChildCount(handlerCount);
|
||||
for (PRInt32 j = 0; j < handlerCount; j++) {
|
||||
nsCOMPtr<nsIContent> handler;
|
||||
handlers->ChildAt(j, *getter_AddRefs(handler));
|
||||
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> newHandler;
|
||||
NS_NewXBLPrototypeHandler(handler, getter_AddRefs(newHandler));
|
||||
if (newHandler) {
|
||||
if (currHandler)
|
||||
currHandler->SetNextHandler(newHandler);
|
||||
else firstHandler = newHandler;
|
||||
currHandler = newHandler;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstHandler) {
|
||||
nsAutoString ref;
|
||||
binding->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, ref);
|
||||
|
||||
nsCAutoString cref;
|
||||
cref.AssignWithConversion(ref);
|
||||
|
||||
aInfo->SetPrototypeHandler(cref, firstHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -96,6 +96,7 @@ public:
|
|||
// This method walks a binding document and removes any text nodes
|
||||
// that contain only whitespace.
|
||||
static nsresult StripWhitespaceNodes(nsIContent* aContent);
|
||||
static nsresult ConstructPrototypeHandlers(nsIXBLDocumentInfo* aInfo);
|
||||
|
||||
// MEMBER VARIABLES
|
||||
public:
|
||||
|
@ -117,7 +118,7 @@ public:
|
|||
|
||||
// XBL Atoms
|
||||
static nsIAtom* kExtendsAtom;
|
||||
|
||||
static nsIAtom* kHandlersAtom;
|
||||
static nsIAtom* kScrollbarAtom;
|
||||
static nsIAtom* kInputAtom;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче