aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/webcore/JSEventEmitterCustom.cpp
blob: 64ae6e1c87613df4d05a26bb37fcd6b9586968df (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include "config.h"
#include "JSEventEmitter.h"

#include "EventEmitter.h"
#include "JSDOMWrapperCache.h"
#include "JSEventListener.h"

namespace WebCore {
using namespace JSC;

JSValue toJSNewlyCreated(JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<EventEmitter>&& value)
{
    return createWrapper<EventEmitter>(globalObject, WTFMove(value));
}

EventEmitter* JSEventEmitter::toWrapped(VM& vm, JSValue value)
{
    if (value.inherits<JSEventEmitter>())
        return &jsCast<JSEventEmitter*>(asObject(value))->wrapped();
    return nullptr;
}

std::unique_ptr<JSEventEmitterWrapper> jsEventEmitterCast(VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSValue thisValue)
{
    if (auto* target = jsDynamicCast<JSEventEmitter*>(thisValue))
        return makeUnique<JSEventEmitterWrapper>(target->wrapped(), *target);
    if (auto* object = jsDynamicCast<JSNonFinalObject*>(thisValue)) {
        // need to create a EventEmitter for Object.
        // use `mapPrivateName` as it is not occupied.
        auto emitterTag = WebCore::clientData(vm)->builtinNames().mapPrivateName();
        JSC::JSValue value = object->getDirect(vm, emitterTag);
        if (!value) {
            Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
            value = WebCore::toJSNewlyCreated(lexicalGlobalObject, globalObject, EventEmitter::create(*globalObject->scriptExecutionContext()));
            object->putDirect(vm, emitterTag, value);
        }
        auto* target = jsCast<JSEventEmitter*>(value);
        return makeUnique<JSEventEmitterWrapper>(target->wrapped(), *target);
    }

    return nullptr;
}

template<typename Visitor>
void JSEventEmitter::visitAdditionalChildren(Visitor& visitor)
{
    wrapped().eventListenerMap().visitJSEventListeners(visitor);
}

DEFINE_VISIT_ADDITIONAL_CHILDREN(JSEventEmitter);

} // namespace WebCore