зеркало из https://github.com/mozilla/gecko-dev.git
Bug 984253 part.2 Merge nsIJSEventListener and nsJSEventListener r=smaug, sr=jst
This commit is contained in:
Родитель
3dd3b64ce7
Коммит
76ada5fabb
|
@ -14,6 +14,7 @@
|
|||
#endif // #ifdef MOZ_B2G
|
||||
#include "mozilla/HalSensor.h"
|
||||
#include "mozilla/InternalMutationEvent.h"
|
||||
#include "mozilla/JSEventHandler.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
@ -30,7 +31,6 @@
|
|||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIJSEventListener.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsIXPConnect.h"
|
||||
|
@ -613,18 +613,18 @@ EventListenerManager::SetEventHandlerInternal(
|
|||
EventListenerFlags flags;
|
||||
flags.mListenerIsJSListener = true;
|
||||
|
||||
nsCOMPtr<nsIJSEventListener> jsListener;
|
||||
NS_NewJSEventListener(mTarget, aName,
|
||||
aHandler, getter_AddRefs(jsListener));
|
||||
nsCOMPtr<nsJSEventListener> jsListener;
|
||||
NS_NewJSEventHandler(mTarget, aName,
|
||||
aHandler, getter_AddRefs(jsListener));
|
||||
EventListenerHolder listenerHolder(jsListener);
|
||||
AddEventListenerInternal(listenerHolder, eventType, aName, aTypeString,
|
||||
flags, true);
|
||||
|
||||
listener = FindEventHandler(eventType, aName, aTypeString);
|
||||
} else {
|
||||
nsIJSEventListener* jsListener = listener->GetJSListener();
|
||||
nsJSEventListener* jsListener = listener->GetJSListener();
|
||||
MOZ_ASSERT(jsListener,
|
||||
"How can we have an event handler with no nsIJSEventListener?");
|
||||
"How can we have an event handler with no nsJSEventListener?");
|
||||
|
||||
bool same = jsListener->GetHandler() == aHandler;
|
||||
// Possibly the same listener, but update still the context and scope.
|
||||
|
@ -785,7 +785,7 @@ EventListenerManager::CompileEventHandlerInternal(Listener* aListener,
|
|||
{
|
||||
MOZ_ASSERT(aListener->GetJSListener());
|
||||
MOZ_ASSERT(aListener->mHandlerIsString, "Why are we compiling a non-string JS listener?");
|
||||
nsIJSEventListener* jsListener = aListener->GetJSListener();
|
||||
nsJSEventListener* jsListener = aListener->GetJSListener();
|
||||
MOZ_ASSERT(!jsListener->GetHandler().HasEventHandler(), "What is there to compile?");
|
||||
|
||||
nsresult result = NS_OK;
|
||||
|
@ -812,7 +812,7 @@ EventListenerManager::CompileEventHandlerInternal(Listener* aListener,
|
|||
// <html:frameset> or <xul:window> or the like.
|
||||
// XXX I don't like that we have to reference content from
|
||||
// here. The alternative is to store the event handler string on
|
||||
// the nsIJSEventListener itself, and that still doesn't address
|
||||
// the nsJSEventListener itself, and that still doesn't address
|
||||
// the arg names issue.
|
||||
nsCOMPtr<Element> element = do_QueryInterface(mTarget);
|
||||
MOZ_ASSERT(element || aBody, "Where will we get our body?");
|
||||
|
@ -1281,7 +1281,7 @@ EventListenerManager::GetEventHandlerInternal(nsIAtom* aEventName,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsIJSEventListener* jsListener = listener->GetJSListener();
|
||||
nsJSEventListener* jsListener = listener->GetJSListener();
|
||||
|
||||
if (listener->mHandlerIsString) {
|
||||
CompileEventHandlerInternal(listener, nullptr, nullptr);
|
||||
|
@ -1302,7 +1302,7 @@ EventListenerManager::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
|||
n += mListeners.SizeOfExcludingThis(aMallocSizeOf);
|
||||
uint32_t count = mListeners.Length();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsIJSEventListener* jsl = mListeners.ElementAt(i).GetJSListener();
|
||||
nsJSEventListener* jsl = mListeners.ElementAt(i).GetJSListener();
|
||||
if (jsl) {
|
||||
n += jsl->SizeOfIncludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
@ -1316,7 +1316,7 @@ EventListenerManager::MarkForCC()
|
|||
uint32_t count = mListeners.Length();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
const Listener& listener = mListeners.ElementAt(i);
|
||||
nsIJSEventListener* jsListener = listener.GetJSListener();
|
||||
nsJSEventListener* jsListener = listener.GetJSListener();
|
||||
if (jsListener) {
|
||||
if (jsListener->GetHandler().HasEventHandler()) {
|
||||
JS::ExposeObjectToActiveJS(jsListener->GetHandler().Ptr()->Callable());
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
|
||||
#include "mozilla/BasicEvents.h"
|
||||
#include "mozilla/dom/EventListenerBinding.h"
|
||||
#include "mozilla/JSEventHandler.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIJSEventListener.h"
|
||||
#include "nsTObserverArray.h"
|
||||
|
||||
class nsIDOMEvent;
|
||||
|
@ -174,10 +174,10 @@ public:
|
|||
|
||||
EventListenerFlags mFlags;
|
||||
|
||||
nsIJSEventListener* GetJSListener() const
|
||||
nsJSEventListener* GetJSListener() const
|
||||
{
|
||||
return (mListenerType == eJSEventListener) ?
|
||||
static_cast<nsIJSEventListener *>(mListener.GetXPCOMCallback()) :
|
||||
static_cast<nsJSEventListener*>(mListener.GetXPCOMCallback()) :
|
||||
nullptr;
|
||||
}
|
||||
|
||||
|
@ -190,7 +190,7 @@ public:
|
|||
~Listener()
|
||||
{
|
||||
if ((mListenerType == eJSEventListener) && mListener) {
|
||||
static_cast<nsIJSEventListener*>(
|
||||
static_cast<nsJSEventListener*>(
|
||||
mListener.GetXPCOMCallback())->Disconnect();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
#include "mozilla/BasicEvents.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
#include "mozilla/JSEventHandler.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsCxPusher.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsIJSEventListener.h"
|
||||
#include "nsIXPConnect.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsMemory.h"
|
||||
|
@ -101,7 +101,7 @@ EventListenerInfo::GetJSVal(JSContext* aCx,
|
|||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIJSEventListener> jsl = do_QueryInterface(mListener);
|
||||
nsCOMPtr<nsJSEventListener> jsl = do_QueryInterface(mListener);
|
||||
if (jsl && jsl->GetHandler().HasEventHandler()) {
|
||||
JS::Handle<JSObject*> handler(jsl->GetHandler().Ptr()->Callable());
|
||||
if (handler) {
|
||||
|
|
|
@ -46,8 +46,11 @@ using namespace mozilla::dom;
|
|||
nsJSEventListener::nsJSEventListener(nsISupports *aTarget,
|
||||
nsIAtom* aType,
|
||||
const nsEventHandler& aHandler)
|
||||
: nsIJSEventListener(aTarget, aType, aHandler)
|
||||
: mEventName(aType)
|
||||
, mHandler(aHandler)
|
||||
{
|
||||
nsCOMPtr<nsISupports> base = do_QueryInterface(aTarget);
|
||||
mTarget = base.get();
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSEventListener)
|
||||
|
@ -98,8 +101,8 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
|
|||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsJSEventListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIJSEventListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsJSEventListener)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsJSEventListener)
|
||||
|
@ -236,9 +239,10 @@ nsJSEventListener::HandleEvent(nsIDOMEvent* aEvent)
|
|||
*/
|
||||
|
||||
nsresult
|
||||
NS_NewJSEventListener(nsISupports*aTarget, nsIAtom* aEventType,
|
||||
const nsEventHandler& aHandler,
|
||||
nsIJSEventListener** aReturn)
|
||||
NS_NewJSEventHandler(nsISupports* aTarget,
|
||||
nsIAtom* aEventType,
|
||||
const nsEventHandler& aHandler,
|
||||
nsJSEventListener** aReturn)
|
||||
{
|
||||
NS_ENSURE_ARG(aEventType || !NS_IsMainThread());
|
||||
nsJSEventListener* it =
|
||||
|
|
|
@ -8,30 +8,250 @@
|
|||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
#include "nsIJSEventListener.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "mozilla/dom/EventHandlerBinding.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIScriptContext.h"
|
||||
|
||||
// nsJSEventListener interface
|
||||
// misnamed - JS no longer has exclusive rights over this interface!
|
||||
class nsJSEventListener : public nsIJSEventListener
|
||||
class nsEventHandler
|
||||
{
|
||||
public:
|
||||
typedef mozilla::dom::EventHandlerNonNull EventHandlerNonNull;
|
||||
typedef mozilla::dom::OnBeforeUnloadEventHandlerNonNull
|
||||
OnBeforeUnloadEventHandlerNonNull;
|
||||
typedef mozilla::dom::OnErrorEventHandlerNonNull OnErrorEventHandlerNonNull;
|
||||
typedef mozilla::dom::CallbackFunction CallbackFunction;
|
||||
|
||||
enum HandlerType
|
||||
{
|
||||
eUnset = 0,
|
||||
eNormal = 0x1,
|
||||
eOnError = 0x2,
|
||||
eOnBeforeUnload = 0x3,
|
||||
eTypeBits = 0x3
|
||||
};
|
||||
|
||||
nsEventHandler()
|
||||
: mBits(0)
|
||||
{
|
||||
}
|
||||
|
||||
nsEventHandler(EventHandlerNonNull* aHandler)
|
||||
{
|
||||
Assign(aHandler, eNormal);
|
||||
}
|
||||
|
||||
nsEventHandler(OnErrorEventHandlerNonNull* aHandler)
|
||||
{
|
||||
Assign(aHandler, eOnError);
|
||||
}
|
||||
|
||||
nsEventHandler(OnBeforeUnloadEventHandlerNonNull* aHandler)
|
||||
{
|
||||
Assign(aHandler, eOnBeforeUnload);
|
||||
}
|
||||
|
||||
nsEventHandler(const nsEventHandler& aOther)
|
||||
{
|
||||
if (aOther.HasEventHandler()) {
|
||||
// Have to make sure we take our own ref
|
||||
Assign(aOther.Ptr(), aOther.Type());
|
||||
} else {
|
||||
mBits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
~nsEventHandler()
|
||||
{
|
||||
ReleaseHandler();
|
||||
}
|
||||
|
||||
HandlerType Type() const
|
||||
{
|
||||
return HandlerType(mBits & eTypeBits);
|
||||
}
|
||||
|
||||
bool HasEventHandler() const
|
||||
{
|
||||
return !!Ptr();
|
||||
}
|
||||
|
||||
void SetHandler(const nsEventHandler& aHandler)
|
||||
{
|
||||
if (aHandler.HasEventHandler()) {
|
||||
ReleaseHandler();
|
||||
Assign(aHandler.Ptr(), aHandler.Type());
|
||||
} else {
|
||||
ForgetHandler();
|
||||
}
|
||||
}
|
||||
|
||||
EventHandlerNonNull* EventHandler() const
|
||||
{
|
||||
MOZ_ASSERT(Type() == eNormal && Ptr());
|
||||
return reinterpret_cast<EventHandlerNonNull*>(Ptr());
|
||||
}
|
||||
|
||||
void SetHandler(EventHandlerNonNull* aHandler)
|
||||
{
|
||||
ReleaseHandler();
|
||||
Assign(aHandler, eNormal);
|
||||
}
|
||||
|
||||
OnBeforeUnloadEventHandlerNonNull* OnBeforeUnloadEventHandler() const
|
||||
{
|
||||
MOZ_ASSERT(Type() == eOnBeforeUnload);
|
||||
return reinterpret_cast<OnBeforeUnloadEventHandlerNonNull*>(Ptr());
|
||||
}
|
||||
|
||||
void SetHandler(OnBeforeUnloadEventHandlerNonNull* aHandler)
|
||||
{
|
||||
ReleaseHandler();
|
||||
Assign(aHandler, eOnBeforeUnload);
|
||||
}
|
||||
|
||||
OnErrorEventHandlerNonNull* OnErrorEventHandler() const
|
||||
{
|
||||
MOZ_ASSERT(Type() == eOnError);
|
||||
return reinterpret_cast<OnErrorEventHandlerNonNull*>(Ptr());
|
||||
}
|
||||
|
||||
void SetHandler(OnErrorEventHandlerNonNull* aHandler)
|
||||
{
|
||||
ReleaseHandler();
|
||||
Assign(aHandler, eOnError);
|
||||
}
|
||||
|
||||
CallbackFunction* Ptr() const
|
||||
{
|
||||
// Have to cast eTypeBits so we don't have to worry about
|
||||
// promotion issues after the bitflip.
|
||||
return reinterpret_cast<CallbackFunction*>(mBits & ~uintptr_t(eTypeBits));
|
||||
}
|
||||
|
||||
void ForgetHandler()
|
||||
{
|
||||
ReleaseHandler();
|
||||
mBits = 0;
|
||||
}
|
||||
|
||||
bool operator==(const nsEventHandler& aOther) const
|
||||
{
|
||||
return
|
||||
Ptr() && aOther.Ptr() &&
|
||||
Ptr()->CallbackPreserveColor() == aOther.Ptr()->CallbackPreserveColor();
|
||||
}
|
||||
|
||||
private:
|
||||
void operator=(const nsEventHandler&) MOZ_DELETE;
|
||||
|
||||
void ReleaseHandler()
|
||||
{
|
||||
nsISupports* ptr = Ptr();
|
||||
NS_IF_RELEASE(ptr);
|
||||
}
|
||||
|
||||
void Assign(nsISupports* aHandler, HandlerType aType)
|
||||
{
|
||||
MOZ_ASSERT(aHandler, "Must have handler");
|
||||
NS_ADDREF(aHandler);
|
||||
mBits = uintptr_t(aHandler) | uintptr_t(aType);
|
||||
}
|
||||
|
||||
uintptr_t mBits;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implemented by script event listeners. Used to retrieve the script object
|
||||
* corresponding to the event target and the handler itself.
|
||||
*
|
||||
* Note, mTarget is a raw pointer and the owner of the nsJSEventListener object
|
||||
* is expected to call Disconnect()!
|
||||
*/
|
||||
|
||||
#define NS_JSEVENTLISTENER_IID \
|
||||
{ 0x4f486881, 0x1956, 0x4079, \
|
||||
{ 0x8c, 0xa0, 0xf3, 0xbd, 0x60, 0x5c, 0xc2, 0x79 } }
|
||||
|
||||
class nsJSEventListener : public nsIDOMEventListener
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_JSEVENTLISTENER_IID)
|
||||
|
||||
nsJSEventListener(nsISupports* aTarget, nsIAtom* aType,
|
||||
const nsEventHandler& aHandler);
|
||||
|
||||
virtual ~nsJSEventListener()
|
||||
{
|
||||
NS_ASSERTION(!mTarget, "Should have called Disconnect()!");
|
||||
}
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
||||
// nsIDOMEventListener interface
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
|
||||
// nsIJSEventListener
|
||||
nsISupports* GetEventTarget() const
|
||||
{
|
||||
return mTarget;
|
||||
}
|
||||
|
||||
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
|
||||
void Disconnect()
|
||||
{
|
||||
mTarget = nullptr;
|
||||
}
|
||||
|
||||
const nsEventHandler& GetHandler() const
|
||||
{
|
||||
return mHandler;
|
||||
}
|
||||
|
||||
void ForgetHandler()
|
||||
{
|
||||
mHandler.ForgetHandler();
|
||||
}
|
||||
|
||||
nsIAtom* EventName() const
|
||||
{
|
||||
return mEventName;
|
||||
}
|
||||
|
||||
// Set a handler for this event listener. The handler must already
|
||||
// be bound to the right target.
|
||||
void SetHandler(const nsEventHandler& aHandler)
|
||||
{
|
||||
mHandler.SetHandler(aHandler);
|
||||
}
|
||||
void SetHandler(mozilla::dom::EventHandlerNonNull* aHandler)
|
||||
{
|
||||
mHandler.SetHandler(aHandler);
|
||||
}
|
||||
void SetHandler(mozilla::dom::OnBeforeUnloadEventHandlerNonNull* aHandler)
|
||||
{
|
||||
mHandler.SetHandler(aHandler);
|
||||
}
|
||||
void SetHandler(mozilla::dom::OnErrorEventHandlerNonNull* aHandler)
|
||||
{
|
||||
mHandler.SetHandler(aHandler);
|
||||
}
|
||||
|
||||
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return 0;
|
||||
|
||||
// Measurement of the following members may be added later if DMD finds it
|
||||
// is worthwhile:
|
||||
// - mTarget
|
||||
//
|
||||
// The following members are not measured:
|
||||
// - mHandler: may be shared with others
|
||||
// - mEventName: shared with others
|
||||
}
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
|
||||
{
|
||||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
@ -39,7 +259,23 @@ public:
|
|||
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS(nsJSEventListener)
|
||||
|
||||
bool IsBlackForCC();
|
||||
|
||||
protected:
|
||||
nsISupports* mTarget;
|
||||
nsCOMPtr<nsIAtom> mEventName;
|
||||
nsEventHandler mHandler;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsJSEventListener, NS_JSEVENTLISTENER_IID)
|
||||
|
||||
/**
|
||||
* Factory function. aHandler must already be bound to aTarget.
|
||||
* aContext is allowed to be null if aHandler is already set up.
|
||||
*/
|
||||
nsresult NS_NewJSEventHandler(nsISupports* aTarget,
|
||||
nsIAtom* aType,
|
||||
const nsEventHandler& aHandler,
|
||||
nsJSEventListener** aReturn);
|
||||
|
||||
#endif // mozilla_JSEventHandler_h_
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ XPIDL_MODULE = 'content_events'
|
|||
|
||||
EXPORTS += [
|
||||
'nsEventStates.h',
|
||||
'nsIJSEventListener.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
|
|
|
@ -1,265 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsIJSEventListener_h__
|
||||
#define nsIJSEventListener_h__
|
||||
|
||||
#include "nsIScriptContext.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/dom/EventHandlerBinding.h"
|
||||
|
||||
#define NS_IJSEVENTLISTENER_IID \
|
||||
{ 0x8f06b4af, 0xbd0d, 0x486b, \
|
||||
{ 0x81, 0xc8, 0x20, 0x42, 0x40, 0x2b, 0xf1, 0xef } }
|
||||
|
||||
class nsEventHandler
|
||||
{
|
||||
public:
|
||||
typedef mozilla::dom::EventHandlerNonNull EventHandlerNonNull;
|
||||
typedef mozilla::dom::OnBeforeUnloadEventHandlerNonNull
|
||||
OnBeforeUnloadEventHandlerNonNull;
|
||||
typedef mozilla::dom::OnErrorEventHandlerNonNull OnErrorEventHandlerNonNull;
|
||||
typedef mozilla::dom::CallbackFunction CallbackFunction;
|
||||
|
||||
enum HandlerType {
|
||||
eUnset = 0,
|
||||
eNormal = 0x1,
|
||||
eOnError = 0x2,
|
||||
eOnBeforeUnload = 0x3,
|
||||
eTypeBits = 0x3
|
||||
};
|
||||
|
||||
nsEventHandler() :
|
||||
mBits(0)
|
||||
{}
|
||||
|
||||
nsEventHandler(EventHandlerNonNull* aHandler)
|
||||
{
|
||||
Assign(aHandler, eNormal);
|
||||
}
|
||||
|
||||
nsEventHandler(OnErrorEventHandlerNonNull* aHandler)
|
||||
{
|
||||
Assign(aHandler, eOnError);
|
||||
}
|
||||
|
||||
nsEventHandler(OnBeforeUnloadEventHandlerNonNull* aHandler)
|
||||
{
|
||||
Assign(aHandler, eOnBeforeUnload);
|
||||
}
|
||||
|
||||
nsEventHandler(const nsEventHandler& aOther)
|
||||
{
|
||||
if (aOther.HasEventHandler()) {
|
||||
// Have to make sure we take our own ref
|
||||
Assign(aOther.Ptr(), aOther.Type());
|
||||
} else {
|
||||
mBits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
~nsEventHandler()
|
||||
{
|
||||
ReleaseHandler();
|
||||
}
|
||||
|
||||
HandlerType Type() const {
|
||||
return HandlerType(mBits & eTypeBits);
|
||||
}
|
||||
|
||||
bool HasEventHandler() const
|
||||
{
|
||||
return !!Ptr();
|
||||
}
|
||||
|
||||
void SetHandler(const nsEventHandler& aHandler)
|
||||
{
|
||||
if (aHandler.HasEventHandler()) {
|
||||
ReleaseHandler();
|
||||
Assign(aHandler.Ptr(), aHandler.Type());
|
||||
} else {
|
||||
ForgetHandler();
|
||||
}
|
||||
}
|
||||
|
||||
EventHandlerNonNull* EventHandler() const
|
||||
{
|
||||
MOZ_ASSERT(Type() == eNormal && Ptr());
|
||||
return reinterpret_cast<EventHandlerNonNull*>(Ptr());
|
||||
}
|
||||
|
||||
void SetHandler(EventHandlerNonNull* aHandler)
|
||||
{
|
||||
ReleaseHandler();
|
||||
Assign(aHandler, eNormal);
|
||||
}
|
||||
|
||||
OnBeforeUnloadEventHandlerNonNull* OnBeforeUnloadEventHandler() const
|
||||
{
|
||||
MOZ_ASSERT(Type() == eOnBeforeUnload);
|
||||
return reinterpret_cast<OnBeforeUnloadEventHandlerNonNull*>(Ptr());
|
||||
}
|
||||
|
||||
void SetHandler(OnBeforeUnloadEventHandlerNonNull* aHandler)
|
||||
{
|
||||
ReleaseHandler();
|
||||
Assign(aHandler, eOnBeforeUnload);
|
||||
}
|
||||
|
||||
OnErrorEventHandlerNonNull* OnErrorEventHandler() const
|
||||
{
|
||||
MOZ_ASSERT(Type() == eOnError);
|
||||
return reinterpret_cast<OnErrorEventHandlerNonNull*>(Ptr());
|
||||
}
|
||||
|
||||
void SetHandler(OnErrorEventHandlerNonNull* aHandler)
|
||||
{
|
||||
ReleaseHandler();
|
||||
Assign(aHandler, eOnError);
|
||||
}
|
||||
|
||||
CallbackFunction* Ptr() const
|
||||
{
|
||||
// Have to cast eTypeBits so we don't have to worry about
|
||||
// promotion issues after the bitflip.
|
||||
return reinterpret_cast<CallbackFunction*>(mBits & ~uintptr_t(eTypeBits));
|
||||
}
|
||||
|
||||
void ForgetHandler()
|
||||
{
|
||||
ReleaseHandler();
|
||||
mBits = 0;
|
||||
}
|
||||
|
||||
bool operator==(const nsEventHandler& aOther) const
|
||||
{
|
||||
return
|
||||
Ptr() && aOther.Ptr() &&
|
||||
Ptr()->CallbackPreserveColor() == aOther.Ptr()->CallbackPreserveColor();
|
||||
}
|
||||
private:
|
||||
void operator=(const nsEventHandler&) MOZ_DELETE;
|
||||
|
||||
void ReleaseHandler()
|
||||
{
|
||||
nsISupports* ptr = Ptr();
|
||||
NS_IF_RELEASE(ptr);
|
||||
}
|
||||
|
||||
void Assign(nsISupports* aHandler, HandlerType aType) {
|
||||
MOZ_ASSERT(aHandler, "Must have handler");
|
||||
NS_ADDREF(aHandler);
|
||||
mBits = uintptr_t(aHandler) | uintptr_t(aType);
|
||||
}
|
||||
|
||||
uintptr_t mBits;
|
||||
};
|
||||
|
||||
// Implemented by script event listeners. Used to retrieve the
|
||||
// script object corresponding to the event target and the handler itself.
|
||||
// (Note this interface is now used to store script objects for all
|
||||
// script languages, so is no longer JS specific)
|
||||
//
|
||||
// Note, mTarget is a raw pointer and the owner of the nsIJSEventListener object
|
||||
// is expected to call Disconnect()!
|
||||
class nsIJSEventListener : public nsIDOMEventListener
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IJSEVENTLISTENER_IID)
|
||||
|
||||
nsIJSEventListener(nsISupports *aTarget, nsIAtom* aType,
|
||||
const nsEventHandler& aHandler)
|
||||
: mEventName(aType), mHandler(aHandler)
|
||||
{
|
||||
nsCOMPtr<nsISupports> base = do_QueryInterface(aTarget);
|
||||
mTarget = base.get();
|
||||
}
|
||||
|
||||
nsISupports *GetEventTarget() const
|
||||
{
|
||||
return mTarget;
|
||||
}
|
||||
|
||||
void Disconnect()
|
||||
{
|
||||
mTarget = nullptr;
|
||||
}
|
||||
|
||||
const nsEventHandler& GetHandler() const
|
||||
{
|
||||
return mHandler;
|
||||
}
|
||||
|
||||
void ForgetHandler()
|
||||
{
|
||||
mHandler.ForgetHandler();
|
||||
}
|
||||
|
||||
nsIAtom* EventName() const
|
||||
{
|
||||
return mEventName;
|
||||
}
|
||||
|
||||
// Set a handler for this event listener. The handler must already
|
||||
// be bound to the right target.
|
||||
void SetHandler(const nsEventHandler& aHandler)
|
||||
{
|
||||
mHandler.SetHandler(aHandler);
|
||||
}
|
||||
void SetHandler(mozilla::dom::EventHandlerNonNull* aHandler)
|
||||
{
|
||||
mHandler.SetHandler(aHandler);
|
||||
}
|
||||
void SetHandler(mozilla::dom::OnBeforeUnloadEventHandlerNonNull* aHandler)
|
||||
{
|
||||
mHandler.SetHandler(aHandler);
|
||||
}
|
||||
void SetHandler(mozilla::dom::OnErrorEventHandlerNonNull* aHandler)
|
||||
{
|
||||
mHandler.SetHandler(aHandler);
|
||||
}
|
||||
|
||||
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return 0;
|
||||
|
||||
// Measurement of the following members may be added later if DMD finds it
|
||||
// is worthwhile:
|
||||
// - mTarget
|
||||
//
|
||||
// The following members are not measured:
|
||||
// - mHandler: may be shared with others
|
||||
// - mEventName: shared with others
|
||||
}
|
||||
|
||||
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~nsIJSEventListener()
|
||||
{
|
||||
NS_ASSERTION(!mTarget, "Should have called Disconnect()!");
|
||||
}
|
||||
|
||||
nsISupports* mTarget;
|
||||
nsCOMPtr<nsIAtom> mEventName;
|
||||
nsEventHandler mHandler;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIJSEventListener, NS_IJSEVENTLISTENER_IID)
|
||||
|
||||
/* factory function. aHandler must already be bound to aTarget.
|
||||
aContext is allowed to be null if aHandler is already set up.
|
||||
*/
|
||||
nsresult NS_NewJSEventListener(nsISupports* aTarget, nsIAtom* aType,
|
||||
const nsEventHandler& aHandler,
|
||||
nsIJSEventListener **aReturn);
|
||||
|
||||
#endif // nsIJSEventListener_h__
|
|
@ -17,7 +17,6 @@
|
|||
#include "nsNameSpaceManager.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIJSEventListener.h"
|
||||
#include "nsIController.h"
|
||||
#include "nsIControllers.h"
|
||||
#include "nsIDOMXULElement.h"
|
||||
|
@ -43,6 +42,7 @@
|
|||
#include "nsXBLSerialize.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "mozilla/BasicEvents.h"
|
||||
#include "mozilla/JSEventHandler.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/EventHandlerBinding.h"
|
||||
|
||||
|
@ -325,10 +325,10 @@ nsXBLPrototypeHandler::ExecuteHandler(EventTarget* aTarget,
|
|||
nsEventHandler eventHandler(handlerCallback);
|
||||
|
||||
// Execute it.
|
||||
nsCOMPtr<nsIJSEventListener> eventListener;
|
||||
rv = NS_NewJSEventListener(scriptTarget, onEventAtom,
|
||||
eventHandler,
|
||||
getter_AddRefs(eventListener));
|
||||
nsCOMPtr<nsJSEventListener> eventListener;
|
||||
rv = NS_NewJSEventHandler(scriptTarget, onEventAtom,
|
||||
eventHandler,
|
||||
getter_AddRefs(eventListener));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Handle the event.
|
||||
|
|
Загрузка…
Ссылка в новой задаче