diff --git a/bridge/bindings/qjs/dom/event_target_test.cc b/bridge/bindings/qjs/dom/event_target_test.cc index c57b0ec52a..9599d5a648 100644 --- a/bridge/bindings/qjs/dom/event_target_test.cc +++ b/bridge/bindings/qjs/dom/event_target_test.cc @@ -184,3 +184,15 @@ TEST(EventTarget, wontLeakWithStringProperty) { "img.any = '1234'"; bridge->evaluateScript(code.c_str(), code.size(), "internal://", 0); } + +TEST(EventTarget, globalBindListener) { + bool static logCalled = false; + kraken::KrakenPage::consoleMessageHandler = [](void* ctx, const std::string& message, int logLevel) { + logCalled = true; + EXPECT_STREQ(message.c_str(), "clicked"); + }; + auto bridge = TEST_init(); + std::string code = "addEventListener('click', () => {console.log('clicked'); }); dispatchEvent(new Event('click'))"; + bridge->evaluateScript(code.c_str(), code.size(), "internal://", 0); + EXPECT_EQ(logCalled, true); +} diff --git a/bridge/bindings/qjs/executing_context.h b/bridge/bindings/qjs/executing_context.h index 26c3d0cd15..f766883f7d 100644 --- a/bridge/bindings/qjs/executing_context.h +++ b/bridge/bindings/qjs/executing_context.h @@ -139,7 +139,14 @@ static JSValue handleCallThisOnProxy(JSContext* ctx, JSValueConst this_val, int if (JS_IsProxy(this_val)) { result = JS_Call(ctx, f, JS_GetProxyTarget(this_val), argc, argv); } else { - result = JS_Call(ctx, f, this_val, argc, argv); + // If this_val is undefined or null, this_val should set to globalThis. + if (JS_IsUndefined(this_val) || JS_IsNull(this_val)) { + this_val = JS_GetGlobalObject(ctx); + result = JS_Call(ctx, f, this_val, argc, argv); + JS_FreeValue(ctx, this_val); + } else { + result = JS_Call(ctx, f, this_val, argc, argv); + } } return result; }