forked from mirrors/gecko-dev
Bug 448602 - Have a way to enumerate event listeners, r=bz
--HG-- extra : rebase_source : 77ed96b23db73ae78ed7f34ed231daf84fae1f54
This commit is contained in:
parent
881607eb48
commit
2d83c2550e
21 changed files with 676 additions and 26 deletions
|
|
@ -122,6 +122,7 @@
|
||||||
@BINPATH@/components/commandlines.xpt
|
@BINPATH@/components/commandlines.xpt
|
||||||
@BINPATH@/components/composer.xpt
|
@BINPATH@/components/composer.xpt
|
||||||
@BINPATH@/components/content_base.xpt
|
@BINPATH@/components/content_base.xpt
|
||||||
|
@BINPATH@/components/content_events.xpt
|
||||||
@BINPATH@/components/content_canvas.xpt
|
@BINPATH@/components/content_canvas.xpt
|
||||||
@BINPATH@/components/content_htmldoc.xpt
|
@BINPATH@/components/content_htmldoc.xpt
|
||||||
@BINPATH@/components/content_html.xpt
|
@BINPATH@/components/content_html.xpt
|
||||||
|
|
|
||||||
|
|
@ -301,6 +301,13 @@
|
||||||
#define NS_SYNCLOADDOMSERVICE_CONTRACTID \
|
#define NS_SYNCLOADDOMSERVICE_CONTRACTID \
|
||||||
"@mozilla.org/content/syncload-dom-service;1"
|
"@mozilla.org/content/syncload-dom-service;1"
|
||||||
|
|
||||||
|
#define NS_EVENTLISTENERSERVICE_CID \
|
||||||
|
{ /* baa34652-f1f1-4185-b224-244ee82a413a */ \
|
||||||
|
0xbaa34652, 0xf1f1, 0x4185, \
|
||||||
|
{0xb2, 0x24, 0x24, 0x4e, 0xe8, 0x2a, 0x41, 0x3a } }
|
||||||
|
#define NS_EVENTLISTENERSERVICE_CONTRACTID \
|
||||||
|
"@mozilla.org/eventlistenerservice;1"
|
||||||
|
|
||||||
// {f96f5ec9-755b-447e-b1f3-717d1a84bb41}
|
// {f96f5ec9-755b-447e-b1f3-717d1a84bb41}
|
||||||
#define NS_PLUGINDOCUMENT_CID \
|
#define NS_PLUGINDOCUMENT_CID \
|
||||||
{ 0xf96f5ec9, 0x755b, 0x447e, { 0xb1, 0xf3, 0x71, 0x7d, 0x1a, 0x84, 0xbb, 0x41 } }
|
{ 0xf96f5ec9, 0x755b, 0x447e, { 0xb1, 0xf3, 0x71, 0x7d, 0x1a, 0x84, 0xbb, 0x41 } }
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ VPATH = @srcdir@
|
||||||
include $(DEPTH)/config/autoconf.mk
|
include $(DEPTH)/config/autoconf.mk
|
||||||
|
|
||||||
MODULE = content
|
MODULE = content
|
||||||
|
XPIDL_MODULE = content_events
|
||||||
|
|
||||||
EXPORTS = \
|
EXPORTS = \
|
||||||
nsMutationEvent.h \
|
nsMutationEvent.h \
|
||||||
|
|
@ -57,5 +58,9 @@ EXPORTS = \
|
||||||
nsPIDOMEventTarget.h \
|
nsPIDOMEventTarget.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
XPIDLSRCS = \
|
||||||
|
nsIEventListenerService.idl \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ class nsIDOMEvent;
|
||||||
class nsPIDOMEventTarget;
|
class nsPIDOMEventTarget;
|
||||||
class nsIScriptGlobalObject;
|
class nsIScriptGlobalObject;
|
||||||
class nsEventTargetChainItem;
|
class nsEventTargetChainItem;
|
||||||
|
template<class E> class nsCOMArray;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* About event dispatching:
|
* About event dispatching:
|
||||||
|
|
@ -230,6 +230,10 @@ public:
|
||||||
* In other words, aEvent->target is only a property of the event and it has
|
* In other words, aEvent->target is only a property of the event and it has
|
||||||
* nothing to do with the construction of the event target chain.
|
* nothing to do with the construction of the event target chain.
|
||||||
* Neither aTarget nor aEvent is allowed to be nsnull.
|
* Neither aTarget nor aEvent is allowed to be nsnull.
|
||||||
|
*
|
||||||
|
* If aTargets is non-null, event target chain will be created, but
|
||||||
|
* event won't be handled. In this case aEvent->message should be
|
||||||
|
* NS_EVENT_TYPE_NULL.
|
||||||
* @note Use this method when dispatching an nsEvent.
|
* @note Use this method when dispatching an nsEvent.
|
||||||
*/
|
*/
|
||||||
static nsresult Dispatch(nsISupports* aTarget,
|
static nsresult Dispatch(nsISupports* aTarget,
|
||||||
|
|
@ -237,7 +241,8 @@ public:
|
||||||
nsEvent* aEvent,
|
nsEvent* aEvent,
|
||||||
nsIDOMEvent* aDOMEvent = nsnull,
|
nsIDOMEvent* aDOMEvent = nsnull,
|
||||||
nsEventStatus* aEventStatus = nsnull,
|
nsEventStatus* aEventStatus = nsnull,
|
||||||
nsDispatchingCallback* aCallback = nsnull);
|
nsDispatchingCallback* aCallback = nsnull,
|
||||||
|
nsCOMArray<nsPIDOMEventTarget>* aTargets = nsnull);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatches an event.
|
* Dispatches an event.
|
||||||
|
|
|
||||||
|
|
@ -48,13 +48,15 @@ class nsIDOMEventTarget;
|
||||||
class nsIDOMEventGroup;
|
class nsIDOMEventGroup;
|
||||||
class nsIAtom;
|
class nsIAtom;
|
||||||
class nsPIDOMEventTarget;
|
class nsPIDOMEventTarget;
|
||||||
|
class nsIEventListenerInfo;
|
||||||
|
template<class E> class nsCOMArray;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Event listener manager interface.
|
* Event listener manager interface.
|
||||||
*/
|
*/
|
||||||
#define NS_IEVENTLISTENERMANAGER_IID \
|
#define NS_IEVENTLISTENERMANAGER_IID \
|
||||||
{ 0xadfdc265, 0xea1c, 0x4c0b, \
|
{ 0xac49ce4e, 0xaecf, 0x45db, \
|
||||||
{ 0x91, 0xca, 0x37, 0x67, 0x2c, 0x83, 0x92, 0x1f } }
|
{ 0xa1, 0xe0, 0xea, 0x1d, 0x38, 0x73, 0x39, 0xa3 } }
|
||||||
|
|
||||||
class nsIEventListenerManager : public nsISupports {
|
class nsIEventListenerManager : public nsISupports {
|
||||||
|
|
||||||
|
|
@ -189,6 +191,12 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual PRUint32 MutationListenerBits() = 0;
|
virtual PRUint32 MutationListenerBits() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets aList to the list of nsIEventListenerInfo objects representing the
|
||||||
|
* listeners managed by this listener manager.
|
||||||
|
*/
|
||||||
|
virtual nsresult GetListenerInfo(nsCOMArray<nsIEventListenerInfo>* aList) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns PR_TRUE if there is at least one event listener for aEventName.
|
* Returns PR_TRUE if there is at least one event listener for aEventName.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
89
content/events/public/nsIEventListenerService.idl
Normal file
89
content/events/public/nsIEventListenerService.idl
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Olli Pettay <Olli.Pettay@helsinki.fi> (Original Author)
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "nsIDOMEventListener.idl"
|
||||||
|
|
||||||
|
interface nsIDOMEventTarget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An instance of this interface describes how an event listener
|
||||||
|
* was added to an event target.
|
||||||
|
*/
|
||||||
|
[scriptable, uuid(4f132988-4709-44e5-985c-9e16d0f7c954)]
|
||||||
|
interface nsIEventListenerInfo : nsISupports
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The type of the event for which the listener was added.
|
||||||
|
*/
|
||||||
|
readonly attribute AString type;
|
||||||
|
readonly attribute boolean capturing;
|
||||||
|
readonly attribute boolean allowsUntrusted;
|
||||||
|
readonly attribute boolean inSystemEventGroup;
|
||||||
|
/**
|
||||||
|
* Tries to serialize event listener to a string.
|
||||||
|
* Returns null if serialization isn't possible
|
||||||
|
* (for example with C++ listeners).
|
||||||
|
*/
|
||||||
|
AString toSource();
|
||||||
|
};
|
||||||
|
|
||||||
|
[scriptable, uuid(551cac0f-31ed-45e0-8d67-bc0d6e117b31)]
|
||||||
|
interface nsIEventListenerService : nsISupports
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns an array of nsIEventListenerInfo objects.
|
||||||
|
* If aEventTarget doesn't have any listeners, this returns null.
|
||||||
|
*/
|
||||||
|
void getListenerInfoFor(in nsIDOMEventTarget aEventTarget,
|
||||||
|
out unsigned long aCount,
|
||||||
|
[retval, array, size_is(aCount)] out
|
||||||
|
nsIEventListenerInfo aOutArray);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of event targets.
|
||||||
|
* aEventTarget will be at index 0.
|
||||||
|
* The objects are the ones that would be used as DOMEvent.currentTarget while
|
||||||
|
* dispatching an event to aEventTarget
|
||||||
|
* @note Some events, especially 'load', may actually have a shorter
|
||||||
|
* event target chain than what this methods returns.
|
||||||
|
*/
|
||||||
|
void getEventTargetChainFor(in nsIDOMEventTarget aEventTarget,
|
||||||
|
out unsigned long aCount,
|
||||||
|
[retval, array, size_is(aCount)] out
|
||||||
|
nsIDOMEventTarget aOutArray);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -74,6 +74,7 @@ CPPSRCS = \
|
||||||
nsEventDispatcher.cpp \
|
nsEventDispatcher.cpp \
|
||||||
nsIMEStateManager.cpp \
|
nsIMEStateManager.cpp \
|
||||||
nsContentEventHandler.cpp \
|
nsContentEventHandler.cpp \
|
||||||
|
nsEventListenerService.cpp \
|
||||||
nsDOMProgressEvent.cpp \
|
nsDOMProgressEvent.cpp \
|
||||||
nsDOMDataTransfer.cpp \
|
nsDOMDataTransfer.cpp \
|
||||||
nsDOMNotifyPaintEvent.cpp \
|
nsDOMNotifyPaintEvent.cpp \
|
||||||
|
|
|
||||||
|
|
@ -200,11 +200,11 @@ public:
|
||||||
|
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
|
||||||
|
static const char* GetEventName(PRUint32 aEventType);
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Internal helper functions
|
// Internal helper functions
|
||||||
nsresult SetEventType(const nsAString& aEventTypeArg);
|
nsresult SetEventType(const nsAString& aEventTypeArg);
|
||||||
static const char* GetEventName(PRUint32 aEventType);
|
|
||||||
already_AddRefed<nsIDOMEventTarget> GetTargetFromFrame();
|
already_AddRefed<nsIDOMEventTarget> GetTargetFromFrame();
|
||||||
nsresult ReportWrongPropertyAccessWarning(const char* aPropertyName);
|
nsresult ReportWrongPropertyAccessWarning(const char* aPropertyName);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -427,11 +427,13 @@ nsEventDispatcher::Dispatch(nsISupports* aTarget,
|
||||||
nsEvent* aEvent,
|
nsEvent* aEvent,
|
||||||
nsIDOMEvent* aDOMEvent,
|
nsIDOMEvent* aDOMEvent,
|
||||||
nsEventStatus* aEventStatus,
|
nsEventStatus* aEventStatus,
|
||||||
nsDispatchingCallback* aCallback)
|
nsDispatchingCallback* aCallback,
|
||||||
|
nsCOMArray<nsPIDOMEventTarget>* aTargets)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aEvent, "Trying to dispatch without nsEvent!");
|
NS_ASSERTION(aEvent, "Trying to dispatch without nsEvent!");
|
||||||
NS_ENSURE_TRUE(!NS_IS_EVENT_IN_DISPATCH(aEvent),
|
NS_ENSURE_TRUE(!NS_IS_EVENT_IN_DISPATCH(aEvent),
|
||||||
NS_ERROR_ILLEGAL_VALUE);
|
NS_ERROR_ILLEGAL_VALUE);
|
||||||
|
NS_ASSERTION(!aTargets || !aEvent->message, "Wrong parameters!");
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMEventTarget> target = do_QueryInterface(aTarget);
|
nsCOMPtr<nsPIDOMEventTarget> target = do_QueryInterface(aTarget);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
@ -530,6 +532,14 @@ nsEventDispatcher::Dispatch(nsISupports* aTarget,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
if (aTargets) {
|
||||||
|
aTargets->Clear();
|
||||||
|
nsEventTargetChainItem* item = targetEtci;
|
||||||
|
while(item) {
|
||||||
|
aTargets->AppendObject(item->CurrentTarget()->GetTargetForDOMEvent());
|
||||||
|
item = item->mParent;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// Event target chain is created. Handle the chain.
|
// Event target chain is created. Handle the chain.
|
||||||
nsEventChainPostVisitor postVisitor(preVisitor);
|
nsEventChainPostVisitor postVisitor(preVisitor);
|
||||||
rv = topEtci->HandleEventTargetChain(postVisitor,
|
rv = topEtci->HandleEventTargetChain(postVisitor,
|
||||||
|
|
@ -545,6 +555,7 @@ nsEventDispatcher::Dispatch(nsISupports* aTarget,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nsEventTargetChainItem::Destroy(pool.GetPool(), targetEtci);
|
nsEventTargetChainItem::Destroy(pool.GetPool(), targetEtci);
|
||||||
targetEtci = nsnull;
|
targetEtci = nsnull;
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,9 @@
|
||||||
#include "nsDOMJSUtils.h"
|
#include "nsDOMJSUtils.h"
|
||||||
#include "nsDOMScriptObjectHolder.h"
|
#include "nsDOMScriptObjectHolder.h"
|
||||||
#include "nsDataHashtable.h"
|
#include "nsDataHashtable.h"
|
||||||
|
#include "nsCOMArray.h"
|
||||||
|
#include "nsEventListenerService.h"
|
||||||
|
#include "nsDOMEvent.h"
|
||||||
|
|
||||||
#define EVENT_TYPE_EQUALS( ls, type, userType ) \
|
#define EVENT_TYPE_EQUALS( ls, type, userType ) \
|
||||||
(ls->mEventType && ls->mEventType == type && \
|
(ls->mEventType && ls->mEventType == type && \
|
||||||
|
|
@ -1383,6 +1386,74 @@ nsEventListenerManager::HasListeners()
|
||||||
return !mListeners.IsEmpty();
|
return !mListeners.IsEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsEventListenerManager::GetListenerInfo(nsCOMArray<nsIEventListenerInfo>* aList)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsPIDOMEventTarget> target = do_QueryInterface(mTarget);
|
||||||
|
NS_ENSURE_STATE(target);
|
||||||
|
aList->Clear();
|
||||||
|
PRUint32 count = mListeners.Length();
|
||||||
|
for (PRUint32 i = 0; i < count; ++i) {
|
||||||
|
const nsListenerStruct& ls = mListeners.ElementAt(i);
|
||||||
|
PRBool capturing = !!(ls.mFlags & NS_EVENT_FLAG_CAPTURE);
|
||||||
|
PRBool systemGroup = !!(ls.mGroupFlags & NS_EVENT_FLAG_SYSTEM_EVENT);
|
||||||
|
PRBool allowsUntrusted = !!(ls.mFlags & NS_PRIV_EVENT_UNTRUSTED_PERMITTED);
|
||||||
|
// If this is a script handler and we haven't yet
|
||||||
|
// compiled the event handler itself
|
||||||
|
if ((ls.mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) && ls.mHandlerIsString) {
|
||||||
|
nsCOMPtr<nsIJSEventListener> jslistener = do_QueryInterface(ls.mListener);
|
||||||
|
if (jslistener) {
|
||||||
|
CompileEventHandlerInternal(jslistener->GetEventContext(),
|
||||||
|
jslistener->GetEventScope(),
|
||||||
|
jslistener->GetEventTarget(),
|
||||||
|
ls.mTypeAtom,
|
||||||
|
const_cast<nsListenerStruct*>(&ls),
|
||||||
|
mTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ls.mTypeData) {
|
||||||
|
// Handle special event listener interfaces, like nsIDOMFocusListener.
|
||||||
|
for (PRInt32 j = 0; j < ls.mTypeData->numEvents; ++j) {
|
||||||
|
const EventDispatchData* dispData = &(ls.mTypeData->events[j]);
|
||||||
|
const char* eventName = nsDOMEvent::GetEventName(dispData->message);
|
||||||
|
if (eventName) {
|
||||||
|
NS_ConvertASCIItoUTF16 eventType(eventName);
|
||||||
|
nsRefPtr<nsEventListenerInfo> info =
|
||||||
|
new nsEventListenerInfo(eventType, ls.mListener, capturing,
|
||||||
|
allowsUntrusted, systemGroup);
|
||||||
|
NS_ENSURE_TRUE(info, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
aList->AppendObject(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ls.mEventType == NS_USER_DEFINED_EVENT) {
|
||||||
|
// Handle user defined event types.
|
||||||
|
if (ls.mTypeAtom) {
|
||||||
|
nsAutoString atomName;
|
||||||
|
ls.mTypeAtom->ToString(atomName);
|
||||||
|
const nsDependentSubstring& eventType =
|
||||||
|
Substring(atomName, 2, atomName.Length() - 2);
|
||||||
|
nsRefPtr<nsEventListenerInfo> info =
|
||||||
|
new nsEventListenerInfo(eventType, ls.mListener, capturing,
|
||||||
|
allowsUntrusted, systemGroup);
|
||||||
|
NS_ENSURE_TRUE(info, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
aList->AppendObject(info);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Handle normal events.
|
||||||
|
const char* eventName = nsDOMEvent::GetEventName(ls.mEventType);
|
||||||
|
if (eventName) {
|
||||||
|
NS_ConvertASCIItoUTF16 eventType(eventName);
|
||||||
|
nsRefPtr<nsEventListenerInfo> info =
|
||||||
|
new nsEventListenerInfo(eventType, ls.mListener, capturing,
|
||||||
|
allowsUntrusted, systemGroup);
|
||||||
|
NS_ENSURE_TRUE(info, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
aList->AppendObject(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
nsEventListenerManager::HasUnloadListeners()
|
nsEventListenerManager::HasUnloadListeners()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -134,6 +134,8 @@ public:
|
||||||
|
|
||||||
virtual PRBool HasListeners();
|
virtual PRBool HasListeners();
|
||||||
|
|
||||||
|
virtual nsresult GetListenerInfo(nsCOMArray<nsIEventListenerInfo>* aList);
|
||||||
|
|
||||||
static PRUint32 GetIdentifierForEvent(nsIAtom* aEvent);
|
static PRUint32 GetIdentifierForEvent(nsIAtom* aEvent);
|
||||||
|
|
||||||
// nsIDOMEventTarget
|
// nsIDOMEventTarget
|
||||||
|
|
|
||||||
204
content/events/src/nsEventListenerService.cpp
Normal file
204
content/events/src/nsEventListenerService.cpp
Normal file
|
|
@ -0,0 +1,204 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Olli Pettay <Olli.Pettay@helsinki.fi> (Original Author)
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
#include "nsEventListenerService.h"
|
||||||
|
#include "nsCOMArray.h"
|
||||||
|
#include "nsIEventListenerManager.h"
|
||||||
|
#include "nsPIDOMEventTarget.h"
|
||||||
|
#include "nsIVariant.h"
|
||||||
|
#include "nsIServiceManager.h"
|
||||||
|
#include "nsMemory.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
#include "nsIXPConnect.h"
|
||||||
|
#include "nsIDOMWindow.h"
|
||||||
|
#include "nsPIDOMWindow.h"
|
||||||
|
#include "nsJSUtils.h"
|
||||||
|
#include "nsIPrivateDOMEvent.h"
|
||||||
|
#include "nsIJSContextStack.h"
|
||||||
|
#include "nsGUIEvent.h"
|
||||||
|
#include "nsEventDispatcher.h"
|
||||||
|
#include "nsIJSEventListener.h"
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_1(nsEventListenerInfo, mListener)
|
||||||
|
|
||||||
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsEventListenerInfo)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIEventListenerInfo)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||||
|
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(EventListenerInfo)
|
||||||
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsEventListenerInfo)
|
||||||
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsEventListenerInfo)
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsEventListenerInfo::GetType(nsAString& aType)
|
||||||
|
{
|
||||||
|
aType = mType;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsEventListenerInfo::GetCapturing(PRBool* aCapturing)
|
||||||
|
{
|
||||||
|
*aCapturing = mCapturing;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsEventListenerInfo::GetAllowsUntrusted(PRBool* aAllowsUntrusted)
|
||||||
|
{
|
||||||
|
*aAllowsUntrusted = mAllowsUntrusted;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsEventListenerInfo::GetInSystemEventGroup(PRBool* aInSystemEventGroup)
|
||||||
|
{
|
||||||
|
*aInSystemEventGroup = mInSystemEventGroup;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(nsEventListenerService, nsIEventListenerService)
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsEventListenerInfo::ToSource(nsAString& aResult)
|
||||||
|
{
|
||||||
|
aResult.SetIsVoid(PR_TRUE);
|
||||||
|
nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS = do_QueryInterface(mListener);
|
||||||
|
if (wrappedJS) {
|
||||||
|
JSObject* object = nsnull;
|
||||||
|
wrappedJS->GetJSObject(&object);
|
||||||
|
if (object) {
|
||||||
|
nsCOMPtr<nsIThreadJSContextStack> stack =
|
||||||
|
nsContentUtils::ThreadJSContextStack();
|
||||||
|
if (stack) {
|
||||||
|
JSContext* cx = nsnull;
|
||||||
|
stack->GetSafeJSContext(&cx);
|
||||||
|
if (cx && NS_SUCCEEDED(stack->Push(cx))) {
|
||||||
|
JSAutoRequest ar(cx);
|
||||||
|
jsval v = OBJECT_TO_JSVAL(object);
|
||||||
|
JSString* str = JS_ValueToSource(cx, v);
|
||||||
|
if (str) {
|
||||||
|
aResult.Assign(nsDependentJSString(str));
|
||||||
|
}
|
||||||
|
stack->Pop(&cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nsCOMPtr<nsIJSEventListener> jsl = do_QueryInterface(mListener);
|
||||||
|
if (jsl) {
|
||||||
|
jsl->ToString(mType, aResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsEventListenerService::GetListenerInfoFor(nsIDOMEventTarget* aEventTarget,
|
||||||
|
PRUint32* aCount,
|
||||||
|
nsIEventListenerInfo*** aOutArray)
|
||||||
|
{
|
||||||
|
*aCount = 0;
|
||||||
|
*aOutArray = nsnull;
|
||||||
|
nsCOMArray<nsIEventListenerInfo> listenerInfos;
|
||||||
|
nsCOMPtr<nsPIDOMEventTarget> target = do_QueryInterface(aEventTarget);
|
||||||
|
if (target) {
|
||||||
|
nsCOMPtr<nsIEventListenerManager> elm =
|
||||||
|
target->GetListenerManager(PR_FALSE);
|
||||||
|
if (elm) {
|
||||||
|
elm->GetListenerInfo(&listenerInfos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PRInt32 count = listenerInfos.Count();
|
||||||
|
if (count == 0) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aOutArray =
|
||||||
|
static_cast<nsIEventListenerInfo**>(
|
||||||
|
nsMemory::Alloc(sizeof(nsIEventListenerInfo*) * count));
|
||||||
|
NS_ENSURE_TRUE(*aOutArray, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
|
for (PRInt32 i = 0; i < count; ++i) {
|
||||||
|
NS_ADDREF((*aOutArray)[i] = listenerInfos[i]);
|
||||||
|
}
|
||||||
|
*aCount = count;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsEventListenerService::GetEventTargetChainFor(nsIDOMEventTarget* aEventTarget,
|
||||||
|
PRUint32* aCount,
|
||||||
|
nsIDOMEventTarget*** aOutArray)
|
||||||
|
{
|
||||||
|
*aCount = 0;
|
||||||
|
*aOutArray = nsnull;
|
||||||
|
nsCOMPtr<nsPIDOMEventTarget> target = do_QueryInterface(aEventTarget);
|
||||||
|
NS_ENSURE_ARG(target);
|
||||||
|
nsEvent event(PR_TRUE, NS_EVENT_TYPE_NULL);
|
||||||
|
nsCOMArray<nsPIDOMEventTarget> targets;
|
||||||
|
nsresult rv = nsEventDispatcher::Dispatch(target, nsnull, &event,
|
||||||
|
nsnull, nsnull, nsnull, &targets);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
PRInt32 count = targets.Count();
|
||||||
|
if (count == 0) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aOutArray =
|
||||||
|
static_cast<nsIDOMEventTarget**>(
|
||||||
|
nsMemory::Alloc(sizeof(nsPIDOMEventTarget*) * count));
|
||||||
|
NS_ENSURE_TRUE(*aOutArray, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
|
for (PRInt32 i = 0; i < count; ++i) {
|
||||||
|
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(targets[i]);
|
||||||
|
(*aOutArray)[i] = target.forget().get();
|
||||||
|
}
|
||||||
|
*aCount = count;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
NS_NewEventListenerService(nsIEventListenerService** aResult)
|
||||||
|
{
|
||||||
|
*aResult = new nsEventListenerService();
|
||||||
|
NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
NS_ADDREF(*aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
76
content/events/src/nsEventListenerService.h
Normal file
76
content/events/src/nsEventListenerService.h
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Olli Pettay <Olli.Pettay@helsinki.fi> (Original Author)
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef nsEventListenerService_h__
|
||||||
|
#define nsEventListenerService_h__
|
||||||
|
#include "nsIEventListenerService.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsIDOMEventListener.h"
|
||||||
|
#include "nsIDOMEventTarget.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsPIDOMEventTarget.h"
|
||||||
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
|
||||||
|
class nsEventListenerInfo : public nsIEventListenerInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsEventListenerInfo(const nsAString& aType, nsIDOMEventListener* aListener,
|
||||||
|
PRBool aCapturing, PRBool aAllowsUntrusted,
|
||||||
|
PRBool aInSystemEventGroup)
|
||||||
|
: mType(aType), mListener(aListener), mCapturing(aCapturing),
|
||||||
|
mAllowsUntrusted(aAllowsUntrusted),
|
||||||
|
mInSystemEventGroup(aInSystemEventGroup) {}
|
||||||
|
virtual ~nsEventListenerInfo() {}
|
||||||
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
|
NS_DECL_CYCLE_COLLECTION_CLASS(nsEventListenerInfo)
|
||||||
|
NS_DECL_NSIEVENTLISTENERINFO
|
||||||
|
protected:
|
||||||
|
nsString mType;
|
||||||
|
// nsReftPtr because that is what nsListenerStruct uses too.
|
||||||
|
nsRefPtr<nsIDOMEventListener> mListener;
|
||||||
|
PRPackedBool mCapturing;
|
||||||
|
PRPackedBool mAllowsUntrusted;
|
||||||
|
PRPackedBool mInSystemEventGroup;
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsEventListenerService : public nsIEventListenerService
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIEVENTLISTENERSERVICE
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
@ -69,6 +69,7 @@ _TEST_FILES = \
|
||||||
test_bug412567.html \
|
test_bug412567.html \
|
||||||
test_bug443985.html \
|
test_bug443985.html \
|
||||||
test_bug447736.html \
|
test_bug447736.html \
|
||||||
|
test_bug448602.html \
|
||||||
test_bug450876.html \
|
test_bug450876.html \
|
||||||
test_bug456273.html \
|
test_bug456273.html \
|
||||||
test_bug457672.html \
|
test_bug457672.html \
|
||||||
|
|
|
||||||
118
content/events/test/test_bug448602.html
Normal file
118
content/events/test/test_bug448602.html
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=448602
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<title>Test for Bug 448602</title>
|
||||||
|
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=448602">Mozilla Bug 448602</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
<script type="application/javascript">
|
||||||
|
|
||||||
|
/** Test for Bug 448602 **/
|
||||||
|
|
||||||
|
|
||||||
|
function runTests() {
|
||||||
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||||
|
var els = Components.classes["@mozilla.org/eventlistenerservice;1"]
|
||||||
|
.getService(Components.interfaces.nsIEventListenerService);
|
||||||
|
|
||||||
|
// Event listener info tests
|
||||||
|
var root = document.getElementById("testroot");
|
||||||
|
var infos = els.getListenerInfoFor(root, {});
|
||||||
|
is(infos.length, 0, "Element shouldn't have listeners (1)");
|
||||||
|
|
||||||
|
var listenerSource = 'alert(event);';
|
||||||
|
root.setAttribute("onclick", listenerSource);
|
||||||
|
infos = els.getListenerInfoFor(root, {});
|
||||||
|
is(infos.length, 1, "Element should have listeners (1)");
|
||||||
|
is(infos[0].toSource(), 'function onclick(event) {' + listenerSource + '}',
|
||||||
|
"Unexpected serialization (1)");
|
||||||
|
is(infos[0].type, "click", "Wrong type (1)");
|
||||||
|
is(infos[0].capturing, false, "Wrong phase (1)");
|
||||||
|
is(infos[0].allowsUntrusted, true, "Should allow untrusted events (1)");
|
||||||
|
|
||||||
|
root.removeAttribute("onclick");
|
||||||
|
infos = els.getListenerInfoFor(root, {});
|
||||||
|
is(infos.length, 0, "Element shouldn't have listeners (2)");
|
||||||
|
|
||||||
|
var l = function (e) { alert(e); };
|
||||||
|
root.addEventListener("foo", l, true, true);
|
||||||
|
root.addEventListener("foo", l, false, false);
|
||||||
|
infos = els.getListenerInfoFor(root, {});
|
||||||
|
is(infos.length, 2, "Element should have listeners (2)");
|
||||||
|
is(infos[0].toSource(), "(function (e) {alert(e);})",
|
||||||
|
"Unexpected serialization (2)");
|
||||||
|
is(infos[0].type, "foo", "Wrong type (2)");
|
||||||
|
is(infos[0].capturing, true, "Wrong phase (2)");
|
||||||
|
is(infos[0].allowsUntrusted, true, "Should allow untrusted events (2)");
|
||||||
|
is(infos[1].toSource(), "(function (e) {alert(e);})",
|
||||||
|
"Unexpected serialization (3)");
|
||||||
|
is(infos[1].type, "foo", "Wrong type (3)");
|
||||||
|
is(infos[1].capturing, false, "Wrong phase (3)");
|
||||||
|
is(infos[1].allowsUntrusted, false, "Shouldn't allow untrusted events (1)");
|
||||||
|
|
||||||
|
root.removeEventListener("foo", l, true);
|
||||||
|
root.removeEventListener("foo", l, false);
|
||||||
|
infos = els.getListenerInfoFor(root, {});
|
||||||
|
is(infos.length, 0, "Element shouldn't have listeners (3)");
|
||||||
|
|
||||||
|
root.onclick = l;
|
||||||
|
infos = els.getListenerInfoFor(root, {});
|
||||||
|
is(infos.length, 1, "Element should have listeners (3)");
|
||||||
|
is(infos[0].toSource(), '(function (e) {alert(e);})',
|
||||||
|
"Unexpected serialization (4)");
|
||||||
|
is(infos[0].type, "click", "Wrong type (4)");
|
||||||
|
is(infos[0].capturing, false, "Wrong phase (4)");
|
||||||
|
is(infos[0].allowsUntrusted, true, "Should allow untrusted events (3)");
|
||||||
|
|
||||||
|
// Event target chain tests
|
||||||
|
var l2 = document.getElementById("testlevel2");
|
||||||
|
var l3 = document.getElementById("testlevel3");
|
||||||
|
var textnode = l3.firstChild;
|
||||||
|
var chain = els.getEventTargetChainFor(textnode, {});
|
||||||
|
ok(chain.length > 3, "Too short event target chain.");
|
||||||
|
is(chain[0], textnode, "Wrong chain item (1)");
|
||||||
|
is(chain[1], l3, "Wrong chain item (2)");
|
||||||
|
is(chain[2], l2, "Wrong chain item (3)");
|
||||||
|
is(chain[3], root, "Wrong chain item (4)");
|
||||||
|
|
||||||
|
var hasDocumentInChain = false;
|
||||||
|
var hasWindowInChain = false;
|
||||||
|
for (var i = 0; i < chain.length; ++i) {
|
||||||
|
if (chain[i] == document) {
|
||||||
|
hasDocumentInChain = true;
|
||||||
|
} else if (chain[i] == window) {
|
||||||
|
hasWindowInChain = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(hasDocumentInChain, "Should have document in event target chain!");
|
||||||
|
ok(hasWindowInChain, "Should have window in event target chain!");
|
||||||
|
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
addLoadEvent(runTests);
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
<div id="testroot">
|
||||||
|
<div id="testlevel2">
|
||||||
|
<div id="testlevel3">
|
||||||
|
Test
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -465,6 +465,8 @@
|
||||||
|
|
||||||
#include "nsIDOMNSMouseEvent.h"
|
#include "nsIDOMNSMouseEvent.h"
|
||||||
|
|
||||||
|
#include "nsIEventListenerService.h"
|
||||||
|
|
||||||
static NS_DEFINE_CID(kDOMSOF_CID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
|
static NS_DEFINE_CID(kDOMSOF_CID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
|
||||||
|
|
||||||
static const char kDOMStringBundleURL[] =
|
static const char kDOMStringBundleURL[] =
|
||||||
|
|
@ -1356,6 +1358,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||||
|
|
||||||
NS_DEFINE_CLASSINFO_DATA(ScrollAreaEvent, nsDOMGenericSH,
|
NS_DEFINE_CLASSINFO_DATA(ScrollAreaEvent, nsDOMGenericSH,
|
||||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||||
|
NS_DEFINE_CLASSINFO_DATA(EventListenerInfo, nsDOMGenericSH,
|
||||||
|
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Objects that shuld be constructable through |new Name();|
|
// Objects that shuld be constructable through |new Name();|
|
||||||
|
|
@ -3764,6 +3768,10 @@ nsDOMClassInfo::Init()
|
||||||
DOM_CLASSINFO_UI_EVENT_MAP_ENTRIES
|
DOM_CLASSINFO_UI_EVENT_MAP_ENTRIES
|
||||||
DOM_CLASSINFO_MAP_END
|
DOM_CLASSINFO_MAP_END
|
||||||
|
|
||||||
|
DOM_CLASSINFO_MAP_BEGIN(EventListenerInfo, nsIEventListenerInfo)
|
||||||
|
DOM_CLASSINFO_MAP_ENTRY(nsIEventListenerInfo)
|
||||||
|
DOM_CLASSINFO_MAP_END
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
{
|
{
|
||||||
PRUint32 i = NS_ARRAY_LENGTH(sClassInfoData);
|
PRUint32 i = NS_ARRAY_LENGTH(sClassInfoData);
|
||||||
|
|
|
||||||
|
|
@ -486,6 +486,8 @@ enum nsDOMClassInfoID {
|
||||||
|
|
||||||
eDOMClassInfo_ScrollAreaEvent_id,
|
eDOMClassInfo_ScrollAreaEvent_id,
|
||||||
|
|
||||||
|
eDOMClassInfo_EventListenerInfo_id,
|
||||||
|
|
||||||
// This one better be the last one in this list
|
// This one better be the last one in this list
|
||||||
eDOMClassInfoIDCount
|
eDOMClassInfoIDCount
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,8 @@ class nsIDOMEventListener;
|
||||||
class nsIAtom;
|
class nsIAtom;
|
||||||
|
|
||||||
#define NS_IJSEVENTLISTENER_IID \
|
#define NS_IJSEVENTLISTENER_IID \
|
||||||
{ 0xa6cf9118, 0x15b3, 0x11d2, \
|
{ 0xe16e7146, 0x109d, 0x4f54, \
|
||||||
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
|
{ 0x94, 0x78, 0xda, 0xc4, 0x3a, 0x71, 0x0b, 0x52 } }
|
||||||
|
|
||||||
// Implemented by script event listeners. Used to retrieve the
|
// Implemented by script event listeners. Used to retrieve the
|
||||||
// script object corresponding to the event target.
|
// script object corresponding to the event target.
|
||||||
|
|
@ -81,6 +81,8 @@ public:
|
||||||
|
|
||||||
virtual void SetEventName(nsIAtom* aName) = 0;
|
virtual void SetEventName(nsIAtom* aName) = 0;
|
||||||
|
|
||||||
|
virtual void ToString(const nsAString& aEventName, nsAString& aResult) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~nsIJSEventListener()
|
virtual ~nsIJSEventListener()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -51,9 +51,9 @@
|
||||||
#include "nsIMutableArray.h"
|
#include "nsIMutableArray.h"
|
||||||
#include "nsVariant.h"
|
#include "nsVariant.h"
|
||||||
#include "nsIDOMBeforeUnloadEvent.h"
|
#include "nsIDOMBeforeUnloadEvent.h"
|
||||||
|
#include "nsPIDOMEventTarget.h"
|
||||||
#ifdef NS_DEBUG
|
|
||||||
#include "nsIJSContextStack.h"
|
#include "nsIJSContextStack.h"
|
||||||
|
#ifdef NS_DEBUG
|
||||||
#include "nsDOMJSUtils.h"
|
#include "nsDOMJSUtils.h"
|
||||||
|
|
||||||
#include "nspr.h" // PR_fprintf
|
#include "nspr.h" // PR_fprintf
|
||||||
|
|
@ -140,6 +140,35 @@ nsJSEventListener::SetEventName(nsIAtom* aName)
|
||||||
mEventName = aName;
|
mEventName = aName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsJSEventListener::ToString(const nsAString& aEventName, nsAString& aResult)
|
||||||
|
{
|
||||||
|
aResult.Truncate();
|
||||||
|
nsCOMPtr<nsIThreadJSContextStack> stack = nsContentUtils::ThreadJSContextStack();
|
||||||
|
nsCOMPtr<nsPIDOMEventTarget> target = do_QueryInterface(mTarget);
|
||||||
|
if (target && stack && mContext) {
|
||||||
|
JSContext* cx = static_cast<JSContext*>(mContext->GetNativeContext());
|
||||||
|
if (cx && NS_SUCCEEDED(stack->Push(cx))) {
|
||||||
|
JSAutoRequest ar(cx);
|
||||||
|
nsAutoString eventString = NS_LITERAL_STRING("on") + aEventName;
|
||||||
|
nsCOMPtr<nsIAtom> atomName = do_GetAtom(eventString);
|
||||||
|
nsScriptObjectHolder funcval(mContext);
|
||||||
|
mContext->GetBoundEventHandler(mTarget, mScopeObject, atomName,
|
||||||
|
funcval);
|
||||||
|
jsval funval =
|
||||||
|
OBJECT_TO_JSVAL(static_cast<JSObject*>(static_cast<void*>(funcval)));
|
||||||
|
|
||||||
|
JSString* str =
|
||||||
|
JS_ValueToSource(static_cast<JSContext*>(mContext->GetNativeContext()),
|
||||||
|
funval);
|
||||||
|
if (str) {
|
||||||
|
aResult.Assign(nsDependentJSString(str));
|
||||||
|
}
|
||||||
|
stack->Pop(&cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsJSEventListener::HandleEvent(nsIDOMEvent* aEvent)
|
nsJSEventListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,8 @@ public:
|
||||||
// nsIJSEventListener interface
|
// nsIJSEventListener interface
|
||||||
virtual void SetEventName(nsIAtom* aName);
|
virtual void SetEventName(nsIAtom* aName);
|
||||||
|
|
||||||
|
virtual void ToString(const nsAString& aEventName, nsAString& aResult);
|
||||||
|
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsJSEventListener,
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsJSEventListener,
|
||||||
nsIDOMEventListener)
|
nsIDOMEventListener)
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@
|
||||||
#include "nsXULPopupManager.h"
|
#include "nsXULPopupManager.h"
|
||||||
#include "nsFocusManager.h"
|
#include "nsFocusManager.h"
|
||||||
|
|
||||||
|
#include "nsIEventListenerService.h"
|
||||||
// Transformiix stuff
|
// Transformiix stuff
|
||||||
#include "nsXPathEvaluator.h"
|
#include "nsXPathEvaluator.h"
|
||||||
#include "txMozillaXSLTProcessor.h"
|
#include "txMozillaXSLTProcessor.h"
|
||||||
|
|
@ -423,6 +424,8 @@ nsresult NS_NewXBLService(nsIXBLService** aResult);
|
||||||
nsresult NS_NewContentPolicy(nsIContentPolicy** aResult);
|
nsresult NS_NewContentPolicy(nsIContentPolicy** aResult);
|
||||||
nsresult NS_NewDOMEventGroup(nsIDOMEventGroup** aResult);
|
nsresult NS_NewDOMEventGroup(nsIDOMEventGroup** aResult);
|
||||||
|
|
||||||
|
nsresult NS_NewEventListenerService(nsIEventListenerService** aResult);
|
||||||
|
|
||||||
NS_IMETHODIMP NS_NewXULControllers(nsISupports* aOuter, REFNSIID aIID, void** aResult);
|
NS_IMETHODIMP NS_NewXULControllers(nsISupports* aOuter, REFNSIID aIID, void** aResult);
|
||||||
|
|
||||||
#define MAKE_CTOR(ctor_, iface_, func_) \
|
#define MAKE_CTOR(ctor_, iface_, func_) \
|
||||||
|
|
@ -523,6 +526,7 @@ MAKE_CTOR(CreateXTFService, nsIXTFService, NS_NewXTF
|
||||||
MAKE_CTOR(CreateXMLContentBuilder, nsIXMLContentBuilder, NS_NewXMLContentBuilder)
|
MAKE_CTOR(CreateXMLContentBuilder, nsIXMLContentBuilder, NS_NewXMLContentBuilder)
|
||||||
#endif
|
#endif
|
||||||
MAKE_CTOR(CreateContentDLF, nsIDocumentLoaderFactory, NS_NewContentDocumentLoaderFactory)
|
MAKE_CTOR(CreateContentDLF, nsIDocumentLoaderFactory, NS_NewContentDocumentLoaderFactory)
|
||||||
|
MAKE_CTOR(CreateEventListenerService, nsIEventListenerService, NS_NewEventListenerService)
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsWyciwygProtocolHandler)
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsWyciwygProtocolHandler)
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsContentAreaDragDrop)
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsContentAreaDragDrop)
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDataDocumentContentPolicy)
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDataDocumentContentPolicy)
|
||||||
|
|
@ -1443,12 +1447,16 @@ static const nsModuleComponentInfo gComponents[] = {
|
||||||
"@mozilla.org/geolocation/service;1",
|
"@mozilla.org/geolocation/service;1",
|
||||||
nsGeolocationServiceConstructor },
|
nsGeolocationServiceConstructor },
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{ "Focus Manager",
|
{ "Focus Manager",
|
||||||
NS_FOCUSMANAGER_CID,
|
NS_FOCUSMANAGER_CID,
|
||||||
"@mozilla.org/focus-manager;1",
|
"@mozilla.org/focus-manager;1",
|
||||||
CreateFocusManager },
|
CreateFocusManager },
|
||||||
|
|
||||||
|
|
||||||
|
{ "Event Listener Service",
|
||||||
|
NS_EVENTLISTENERSERVICE_CID,
|
||||||
|
NS_EVENTLISTENERSERVICE_CONTRACTID,
|
||||||
|
CreateEventListenerService }
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_NSGETMODULE_WITH_CTOR(nsLayoutModule, gComponents, Initialize)
|
NS_IMPL_NSGETMODULE_WITH_CTOR(nsLayoutModule, gComponents, Initialize)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue