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 | |
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".
-rw-r--r-- | cli/rt/99_main.js | 53 | ||||
-rw-r--r-- | cli/tests/034_onload.out | 4 | ||||
-rw-r--r-- | docs/runtime/program_lifecycle.md | 4 |
3 files changed, 44 insertions, 17 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(); diff --git a/cli/tests/034_onload.out b/cli/tests/034_onload.out index c9556e991..9b1f454c9 100644 --- a/cli/tests/034_onload.out +++ b/cli/tests/034_onload.out @@ -1,11 +1,11 @@ log from nest_imported script log from imported script log from main -got load event in onload function got load event in event handler (nest_imported) got load event in event handler (imported) got load event in event handler (main) -got unload event in onunload function +got load event in onload function got unload event in event handler (nest_imported) got unload event in event handler (imported) got unload event in event handler (main) +got unload event in onunload function diff --git a/docs/runtime/program_lifecycle.md b/docs/runtime/program_lifecycle.md index 7f6035048..f0ebbd448 100644 --- a/docs/runtime/program_lifecycle.md +++ b/docs/runtime/program_lifecycle.md @@ -61,12 +61,12 @@ major difference between them, let's run the example: $ deno run main.ts log from imported script log from main script -got load event in onload function (main) got load event in event handler (imported) got load event in event handler (main) -got unload event in onunload function (main) +got load event in onload function (main) got unload event in event handler (imported) got unload event in event handler (main) +got unload event in onunload function (main) ``` All listeners added using `window.addEventListener` were run, but |