gecko-dev/dom/workers/EventListenerManager.h

137 строки
3.0 KiB
C++

/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* 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 mozilla_dom_workers_listenermanager_h__
#define mozilla_dom_workers_listenermanager_h__
#include "mozilla/dom/workers/Workers.h"
#include "mozilla/LinkedList.h"
#include "mozilla/ErrorResult.h"
BEGIN_WORKERS_NAMESPACE
class EventTarget;
// XXX Current impl doesn't divide into phases.
// XXX Current impl doesn't handle event target chains.
class EventListenerManager
{
public:
struct ListenerCollection;
private:
LinkedList<ListenerCollection> mCollections;
public:
EventListenerManager()
{
}
#ifdef DEBUG
~EventListenerManager();
#endif
void
_trace(JSTracer* aTrc) const
{
if (!mCollections.isEmpty()) {
TraceInternal(aTrc);
}
}
void
_finalize(JSFreeOp* aFop)
{
if (!mCollections.isEmpty()) {
FinalizeInternal(aFop);
}
}
enum Phase
{
All = 0,
Capturing,
Onfoo,
Bubbling
};
void
AddEventListener(JSContext* aCx, const jsid& aType,
JS::Handle<JSObject*> aListener,
bool aCapturing, bool aWantsUntrusted, ErrorResult& aRv)
{
Add(aCx, aType, aListener, aCapturing ? Capturing : Bubbling,
aWantsUntrusted, aRv);
}
void
RemoveEventListener(JSContext* aCx, const jsid& aType,
JS::Handle<JSObject*> aListener, bool aCapturing)
{
if (mCollections.isEmpty()) {
return;
}
Remove(aCx, aType, aListener, aCapturing ? Capturing : Bubbling, true);
}
bool
DispatchEvent(JSContext* aCx, const EventTarget& aTarget, JSObject* aEvent,
ErrorResult& aRv) const;
JSObject*
GetEventListener(const jsid& aType) const;
void
SetEventListener(JSContext* aCx, const jsid& aType,
JS::Handle<JSObject*> aListener,
ErrorResult& aRv)
{
JS::Rooted<JSObject*> existing(aCx, GetEventListener(aType));
if (existing) {
Remove(aCx, aType, existing, Onfoo, false);
}
if (aListener) {
Add(aCx, aType, aListener, Onfoo, false, aRv);
}
}
bool
HasListeners() const
{
return !mCollections.isEmpty();
}
bool
HasListenersForType(JSContext* aCx, const jsid& aType) const
{
return HasListeners() && HasListenersForTypeInternal(aCx, aType);
}
private:
void
TraceInternal(JSTracer* aTrc) const;
void
FinalizeInternal(JSFreeOp* aFop);
void
Add(JSContext* aCx, const jsid& aType, JS::Handle<JSObject*> aListener,
Phase aPhase, bool aWantsUntrusted, ErrorResult& aRv);
void
Remove(JSContext* aCx, const jsid& aType, JS::Handle<JSObject*> aListener,
Phase aPhase, bool aClearEmpty);
bool
HasListenersForTypeInternal(JSContext* aCx, const jsid& aType) const;
};
END_WORKERS_NAMESPACE
#endif /* mozilla_dom_workers_listenermanager_h__ */