diff options
-rw-r--r-- | cli/tests/078_unload_on_exit.ts | 5 | ||||
-rw-r--r-- | cli/tests/integration_tests.rs | 1 | ||||
-rw-r--r-- | runtime/js/30_os.js | 9 | ||||
-rw-r--r-- | runtime/js/99_main.js | 9 |
4 files changed, 21 insertions, 3 deletions
diff --git a/cli/tests/078_unload_on_exit.ts b/cli/tests/078_unload_on_exit.ts index e8288ef31..43d33eb25 100644 --- a/cli/tests/078_unload_on_exit.ts +++ b/cli/tests/078_unload_on_exit.ts @@ -1,4 +1,9 @@ window.onunload = () => { console.log("onunload is called"); + // This second exit call doesn't trigger unload event, + // and therefore actually stops the process. + Deno.exit(1); + console.log("This doesn't show up in console"); }; +// This exit call triggers the above unload event handler. Deno.exit(0); diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index be7bb63c5..428d1ff30 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -2665,6 +2665,7 @@ itest!(_077_fetch_empty { itest!(_078_unload_on_exit { args: "run 078_unload_on_exit.ts", output: "078_unload_on_exit.ts.out", + exit_code: 1, }); itest!(_079_location_authentication { diff --git a/runtime/js/30_os.js b/runtime/js/30_os.js index 1d700b561..5a3c990b0 100644 --- a/runtime/js/30_os.js +++ b/runtime/js/30_os.js @@ -24,9 +24,12 @@ } function exit(code = 0) { - // Invokes the `unload` hooks before exiting - // ref: https://github.com/denoland/deno/issues/3603 - window.dispatchEvent(new Event("unload")); + // Dispatches `unload` only when it's not dispatched yet. + if (!window[Symbol.for("isUnloadDispatched")]) { + // Invokes the `unload` hooks before exiting + // ref: https://github.com/denoland/deno/issues/3603 + window.dispatchEvent(new Event("unload")); + } core.jsonOpSync("op_exit", { code }); throw new Error("Code not reachable"); } diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index a6abc8d27..fd846af20 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -305,6 +305,15 @@ delete Object.prototype.__proto__; defineEventHandler(window, "load", null); defineEventHandler(window, "unload", null); + const isUnloadDispatched = Symbol.for("isUnloadDispatched"); + // Stores the flag for checking whether unload is dispatched or not. + // This prevents the recursive dispatches of unload events. + // See https://github.com/denoland/deno/issues/9201. + window[isUnloadDispatched] = false; + window.addEventListener("unload", () => { + window[isUnloadDispatched] = true; + }); + runtimeStart(runtimeOptions); const { args, |