From b566d184fedcd0fae3de19a54adfa5ce09466cc1 Mon Sep 17 00:00:00 2001 From: Benjamin Gruenbaum Date: Mon, 7 Dec 2020 22:22:58 +0200 Subject: [PATCH] refactor(cli/rt): deduplicate code (#8649) --- cli/rt/01_web_util.js | 4 +-- cli/rt/99_main.js | 43 +++---------------------------- cli/tests/034_onload/main.ts | 3 +++ docs/runtime/program_lifecycle.md | 3 ++- 4 files changed, 10 insertions(+), 43 deletions(-) diff --git a/cli/rt/01_web_util.js b/cli/rt/01_web_util.js index 3076993ff3..a9573a71db 100644 --- a/cli/rt/01_web_util.js +++ b/cli/rt/01_web_util.js @@ -128,11 +128,11 @@ wrappedHandler.handler = handler; return wrappedHandler; } - function defineEventHandler(emitter, name) { + function defineEventHandler(emitter, name, defaultValue = undefined) { // HTML specification section 8.1.5.1 Object.defineProperty(emitter, `on${name}`, { get() { - return this[handlerSymbol]?.get(name)?.handler; + return this[handlerSymbol]?.get(name)?.handler ?? defaultValue; }, set(value) { if (!this[handlerSymbol]) { diff --git a/cli/rt/99_main.js b/cli/rt/99_main.js index f582994c7f..40c9c636f5 100644 --- a/cli/rt/99_main.js +++ b/cli/rt/99_main.js @@ -31,6 +31,7 @@ delete Object.prototype.__proto__; const denoNs = window.__bootstrap.denoNs; const denoNsUnstable = window.__bootstrap.denoNsUnstable; const errors = window.__bootstrap.errors.errors; + const { defineEventHandler } = window.__bootstrap.webUtil; let windowIsClosing = false; @@ -289,46 +290,8 @@ delete Object.prototype.__proto__; Object.setPrototypeOf(globalThis, Window.prototype); eventTarget.setEventTargetData(globalThis); - 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; - } - // TODO(benjamingr) reuse when we can reuse code between web crates - // This function is very similar to `defineEventHandler` in `01_web_util.js` - // but it returns `null` instead of `undefined` is handler is not defined. - function defineEventHandler(emitter, name) { - // HTML specification section 8.1.5.1 - Object.defineProperty(emitter, `on${name}`, { - get() { - return this[handlerSymbol]?.get(name)?.handler ?? null; - }, - 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, - }); - } - defineEventHandler(window, "load"); - defineEventHandler(window, "unload"); + defineEventHandler(window, "load", null); + defineEventHandler(window, "unload", null); const { args, noColor, pid, ppid, unstableFlag } = runtimeStart(); diff --git a/cli/tests/034_onload/main.ts b/cli/tests/034_onload/main.ts index db6ca669a3..aca38869e1 100644 --- a/cli/tests/034_onload/main.ts +++ b/cli/tests/034_onload/main.ts @@ -1,6 +1,9 @@ import { assert } from "../../../std/testing/asserts.ts"; import "./imported.ts"; +assert(window.hasOwnProperty("onload")); +assert(window.onload === null); + const eventHandler = (e: Event): void => { assert(!e.cancelable); console.log(`got ${e.type} event in event handler (main)`); diff --git a/docs/runtime/program_lifecycle.md b/docs/runtime/program_lifecycle.md index f0ebbd4487..72e21c4f4b 100644 --- a/docs/runtime/program_lifecycle.md +++ b/docs/runtime/program_lifecycle.md @@ -75,4 +75,5 @@ defined in `imported.ts`. In other words, you can register multiple `window.addEventListener` `"load"` or `"unload"` events, but only the last loaded `window.onload` or `window.onunload` -events will be executed. +event handlers will be executed. It is preferable to use `addEventListener` when +possible for this reason.