diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/rt/01_web_util.js | 35 | ||||
-rw-r--r-- | cli/rt/27_websocket.js | 23 | ||||
-rw-r--r-- | cli/tests/websocket_test.ts | 20 |
3 files changed, 60 insertions, 18 deletions
diff --git a/cli/rt/01_web_util.js b/cli/rt/01_web_util.js index 4a3df65ce..c843ac086 100644 --- a/cli/rt/01_web_util.js +++ b/cli/rt/01_web_util.js @@ -113,9 +113,44 @@ } } + const handlerSymbol = Symbol("eventHandlers"); + function makeWrappedHandler(handler) { + function wrappedHandler(...args) { + if (typeof wrappedHandler.handler !== "function") { + return; + } + return wrappedHandler.handler.call(this, ...args); + } + wrappedHandler.handler = handler; + return wrappedHandler; + } + function defineEventHandler(emitter, name) { + // HTML specification section 8.1.5.1 + Object.defineProperty(emitter, `on${name}`, { + get() { + return this[handlerSymbol]?.get(name)?.handler; + }, + set(value) { + if (!this[handlerSymbol]) { + this[handlerSymbol] = new Map(); + } + let handlerWrapper = this[handlerSymbol]?.get(name); + if (handlerWrapper) { + handlerWrapper.handler = value; + } else { + handlerWrapper = makeWrappedHandler(value); + this.addEventListener(name, handlerWrapper); + } + this[handlerSymbol].set(name, handlerWrapper); + }, + configurable: true, + enumerable: true, + }); + } window.__bootstrap.webUtil = { illegalConstructorKey, requiredArguments, + defineEventHandler, cloneValue, }; })(this); diff --git a/cli/rt/27_websocket.js b/cli/rt/27_websocket.js index c0790d14d..675c1e836 100644 --- a/cli/rt/27_websocket.js +++ b/cli/rt/27_websocket.js @@ -2,7 +2,7 @@ ((window) => { const core = window.Deno.core; - const { requiredArguments } = window.__bootstrap.webUtil; + const { requiredArguments, defineEventHandler } = window.__bootstrap.webUtil; const CONNECTING = 0; const OPEN = 1; const CLOSING = 2; @@ -63,12 +63,10 @@ const errEvent = new ErrorEvent("error"); errEvent.target = this; - this.onerror?.(errEvent); this.dispatchEvent(errEvent); const event = new CloseEvent("close"); event.target = this; - this.onclose?.(event); this.dispatchEvent(event); core.close(this.#rid); }); @@ -76,7 +74,6 @@ this.#readyState = OPEN; const event = new Event("open"); event.target = this; - this.onopen?.(event); this.dispatchEvent(event); this.#eventLoop(); @@ -86,12 +83,10 @@ const errEvent = new ErrorEvent("error"); errEvent.target = this; - this.onerror?.(errEvent); this.dispatchEvent(errEvent); const closeEvent = new CloseEvent("close"); closeEvent.target = this; - this.onclose?.(closeEvent); this.dispatchEvent(closeEvent); } }).catch((err) => { @@ -102,12 +97,10 @@ { error: err, message: err.toString() }, ); errorEv.target = this; - this.onerror?.(errorEv); this.dispatchEvent(errorEv); const closeEv = new CloseEvent("close"); closeEv.target = this; - this.onclose?.(closeEv); this.dispatchEvent(closeEv); }); } @@ -159,11 +152,6 @@ return this.#url; } - onopen = () => {}; - onerror = () => {}; - onclose = () => {}; - onmessage = () => {}; - send(data) { requiredArguments("WebSocket.send", arguments.length, 1); @@ -241,7 +229,6 @@ reason, }); event.target = this; - this.onclose?.(event); this.dispatchEvent(event); core.close(this.#rid); }); @@ -272,7 +259,6 @@ origin: this.#url, }); event.target = this; - this.onmessage?.(event); this.dispatchEvent(event); this.#eventLoop(); @@ -284,20 +270,17 @@ reason: message.reason, }); event.target = this; - this.onclose?.(event); this.dispatchEvent(event); } else if (message.type === "error") { this.#readyState = CLOSED; const errorEv = new ErrorEvent("error"); errorEv.target = this; - this.onerror?.(errorEv); this.dispatchEvent(errorEv); this.#readyState = CLOSED; const closeEv = new CloseEvent("close"); closeEv.target = this; - this.onclose?.(closeEv); this.dispatchEvent(closeEv); } } @@ -319,6 +302,10 @@ }, }); + defineEventHandler(WebSocket.prototype, "message"); + defineEventHandler(WebSocket.prototype, "error"); + defineEventHandler(WebSocket.prototype, "close"); + defineEventHandler(WebSocket.prototype, "open"); window.__bootstrap.webSocket = { WebSocket, }; diff --git a/cli/tests/websocket_test.ts b/cli/tests/websocket_test.ts index 93fddf446..0a91ac308 100644 --- a/cli/tests/websocket_test.ts +++ b/cli/tests/websocket_test.ts @@ -273,3 +273,23 @@ Deno.test("echo arraybuffer with binaryType arraybuffer", async () => { }; await promise; }); + +Deno.test("Event Handlers order", async () => { + const promise = createResolvable(); + const ws = new WebSocket("ws://localhost:4242"); + const arr: number[] = []; + ws.onerror = (): void => fail(); + ws.addEventListener("message", () => arr.push(1)); + ws.onmessage = () => fail(); + ws.addEventListener("message", () => { + arr.push(3); + ws.close(); + assertEquals(arr, [1, 2, 3]); + }); + ws.onmessage = () => arr.push(2); + ws.onopen = (): void => ws.send("Echo"); + ws.onclose = (): void => { + promise.resolve(); + }; + await promise; +}); |