summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/lib.rs7
-rw-r--r--cli/tests/034_onload.out4
-rw-r--r--cli/tests/034_onload/imported.ts15
-rw-r--r--cli/tests/034_onload/main.ts21
-rw-r--r--cli/tests/034_onload/nest_imported.ts15
-rw-r--r--cli/tests/034_onload_imported.ts1
-rw-r--r--js/globals.ts11
-rw-r--r--js/lib.deno_runtime.d.ts2
-rw-r--r--website/manual.md70
9 files changed, 126 insertions, 20 deletions
diff --git a/cli/lib.rs b/cli/lib.rs
index 1e598e262..09134dcdb 100644
--- a/cli/lib.rs
+++ b/cli/lib.rs
@@ -371,12 +371,17 @@ fn run_script(flags: DenoFlags, argv: Vec<String>) {
js_check(worker.execute("denoMain()"));
debug!("main_module {}", main_module);
+ let mut worker_ = worker.clone();
+
worker
.execute_mod_async(&main_module, false)
.and_then(move |()| {
js_check(worker.execute("window.dispatchEvent(new Event('load'))"));
- worker.then(|result| {
+ worker.then(move |result| {
js_check(result);
+ js_check(
+ worker_.execute("window.dispatchEvent(new Event('unload'))"),
+ );
Ok(())
})
})
diff --git a/cli/tests/034_onload.out b/cli/tests/034_onload.out
index 0939be8cd..c9556e991 100644
--- a/cli/tests/034_onload.out
+++ b/cli/tests/034_onload.out
@@ -5,3 +5,7 @@ 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 unload event in event handler (nest_imported)
+got unload event in event handler (imported)
+got unload event in event handler (main)
diff --git a/cli/tests/034_onload/imported.ts b/cli/tests/034_onload/imported.ts
index 5cf2d7b4c..d71f9d654 100644
--- a/cli/tests/034_onload/imported.ts
+++ b/cli/tests/034_onload/imported.ts
@@ -1,8 +1,11 @@
+import { assert } from "../../../js/deps/https/deno.land/std/testing/asserts.ts";
import "./nest_imported.ts";
-window.addEventListener(
- "load",
- (e: Event): void => {
- console.log(`got ${e.type} event in event handler (imported)`);
- }
-);
+
+const handler = (e: Event): void => {
+ assert(!e.cancelable);
+ console.log(`got ${e.type} event in event handler (imported)`);
+};
+
+window.addEventListener("load", handler);
+window.addEventListener("unload", handler);
console.log("log from imported script");
diff --git a/cli/tests/034_onload/main.ts b/cli/tests/034_onload/main.ts
index 68851950a..c3c6bdcc9 100644
--- a/cli/tests/034_onload/main.ts
+++ b/cli/tests/034_onload/main.ts
@@ -1,14 +1,23 @@
+import { assert } from "../../../js/deps/https/deno.land/std/testing/asserts.ts";
import "./imported.ts";
-window.addEventListener(
- "load",
- (e: Event): void => {
- console.log(`got ${e.type} event in event handler (main)`);
- }
-);
+const eventHandler = (e: Event): void => {
+ assert(!e.cancelable);
+ console.log(`got ${e.type} event in event handler (main)`);
+};
+
+window.addEventListener("load", eventHandler);
+
+window.addEventListener("unload", eventHandler);
window.onload = (e: Event): void => {
+ assert(!e.cancelable);
console.log(`got ${e.type} event in onload function`);
};
+window.onunload = (e: Event): void => {
+ assert(!e.cancelable);
+ console.log(`got ${e.type} event in onunload function`);
+};
+
console.log("log from main");
diff --git a/cli/tests/034_onload/nest_imported.ts b/cli/tests/034_onload/nest_imported.ts
index 2e2bee1d5..3c4b1d96a 100644
--- a/cli/tests/034_onload/nest_imported.ts
+++ b/cli/tests/034_onload/nest_imported.ts
@@ -1,7 +1,10 @@
-window.addEventListener(
- "load",
- (e: Event): void => {
- console.log(`got ${e.type} event in event handler (nest_imported)`);
- }
-);
+import { assert } from "../../../js/deps/https/deno.land/std/testing/asserts.ts";
+
+const handler = (e: Event): void => {
+ assert(!e.cancelable);
+ console.log(`got ${e.type} event in event handler (nest_imported)`);
+};
+
+window.addEventListener("load", handler);
+window.addEventListener("unload", handler);
console.log("log from nest_imported script");
diff --git a/cli/tests/034_onload_imported.ts b/cli/tests/034_onload_imported.ts
deleted file mode 100644
index d97aabeca..000000000
--- a/cli/tests/034_onload_imported.ts
+++ /dev/null
@@ -1 +0,0 @@
-console.log("from imported script");
diff --git a/js/globals.ts b/js/globals.ts
index 50f119971..b734b8da3 100644
--- a/js/globals.ts
+++ b/js/globals.ts
@@ -84,6 +84,7 @@ window.setTimeout = timers.setTimeout;
window.setInterval = timers.setInterval;
window.location = (undefined as unknown) as domTypes.Location;
window.onload = undefined as undefined | Function;
+window.onunload = undefined as undefined | Function;
// The following Crypto interface implementation is not up to par with the
// standard https://www.w3.org/TR/WebCryptoAPI/#crypto-interface as it does not
// yet incorporate the SubtleCrypto interface as its "subtle" property.
@@ -171,6 +172,16 @@ window.addEventListener(
}
}
);
+// Registers the handler for window.onunload function.
+window.addEventListener(
+ "unload",
+ (e: domTypes.Event): void => {
+ const onunload = window.onunload;
+ if (typeof onunload === "function") {
+ onunload(e);
+ }
+ }
+);
// below are interfaces that are available in TypeScript but
// have different signatures
diff --git a/js/lib.deno_runtime.d.ts b/js/lib.deno_runtime.d.ts
index 1e220a29d..d0a720769 100644
--- a/js/lib.deno_runtime.d.ts
+++ b/js/lib.deno_runtime.d.ts
@@ -1248,6 +1248,7 @@ declare interface Window {
setInterval: typeof timers.setInterval;
location: domTypes.Location;
onload: Function | undefined;
+ onunload: Function | undefined;
crypto: Crypto;
Blob: typeof blob.DenoBlob;
File: domTypes.DomFileConstructor;
@@ -1294,6 +1295,7 @@ declare const setTimeout: typeof timers.setTimeout;
declare const setInterval: typeof timers.setInterval;
declare const location: domTypes.Location;
declare const onload: Function | undefined;
+declare const onunload: Function | undefined;
declare const crypto: Crypto;
declare const Blob: typeof blob.DenoBlob;
declare const File: domTypes.DomFileConstructor;
diff --git a/website/manual.md b/website/manual.md
index 7a659460c..dabb08e41 100644
--- a/website/manual.md
+++ b/website/manual.md
@@ -928,6 +928,76 @@ window.onload = async function() {
$ deno run --importmap=import_map.json hello_server.ts
```
+## Program lifecycle
+
+Deno supports browser compatible lifecycle events: `load` and `unload`. You can
+use these event to provide setup and cleanup code in your program.
+
+`load` event listener supports asynchronous functions and will await these
+functions. `unload` event listener supports only synchronous code. Both events
+are not cancellable.
+
+Example:
+
+```typescript
+// main.ts
+import "./imported.ts";
+
+const handler = (e: Event): void => {
+ console.log(`got ${e.type} event in event handler (main)`);
+};
+
+window.addEventListener("load", handler);
+
+window.addEventListener("unload", handler);
+
+window.onload = (e: Event): void => {
+ console.log(`got ${e.type} event in onload function (main)`);
+};
+
+window.onunload = (e: Event): void => {
+ console.log(`got ${e.type} event in onunload function (main)`);
+};
+
+// imported.ts
+const handler = (e: Event): void => {
+ console.log(`got ${e.type} event in event handler (imported)`);
+};
+
+window.addEventListener("load", handler);
+window.addEventListener("unload", handler);
+
+window.onload = (e: Event): void => {
+ console.log(`got ${e.type} event in onload function (imported)`);
+};
+
+window.onunload = (e: Event): void => {
+ console.log(`got ${e.type} event in onunload function (imported)`);
+};
+
+console.log("log from imported script");
+```
+
+Note that you can use both `window.addEventListener` and
+`window.onload`/`window.onunload` to define handlers for events. There is a
+major difference between them, let's run example:
+
+```shell
+$ deno 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 unload event in event handler (imported)
+got unload event in event handler (main)
+```
+
+All listeners added using `window.addEventListener` were run, but
+`window.onload` and `window.onunload` defined in `main.ts` overridden handlers
+defined in `imported.ts`.
+
## Internal details
### Deno and Linux analogy