summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/rt/99_main.js53
-rw-r--r--cli/tests/034_onload.out4
-rw-r--r--docs/runtime/program_lifecycle.md4
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