Bug 699925 - support event.stopImmediatePropagation in workers, r=bent

This commit is contained in:
Olli Pettay 2011-11-05 23:41:16 +02:00
parent 06cb7a08f0
commit a6b0b55ae2
4 changed files with 44 additions and 1 deletions

View File

@ -75,6 +75,7 @@ class Event : public PrivatizableBase
protected:
bool mStopPropagationCalled;
bool mStopImmediatePropagationCalled;
public:
static bool
@ -168,9 +169,16 @@ public:
return JSVAL_TO_BOOLEAN(canceled);
}
static bool
ImmediatePropagationStopped(JSContext* aCx, JSObject* aEvent)
{
Event* event = GetPrivate(aCx, aEvent);
return event ? event->mStopImmediatePropagationCalled : false;
}
protected:
Event()
: mStopPropagationCalled(false)
: mStopPropagationCalled(false), mStopImmediatePropagationCalled(false)
{
MOZ_COUNT_CTOR(mozilla::dom::workers::Event);
}
@ -230,6 +238,7 @@ protected:
bool aIsTrusted)
{
aEvent->mStopPropagationCalled = false;
aEvent->mStopImmediatePropagationCalled = false;
jsval now;
if (!JS_NewNumberValue(aCx, JS_Now(), &now)) {
@ -319,6 +328,21 @@ private:
return true;
}
static JSBool
StopImmediatePropagation(JSContext* aCx, uintN aArgc, jsval* aVp)
{
JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
Event* event = GetInstancePrivate(aCx, obj, sFunctions[3].name);
if (!event) {
return false;
}
event->mStopImmediatePropagationCalled = true;
return true;
}
static JSBool
PreventDefault(JSContext* aCx, uintN aArgc, jsval* aVp)
{
@ -399,6 +423,7 @@ JSFunctionSpec Event::sFunctions[] = {
JS_FN("stopPropagation", StopPropagation, 0, FUNCTION_FLAGS),
JS_FN("preventDefault", PreventDefault, 0, FUNCTION_FLAGS),
JS_FN("initEvent", InitEvent, 3, FUNCTION_FLAGS),
JS_FN("stopImmediatePropagation", StopImmediatePropagation, 0, FUNCTION_FLAGS),
JS_FS_END
};
@ -1115,6 +1140,12 @@ EventWasCanceled(JSContext* aCx, JSObject* aEvent)
return Event::WasCanceled(aCx, aEvent);
}
bool
EventImmediatePropagationStopped(JSContext* aCx, JSObject* aEvent)
{
return Event::ImmediatePropagationStopped(aCx, aEvent);
}
bool
DispatchEventToTarget(JSContext* aCx, JSObject* aTarget, JSObject* aEvent,
bool* aPreventDefaultCalled)

View File

@ -80,6 +80,9 @@ SetEventTarget(JSContext* aCx, JSObject* aEvent, JSObject* aTarget);
bool
EventWasCanceled(JSContext* aCx, JSObject* aEvent);
bool
EventImmediatePropagationStopped(JSContext* aCx, JSObject* aEvent);
bool
DispatchEventToTarget(JSContext* aCx, JSObject* aTarget, JSObject* aEvent,
bool* aPreventDefaultCalled);

View File

@ -392,6 +392,10 @@ ListenerManager::DispatchEvent(JSContext* aCx, JSObject* aTarget,
}
for (size_t index = 0; index < listeners.length(); index++) {
if (events::EventImmediatePropagationStopped(aCx, aEvent)) {
break;
}
// If anything fails in here we want to report the exception and continue on
// to the next listener rather than bailing out. If something fails and
// does not set an exception then we bail out entirely as we've either run

View File

@ -22,9 +22,14 @@ addEventListener(fakeEventType, function(event) {
if (event.isTrusted) {
throw new Error("Event should be untrusted!");
}
event.stopImmediatePropagation();
postMessage(event.data);
}, false, true);
addEventListener(fakeEventType, function(event) {
throw new Error("This shouldn't get called because of stopImmediatePropagation.");
}, false, true);
var count = 0;
onmessage = function(event) {
if (event.target !== self || event.currentTarget !== self) {