mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
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".
This commit is contained in:
parent
e84704968e
commit
4f46dc999b
3 changed files with 44 additions and 17 deletions
|
@ -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);
|
||||
|
||||
const handlerSymbol = Symbol("eventHandlers");
|
||||
|
||||
function makeWrappedHandler(handler) {
|
||||
function wrappedHandler(...args) {
|
||||
if (typeof wrappedHandler.handler !== "function") {
|
||||
return;
|
||||
}
|
||||
return wrappedHandler.handler.call(this, ...args);
|
||||
}
|
||||
});
|
||||
// Registers the handler for window.onunload function.
|
||||
globalThis.addEventListener("unload", (e) => {
|
||||
const { onunload } = globalThis;
|
||||
if (typeof onunload === "function") {
|
||||
onunload(e);
|
||||
}
|
||||
});
|
||||
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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue