From dd88339f190d88acce54b1c0e52945ce9318a967 Mon Sep 17 00:00:00 2001 From: "vidur%netscape.com" Date: Thu, 25 Nov 1999 00:05:21 +0000 Subject: [PATCH] Fixes for 19650 and 15133. Added nsHTMLDocument::Resolve(). Script event handler compilation is deferred till when the event handler is first invoked. Atoms used for event name comparisions instead of strings. R=joki --- content/base/src/nsDocument.cpp | 36 ++- content/base/src/nsGenericElement.cpp | 42 +-- .../events/public/nsIEventListenerManager.h | 12 +- content/events/src/nsEventListenerManager.cpp | 301 +++++++++++++----- content/events/src/nsEventListenerManager.h | 17 +- .../html/content/src/nsGenericHTMLElement.cpp | 47 +-- content/html/content/src/nsHTMLAtomList.h | 23 -- content/html/document/src/nsHTMLDocument.cpp | 46 +++ content/html/document/src/nsHTMLDocument.h | 3 + content/shared/public/nsHTMLAtomList.h | 23 -- content/shared/public/nsLayoutAtomList.h | 34 ++ layout/base/nsLayoutAtomList.h | 34 ++ layout/base/public/nsLayoutAtomList.h | 34 ++ layout/base/src/nsDocument.cpp | 36 ++- layout/base/src/nsGenericElement.cpp | 42 +-- .../events/public/nsIEventListenerManager.h | 12 +- layout/events/src/nsEventListenerManager.cpp | 301 +++++++++++++----- layout/events/src/nsEventListenerManager.h | 17 +- layout/html/base/src/nsHTMLAtomList.h | 23 -- .../html/content/src/nsGenericHTMLElement.cpp | 47 +-- layout/html/document/src/nsHTMLDocument.cpp | 46 +++ layout/html/document/src/nsHTMLDocument.h | 3 + 22 files changed, 826 insertions(+), 353 deletions(-) diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index 695c748d9320..be50a7f73316 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -72,6 +72,7 @@ #include "nsINameSpaceManager.h" #include "nsIServiceManager.h" +#include "nsLayoutAtoms.h" #include "nsLayoutCID.h" #include "nsIDOMSelection.h" #include "nsIDOMRange.h" @@ -2499,71 +2500,72 @@ PRBool nsDocument::SetProperty(JSContext *aContext, jsval aID, jsval *aVp) mPropName.SetString(JS_GetStringChars(JS_ValueToString(aContext, aID))); mPrefix.SetString(mPropName.GetUnicode(), 2); if (mPrefix == "on") { + nsCOMPtr atom = getter_AddRefs(NS_NewAtom(mPropName)); nsIEventListenerManager *mManager = nsnull; - if (mPropName == "onmousedown" || mPropName == "onmouseup" || mPropName == "onclick" || - mPropName == "onmouseover" || mPropName == "onmouseout") { + if (atom == nsLayoutAtoms::onmousedown || atom == nsLayoutAtoms::onmouseup || atom == nsLayoutAtoms::onclick || + atom == nsLayoutAtoms::onmouseover || atom == nsLayoutAtoms::onmouseout) { if (NS_OK == GetListenerManager(&mManager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMMouseListenerIID)) { + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, atom, kIDOMMouseListenerIID)) { NS_RELEASE(mManager); return PR_FALSE; } } } - else if (mPropName == "onkeydown" || mPropName == "onkeyup" || mPropName == "onkeypress") { + else if (atom == nsLayoutAtoms::onkeydown || atom == nsLayoutAtoms::onkeyup || atom == nsLayoutAtoms::onkeypress) { if (NS_OK == GetListenerManager(&mManager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMKeyListenerIID)) { + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, atom, kIDOMKeyListenerIID)) { NS_RELEASE(mManager); return PR_FALSE; } } } - else if (mPropName == "onmousemove") { + else if (atom == nsLayoutAtoms::onmousemove) { if (NS_OK == GetListenerManager(&mManager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMMouseMotionListenerIID)) { + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, atom, kIDOMMouseMotionListenerIID)) { NS_RELEASE(mManager); return PR_FALSE; } } } - else if (mPropName == "onfocus" || mPropName == "onblur") { + else if (atom == nsLayoutAtoms::onfocus || atom == nsLayoutAtoms::onblur) { if (NS_OK == GetListenerManager(&mManager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMFocusListenerIID)) { + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, atom, kIDOMFocusListenerIID)) { NS_RELEASE(mManager); return PR_FALSE; } } } - else if (mPropName == "onsubmit" || mPropName == "onreset" || mPropName == "onchange" || - mPropName == "onselect") { + else if (atom == nsLayoutAtoms::onsubmit || atom == nsLayoutAtoms::onreset || atom == nsLayoutAtoms::onchange || + atom == nsLayoutAtoms::onselect) { if (NS_OK == GetListenerManager(&mManager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMFormListenerIID)) { + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, atom, kIDOMFormListenerIID)) { NS_RELEASE(mManager); return PR_FALSE; } } } - else if (mPropName == "onload" || mPropName == "onunload" || mPropName == "onabort" || - mPropName == "onerror") { + else if (atom == nsLayoutAtoms::onload || atom == nsLayoutAtoms::onunload || atom == nsLayoutAtoms::onabort || + atom == nsLayoutAtoms::onerror) { if (NS_OK == GetListenerManager(&mManager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMLoadListenerIID)) { + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, atom, kIDOMLoadListenerIID)) { NS_RELEASE(mManager); return PR_FALSE; } } } - else if (mPropName == "onpaint") { + else if (atom == nsLayoutAtoms::onpaint) { if (NS_OK == GetListenerManager(&mManager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *) JS_GetContextPrivate(aContext); if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, - kIDOMPaintListenerIID)) { + atom, kIDOMPaintListenerIID)) { NS_RELEASE(mManager); return PR_FALSE; } diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index c4061f6d8f4b..95cb0200ab42 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -965,7 +965,8 @@ nsGenericElement::GetScriptObject(nsIScriptContext* aContext, nsAutoString tag; mTag->ToString(tag); res = factory->NewScriptElement(tag, aContext, mContent, - mParent, (void**)&slots->mScriptObject); + mParent ? (nsISupports*)mParent : (nsISupports*)mDocument, + (void**)&slots->mScriptObject); NS_RELEASE(factory); char tagBuf[50]; @@ -1112,71 +1113,72 @@ nsGenericElement::SetProperty(JSContext *aContext, jsval aID, jsval *aVp) propName.SetString(JS_GetStringChars(JS_ValueToString(aContext, aID))); prefix.SetString(propName.GetUnicode(), 2); if (prefix == "on") { + nsCOMPtr atom = getter_AddRefs(NS_NewAtom(propName)); nsIEventListenerManager *manager = nsnull; - if (propName == "onmousedown" || propName == "onmouseup" || propName == "onclick" || - propName == "onmouseover" || propName == "onmouseout") { + if (atom == nsLayoutAtoms::onmousedown || atom == nsLayoutAtoms::onmouseup || atom == nsLayoutAtoms::onclick || + atom == nsLayoutAtoms::onmouseover || atom == nsLayoutAtoms::onmouseout) { if (NS_OK == GetListenerManager(&manager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMMouseListenerIID)) { + if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, atom, kIDOMMouseListenerIID)) { NS_RELEASE(manager); return PR_FALSE; } } } - else if (propName == "onkeydown" || propName == "onkeyup" || propName == "onkeypress") { + else if (atom == nsLayoutAtoms::onkeydown || atom == nsLayoutAtoms::onkeyup || atom == nsLayoutAtoms::onkeypress) { if (NS_OK == GetListenerManager(&manager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMKeyListenerIID)) { + if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, atom, kIDOMKeyListenerIID)) { NS_RELEASE(manager); return PR_FALSE; } } } - else if (propName == "onmousemove") { + else if (atom == nsLayoutAtoms::onmousemove) { if (NS_OK == GetListenerManager(&manager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMMouseMotionListenerIID)) { + if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, atom, kIDOMMouseMotionListenerIID)) { NS_RELEASE(manager); return PR_FALSE; } } } - else if (propName == "onfocus" || propName == "onblur") { + else if (atom == nsLayoutAtoms::onfocus || atom == nsLayoutAtoms::onblur) { if (NS_OK == GetListenerManager(&manager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMFocusListenerIID)) { + if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, atom, kIDOMFocusListenerIID)) { NS_RELEASE(manager); return PR_FALSE; } } } - else if (propName == "onsubmit" || propName == "onreset" || propName == "onchange" || - propName == "onselect") { + else if (atom == nsLayoutAtoms::onsubmit || atom == nsLayoutAtoms::onreset || atom == nsLayoutAtoms::onchange || + atom == nsLayoutAtoms::onselect) { if (NS_OK == GetListenerManager(&manager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMFormListenerIID)) { + if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, atom, kIDOMFormListenerIID)) { NS_RELEASE(manager); return PR_FALSE; } } } - else if (propName == "onload" || propName == "onunload" || propName == "onabort" || - propName == "onerror") { + else if (atom == nsLayoutAtoms::onload || atom == nsLayoutAtoms::onunload || atom == nsLayoutAtoms::onabort || + atom == nsLayoutAtoms::onerror) { if (NS_OK == GetListenerManager(&manager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMLoadListenerIID)) { + if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, atom, kIDOMLoadListenerIID)) { NS_RELEASE(manager); return PR_FALSE; } } } - else if (propName == "onpaint") { + else if (atom == nsLayoutAtoms::onpaint) { if (NS_OK == GetListenerManager(&manager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *) JS_GetContextPrivate(aContext); if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, - kIDOMPaintListenerIID)) { + atom, kIDOMPaintListenerIID)) { NS_RELEASE(manager); return PR_FALSE; } @@ -1305,7 +1307,7 @@ nsGenericElement::AddScriptEventListener(nsIAtom* aAttribute, if (NS_OK == receiver->GetListenerManager(&manager)) { nsIScriptObjectOwner *mObjectOwner; if (NS_OK == global->QueryInterface(kIScriptObjectOwnerIID, (void**)&mObjectOwner)) { - ret = manager->AddScriptEventListener(context, mObjectOwner, aAttribute, aValue, aIID); + ret = manager->AddScriptEventListener(context, mObjectOwner, aAttribute, aValue, aIID, PR_FALSE); NS_RELEASE(mObjectOwner); } NS_RELEASE(manager); @@ -1321,7 +1323,7 @@ nsGenericElement::AddScriptEventListener(nsIAtom* aAttribute, if (NS_OK == mContent->QueryInterface(kIScriptObjectOwnerIID, (void**) &cowner)) { ret = manager->AddScriptEventListener(context, cowner, - aAttribute, aValue, aIID); + aAttribute, aValue, aIID, PR_TRUE); NS_RELEASE(cowner); } NS_RELEASE(manager); diff --git a/content/events/public/nsIEventListenerManager.h b/content/events/public/nsIEventListenerManager.h index 768f272b68fb..5b792fdcf8c7 100644 --- a/content/events/public/nsIEventListenerManager.h +++ b/content/events/public/nsIEventListenerManager.h @@ -85,15 +85,21 @@ public: * @param an event listener */ - virtual nsresult AddScriptEventListener(nsIScriptContext*aContext, nsIScriptObjectOwner *aScriptObjectOwner, - nsIAtom *aName, const nsString& aFunc, REFNSIID aIID) = 0; + virtual nsresult AddScriptEventListener(nsIScriptContext*aContext, + nsIScriptObjectOwner *aScriptObjectOwner, + nsIAtom *aName, + const nsString& aFunc, + REFNSIID aIID, + PRBool aDeferCompilation) = 0; /** * Registers an event listners which already exists on the given script object with the event * listener manager. * @param an event listener */ - virtual nsresult RegisterScriptEventListener(nsIScriptContext *aContext, nsIScriptObjectOwner *aScriptObjectOwner, + virtual nsresult RegisterScriptEventListener(nsIScriptContext *aContext, + nsIScriptObjectOwner *aScriptObjectOwner, + nsIAtom* aName, REFNSIID aIID) = 0; /** diff --git a/content/events/src/nsEventListenerManager.cpp b/content/events/src/nsEventListenerManager.cpp index 9818cdb7b16c..15b420d15393 100644 --- a/content/events/src/nsEventListenerManager.cpp +++ b/content/events/src/nsEventListenerManager.cpp @@ -41,10 +41,14 @@ #include "nsIPrivateDOMEvent.h" #include "nsIScriptObjectOwner.h" #include "nsIScriptEventListener.h" +#include "nsIJSEventListener.h" #include "nsDOMEventsIIDs.h" #include "prmem.h" #include "nsIScriptGlobalObject.h" #include "nsIScriptGlobalObjectData.h" +#include "nsLayoutAtoms.h" +#include "nsINameSpaceManager.h" +#include "nsIContent.h" #include "nsCOMPtr.h" static NS_DEFINE_IID(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID); @@ -236,6 +240,7 @@ nsresult nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener ls->mListener = aListener; ls->mFlags = aFlags; ls->mSubType = aSubType; + ls->mHandlerIsString = 0; (*listeners)->InsertElementAt((void*)ls, (*listeners)->Count()); NS_ADDREF(aListener); } @@ -288,133 +293,133 @@ nsresult nsEventListenerManager::RemoveEventListenerByIID(nsIDOMEventListener *a return NS_OK; } -nsresult nsEventListenerManager::GetIdentifiersForType(const nsString& aType, nsIID& aIID, PRInt32* aFlags) +nsresult nsEventListenerManager::GetIdentifiersForType(nsIAtom* aType, nsIID& aIID, PRInt32* aFlags) { - if (aType == "mousedown") { + if (aType == nsLayoutAtoms::onmousedown) { aIID = kIDOMMouseListenerIID; *aFlags = NS_EVENT_BITS_MOUSE_MOUSEDOWN; } - else if (aType == "mouseup") { + else if (aType == nsLayoutAtoms::onmouseup) { aIID = kIDOMMouseListenerIID; *aFlags = NS_EVENT_BITS_MOUSE_MOUSEUP; } - else if (aType == "click") { + else if (aType == nsLayoutAtoms::onclick) { aIID = kIDOMMouseListenerIID; *aFlags = NS_EVENT_BITS_MOUSE_CLICK; } - else if (aType == "dblclick") { + else if (aType == nsLayoutAtoms::ondblclick) { aIID = kIDOMMouseListenerIID; *aFlags = NS_EVENT_BITS_MOUSE_DBLCLICK; } - else if (aType == "mouseover") { + else if (aType == nsLayoutAtoms::onmouseover) { aIID = kIDOMMouseListenerIID; *aFlags = NS_EVENT_BITS_MOUSE_MOUSEOVER; } - else if (aType == "mouseout") { + else if (aType == nsLayoutAtoms::onmouseout) { aIID = kIDOMMouseListenerIID; *aFlags = NS_EVENT_BITS_MOUSE_MOUSEOUT; } - else if (aType == "keydown") { + else if (aType == nsLayoutAtoms::onkeydown) { aIID = kIDOMKeyListenerIID; *aFlags = NS_EVENT_BITS_KEY_KEYDOWN; } - else if (aType == "keyup") { + else if (aType == nsLayoutAtoms::onkeyup) { aIID = kIDOMKeyListenerIID; *aFlags = NS_EVENT_BITS_KEY_KEYUP; } - else if (aType == "keypress") { + else if (aType == nsLayoutAtoms::onkeypress) { aIID = kIDOMKeyListenerIID; *aFlags = NS_EVENT_BITS_KEY_KEYPRESS; } - else if (aType == "mousemove") { + else if (aType == nsLayoutAtoms::onmousemove) { aIID = kIDOMMouseMotionListenerIID; *aFlags = NS_EVENT_BITS_MOUSEMOTION_MOUSEMOVE; } - else if (aType == "focus") { + else if (aType == nsLayoutAtoms::onfocus) { aIID = kIDOMFocusListenerIID; *aFlags = NS_EVENT_BITS_FOCUS_FOCUS; } - else if (aType == "blur") { + else if (aType == nsLayoutAtoms::onblur) { aIID = kIDOMFocusListenerIID; *aFlags = NS_EVENT_BITS_FOCUS_BLUR; } - else if (aType == "submit") { + else if (aType == nsLayoutAtoms::onsubmit) { aIID = kIDOMFormListenerIID; *aFlags = NS_EVENT_BITS_FORM_SUBMIT; } - else if (aType == "reset") { + else if (aType == nsLayoutAtoms::onreset) { aIID = kIDOMFormListenerIID; *aFlags = NS_EVENT_BITS_FORM_RESET; } - else if (aType == "change") { + else if (aType == nsLayoutAtoms::onchange) { aIID = kIDOMFormListenerIID; *aFlags = NS_EVENT_BITS_FORM_CHANGE; } - else if (aType == "select") { + else if (aType == nsLayoutAtoms::onselect) { aIID = kIDOMFormListenerIID; *aFlags = NS_EVENT_BITS_FORM_SELECT; } - else if (aType == "input") { + else if (aType == nsLayoutAtoms::oninput) { aIID = kIDOMFormListenerIID; *aFlags = NS_EVENT_BITS_FORM_INPUT; } - else if (aType == "load") { + else if (aType == nsLayoutAtoms::onload) { aIID = kIDOMLoadListenerIID; *aFlags = NS_EVENT_BITS_LOAD_LOAD; } - else if (aType == "unload") { + else if (aType == nsLayoutAtoms::onunload) { aIID = kIDOMLoadListenerIID; *aFlags = NS_EVENT_BITS_LOAD_UNLOAD; } - else if (aType == "abort") { + else if (aType == nsLayoutAtoms::onabort) { aIID = kIDOMLoadListenerIID; *aFlags = NS_EVENT_BITS_LOAD_ABORT; } - else if (aType == "error") { + else if (aType == nsLayoutAtoms::onerror) { aIID = kIDOMLoadListenerIID; *aFlags = NS_EVENT_BITS_LOAD_ERROR; } - else if (aType == "paint") { + else if (aType == nsLayoutAtoms::onpaint) { aIID = kIDOMPaintListenerIID; *aFlags = NS_EVENT_BITS_PAINT_PAINT; } // extened this to handle IME related events - else if (aType == "create") { + else if (aType == nsLayoutAtoms::oncreate) { aIID = kIDOMMenuListenerIID; *aFlags = NS_EVENT_BITS_MENU_CREATE; } - else if (aType == "destroy") { + else if (aType == nsLayoutAtoms::ondestroy) { aIID = kIDOMMenuListenerIID; *aFlags = NS_EVENT_BITS_MENU_DESTROY; } - else if (aType == "command") { + else if (aType == nsLayoutAtoms::oncommand) { aIID = kIDOMMenuListenerIID; *aFlags = NS_EVENT_BITS_MENU_ACTION; } - else if (aType == "broadcast") { + else if (aType == nsLayoutAtoms::onbroadcast) { aIID = kIDOMMenuListenerIID; *aFlags = NS_EVENT_BITS_XUL_BROADCAST; } - else if (aType == "commandupdate") { + else if (aType == nsLayoutAtoms::oncommandupdate) { aIID = kIDOMMenuListenerIID; *aFlags = NS_EVENT_BITS_XUL_COMMAND_UPDATE; } - else if (aType == "dragenter") { + else if (aType == nsLayoutAtoms::ondragenter) { aIID = NS_GET_IID(nsIDOMDragListener); *aFlags = NS_EVENT_BITS_DRAG_ENTER; } - else if (aType == "dragover") { + else if (aType == nsLayoutAtoms::ondragover) { aIID = NS_GET_IID(nsIDOMDragListener); *aFlags = NS_EVENT_BITS_DRAG_OVER; } - else if (aType == "dragexit") { + else if (aType == nsLayoutAtoms::ondragexit) { aIID = NS_GET_IID(nsIDOMDragListener); *aFlags = NS_EVENT_BITS_DRAG_EXIT; } - else if (aType == "dragdrop") { + else if (aType == nsLayoutAtoms::ondragdrop) { aIID = NS_GET_IID(nsIDOMDragListener); *aFlags = NS_EVENT_BITS_DRAG_DROP; } - else if (aType == "draggesture") { + else if (aType == nsLayoutAtoms::ondraggesture) { aIID = NS_GET_IID(nsIDOMDragListener); *aFlags = NS_EVENT_BITS_DRAG_GESTURE; } @@ -429,11 +434,18 @@ nsresult nsEventListenerManager::AddEventListenerByType(nsIDOMEventListener *aLi { PRInt32 subType; nsIID iid; + nsAutoString str("on"); + nsIAtom* atom; - if (NS_OK == GetIdentifiersForType(aType, iid, &subType)) { + str.Append(aType); + atom = NS_NewAtom(str); + + if (NS_OK == GetIdentifiersForType(atom, iid, &subType)) { AddEventListener(aListener, iid, aFlags, subType); } + NS_IF_RELEASE(atom); + return NS_OK; } @@ -443,38 +455,81 @@ nsresult nsEventListenerManager::RemoveEventListenerByType(nsIDOMEventListener * PRInt32 subType; nsIID iid; - if (NS_OK == GetIdentifiersForType(aType, iid, &subType)) { + nsAutoString str("on"); + nsIAtom* atom; + + str.Append(aType); + atom = NS_NewAtom(str); + + if (NS_OK == GetIdentifiersForType(atom, iid, &subType)) { RemoveEventListener(aListener, iid, aFlags, subType); } + NS_IF_RELEASE(atom); + return NS_OK; } -nsresult nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext, JSObject *aObject, REFNSIID aIID) +nsListenerStruct* +nsEventListenerManager::FindJSEventListener(REFNSIID aIID) { - nsVoidArray *mListeners; + nsVoidArray *listeners; - if (NS_OK == GetEventListeners(&mListeners, aIID)) { + nsresult result = GetEventListeners(&listeners, aIID); + if (NS_SUCCEEDED(result)) { //Run through the listeners for this IID and see if a script listener is registered - //If so, we're set. - if (nsnull != mListeners) { + if (nsnull != listeners) { nsListenerStruct *ls; - for (int i=0; iCount(); i++) { - ls = (nsListenerStruct*)mListeners->ElementAt(i); + for (int i=0; iCount(); i++) { + ls = (nsListenerStruct*)listeners->ElementAt(i); if (ls->mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) { - return NS_OK; + return ls; } } } + } + + return nsnull; +} + +nsresult nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext, + nsIScriptObjectOwner *aOwner, + nsIAtom* aName, + REFNSIID aIID, + PRBool aIsString) +{ + nsIDOMEventListener* theListener = nsnull; + nsresult result = NS_OK; + nsListenerStruct *ls; + + ls = FindJSEventListener(aIID); + + if (nsnull == ls) { //If we didn't find a script listener or no listeners existed create and add a new one. - nsIDOMEventListener *mScriptListener; - if (NS_OK == NS_NewJSEventListener(&mScriptListener, aContext, aObject)) { - AddEventListenerByIID(mScriptListener, aIID, NS_EVENT_FLAG_BUBBLE | NS_PRIV_EVENT_FLAG_SCRIPT); - NS_RELEASE(mScriptListener); - return NS_OK; + nsIDOMEventListener* scriptListener; + result = NS_NewJSEventListener(&scriptListener, aContext, aOwner); + if (NS_SUCCEEDED(result)) { + AddEventListenerByIID(scriptListener, aIID, NS_EVENT_FLAG_BUBBLE | NS_PRIV_EVENT_FLAG_SCRIPT); + NS_RELEASE(scriptListener); + ls = FindJSEventListener(aIID); } } - return NS_ERROR_FAILURE; + + if (NS_SUCCEEDED(result) && ls) { + PRInt32 flags; + nsIID iid; + result = GetIdentifiersForType(aName, iid, &flags); + if (NS_SUCCEEDED(result)) { + if (aIsString) { + ls->mHandlerIsString |= flags; + } + else { + ls->mHandlerIsString &= ~flags; + } + } + } + + return result; } nsresult @@ -482,28 +537,82 @@ nsEventListenerManager::AddScriptEventListener(nsIScriptContext* aContext, nsIScriptObjectOwner *aScriptObjectOwner, nsIAtom *aName, const nsString& aBody, - REFNSIID aIID) + REFNSIID aIID, + PRBool aDeferCompilation) { JSObject *scriptObject; nsresult rv; - rv = aScriptObjectOwner->GetScriptObject(aContext, (void**)&scriptObject); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; - rv = aContext->CompileFunction(scriptObject, aName, aBody); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; - return SetJSEventListener(aContext, scriptObject, aIID); + if (!aDeferCompilation) { + rv = aScriptObjectOwner->GetScriptObject(aContext, (void**)&scriptObject); + if (NS_FAILED(rv)) + return rv; + rv = aContext->CompileFunction(scriptObject, aName, aBody); + if (NS_FAILED(rv)) + return rv; + } + return SetJSEventListener(aContext, aScriptObjectOwner, aName, aIID, aDeferCompilation); } -nsresult nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *aContext, nsIScriptObjectOwner *aScriptObjectOwner, - REFNSIID aIID) +nsresult nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *aContext, + nsIScriptObjectOwner *aScriptObjectOwner, + nsIAtom *aName, + REFNSIID aIID) { - JSObject *scriptObject; - if (NS_SUCCEEDED(aScriptObjectOwner->GetScriptObject(aContext, (void**)&scriptObject))) { - return SetJSEventListener(aContext, scriptObject, aIID); + return SetJSEventListener(aContext, aScriptObjectOwner, aName, aIID, PR_FALSE); +} + +nsresult +nsEventListenerManager::HandleEventSubType(nsListenerStruct* aListenerStruct, + nsIDOMEvent* aDOMEvent, + PRUint32 aSubType) +{ + nsresult result = NS_OK; + + // If this is a script handler and we haven't yet + // compiled the event handler itself + if ((aListenerStruct->mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) && + (aListenerStruct->mHandlerIsString & aSubType)) { + nsCOMPtr jslistener = do_QueryInterface(aListenerStruct->mListener); + if (jslistener) { + nsCOMPtr owner; + nsCOMPtr scriptCX; + result = jslistener->GetEventTarget(getter_AddRefs(scriptCX), getter_AddRefs(owner)); + + if (NS_SUCCEEDED(result)) { + JSObject* jsobj; + result = owner->GetScriptObject(scriptCX, (void**)&jsobj); + // This should never happen for anything but content + // XXX I don't like that we have to reference content + // from here. The alternative is to store the event handler + // string on the JS object itself. + if (NS_SUCCEEDED(result)) { + nsCOMPtr content = do_QueryInterface(owner); + NS_ASSERTION(content, "only content should have event handler attributes"); + if (content) { + nsAutoString eventString; + if (NS_SUCCEEDED(aDOMEvent->GetType(eventString))) { + + eventString.Insert("on", 0, 2); + nsCOMPtr atom = getter_AddRefs(NS_NewAtom(eventString)); + nsString handlerBody; + result = content->GetAttribute(kNameSpaceID_None, atom, handlerBody); + if (NS_SUCCEEDED(result)) { + result = scriptCX->CompileFunction(jsobj, atom, handlerBody); + aListenerStruct->mHandlerIsString &= ~aSubType; + } + } + } + } + } + } } - return NS_ERROR_FAILURE; + + if (NS_SUCCEEDED(result)) { + result = aListenerStruct->mListener->HandleEvent(aDOMEvent); + } + + return result; } /** @@ -548,7 +657,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, nsIDOMMouseListener *mMouseListener; ls = (nsListenerStruct*)mMouseListeners->ElementAt(i); - + if (ls->mFlags & aFlags) { if (NS_OK == ls->mListener->QueryInterface(kIDOMMouseListenerIID, (void**)&mMouseListener)) { switch(aEvent->message) { @@ -585,10 +694,12 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_MOUSE_LEFT_BUTTON_DOWN: case NS_MOUSE_MIDDLE_BUTTON_DOWN: case NS_MOUSE_RIGHT_BUTTON_DOWN: + subType = NS_EVENT_BITS_MOUSE_MOUSEDOWN; if (ls->mSubType & NS_EVENT_BITS_MOUSE_MOUSEDOWN) { correctSubType = PR_TRUE; } @@ -596,6 +707,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, case NS_MOUSE_LEFT_BUTTON_UP: case NS_MOUSE_MIDDLE_BUTTON_UP: case NS_MOUSE_RIGHT_BUTTON_UP: + subType = NS_EVENT_BITS_MOUSE_MOUSEUP; if (ls->mSubType & NS_EVENT_BITS_MOUSE_MOUSEUP) { correctSubType = PR_TRUE; } @@ -603,6 +715,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, case NS_MOUSE_LEFT_CLICK: case NS_MOUSE_MIDDLE_CLICK: case NS_MOUSE_RIGHT_CLICK: + subType = NS_EVENT_BITS_MOUSE_CLICK; if (ls->mSubType & NS_EVENT_BITS_MOUSE_CLICK) { correctSubType = PR_TRUE; } @@ -610,16 +723,19 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, case NS_MOUSE_LEFT_DOUBLECLICK: case NS_MOUSE_MIDDLE_DOUBLECLICK: case NS_MOUSE_RIGHT_DOUBLECLICK: + subType = NS_EVENT_BITS_MOUSE_DBLCLICK; if (ls->mSubType & NS_EVENT_BITS_MOUSE_DBLCLICK) { correctSubType = PR_TRUE; } break; case NS_MOUSE_ENTER: + subType = NS_EVENT_BITS_MOUSE_MOUSEOVER; if (ls->mSubType & NS_EVENT_BITS_MOUSE_MOUSEOVER) { correctSubType = PR_TRUE; } break; case NS_MOUSE_EXIT: + subType = NS_EVENT_BITS_MOUSE_MOUSEOUT; if (ls->mSubType & NS_EVENT_BITS_MOUSE_MOUSEOUT) { correctSubType = PR_TRUE; } @@ -628,7 +744,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -662,8 +778,10 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_MOUSE_MOVE: + subType = NS_EVENT_BITS_MOUSEMOTION_MOUSEMOVE; if (ls->mSubType & NS_EVENT_BITS_MOUSEMOTION_MOUSEMOVE) { correctSubType = PR_TRUE; } @@ -672,7 +790,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -709,13 +827,16 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_COMPOSITION_START: + subType = NS_EVENT_BITS_COMPOSITION_START; if (ls->mSubType & NS_EVENT_BITS_COMPOSITION_START) { correctSubType = PR_TRUE; } break; case NS_COMPOSITION_END: + subType = NS_EVENT_BITS_COMPOSITION_END; if (ls->mSubType & NS_EVENT_BITS_COMPOSITION_END) { correctSubType = PR_TRUE; } @@ -724,7 +845,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -754,11 +875,12 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = NS_EVENT_BITS_TEXT_TEXT; if (ls->mSubType & NS_EVENT_BITS_TEXT_TEXT) { correctSubType = PR_TRUE; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -800,18 +922,22 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_KEY_UP: + subType = NS_EVENT_BITS_KEY_KEYUP; if (ls->mSubType & NS_EVENT_BITS_KEY_KEYUP) { correctSubType = PR_TRUE; } break; case NS_KEY_DOWN: + subType = NS_EVENT_BITS_KEY_KEYDOWN; if (ls->mSubType & NS_EVENT_BITS_KEY_KEYDOWN) { correctSubType = PR_TRUE; } break; case NS_KEY_PRESS: + subType = NS_EVENT_BITS_KEY_KEYPRESS; if (ls->mSubType & NS_EVENT_BITS_KEY_KEYPRESS) { correctSubType = PR_TRUE; } @@ -820,7 +946,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -858,13 +984,16 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_FOCUS_CONTENT: + subType = NS_EVENT_BITS_FOCUS_FOCUS; if (ls->mSubType & NS_EVENT_BITS_FOCUS_FOCUS) { correctSubType = PR_TRUE; } break; case NS_BLUR_CONTENT: + subType = NS_EVENT_BITS_FOCUS_BLUR; if (ls->mSubType & NS_EVENT_BITS_FOCUS_BLUR) { correctSubType = PR_TRUE; } @@ -873,7 +1002,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -923,28 +1052,34 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_FORM_SUBMIT: + subType = NS_EVENT_BITS_FORM_SUBMIT; if (ls->mSubType & NS_EVENT_BITS_FORM_SUBMIT) { correctSubType = PR_TRUE; } break; case NS_FORM_RESET: + subType = NS_EVENT_BITS_FORM_RESET; if (ls->mSubType & NS_EVENT_BITS_FORM_RESET) { correctSubType = PR_TRUE; } break; case NS_FORM_CHANGE: + subType = NS_EVENT_BITS_FORM_CHANGE; if (ls->mSubType & NS_EVENT_BITS_FORM_CHANGE) { correctSubType = PR_TRUE; } break; case NS_FORM_SELECTED: + subType = NS_EVENT_BITS_FORM_SELECT; if (ls->mSubType & NS_EVENT_BITS_FORM_SELECT) { correctSubType = PR_TRUE; } break; case NS_FORM_INPUT: + subType = NS_EVENT_BITS_FORM_INPUT; if (ls->mSubType & NS_EVENT_BITS_FORM_INPUT) { correctSubType = PR_TRUE; } @@ -953,7 +1088,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -992,13 +1127,16 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_PAGE_LOAD: + subType = NS_EVENT_BITS_LOAD_LOAD; if (ls->mSubType & NS_EVENT_BITS_LOAD_LOAD) { correctSubType = PR_TRUE; } break; case NS_PAGE_UNLOAD: + subType = NS_EVENT_BITS_LOAD_UNLOAD; if (ls->mSubType & NS_EVENT_BITS_LOAD_UNLOAD) { correctSubType = PR_TRUE; } @@ -1007,7 +1145,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -1036,11 +1174,12 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = NS_EVENT_BITS_PAINT_PAINT; if (ls->mSubType & NS_EVENT_BITS_PAINT_PAINT) { correctSubType = PR_TRUE; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -1088,24 +1227,30 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_DRAGDROP_ENTER: + subType = NS_EVENT_BITS_DRAG_ENTER; if (dragStruct->mSubType & NS_EVENT_BITS_DRAG_ENTER) correctSubType = PR_TRUE; break; case NS_DRAGDROP_OVER: + subType = NS_EVENT_BITS_DRAG_OVER; if (dragStruct->mSubType & NS_EVENT_BITS_DRAG_OVER) correctSubType = PR_TRUE; break; case NS_DRAGDROP_EXIT: + subType = NS_EVENT_BITS_DRAG_EXIT; if (dragStruct->mSubType & NS_EVENT_BITS_DRAG_EXIT) correctSubType = PR_TRUE; break; case NS_DRAGDROP_DROP: + subType = NS_EVENT_BITS_DRAG_DROP; if (dragStruct->mSubType & NS_EVENT_BITS_DRAG_DROP) correctSubType = PR_TRUE; break; case NS_DRAGDROP_GESTURE: + subType = NS_EVENT_BITS_DRAG_GESTURE; if (dragStruct->mSubType & NS_EVENT_BITS_DRAG_GESTURE) correctSubType = PR_TRUE; break; @@ -1113,7 +1258,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || dragStruct->mSubType == NS_EVENT_BITS_DRAG_NONE) - ret = dragStruct->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(dragStruct, *aDOMEvent, subType); } } } @@ -1162,28 +1307,34 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_MENU_CREATE: + subType = NS_EVENT_BITS_MENU_CREATE; if (ls->mSubType & NS_EVENT_BITS_MENU_CREATE) { correctSubType = PR_TRUE; } break; case NS_MENU_DESTROY: + subType = NS_EVENT_BITS_MENU_DESTROY; if (ls->mSubType & NS_EVENT_BITS_MENU_DESTROY) { correctSubType = PR_TRUE; } break; case NS_MENU_ACTION: + subType = NS_EVENT_BITS_MENU_ACTION; if (ls->mSubType & NS_EVENT_BITS_MENU_ACTION) { correctSubType = PR_TRUE; } break; case NS_XUL_BROADCAST: + subType = NS_EVENT_BITS_XUL_BROADCAST; if (ls->mSubType & NS_EVENT_BITS_XUL_BROADCAST) { correctSubType = PR_TRUE; } break; case NS_XUL_COMMAND_UPDATE: + subType = NS_EVENT_BITS_XUL_COMMAND_UPDATE; if (ls->mSubType & NS_EVENT_BITS_XUL_COMMAND_UPDATE) { correctSubType = PR_TRUE; } @@ -1192,7 +1343,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } diff --git a/content/events/src/nsEventListenerManager.h b/content/events/src/nsEventListenerManager.h index 2d781a157a67..2f9928014809 100644 --- a/content/events/src/nsEventListenerManager.h +++ b/content/events/src/nsEventListenerManager.h @@ -27,11 +27,13 @@ #include "jsapi.h" class nsIDOMEvent; +class nsIAtom; typedef struct { nsIDOMEventListener* mListener; PRUint8 mFlags; PRUint8 mSubType; + PRUint32 mHandlerIsString; } nsListenerStruct; //Flag must live higher than all event flags in nsGUIEvent.h @@ -68,13 +70,15 @@ public: virtual nsresult AddEventListenerByType(nsIDOMEventListener *aListener, const nsString& type, PRInt32 aFlags); virtual nsresult RemoveEventListenerByType(nsIDOMEventListener *aListener, const nsString& type, PRInt32 aFlags) ; - virtual nsresult AddScriptEventListener(nsIScriptContext* aContext, + virtual nsresult AddScriptEventListener(nsIScriptContext*aContext, nsIScriptObjectOwner *aScriptObjectOwner, nsIAtom *aName, const nsString& aFunc, - const nsIID& aIID); + REFNSIID aIID, + PRBool aDeferCompilation); virtual nsresult RegisterScriptEventListener(nsIScriptContext *aContext, nsIScriptObjectOwner *aScriptObjectOwner, + nsIAtom* aName, const nsIID& aIID); @@ -93,9 +97,14 @@ public: virtual nsresult RemoveAllListeners(PRBool aScriptOnly); + static nsresult GetIdentifiersForType(nsIAtom* aType, nsIID& aIID, PRInt32* aSubType); + protected: - nsresult SetJSEventListener(nsIScriptContext *aContext, JSObject *aObject, REFNSIID aIID); - nsresult GetIdentifiersForType(const nsString& aType, nsIID& aIID, PRInt32* aSubType); + nsresult HandleEventSubType(nsListenerStruct* aListenerStruct, + nsIDOMEvent* aDOMEvent, + PRUint32 aSubType); + nsListenerStruct* FindJSEventListener(REFNSIID aIID); + nsresult SetJSEventListener(nsIScriptContext *aContext, nsIScriptObjectOwner *aOwner, nsIAtom* aName, REFNSIID aIID, PRBool aIsString); nsresult AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 aFlags, PRInt32 aSubType); nsresult RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 aFlags, PRInt32 aSubType); void ReleaseListeners(nsVoidArray** aListeners, PRBool aScriptOnly); diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index e11f45c01fdb..f9ad8caf9258 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -61,6 +61,7 @@ #include "nsIHTMLContentContainer.h" #include "nsHTMLParts.h" #include "nsString.h" +#include "nsLayoutAtoms.h" #include "nsHTMLAtoms.h" #include "nsDOMEventsIIDs.h" #include "nsIEventStateManager.h" @@ -632,36 +633,36 @@ nsGenericHTMLElement::SetAttribute(PRInt32 aNameSpaceID, } else { // Check for event handlers - if ((nsHTMLAtoms::onclick == aAttribute) || - (nsHTMLAtoms::ondblclick == aAttribute) || - (nsHTMLAtoms::onmousedown == aAttribute) || - (nsHTMLAtoms::onmouseup == aAttribute) || - (nsHTMLAtoms::onmouseover == aAttribute) || - (nsHTMLAtoms::onmouseout == aAttribute)) + if ((nsLayoutAtoms::onclick == aAttribute) || + (nsLayoutAtoms::ondblclick == aAttribute) || + (nsLayoutAtoms::onmousedown == aAttribute) || + (nsLayoutAtoms::onmouseup == aAttribute) || + (nsLayoutAtoms::onmouseover == aAttribute) || + (nsLayoutAtoms::onmouseout == aAttribute)) AddScriptEventListener(aAttribute, aValue, kIDOMMouseListenerIID); - else if ((nsHTMLAtoms::onkeydown == aAttribute) || - (nsHTMLAtoms::onkeyup == aAttribute) || - (nsHTMLAtoms::onkeypress == aAttribute)) + else if ((nsLayoutAtoms::onkeydown == aAttribute) || + (nsLayoutAtoms::onkeyup == aAttribute) || + (nsLayoutAtoms::onkeypress == aAttribute)) AddScriptEventListener(aAttribute, aValue, kIDOMKeyListenerIID); - else if (nsHTMLAtoms::onmousemove == aAttribute) + else if (nsLayoutAtoms::onmousemove == aAttribute) AddScriptEventListener(aAttribute, aValue, kIDOMMouseMotionListenerIID); - else if (nsHTMLAtoms::onload == aAttribute) - AddScriptEventListener(nsHTMLAtoms::onload, aValue, kIDOMLoadListenerIID); - else if ((nsHTMLAtoms::onunload == aAttribute) || - (nsHTMLAtoms::onabort == aAttribute) || - (nsHTMLAtoms::onerror == aAttribute)) + else if (nsLayoutAtoms::onload == aAttribute) + AddScriptEventListener(nsLayoutAtoms::onload, aValue, kIDOMLoadListenerIID); + else if ((nsLayoutAtoms::onunload == aAttribute) || + (nsLayoutAtoms::onabort == aAttribute) || + (nsLayoutAtoms::onerror == aAttribute)) AddScriptEventListener(aAttribute, aValue, kIDOMLoadListenerIID); - else if ((nsHTMLAtoms::onfocus == aAttribute) || - (nsHTMLAtoms::onblur == aAttribute)) + else if ((nsLayoutAtoms::onfocus == aAttribute) || + (nsLayoutAtoms::onblur == aAttribute)) AddScriptEventListener(aAttribute, aValue, kIDOMFocusListenerIID); - else if ((nsHTMLAtoms::onsubmit == aAttribute) || - (nsHTMLAtoms::onreset == aAttribute) || - (nsHTMLAtoms::onchange == aAttribute) || - (nsHTMLAtoms::onselect == aAttribute)) + else if ((nsLayoutAtoms::onsubmit == aAttribute) || + (nsLayoutAtoms::onreset == aAttribute) || + (nsLayoutAtoms::onchange == aAttribute) || + (nsLayoutAtoms::onselect == aAttribute)) AddScriptEventListener(aAttribute, aValue, kIDOMFormListenerIID); - else if (nsHTMLAtoms::onpaint == aAttribute) + else if (nsLayoutAtoms::onpaint == aAttribute) AddScriptEventListener(aAttribute, aValue, kIDOMPaintListenerIID); - else if (nsHTMLAtoms::oninput == aAttribute) + else if (nsLayoutAtoms::oninput == aAttribute) AddScriptEventListener(aAttribute, aValue, kIDOMFormListenerIID); } diff --git a/content/html/content/src/nsHTMLAtomList.h b/content/html/content/src/nsHTMLAtomList.h index 1d9c7ee9a167..9d68783e7e32 100644 --- a/content/html/content/src/nsHTMLAtomList.h +++ b/content/html/content/src/nsHTMLAtomList.h @@ -192,29 +192,6 @@ HTML_ATOM(noshade, "noshade") HTML_ATOM(nowrap, "nowrap") HTML_ATOM(object, "object") HTML_ATOM(ol, "ol") -HTML_ATOM(onabort, "onabort") -HTML_ATOM(onblur, "onblur") -HTML_ATOM(onchange, "onchange") -HTML_ATOM(onselect, "onselect") -HTML_ATOM(onclick, "onclick") -HTML_ATOM(ondblclick, "ondblclick") -HTML_ATOM(ondragdrop, "ondragdrop") -HTML_ATOM(onerror, "onerror") -HTML_ATOM(onfocus, "onfocus") -HTML_ATOM(oninput, "oninput") -HTML_ATOM(onkeydown, "onkeydown") -HTML_ATOM(onkeypress, "onkeypress") -HTML_ATOM(onkeyup, "onkeyup") -HTML_ATOM(onload, "onload") -HTML_ATOM(onmousedown, "onmousedown") -HTML_ATOM(onmousemove, "onmousemove") -HTML_ATOM(onmouseover, "onmouseover") -HTML_ATOM(onmouseout, "onmouseout") -HTML_ATOM(onmouseup, "onmouseup") -HTML_ATOM(onpaint, "onpaint") -HTML_ATOM(onreset, "onreset") -HTML_ATOM(onsubmit, "onsubmit") -HTML_ATOM(onunload, "onunload") HTML_ATOM(option, "option") HTML_ATOM(overflow, "overflow") HTML_ATOM(p, "p") diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index baa39825e6d3..7bd9b201ad2b 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -2495,6 +2495,52 @@ nsHTMLDocument::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject return res; } +PRBool +nsHTMLDocument::Resolve(JSContext *aContext, jsval aID) +{ + nsCOMPtr element; + char* str = JS_GetStringBytes(JS_ValueToString(aContext, aID)); + nsAutoString name(str); + nsresult result = NS_OK; + PRBool ret = PR_TRUE; + + result = NamedItem(name, getter_AddRefs(element)); + if (NS_SUCCEEDED(result) && element) { + nsCOMPtr owner = do_QueryInterface(element); + + if (owner) { + nsCOMPtr scriptContext; + nsCOMPtr contextOwner; + + contextOwner = getter_AddRefs(GetScriptContextOwner()); + if (contextOwner) { + result = contextOwner->GetScriptContext(getter_AddRefs(scriptContext)); + } + + if (!scriptContext) { + scriptContext = dont_AddRef((nsIScriptContext*)JS_GetContextPrivate(aContext)); + } + + JSObject* obj; + if (scriptContext) { + result = owner->GetScriptObject(scriptContext, (void**)&obj); + if (NS_SUCCEEDED(result) && (nsnull != obj)) { + JSObject* myObj; + result = GetScriptObject(scriptContext, (void**)&myObj); + ret = ::JS_DefineProperty(aContext, myObj, + str, OBJECT_TO_JSVAL(obj), + nsnull, nsnull, 0); + } + } + } + } + + if (NS_FAILED(result)) { + ret = PR_FALSE; + } + + return ret; +} //---------------------------- static PRBool IsInline(eHTMLTags aTag) diff --git a/content/html/document/src/nsHTMLDocument.h b/content/html/document/src/nsHTMLDocument.h index 896861b7f912..5abd086bfaab 100644 --- a/content/html/document/src/nsHTMLDocument.h +++ b/content/html/document/src/nsHTMLDocument.h @@ -124,6 +124,9 @@ public: // From nsIScriptObjectOwner interface, implemented by nsDocument NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject); + + // From nsJSScriptObject interface, implemented by nsDocument + virtual PRBool Resolve(JSContext *aContext, jsval aID); /** * Finds text in content diff --git a/content/shared/public/nsHTMLAtomList.h b/content/shared/public/nsHTMLAtomList.h index 1d9c7ee9a167..9d68783e7e32 100644 --- a/content/shared/public/nsHTMLAtomList.h +++ b/content/shared/public/nsHTMLAtomList.h @@ -192,29 +192,6 @@ HTML_ATOM(noshade, "noshade") HTML_ATOM(nowrap, "nowrap") HTML_ATOM(object, "object") HTML_ATOM(ol, "ol") -HTML_ATOM(onabort, "onabort") -HTML_ATOM(onblur, "onblur") -HTML_ATOM(onchange, "onchange") -HTML_ATOM(onselect, "onselect") -HTML_ATOM(onclick, "onclick") -HTML_ATOM(ondblclick, "ondblclick") -HTML_ATOM(ondragdrop, "ondragdrop") -HTML_ATOM(onerror, "onerror") -HTML_ATOM(onfocus, "onfocus") -HTML_ATOM(oninput, "oninput") -HTML_ATOM(onkeydown, "onkeydown") -HTML_ATOM(onkeypress, "onkeypress") -HTML_ATOM(onkeyup, "onkeyup") -HTML_ATOM(onload, "onload") -HTML_ATOM(onmousedown, "onmousedown") -HTML_ATOM(onmousemove, "onmousemove") -HTML_ATOM(onmouseover, "onmouseover") -HTML_ATOM(onmouseout, "onmouseout") -HTML_ATOM(onmouseup, "onmouseup") -HTML_ATOM(onpaint, "onpaint") -HTML_ATOM(onreset, "onreset") -HTML_ATOM(onsubmit, "onsubmit") -HTML_ATOM(onunload, "onunload") HTML_ATOM(option, "option") HTML_ATOM(overflow, "overflow") HTML_ATOM(p, "p") diff --git a/content/shared/public/nsLayoutAtomList.h b/content/shared/public/nsLayoutAtomList.h index 19a66b96de2a..c374090684fe 100644 --- a/content/shared/public/nsLayoutAtomList.h +++ b/content/shared/public/nsLayoutAtomList.h @@ -111,6 +111,40 @@ LAYOUT_ATOM(overflowProperty, "OverflowProperty") LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") LAYOUT_ATOM(viewProperty, "ViewProperty") + // Alphabetical list of event handler names +LAYOUT_ATOM(onabort, "onabort") +LAYOUT_ATOM(onblur, "onblur") +LAYOUT_ATOM(onbroadcast, "onbroadcast") +LAYOUT_ATOM(onchange, "onchange") +LAYOUT_ATOM(onclick, "onclick") +LAYOUT_ATOM(oncommand, "oncommand") +LAYOUT_ATOM(oncommandupdate, "oncommandupdate") +LAYOUT_ATOM(oncreate, "oncreate") +LAYOUT_ATOM(ondblclick, "ondblclick") +LAYOUT_ATOM(ondestroy, "ondestroy") +LAYOUT_ATOM(ondragdrop, "ondragdrop") +LAYOUT_ATOM(ondragenter, "ondragenter") +LAYOUT_ATOM(ondragexit, "ondragexit") +LAYOUT_ATOM(ondraggesture, "ondraggesture") +LAYOUT_ATOM(ondragover, "ondragover") +LAYOUT_ATOM(onerror, "onerror") +LAYOUT_ATOM(onfocus, "onfocus") +LAYOUT_ATOM(oninput, "oninput") +LAYOUT_ATOM(onkeydown, "onkeydown") +LAYOUT_ATOM(onkeypress, "onkeypress") +LAYOUT_ATOM(onkeyup, "onkeyup") +LAYOUT_ATOM(onload, "onload") +LAYOUT_ATOM(onmousedown, "onmousedown") +LAYOUT_ATOM(onmousemove, "onmousemove") +LAYOUT_ATOM(onmouseover, "onmouseover") +LAYOUT_ATOM(onmouseout, "onmouseout") +LAYOUT_ATOM(onmouseup, "onmouseup") +LAYOUT_ATOM(onpaint, "onpaint") +LAYOUT_ATOM(onreset, "onreset") +LAYOUT_ATOM(onselect, "onselect") +LAYOUT_ATOM(onsubmit, "onsubmit") +LAYOUT_ATOM(onunload, "onunload") + #ifdef DEBUG // Alphabetical list of atoms used by debugging code LAYOUT_ATOM(cellMap, "TableCellMap") diff --git a/layout/base/nsLayoutAtomList.h b/layout/base/nsLayoutAtomList.h index 19a66b96de2a..c374090684fe 100644 --- a/layout/base/nsLayoutAtomList.h +++ b/layout/base/nsLayoutAtomList.h @@ -111,6 +111,40 @@ LAYOUT_ATOM(overflowProperty, "OverflowProperty") LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") LAYOUT_ATOM(viewProperty, "ViewProperty") + // Alphabetical list of event handler names +LAYOUT_ATOM(onabort, "onabort") +LAYOUT_ATOM(onblur, "onblur") +LAYOUT_ATOM(onbroadcast, "onbroadcast") +LAYOUT_ATOM(onchange, "onchange") +LAYOUT_ATOM(onclick, "onclick") +LAYOUT_ATOM(oncommand, "oncommand") +LAYOUT_ATOM(oncommandupdate, "oncommandupdate") +LAYOUT_ATOM(oncreate, "oncreate") +LAYOUT_ATOM(ondblclick, "ondblclick") +LAYOUT_ATOM(ondestroy, "ondestroy") +LAYOUT_ATOM(ondragdrop, "ondragdrop") +LAYOUT_ATOM(ondragenter, "ondragenter") +LAYOUT_ATOM(ondragexit, "ondragexit") +LAYOUT_ATOM(ondraggesture, "ondraggesture") +LAYOUT_ATOM(ondragover, "ondragover") +LAYOUT_ATOM(onerror, "onerror") +LAYOUT_ATOM(onfocus, "onfocus") +LAYOUT_ATOM(oninput, "oninput") +LAYOUT_ATOM(onkeydown, "onkeydown") +LAYOUT_ATOM(onkeypress, "onkeypress") +LAYOUT_ATOM(onkeyup, "onkeyup") +LAYOUT_ATOM(onload, "onload") +LAYOUT_ATOM(onmousedown, "onmousedown") +LAYOUT_ATOM(onmousemove, "onmousemove") +LAYOUT_ATOM(onmouseover, "onmouseover") +LAYOUT_ATOM(onmouseout, "onmouseout") +LAYOUT_ATOM(onmouseup, "onmouseup") +LAYOUT_ATOM(onpaint, "onpaint") +LAYOUT_ATOM(onreset, "onreset") +LAYOUT_ATOM(onselect, "onselect") +LAYOUT_ATOM(onsubmit, "onsubmit") +LAYOUT_ATOM(onunload, "onunload") + #ifdef DEBUG // Alphabetical list of atoms used by debugging code LAYOUT_ATOM(cellMap, "TableCellMap") diff --git a/layout/base/public/nsLayoutAtomList.h b/layout/base/public/nsLayoutAtomList.h index 19a66b96de2a..c374090684fe 100644 --- a/layout/base/public/nsLayoutAtomList.h +++ b/layout/base/public/nsLayoutAtomList.h @@ -111,6 +111,40 @@ LAYOUT_ATOM(overflowProperty, "OverflowProperty") LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") LAYOUT_ATOM(viewProperty, "ViewProperty") + // Alphabetical list of event handler names +LAYOUT_ATOM(onabort, "onabort") +LAYOUT_ATOM(onblur, "onblur") +LAYOUT_ATOM(onbroadcast, "onbroadcast") +LAYOUT_ATOM(onchange, "onchange") +LAYOUT_ATOM(onclick, "onclick") +LAYOUT_ATOM(oncommand, "oncommand") +LAYOUT_ATOM(oncommandupdate, "oncommandupdate") +LAYOUT_ATOM(oncreate, "oncreate") +LAYOUT_ATOM(ondblclick, "ondblclick") +LAYOUT_ATOM(ondestroy, "ondestroy") +LAYOUT_ATOM(ondragdrop, "ondragdrop") +LAYOUT_ATOM(ondragenter, "ondragenter") +LAYOUT_ATOM(ondragexit, "ondragexit") +LAYOUT_ATOM(ondraggesture, "ondraggesture") +LAYOUT_ATOM(ondragover, "ondragover") +LAYOUT_ATOM(onerror, "onerror") +LAYOUT_ATOM(onfocus, "onfocus") +LAYOUT_ATOM(oninput, "oninput") +LAYOUT_ATOM(onkeydown, "onkeydown") +LAYOUT_ATOM(onkeypress, "onkeypress") +LAYOUT_ATOM(onkeyup, "onkeyup") +LAYOUT_ATOM(onload, "onload") +LAYOUT_ATOM(onmousedown, "onmousedown") +LAYOUT_ATOM(onmousemove, "onmousemove") +LAYOUT_ATOM(onmouseover, "onmouseover") +LAYOUT_ATOM(onmouseout, "onmouseout") +LAYOUT_ATOM(onmouseup, "onmouseup") +LAYOUT_ATOM(onpaint, "onpaint") +LAYOUT_ATOM(onreset, "onreset") +LAYOUT_ATOM(onselect, "onselect") +LAYOUT_ATOM(onsubmit, "onsubmit") +LAYOUT_ATOM(onunload, "onunload") + #ifdef DEBUG // Alphabetical list of atoms used by debugging code LAYOUT_ATOM(cellMap, "TableCellMap") diff --git a/layout/base/src/nsDocument.cpp b/layout/base/src/nsDocument.cpp index 695c748d9320..be50a7f73316 100644 --- a/layout/base/src/nsDocument.cpp +++ b/layout/base/src/nsDocument.cpp @@ -72,6 +72,7 @@ #include "nsINameSpaceManager.h" #include "nsIServiceManager.h" +#include "nsLayoutAtoms.h" #include "nsLayoutCID.h" #include "nsIDOMSelection.h" #include "nsIDOMRange.h" @@ -2499,71 +2500,72 @@ PRBool nsDocument::SetProperty(JSContext *aContext, jsval aID, jsval *aVp) mPropName.SetString(JS_GetStringChars(JS_ValueToString(aContext, aID))); mPrefix.SetString(mPropName.GetUnicode(), 2); if (mPrefix == "on") { + nsCOMPtr atom = getter_AddRefs(NS_NewAtom(mPropName)); nsIEventListenerManager *mManager = nsnull; - if (mPropName == "onmousedown" || mPropName == "onmouseup" || mPropName == "onclick" || - mPropName == "onmouseover" || mPropName == "onmouseout") { + if (atom == nsLayoutAtoms::onmousedown || atom == nsLayoutAtoms::onmouseup || atom == nsLayoutAtoms::onclick || + atom == nsLayoutAtoms::onmouseover || atom == nsLayoutAtoms::onmouseout) { if (NS_OK == GetListenerManager(&mManager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMMouseListenerIID)) { + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, atom, kIDOMMouseListenerIID)) { NS_RELEASE(mManager); return PR_FALSE; } } } - else if (mPropName == "onkeydown" || mPropName == "onkeyup" || mPropName == "onkeypress") { + else if (atom == nsLayoutAtoms::onkeydown || atom == nsLayoutAtoms::onkeyup || atom == nsLayoutAtoms::onkeypress) { if (NS_OK == GetListenerManager(&mManager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMKeyListenerIID)) { + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, atom, kIDOMKeyListenerIID)) { NS_RELEASE(mManager); return PR_FALSE; } } } - else if (mPropName == "onmousemove") { + else if (atom == nsLayoutAtoms::onmousemove) { if (NS_OK == GetListenerManager(&mManager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMMouseMotionListenerIID)) { + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, atom, kIDOMMouseMotionListenerIID)) { NS_RELEASE(mManager); return PR_FALSE; } } } - else if (mPropName == "onfocus" || mPropName == "onblur") { + else if (atom == nsLayoutAtoms::onfocus || atom == nsLayoutAtoms::onblur) { if (NS_OK == GetListenerManager(&mManager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMFocusListenerIID)) { + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, atom, kIDOMFocusListenerIID)) { NS_RELEASE(mManager); return PR_FALSE; } } } - else if (mPropName == "onsubmit" || mPropName == "onreset" || mPropName == "onchange" || - mPropName == "onselect") { + else if (atom == nsLayoutAtoms::onsubmit || atom == nsLayoutAtoms::onreset || atom == nsLayoutAtoms::onchange || + atom == nsLayoutAtoms::onselect) { if (NS_OK == GetListenerManager(&mManager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMFormListenerIID)) { + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, atom, kIDOMFormListenerIID)) { NS_RELEASE(mManager); return PR_FALSE; } } } - else if (mPropName == "onload" || mPropName == "onunload" || mPropName == "onabort" || - mPropName == "onerror") { + else if (atom == nsLayoutAtoms::onload || atom == nsLayoutAtoms::onunload || atom == nsLayoutAtoms::onabort || + atom == nsLayoutAtoms::onerror) { if (NS_OK == GetListenerManager(&mManager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMLoadListenerIID)) { + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, atom, kIDOMLoadListenerIID)) { NS_RELEASE(mManager); return PR_FALSE; } } } - else if (mPropName == "onpaint") { + else if (atom == nsLayoutAtoms::onpaint) { if (NS_OK == GetListenerManager(&mManager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *) JS_GetContextPrivate(aContext); if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, - kIDOMPaintListenerIID)) { + atom, kIDOMPaintListenerIID)) { NS_RELEASE(mManager); return PR_FALSE; } diff --git a/layout/base/src/nsGenericElement.cpp b/layout/base/src/nsGenericElement.cpp index c4061f6d8f4b..95cb0200ab42 100644 --- a/layout/base/src/nsGenericElement.cpp +++ b/layout/base/src/nsGenericElement.cpp @@ -965,7 +965,8 @@ nsGenericElement::GetScriptObject(nsIScriptContext* aContext, nsAutoString tag; mTag->ToString(tag); res = factory->NewScriptElement(tag, aContext, mContent, - mParent, (void**)&slots->mScriptObject); + mParent ? (nsISupports*)mParent : (nsISupports*)mDocument, + (void**)&slots->mScriptObject); NS_RELEASE(factory); char tagBuf[50]; @@ -1112,71 +1113,72 @@ nsGenericElement::SetProperty(JSContext *aContext, jsval aID, jsval *aVp) propName.SetString(JS_GetStringChars(JS_ValueToString(aContext, aID))); prefix.SetString(propName.GetUnicode(), 2); if (prefix == "on") { + nsCOMPtr atom = getter_AddRefs(NS_NewAtom(propName)); nsIEventListenerManager *manager = nsnull; - if (propName == "onmousedown" || propName == "onmouseup" || propName == "onclick" || - propName == "onmouseover" || propName == "onmouseout") { + if (atom == nsLayoutAtoms::onmousedown || atom == nsLayoutAtoms::onmouseup || atom == nsLayoutAtoms::onclick || + atom == nsLayoutAtoms::onmouseover || atom == nsLayoutAtoms::onmouseout) { if (NS_OK == GetListenerManager(&manager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMMouseListenerIID)) { + if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, atom, kIDOMMouseListenerIID)) { NS_RELEASE(manager); return PR_FALSE; } } } - else if (propName == "onkeydown" || propName == "onkeyup" || propName == "onkeypress") { + else if (atom == nsLayoutAtoms::onkeydown || atom == nsLayoutAtoms::onkeyup || atom == nsLayoutAtoms::onkeypress) { if (NS_OK == GetListenerManager(&manager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMKeyListenerIID)) { + if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, atom, kIDOMKeyListenerIID)) { NS_RELEASE(manager); return PR_FALSE; } } } - else if (propName == "onmousemove") { + else if (atom == nsLayoutAtoms::onmousemove) { if (NS_OK == GetListenerManager(&manager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMMouseMotionListenerIID)) { + if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, atom, kIDOMMouseMotionListenerIID)) { NS_RELEASE(manager); return PR_FALSE; } } } - else if (propName == "onfocus" || propName == "onblur") { + else if (atom == nsLayoutAtoms::onfocus || atom == nsLayoutAtoms::onblur) { if (NS_OK == GetListenerManager(&manager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMFocusListenerIID)) { + if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, atom, kIDOMFocusListenerIID)) { NS_RELEASE(manager); return PR_FALSE; } } } - else if (propName == "onsubmit" || propName == "onreset" || propName == "onchange" || - propName == "onselect") { + else if (atom == nsLayoutAtoms::onsubmit || atom == nsLayoutAtoms::onreset || atom == nsLayoutAtoms::onchange || + atom == nsLayoutAtoms::onselect) { if (NS_OK == GetListenerManager(&manager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMFormListenerIID)) { + if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, atom, kIDOMFormListenerIID)) { NS_RELEASE(manager); return PR_FALSE; } } } - else if (propName == "onload" || propName == "onunload" || propName == "onabort" || - propName == "onerror") { + else if (atom == nsLayoutAtoms::onload || atom == nsLayoutAtoms::onunload || atom == nsLayoutAtoms::onabort || + atom == nsLayoutAtoms::onerror) { if (NS_OK == GetListenerManager(&manager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); - if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, kIDOMLoadListenerIID)) { + if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, atom, kIDOMLoadListenerIID)) { NS_RELEASE(manager); return PR_FALSE; } } } - else if (propName == "onpaint") { + else if (atom == nsLayoutAtoms::onpaint) { if (NS_OK == GetListenerManager(&manager)) { nsIScriptContext *mScriptCX = (nsIScriptContext *) JS_GetContextPrivate(aContext); if (NS_OK != manager->RegisterScriptEventListener(mScriptCX, owner, - kIDOMPaintListenerIID)) { + atom, kIDOMPaintListenerIID)) { NS_RELEASE(manager); return PR_FALSE; } @@ -1305,7 +1307,7 @@ nsGenericElement::AddScriptEventListener(nsIAtom* aAttribute, if (NS_OK == receiver->GetListenerManager(&manager)) { nsIScriptObjectOwner *mObjectOwner; if (NS_OK == global->QueryInterface(kIScriptObjectOwnerIID, (void**)&mObjectOwner)) { - ret = manager->AddScriptEventListener(context, mObjectOwner, aAttribute, aValue, aIID); + ret = manager->AddScriptEventListener(context, mObjectOwner, aAttribute, aValue, aIID, PR_FALSE); NS_RELEASE(mObjectOwner); } NS_RELEASE(manager); @@ -1321,7 +1323,7 @@ nsGenericElement::AddScriptEventListener(nsIAtom* aAttribute, if (NS_OK == mContent->QueryInterface(kIScriptObjectOwnerIID, (void**) &cowner)) { ret = manager->AddScriptEventListener(context, cowner, - aAttribute, aValue, aIID); + aAttribute, aValue, aIID, PR_TRUE); NS_RELEASE(cowner); } NS_RELEASE(manager); diff --git a/layout/events/public/nsIEventListenerManager.h b/layout/events/public/nsIEventListenerManager.h index 768f272b68fb..5b792fdcf8c7 100644 --- a/layout/events/public/nsIEventListenerManager.h +++ b/layout/events/public/nsIEventListenerManager.h @@ -85,15 +85,21 @@ public: * @param an event listener */ - virtual nsresult AddScriptEventListener(nsIScriptContext*aContext, nsIScriptObjectOwner *aScriptObjectOwner, - nsIAtom *aName, const nsString& aFunc, REFNSIID aIID) = 0; + virtual nsresult AddScriptEventListener(nsIScriptContext*aContext, + nsIScriptObjectOwner *aScriptObjectOwner, + nsIAtom *aName, + const nsString& aFunc, + REFNSIID aIID, + PRBool aDeferCompilation) = 0; /** * Registers an event listners which already exists on the given script object with the event * listener manager. * @param an event listener */ - virtual nsresult RegisterScriptEventListener(nsIScriptContext *aContext, nsIScriptObjectOwner *aScriptObjectOwner, + virtual nsresult RegisterScriptEventListener(nsIScriptContext *aContext, + nsIScriptObjectOwner *aScriptObjectOwner, + nsIAtom* aName, REFNSIID aIID) = 0; /** diff --git a/layout/events/src/nsEventListenerManager.cpp b/layout/events/src/nsEventListenerManager.cpp index 9818cdb7b16c..15b420d15393 100644 --- a/layout/events/src/nsEventListenerManager.cpp +++ b/layout/events/src/nsEventListenerManager.cpp @@ -41,10 +41,14 @@ #include "nsIPrivateDOMEvent.h" #include "nsIScriptObjectOwner.h" #include "nsIScriptEventListener.h" +#include "nsIJSEventListener.h" #include "nsDOMEventsIIDs.h" #include "prmem.h" #include "nsIScriptGlobalObject.h" #include "nsIScriptGlobalObjectData.h" +#include "nsLayoutAtoms.h" +#include "nsINameSpaceManager.h" +#include "nsIContent.h" #include "nsCOMPtr.h" static NS_DEFINE_IID(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID); @@ -236,6 +240,7 @@ nsresult nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener ls->mListener = aListener; ls->mFlags = aFlags; ls->mSubType = aSubType; + ls->mHandlerIsString = 0; (*listeners)->InsertElementAt((void*)ls, (*listeners)->Count()); NS_ADDREF(aListener); } @@ -288,133 +293,133 @@ nsresult nsEventListenerManager::RemoveEventListenerByIID(nsIDOMEventListener *a return NS_OK; } -nsresult nsEventListenerManager::GetIdentifiersForType(const nsString& aType, nsIID& aIID, PRInt32* aFlags) +nsresult nsEventListenerManager::GetIdentifiersForType(nsIAtom* aType, nsIID& aIID, PRInt32* aFlags) { - if (aType == "mousedown") { + if (aType == nsLayoutAtoms::onmousedown) { aIID = kIDOMMouseListenerIID; *aFlags = NS_EVENT_BITS_MOUSE_MOUSEDOWN; } - else if (aType == "mouseup") { + else if (aType == nsLayoutAtoms::onmouseup) { aIID = kIDOMMouseListenerIID; *aFlags = NS_EVENT_BITS_MOUSE_MOUSEUP; } - else if (aType == "click") { + else if (aType == nsLayoutAtoms::onclick) { aIID = kIDOMMouseListenerIID; *aFlags = NS_EVENT_BITS_MOUSE_CLICK; } - else if (aType == "dblclick") { + else if (aType == nsLayoutAtoms::ondblclick) { aIID = kIDOMMouseListenerIID; *aFlags = NS_EVENT_BITS_MOUSE_DBLCLICK; } - else if (aType == "mouseover") { + else if (aType == nsLayoutAtoms::onmouseover) { aIID = kIDOMMouseListenerIID; *aFlags = NS_EVENT_BITS_MOUSE_MOUSEOVER; } - else if (aType == "mouseout") { + else if (aType == nsLayoutAtoms::onmouseout) { aIID = kIDOMMouseListenerIID; *aFlags = NS_EVENT_BITS_MOUSE_MOUSEOUT; } - else if (aType == "keydown") { + else if (aType == nsLayoutAtoms::onkeydown) { aIID = kIDOMKeyListenerIID; *aFlags = NS_EVENT_BITS_KEY_KEYDOWN; } - else if (aType == "keyup") { + else if (aType == nsLayoutAtoms::onkeyup) { aIID = kIDOMKeyListenerIID; *aFlags = NS_EVENT_BITS_KEY_KEYUP; } - else if (aType == "keypress") { + else if (aType == nsLayoutAtoms::onkeypress) { aIID = kIDOMKeyListenerIID; *aFlags = NS_EVENT_BITS_KEY_KEYPRESS; } - else if (aType == "mousemove") { + else if (aType == nsLayoutAtoms::onmousemove) { aIID = kIDOMMouseMotionListenerIID; *aFlags = NS_EVENT_BITS_MOUSEMOTION_MOUSEMOVE; } - else if (aType == "focus") { + else if (aType == nsLayoutAtoms::onfocus) { aIID = kIDOMFocusListenerIID; *aFlags = NS_EVENT_BITS_FOCUS_FOCUS; } - else if (aType == "blur") { + else if (aType == nsLayoutAtoms::onblur) { aIID = kIDOMFocusListenerIID; *aFlags = NS_EVENT_BITS_FOCUS_BLUR; } - else if (aType == "submit") { + else if (aType == nsLayoutAtoms::onsubmit) { aIID = kIDOMFormListenerIID; *aFlags = NS_EVENT_BITS_FORM_SUBMIT; } - else if (aType == "reset") { + else if (aType == nsLayoutAtoms::onreset) { aIID = kIDOMFormListenerIID; *aFlags = NS_EVENT_BITS_FORM_RESET; } - else if (aType == "change") { + else if (aType == nsLayoutAtoms::onchange) { aIID = kIDOMFormListenerIID; *aFlags = NS_EVENT_BITS_FORM_CHANGE; } - else if (aType == "select") { + else if (aType == nsLayoutAtoms::onselect) { aIID = kIDOMFormListenerIID; *aFlags = NS_EVENT_BITS_FORM_SELECT; } - else if (aType == "input") { + else if (aType == nsLayoutAtoms::oninput) { aIID = kIDOMFormListenerIID; *aFlags = NS_EVENT_BITS_FORM_INPUT; } - else if (aType == "load") { + else if (aType == nsLayoutAtoms::onload) { aIID = kIDOMLoadListenerIID; *aFlags = NS_EVENT_BITS_LOAD_LOAD; } - else if (aType == "unload") { + else if (aType == nsLayoutAtoms::onunload) { aIID = kIDOMLoadListenerIID; *aFlags = NS_EVENT_BITS_LOAD_UNLOAD; } - else if (aType == "abort") { + else if (aType == nsLayoutAtoms::onabort) { aIID = kIDOMLoadListenerIID; *aFlags = NS_EVENT_BITS_LOAD_ABORT; } - else if (aType == "error") { + else if (aType == nsLayoutAtoms::onerror) { aIID = kIDOMLoadListenerIID; *aFlags = NS_EVENT_BITS_LOAD_ERROR; } - else if (aType == "paint") { + else if (aType == nsLayoutAtoms::onpaint) { aIID = kIDOMPaintListenerIID; *aFlags = NS_EVENT_BITS_PAINT_PAINT; } // extened this to handle IME related events - else if (aType == "create") { + else if (aType == nsLayoutAtoms::oncreate) { aIID = kIDOMMenuListenerIID; *aFlags = NS_EVENT_BITS_MENU_CREATE; } - else if (aType == "destroy") { + else if (aType == nsLayoutAtoms::ondestroy) { aIID = kIDOMMenuListenerIID; *aFlags = NS_EVENT_BITS_MENU_DESTROY; } - else if (aType == "command") { + else if (aType == nsLayoutAtoms::oncommand) { aIID = kIDOMMenuListenerIID; *aFlags = NS_EVENT_BITS_MENU_ACTION; } - else if (aType == "broadcast") { + else if (aType == nsLayoutAtoms::onbroadcast) { aIID = kIDOMMenuListenerIID; *aFlags = NS_EVENT_BITS_XUL_BROADCAST; } - else if (aType == "commandupdate") { + else if (aType == nsLayoutAtoms::oncommandupdate) { aIID = kIDOMMenuListenerIID; *aFlags = NS_EVENT_BITS_XUL_COMMAND_UPDATE; } - else if (aType == "dragenter") { + else if (aType == nsLayoutAtoms::ondragenter) { aIID = NS_GET_IID(nsIDOMDragListener); *aFlags = NS_EVENT_BITS_DRAG_ENTER; } - else if (aType == "dragover") { + else if (aType == nsLayoutAtoms::ondragover) { aIID = NS_GET_IID(nsIDOMDragListener); *aFlags = NS_EVENT_BITS_DRAG_OVER; } - else if (aType == "dragexit") { + else if (aType == nsLayoutAtoms::ondragexit) { aIID = NS_GET_IID(nsIDOMDragListener); *aFlags = NS_EVENT_BITS_DRAG_EXIT; } - else if (aType == "dragdrop") { + else if (aType == nsLayoutAtoms::ondragdrop) { aIID = NS_GET_IID(nsIDOMDragListener); *aFlags = NS_EVENT_BITS_DRAG_DROP; } - else if (aType == "draggesture") { + else if (aType == nsLayoutAtoms::ondraggesture) { aIID = NS_GET_IID(nsIDOMDragListener); *aFlags = NS_EVENT_BITS_DRAG_GESTURE; } @@ -429,11 +434,18 @@ nsresult nsEventListenerManager::AddEventListenerByType(nsIDOMEventListener *aLi { PRInt32 subType; nsIID iid; + nsAutoString str("on"); + nsIAtom* atom; - if (NS_OK == GetIdentifiersForType(aType, iid, &subType)) { + str.Append(aType); + atom = NS_NewAtom(str); + + if (NS_OK == GetIdentifiersForType(atom, iid, &subType)) { AddEventListener(aListener, iid, aFlags, subType); } + NS_IF_RELEASE(atom); + return NS_OK; } @@ -443,38 +455,81 @@ nsresult nsEventListenerManager::RemoveEventListenerByType(nsIDOMEventListener * PRInt32 subType; nsIID iid; - if (NS_OK == GetIdentifiersForType(aType, iid, &subType)) { + nsAutoString str("on"); + nsIAtom* atom; + + str.Append(aType); + atom = NS_NewAtom(str); + + if (NS_OK == GetIdentifiersForType(atom, iid, &subType)) { RemoveEventListener(aListener, iid, aFlags, subType); } + NS_IF_RELEASE(atom); + return NS_OK; } -nsresult nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext, JSObject *aObject, REFNSIID aIID) +nsListenerStruct* +nsEventListenerManager::FindJSEventListener(REFNSIID aIID) { - nsVoidArray *mListeners; + nsVoidArray *listeners; - if (NS_OK == GetEventListeners(&mListeners, aIID)) { + nsresult result = GetEventListeners(&listeners, aIID); + if (NS_SUCCEEDED(result)) { //Run through the listeners for this IID and see if a script listener is registered - //If so, we're set. - if (nsnull != mListeners) { + if (nsnull != listeners) { nsListenerStruct *ls; - for (int i=0; iCount(); i++) { - ls = (nsListenerStruct*)mListeners->ElementAt(i); + for (int i=0; iCount(); i++) { + ls = (nsListenerStruct*)listeners->ElementAt(i); if (ls->mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) { - return NS_OK; + return ls; } } } + } + + return nsnull; +} + +nsresult nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext, + nsIScriptObjectOwner *aOwner, + nsIAtom* aName, + REFNSIID aIID, + PRBool aIsString) +{ + nsIDOMEventListener* theListener = nsnull; + nsresult result = NS_OK; + nsListenerStruct *ls; + + ls = FindJSEventListener(aIID); + + if (nsnull == ls) { //If we didn't find a script listener or no listeners existed create and add a new one. - nsIDOMEventListener *mScriptListener; - if (NS_OK == NS_NewJSEventListener(&mScriptListener, aContext, aObject)) { - AddEventListenerByIID(mScriptListener, aIID, NS_EVENT_FLAG_BUBBLE | NS_PRIV_EVENT_FLAG_SCRIPT); - NS_RELEASE(mScriptListener); - return NS_OK; + nsIDOMEventListener* scriptListener; + result = NS_NewJSEventListener(&scriptListener, aContext, aOwner); + if (NS_SUCCEEDED(result)) { + AddEventListenerByIID(scriptListener, aIID, NS_EVENT_FLAG_BUBBLE | NS_PRIV_EVENT_FLAG_SCRIPT); + NS_RELEASE(scriptListener); + ls = FindJSEventListener(aIID); } } - return NS_ERROR_FAILURE; + + if (NS_SUCCEEDED(result) && ls) { + PRInt32 flags; + nsIID iid; + result = GetIdentifiersForType(aName, iid, &flags); + if (NS_SUCCEEDED(result)) { + if (aIsString) { + ls->mHandlerIsString |= flags; + } + else { + ls->mHandlerIsString &= ~flags; + } + } + } + + return result; } nsresult @@ -482,28 +537,82 @@ nsEventListenerManager::AddScriptEventListener(nsIScriptContext* aContext, nsIScriptObjectOwner *aScriptObjectOwner, nsIAtom *aName, const nsString& aBody, - REFNSIID aIID) + REFNSIID aIID, + PRBool aDeferCompilation) { JSObject *scriptObject; nsresult rv; - rv = aScriptObjectOwner->GetScriptObject(aContext, (void**)&scriptObject); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; - rv = aContext->CompileFunction(scriptObject, aName, aBody); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; - return SetJSEventListener(aContext, scriptObject, aIID); + if (!aDeferCompilation) { + rv = aScriptObjectOwner->GetScriptObject(aContext, (void**)&scriptObject); + if (NS_FAILED(rv)) + return rv; + rv = aContext->CompileFunction(scriptObject, aName, aBody); + if (NS_FAILED(rv)) + return rv; + } + return SetJSEventListener(aContext, aScriptObjectOwner, aName, aIID, aDeferCompilation); } -nsresult nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *aContext, nsIScriptObjectOwner *aScriptObjectOwner, - REFNSIID aIID) +nsresult nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *aContext, + nsIScriptObjectOwner *aScriptObjectOwner, + nsIAtom *aName, + REFNSIID aIID) { - JSObject *scriptObject; - if (NS_SUCCEEDED(aScriptObjectOwner->GetScriptObject(aContext, (void**)&scriptObject))) { - return SetJSEventListener(aContext, scriptObject, aIID); + return SetJSEventListener(aContext, aScriptObjectOwner, aName, aIID, PR_FALSE); +} + +nsresult +nsEventListenerManager::HandleEventSubType(nsListenerStruct* aListenerStruct, + nsIDOMEvent* aDOMEvent, + PRUint32 aSubType) +{ + nsresult result = NS_OK; + + // If this is a script handler and we haven't yet + // compiled the event handler itself + if ((aListenerStruct->mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) && + (aListenerStruct->mHandlerIsString & aSubType)) { + nsCOMPtr jslistener = do_QueryInterface(aListenerStruct->mListener); + if (jslistener) { + nsCOMPtr owner; + nsCOMPtr scriptCX; + result = jslistener->GetEventTarget(getter_AddRefs(scriptCX), getter_AddRefs(owner)); + + if (NS_SUCCEEDED(result)) { + JSObject* jsobj; + result = owner->GetScriptObject(scriptCX, (void**)&jsobj); + // This should never happen for anything but content + // XXX I don't like that we have to reference content + // from here. The alternative is to store the event handler + // string on the JS object itself. + if (NS_SUCCEEDED(result)) { + nsCOMPtr content = do_QueryInterface(owner); + NS_ASSERTION(content, "only content should have event handler attributes"); + if (content) { + nsAutoString eventString; + if (NS_SUCCEEDED(aDOMEvent->GetType(eventString))) { + + eventString.Insert("on", 0, 2); + nsCOMPtr atom = getter_AddRefs(NS_NewAtom(eventString)); + nsString handlerBody; + result = content->GetAttribute(kNameSpaceID_None, atom, handlerBody); + if (NS_SUCCEEDED(result)) { + result = scriptCX->CompileFunction(jsobj, atom, handlerBody); + aListenerStruct->mHandlerIsString &= ~aSubType; + } + } + } + } + } + } } - return NS_ERROR_FAILURE; + + if (NS_SUCCEEDED(result)) { + result = aListenerStruct->mListener->HandleEvent(aDOMEvent); + } + + return result; } /** @@ -548,7 +657,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, nsIDOMMouseListener *mMouseListener; ls = (nsListenerStruct*)mMouseListeners->ElementAt(i); - + if (ls->mFlags & aFlags) { if (NS_OK == ls->mListener->QueryInterface(kIDOMMouseListenerIID, (void**)&mMouseListener)) { switch(aEvent->message) { @@ -585,10 +694,12 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_MOUSE_LEFT_BUTTON_DOWN: case NS_MOUSE_MIDDLE_BUTTON_DOWN: case NS_MOUSE_RIGHT_BUTTON_DOWN: + subType = NS_EVENT_BITS_MOUSE_MOUSEDOWN; if (ls->mSubType & NS_EVENT_BITS_MOUSE_MOUSEDOWN) { correctSubType = PR_TRUE; } @@ -596,6 +707,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, case NS_MOUSE_LEFT_BUTTON_UP: case NS_MOUSE_MIDDLE_BUTTON_UP: case NS_MOUSE_RIGHT_BUTTON_UP: + subType = NS_EVENT_BITS_MOUSE_MOUSEUP; if (ls->mSubType & NS_EVENT_BITS_MOUSE_MOUSEUP) { correctSubType = PR_TRUE; } @@ -603,6 +715,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, case NS_MOUSE_LEFT_CLICK: case NS_MOUSE_MIDDLE_CLICK: case NS_MOUSE_RIGHT_CLICK: + subType = NS_EVENT_BITS_MOUSE_CLICK; if (ls->mSubType & NS_EVENT_BITS_MOUSE_CLICK) { correctSubType = PR_TRUE; } @@ -610,16 +723,19 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, case NS_MOUSE_LEFT_DOUBLECLICK: case NS_MOUSE_MIDDLE_DOUBLECLICK: case NS_MOUSE_RIGHT_DOUBLECLICK: + subType = NS_EVENT_BITS_MOUSE_DBLCLICK; if (ls->mSubType & NS_EVENT_BITS_MOUSE_DBLCLICK) { correctSubType = PR_TRUE; } break; case NS_MOUSE_ENTER: + subType = NS_EVENT_BITS_MOUSE_MOUSEOVER; if (ls->mSubType & NS_EVENT_BITS_MOUSE_MOUSEOVER) { correctSubType = PR_TRUE; } break; case NS_MOUSE_EXIT: + subType = NS_EVENT_BITS_MOUSE_MOUSEOUT; if (ls->mSubType & NS_EVENT_BITS_MOUSE_MOUSEOUT) { correctSubType = PR_TRUE; } @@ -628,7 +744,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -662,8 +778,10 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_MOUSE_MOVE: + subType = NS_EVENT_BITS_MOUSEMOTION_MOUSEMOVE; if (ls->mSubType & NS_EVENT_BITS_MOUSEMOTION_MOUSEMOVE) { correctSubType = PR_TRUE; } @@ -672,7 +790,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -709,13 +827,16 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_COMPOSITION_START: + subType = NS_EVENT_BITS_COMPOSITION_START; if (ls->mSubType & NS_EVENT_BITS_COMPOSITION_START) { correctSubType = PR_TRUE; } break; case NS_COMPOSITION_END: + subType = NS_EVENT_BITS_COMPOSITION_END; if (ls->mSubType & NS_EVENT_BITS_COMPOSITION_END) { correctSubType = PR_TRUE; } @@ -724,7 +845,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -754,11 +875,12 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = NS_EVENT_BITS_TEXT_TEXT; if (ls->mSubType & NS_EVENT_BITS_TEXT_TEXT) { correctSubType = PR_TRUE; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -800,18 +922,22 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_KEY_UP: + subType = NS_EVENT_BITS_KEY_KEYUP; if (ls->mSubType & NS_EVENT_BITS_KEY_KEYUP) { correctSubType = PR_TRUE; } break; case NS_KEY_DOWN: + subType = NS_EVENT_BITS_KEY_KEYDOWN; if (ls->mSubType & NS_EVENT_BITS_KEY_KEYDOWN) { correctSubType = PR_TRUE; } break; case NS_KEY_PRESS: + subType = NS_EVENT_BITS_KEY_KEYPRESS; if (ls->mSubType & NS_EVENT_BITS_KEY_KEYPRESS) { correctSubType = PR_TRUE; } @@ -820,7 +946,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -858,13 +984,16 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_FOCUS_CONTENT: + subType = NS_EVENT_BITS_FOCUS_FOCUS; if (ls->mSubType & NS_EVENT_BITS_FOCUS_FOCUS) { correctSubType = PR_TRUE; } break; case NS_BLUR_CONTENT: + subType = NS_EVENT_BITS_FOCUS_BLUR; if (ls->mSubType & NS_EVENT_BITS_FOCUS_BLUR) { correctSubType = PR_TRUE; } @@ -873,7 +1002,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -923,28 +1052,34 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_FORM_SUBMIT: + subType = NS_EVENT_BITS_FORM_SUBMIT; if (ls->mSubType & NS_EVENT_BITS_FORM_SUBMIT) { correctSubType = PR_TRUE; } break; case NS_FORM_RESET: + subType = NS_EVENT_BITS_FORM_RESET; if (ls->mSubType & NS_EVENT_BITS_FORM_RESET) { correctSubType = PR_TRUE; } break; case NS_FORM_CHANGE: + subType = NS_EVENT_BITS_FORM_CHANGE; if (ls->mSubType & NS_EVENT_BITS_FORM_CHANGE) { correctSubType = PR_TRUE; } break; case NS_FORM_SELECTED: + subType = NS_EVENT_BITS_FORM_SELECT; if (ls->mSubType & NS_EVENT_BITS_FORM_SELECT) { correctSubType = PR_TRUE; } break; case NS_FORM_INPUT: + subType = NS_EVENT_BITS_FORM_INPUT; if (ls->mSubType & NS_EVENT_BITS_FORM_INPUT) { correctSubType = PR_TRUE; } @@ -953,7 +1088,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -992,13 +1127,16 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_PAGE_LOAD: + subType = NS_EVENT_BITS_LOAD_LOAD; if (ls->mSubType & NS_EVENT_BITS_LOAD_LOAD) { correctSubType = PR_TRUE; } break; case NS_PAGE_UNLOAD: + subType = NS_EVENT_BITS_LOAD_UNLOAD; if (ls->mSubType & NS_EVENT_BITS_LOAD_UNLOAD) { correctSubType = PR_TRUE; } @@ -1007,7 +1145,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -1036,11 +1174,12 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = NS_EVENT_BITS_PAINT_PAINT; if (ls->mSubType & NS_EVENT_BITS_PAINT_PAINT) { correctSubType = PR_TRUE; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } @@ -1088,24 +1227,30 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_DRAGDROP_ENTER: + subType = NS_EVENT_BITS_DRAG_ENTER; if (dragStruct->mSubType & NS_EVENT_BITS_DRAG_ENTER) correctSubType = PR_TRUE; break; case NS_DRAGDROP_OVER: + subType = NS_EVENT_BITS_DRAG_OVER; if (dragStruct->mSubType & NS_EVENT_BITS_DRAG_OVER) correctSubType = PR_TRUE; break; case NS_DRAGDROP_EXIT: + subType = NS_EVENT_BITS_DRAG_EXIT; if (dragStruct->mSubType & NS_EVENT_BITS_DRAG_EXIT) correctSubType = PR_TRUE; break; case NS_DRAGDROP_DROP: + subType = NS_EVENT_BITS_DRAG_DROP; if (dragStruct->mSubType & NS_EVENT_BITS_DRAG_DROP) correctSubType = PR_TRUE; break; case NS_DRAGDROP_GESTURE: + subType = NS_EVENT_BITS_DRAG_GESTURE; if (dragStruct->mSubType & NS_EVENT_BITS_DRAG_GESTURE) correctSubType = PR_TRUE; break; @@ -1113,7 +1258,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || dragStruct->mSubType == NS_EVENT_BITS_DRAG_NONE) - ret = dragStruct->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(dragStruct, *aDOMEvent, subType); } } } @@ -1162,28 +1307,34 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } else { PRBool correctSubType = PR_FALSE; + PRUint32 subType = 0; switch(aEvent->message) { case NS_MENU_CREATE: + subType = NS_EVENT_BITS_MENU_CREATE; if (ls->mSubType & NS_EVENT_BITS_MENU_CREATE) { correctSubType = PR_TRUE; } break; case NS_MENU_DESTROY: + subType = NS_EVENT_BITS_MENU_DESTROY; if (ls->mSubType & NS_EVENT_BITS_MENU_DESTROY) { correctSubType = PR_TRUE; } break; case NS_MENU_ACTION: + subType = NS_EVENT_BITS_MENU_ACTION; if (ls->mSubType & NS_EVENT_BITS_MENU_ACTION) { correctSubType = PR_TRUE; } break; case NS_XUL_BROADCAST: + subType = NS_EVENT_BITS_XUL_BROADCAST; if (ls->mSubType & NS_EVENT_BITS_XUL_BROADCAST) { correctSubType = PR_TRUE; } break; case NS_XUL_COMMAND_UPDATE: + subType = NS_EVENT_BITS_XUL_COMMAND_UPDATE; if (ls->mSubType & NS_EVENT_BITS_XUL_COMMAND_UPDATE) { correctSubType = PR_TRUE; } @@ -1192,7 +1343,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, break; } if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) { - ret = ls->mListener->HandleEvent(*aDOMEvent); + ret = HandleEventSubType(ls, *aDOMEvent, subType); } } } diff --git a/layout/events/src/nsEventListenerManager.h b/layout/events/src/nsEventListenerManager.h index 2d781a157a67..2f9928014809 100644 --- a/layout/events/src/nsEventListenerManager.h +++ b/layout/events/src/nsEventListenerManager.h @@ -27,11 +27,13 @@ #include "jsapi.h" class nsIDOMEvent; +class nsIAtom; typedef struct { nsIDOMEventListener* mListener; PRUint8 mFlags; PRUint8 mSubType; + PRUint32 mHandlerIsString; } nsListenerStruct; //Flag must live higher than all event flags in nsGUIEvent.h @@ -68,13 +70,15 @@ public: virtual nsresult AddEventListenerByType(nsIDOMEventListener *aListener, const nsString& type, PRInt32 aFlags); virtual nsresult RemoveEventListenerByType(nsIDOMEventListener *aListener, const nsString& type, PRInt32 aFlags) ; - virtual nsresult AddScriptEventListener(nsIScriptContext* aContext, + virtual nsresult AddScriptEventListener(nsIScriptContext*aContext, nsIScriptObjectOwner *aScriptObjectOwner, nsIAtom *aName, const nsString& aFunc, - const nsIID& aIID); + REFNSIID aIID, + PRBool aDeferCompilation); virtual nsresult RegisterScriptEventListener(nsIScriptContext *aContext, nsIScriptObjectOwner *aScriptObjectOwner, + nsIAtom* aName, const nsIID& aIID); @@ -93,9 +97,14 @@ public: virtual nsresult RemoveAllListeners(PRBool aScriptOnly); + static nsresult GetIdentifiersForType(nsIAtom* aType, nsIID& aIID, PRInt32* aSubType); + protected: - nsresult SetJSEventListener(nsIScriptContext *aContext, JSObject *aObject, REFNSIID aIID); - nsresult GetIdentifiersForType(const nsString& aType, nsIID& aIID, PRInt32* aSubType); + nsresult HandleEventSubType(nsListenerStruct* aListenerStruct, + nsIDOMEvent* aDOMEvent, + PRUint32 aSubType); + nsListenerStruct* FindJSEventListener(REFNSIID aIID); + nsresult SetJSEventListener(nsIScriptContext *aContext, nsIScriptObjectOwner *aOwner, nsIAtom* aName, REFNSIID aIID, PRBool aIsString); nsresult AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 aFlags, PRInt32 aSubType); nsresult RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 aFlags, PRInt32 aSubType); void ReleaseListeners(nsVoidArray** aListeners, PRBool aScriptOnly); diff --git a/layout/html/base/src/nsHTMLAtomList.h b/layout/html/base/src/nsHTMLAtomList.h index 1d9c7ee9a167..9d68783e7e32 100644 --- a/layout/html/base/src/nsHTMLAtomList.h +++ b/layout/html/base/src/nsHTMLAtomList.h @@ -192,29 +192,6 @@ HTML_ATOM(noshade, "noshade") HTML_ATOM(nowrap, "nowrap") HTML_ATOM(object, "object") HTML_ATOM(ol, "ol") -HTML_ATOM(onabort, "onabort") -HTML_ATOM(onblur, "onblur") -HTML_ATOM(onchange, "onchange") -HTML_ATOM(onselect, "onselect") -HTML_ATOM(onclick, "onclick") -HTML_ATOM(ondblclick, "ondblclick") -HTML_ATOM(ondragdrop, "ondragdrop") -HTML_ATOM(onerror, "onerror") -HTML_ATOM(onfocus, "onfocus") -HTML_ATOM(oninput, "oninput") -HTML_ATOM(onkeydown, "onkeydown") -HTML_ATOM(onkeypress, "onkeypress") -HTML_ATOM(onkeyup, "onkeyup") -HTML_ATOM(onload, "onload") -HTML_ATOM(onmousedown, "onmousedown") -HTML_ATOM(onmousemove, "onmousemove") -HTML_ATOM(onmouseover, "onmouseover") -HTML_ATOM(onmouseout, "onmouseout") -HTML_ATOM(onmouseup, "onmouseup") -HTML_ATOM(onpaint, "onpaint") -HTML_ATOM(onreset, "onreset") -HTML_ATOM(onsubmit, "onsubmit") -HTML_ATOM(onunload, "onunload") HTML_ATOM(option, "option") HTML_ATOM(overflow, "overflow") HTML_ATOM(p, "p") diff --git a/layout/html/content/src/nsGenericHTMLElement.cpp b/layout/html/content/src/nsGenericHTMLElement.cpp index e11f45c01fdb..f9ad8caf9258 100644 --- a/layout/html/content/src/nsGenericHTMLElement.cpp +++ b/layout/html/content/src/nsGenericHTMLElement.cpp @@ -61,6 +61,7 @@ #include "nsIHTMLContentContainer.h" #include "nsHTMLParts.h" #include "nsString.h" +#include "nsLayoutAtoms.h" #include "nsHTMLAtoms.h" #include "nsDOMEventsIIDs.h" #include "nsIEventStateManager.h" @@ -632,36 +633,36 @@ nsGenericHTMLElement::SetAttribute(PRInt32 aNameSpaceID, } else { // Check for event handlers - if ((nsHTMLAtoms::onclick == aAttribute) || - (nsHTMLAtoms::ondblclick == aAttribute) || - (nsHTMLAtoms::onmousedown == aAttribute) || - (nsHTMLAtoms::onmouseup == aAttribute) || - (nsHTMLAtoms::onmouseover == aAttribute) || - (nsHTMLAtoms::onmouseout == aAttribute)) + if ((nsLayoutAtoms::onclick == aAttribute) || + (nsLayoutAtoms::ondblclick == aAttribute) || + (nsLayoutAtoms::onmousedown == aAttribute) || + (nsLayoutAtoms::onmouseup == aAttribute) || + (nsLayoutAtoms::onmouseover == aAttribute) || + (nsLayoutAtoms::onmouseout == aAttribute)) AddScriptEventListener(aAttribute, aValue, kIDOMMouseListenerIID); - else if ((nsHTMLAtoms::onkeydown == aAttribute) || - (nsHTMLAtoms::onkeyup == aAttribute) || - (nsHTMLAtoms::onkeypress == aAttribute)) + else if ((nsLayoutAtoms::onkeydown == aAttribute) || + (nsLayoutAtoms::onkeyup == aAttribute) || + (nsLayoutAtoms::onkeypress == aAttribute)) AddScriptEventListener(aAttribute, aValue, kIDOMKeyListenerIID); - else if (nsHTMLAtoms::onmousemove == aAttribute) + else if (nsLayoutAtoms::onmousemove == aAttribute) AddScriptEventListener(aAttribute, aValue, kIDOMMouseMotionListenerIID); - else if (nsHTMLAtoms::onload == aAttribute) - AddScriptEventListener(nsHTMLAtoms::onload, aValue, kIDOMLoadListenerIID); - else if ((nsHTMLAtoms::onunload == aAttribute) || - (nsHTMLAtoms::onabort == aAttribute) || - (nsHTMLAtoms::onerror == aAttribute)) + else if (nsLayoutAtoms::onload == aAttribute) + AddScriptEventListener(nsLayoutAtoms::onload, aValue, kIDOMLoadListenerIID); + else if ((nsLayoutAtoms::onunload == aAttribute) || + (nsLayoutAtoms::onabort == aAttribute) || + (nsLayoutAtoms::onerror == aAttribute)) AddScriptEventListener(aAttribute, aValue, kIDOMLoadListenerIID); - else if ((nsHTMLAtoms::onfocus == aAttribute) || - (nsHTMLAtoms::onblur == aAttribute)) + else if ((nsLayoutAtoms::onfocus == aAttribute) || + (nsLayoutAtoms::onblur == aAttribute)) AddScriptEventListener(aAttribute, aValue, kIDOMFocusListenerIID); - else if ((nsHTMLAtoms::onsubmit == aAttribute) || - (nsHTMLAtoms::onreset == aAttribute) || - (nsHTMLAtoms::onchange == aAttribute) || - (nsHTMLAtoms::onselect == aAttribute)) + else if ((nsLayoutAtoms::onsubmit == aAttribute) || + (nsLayoutAtoms::onreset == aAttribute) || + (nsLayoutAtoms::onchange == aAttribute) || + (nsLayoutAtoms::onselect == aAttribute)) AddScriptEventListener(aAttribute, aValue, kIDOMFormListenerIID); - else if (nsHTMLAtoms::onpaint == aAttribute) + else if (nsLayoutAtoms::onpaint == aAttribute) AddScriptEventListener(aAttribute, aValue, kIDOMPaintListenerIID); - else if (nsHTMLAtoms::oninput == aAttribute) + else if (nsLayoutAtoms::oninput == aAttribute) AddScriptEventListener(aAttribute, aValue, kIDOMFormListenerIID); } diff --git a/layout/html/document/src/nsHTMLDocument.cpp b/layout/html/document/src/nsHTMLDocument.cpp index baa39825e6d3..7bd9b201ad2b 100644 --- a/layout/html/document/src/nsHTMLDocument.cpp +++ b/layout/html/document/src/nsHTMLDocument.cpp @@ -2495,6 +2495,52 @@ nsHTMLDocument::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject return res; } +PRBool +nsHTMLDocument::Resolve(JSContext *aContext, jsval aID) +{ + nsCOMPtr element; + char* str = JS_GetStringBytes(JS_ValueToString(aContext, aID)); + nsAutoString name(str); + nsresult result = NS_OK; + PRBool ret = PR_TRUE; + + result = NamedItem(name, getter_AddRefs(element)); + if (NS_SUCCEEDED(result) && element) { + nsCOMPtr owner = do_QueryInterface(element); + + if (owner) { + nsCOMPtr scriptContext; + nsCOMPtr contextOwner; + + contextOwner = getter_AddRefs(GetScriptContextOwner()); + if (contextOwner) { + result = contextOwner->GetScriptContext(getter_AddRefs(scriptContext)); + } + + if (!scriptContext) { + scriptContext = dont_AddRef((nsIScriptContext*)JS_GetContextPrivate(aContext)); + } + + JSObject* obj; + if (scriptContext) { + result = owner->GetScriptObject(scriptContext, (void**)&obj); + if (NS_SUCCEEDED(result) && (nsnull != obj)) { + JSObject* myObj; + result = GetScriptObject(scriptContext, (void**)&myObj); + ret = ::JS_DefineProperty(aContext, myObj, + str, OBJECT_TO_JSVAL(obj), + nsnull, nsnull, 0); + } + } + } + } + + if (NS_FAILED(result)) { + ret = PR_FALSE; + } + + return ret; +} //---------------------------- static PRBool IsInline(eHTMLTags aTag) diff --git a/layout/html/document/src/nsHTMLDocument.h b/layout/html/document/src/nsHTMLDocument.h index 896861b7f912..5abd086bfaab 100644 --- a/layout/html/document/src/nsHTMLDocument.h +++ b/layout/html/document/src/nsHTMLDocument.h @@ -124,6 +124,9 @@ public: // From nsIScriptObjectOwner interface, implemented by nsDocument NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject); + + // From nsJSScriptObject interface, implemented by nsDocument + virtual PRBool Resolve(JSContext *aContext, jsval aID); /** * Finds text in content