diff options
author | Benjamin Gruenbaum <benjamingr@gmail.com> | 2020-11-26 23:27:55 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-26 22:27:55 +0100 |
commit | 4f46dc999b9fd3f26b6586d06d099d7039ca35c8 (patch) | |
tree | 360a41d113fed4cfe90158205ee9b96d992daf8e /cli/rt/99_main.js | |
parent | e84704968e92638fae02c6ec2d629158dab3f25f (diff) |
fix: "onload" event order (#8376)
This commit fixes order of events for "onload" event.
Previously handler attached using "window.onload" was
always fired before handlers added using "addEventListener".
Diffstat (limited to 'cli/rt/99_main.js')
-rw-r--r-- | cli/rt/99_main.js | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/cli/rt/99_main.js b/cli/rt/99_main.js index 68572f79a..69c27c579 100644 --- a/cli/rt/99_main.js +++ b/cli/rt/99_main.js @@ -283,20 +283,47 @@ delete Object.prototype.__proto__; Object.defineProperties(globalThis, mainRuntimeGlobalProperties); Object.setPrototypeOf(globalThis, Window.prototype); eventTarget.setEventTargetData(globalThis); - // Registers the handler for window.onload function. - globalThis.addEventListener("load", (e) => { - const { onload } = globalThis; - if (typeof onload === "function") { - onload(e); - } - }); - // Registers the handler for window.onunload function. - globalThis.addEventListener("unload", (e) => { - const { onunload } = globalThis; - if (typeof onunload === "function") { - onunload(e); + + 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"); const { args, noColor, pid, ppid, unstableFlag } = runtimeStart(); |