Skip to content

Commit

Permalink
Implement the Web Platform standard CustomEvent (#1270)
Browse files Browse the repository at this point in the history
  • Loading branch information
jasnell authored Oct 3, 2023
1 parent 455227f commit e51f3be
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 2 deletions.
23 changes: 23 additions & 0 deletions src/workerd/api/basics.c++
Original file line number Diff line number Diff line change
Expand Up @@ -585,4 +585,27 @@ jsg::Optional<jsg::Ref<ActorState>> ExtendableEvent::getActorState() {
});
}

CustomEvent::CustomEvent(kj::String ownType, CustomEventInit init)
: Event(kj::mv(ownType), (Event::Init)init),
detail(kj::mv(init.detail)) {}

jsg::Ref<CustomEvent> CustomEvent::constructor(jsg::Lock& js, kj::String type,
jsg::Optional<CustomEventInit> init) {
return jsg::alloc<CustomEvent>(kj::mv(type), kj::mv(init).orDefault({}));
}

jsg::Optional<jsg::JsValue> CustomEvent::getDetail(jsg::Lock& js) {
return detail.map([&](jsg::JsRef<jsg::JsValue>& val) {
return val.getHandle(js);
});
}

CustomEvent::CustomEventInit::operator Event::Init() {
return {
.bubbles = this->bubbles.map([](auto& val) { return val; }),
.cancelable = this->cancelable.map([](auto& val) { return val; }),
.composed = this->composed.map([](auto& val) { return val; }),
};
}

} // namespace workerd::api
33 changes: 32 additions & 1 deletion src/workerd/api/basics.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,35 @@ class ExtendableEvent: public Event {
}
};

// An implementation of the Web Platform Standard CustomEvent API
class CustomEvent: public Event {
public:
struct CustomEventInit final {
jsg::Optional<bool> bubbles;
jsg::Optional<bool> cancelable;
jsg::Optional<bool> composed;
jsg::Optional<jsg::JsRef<jsg::JsValue>> detail;
JSG_STRUCT(bubbles, cancelable, composed, detail);

operator Event::Init();
};

explicit CustomEvent(kj::String ownType, CustomEventInit init = CustomEventInit());

static jsg::Ref<CustomEvent> constructor(jsg::Lock& js, kj::String type,
jsg::Optional<CustomEventInit> init);

jsg::Optional<jsg::JsValue> getDetail(jsg::Lock& js);

JSG_RESOURCE_TYPE(CustomEvent) {
JSG_INHERIT(Event);
JSG_READONLY_PROTOTYPE_PROPERTY(detail, getDetail);
}

private:
jsg::Optional<jsg::JsRef<jsg::JsValue>> detail;
};

// An implementation of the Web Platform Standard EventTarget API
class EventTarget: public jsg::Object {
public:
Expand Down Expand Up @@ -632,7 +661,9 @@ class Scheduler final: public jsg::Object {
api::AbortSignal, \
api::Scheduler, \
api::Scheduler::WaitOptions, \
api::ExtendableEvent
api::ExtendableEvent, \
api::CustomEvent, \
api::CustomEvent::CustomEventInit
// The list of basics.h types that are added to worker.c++'s JSG_DECLARE_ISOLATE_TYPE

} // namespace workerd::api
1 change: 1 addition & 0 deletions src/workerd/api/global-scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ class ServiceWorkerGlobalScope: public WorkerGlobalScope {

JSG_NESTED_TYPE(Event);
JSG_NESTED_TYPE(ExtendableEvent);
JSG_NESTED_TYPE(CustomEvent);
JSG_NESTED_TYPE(PromiseRejectionEvent);
JSG_NESTED_TYPE(FetchEvent);
JSG_NESTED_TYPE(TailEvent);
Expand Down
12 changes: 11 additions & 1 deletion src/workerd/api/tests/events-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {
deepStrictEqual,
strictEqual,
throws
throws,
ok,
} from 'node:assert';

// Test for the Event and EventTarget standard Web API implementations.
Expand Down Expand Up @@ -369,3 +370,12 @@ export const nullUndefinedHandler = {
// target.addEventListener('foo', undefined);
}
};

export const customEvent = {
test() {
const event = new CustomEvent('foo', { detail: { a: 123 } });
ok(event instanceof Event);
strictEqual(event.type, 'foo');
deepStrictEqual(event.detail, { a: 123 });
}
};

0 comments on commit e51f3be

Please sign in to comment.