From 5f3028af13c25fb3af8f36d3d5913ef0688e5ce7 Mon Sep 17 00:00:00 2001 From: Nayeem Rahman Date: Sun, 11 Oct 2020 23:04:43 +0100 Subject: [PATCH] fix(cli/rt/main): Add global interface objects (#7875) --- cli/dts/lib.deno.window.d.ts | 3 +- cli/dts/lib.deno.worker.d.ts | 25 +++++++++------- cli/rt/99_main.js | 47 ++++++++++++++++++++++++++---- cli/tests/subdir/worker_globals.ts | 10 +++++++ cli/tests/unit/globals_test.ts | 8 +++++ cli/tests/workers_test.ts | 18 ++++++++++++ 6 files changed, 95 insertions(+), 16 deletions(-) create mode 100644 cli/tests/subdir/worker_globals.ts diff --git a/cli/dts/lib.deno.window.d.ts b/cli/dts/lib.deno.window.d.ts index 5c113cd0d5..03341636f3 100644 --- a/cli/dts/lib.deno.window.d.ts +++ b/cli/dts/lib.deno.window.d.ts @@ -7,7 +7,8 @@ /// /// -declare interface Window extends EventTarget { +declare class Window extends EventTarget { + new(): Window; readonly window: Window & typeof globalThis; readonly self: Window & typeof globalThis; onload: ((this: Window, ev: Event) => any) | null; diff --git a/cli/dts/lib.deno.worker.d.ts b/cli/dts/lib.deno.worker.d.ts index 3fc95a97ed..a10b1a2768 100644 --- a/cli/dts/lib.deno.worker.d.ts +++ b/cli/dts/lib.deno.worker.d.ts @@ -7,48 +7,53 @@ /// /// -declare interface DedicatedWorkerGlobalScope { - self: DedicatedWorkerGlobalScope & typeof globalThis; +declare class WorkerGlobalScope { + new(): WorkerGlobalScope; + self: WorkerGlobalScope & typeof globalThis; onmessage: | (( - this: DedicatedWorkerGlobalScope & typeof globalThis, + this: WorkerGlobalScope & typeof globalThis, ev: MessageEvent, ) => any) | null; onmessageerror: | (( - this: DedicatedWorkerGlobalScope & typeof globalThis, + this: WorkerGlobalScope & typeof globalThis, ev: MessageEvent, ) => any) | null; onerror: | (( - this: DedicatedWorkerGlobalScope & typeof globalThis, + this: WorkerGlobalScope & typeof globalThis, ev: ErrorEvent, ) => any) | null; - name: string; close: () => void; postMessage: (message: any) => void; Deno: typeof Deno; } -declare var self: DedicatedWorkerGlobalScope & typeof globalThis; +declare class DedicatedWorkerGlobalScope extends WorkerGlobalScope { + new(): DedicatedWorkerGlobalScope; + name: string; +} + +declare var self: WorkerGlobalScope & typeof globalThis; declare var onmessage: | (( - this: DedicatedWorkerGlobalScope & typeof globalThis, + this: WorkerGlobalScope & typeof globalThis, ev: MessageEvent, ) => any) | null; declare var onmessageerror: | (( - this: DedicatedWorkerGlobalScope & typeof globalThis, + this: WorkerGlobalScope & typeof globalThis, ev: MessageEvent, ) => any) | null; declare var onerror: | (( - this: DedicatedWorkerGlobalScope & typeof globalThis, + this: WorkerGlobalScope & typeof globalThis, ev: ErrorEvent, ) => any) | null; diff --git a/cli/rt/99_main.js b/cli/rt/99_main.js index d8462ce662..d8c34bcb35 100644 --- a/cli/rt/99_main.js +++ b/cli/rt/99_main.js @@ -7,6 +7,7 @@ delete Object.prototype.__proto__; ((window) => { const core = Deno.core; const util = window.__bootstrap.util; + const { illegalConstructorKey } = window.__bootstrap.webUtil; const eventTarget = window.__bootstrap.eventTarget; const dispatchMinimal = window.__bootstrap.dispatchMinimal; const build = window.__bootstrap.build; @@ -190,6 +191,42 @@ delete Object.prototype.__proto__; core.registerErrorClass("URIError", URIError); } + class Window extends EventTarget { + constructor(key) { + if (key !== illegalConstructorKey) { + throw new TypeError("Illegal constructor."); + } + } + + get [Symbol.toStringTag]() { + return "Window"; + } + } + + class WorkerGlobalScope extends EventTarget { + constructor(key) { + if (key != illegalConstructorKey) { + throw new TypeError("Illegal constructor."); + } + } + + get [Symbol.toStringTag]() { + return "WorkerGlobalScope"; + } + } + + class DedicatedWorkerGlobalScope extends WorkerGlobalScope { + constructor(key) { + if (key != illegalConstructorKey) { + throw new TypeError("Illegal constructor."); + } + } + + get [Symbol.toStringTag]() { + return "DedicatedWorkerGlobalScope"; + } + } + // https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope const windowOrWorkerGlobalScope = { Blob: util.nonEnumerable(fetch.Blob), @@ -226,24 +263,20 @@ delete Object.prototype.__proto__; WebSocket: util.nonEnumerable(webSocket.WebSocket), Worker: util.nonEnumerable(worker.Worker), WritableStream: util.nonEnumerable(streams.WritableStream), - addEventListener: util.readOnly(EventTarget.prototype.addEventListener), atob: util.writable(atob), btoa: util.writable(btoa), clearInterval: util.writable(timers.clearInterval), clearTimeout: util.writable(timers.clearTimeout), console: util.writable(new Console(core.print)), crypto: util.readOnly(crypto), - dispatchEvent: util.readOnly(EventTarget.prototype.dispatchEvent), fetch: util.writable(fetch.fetch), performance: util.writable(performance.performance), - removeEventListener: util.readOnly( - EventTarget.prototype.removeEventListener, - ), setInterval: util.writable(timers.setInterval), setTimeout: util.writable(timers.setTimeout), }; const mainRuntimeGlobalProperties = { + Window: util.nonEnumerable(Window), window: util.readOnly(globalThis), self: util.readOnly(globalThis), // TODO(bartlomieju): from MDN docs (https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope) @@ -255,6 +288,8 @@ delete Object.prototype.__proto__; }; const workerRuntimeGlobalProperties = { + WorkerGlobalScope: util.nonEnumerable(WorkerGlobalScope), + DedicatedWorkerGlobalScope: util.nonEnumerable(DedicatedWorkerGlobalScope), self: util.readOnly(globalThis), onmessage: util.writable(onmessage), onerror: util.writable(onerror), @@ -277,6 +312,7 @@ delete Object.prototype.__proto__; hasBootstrapped = true; Object.defineProperties(globalThis, windowOrWorkerGlobalScope); Object.defineProperties(globalThis, mainRuntimeGlobalProperties); + Object.setPrototypeOf(globalThis, Window.prototype); eventTarget.setEventTargetData(globalThis); // Registers the handler for window.onload function. globalThis.addEventListener("load", (e) => { @@ -341,6 +377,7 @@ delete Object.prototype.__proto__; Object.defineProperties(globalThis, windowOrWorkerGlobalScope); Object.defineProperties(globalThis, workerRuntimeGlobalProperties); Object.defineProperties(globalThis, { name: util.readOnly(name) }); + Object.setPrototypeOf(globalThis, DedicatedWorkerGlobalScope.prototype); eventTarget.setEventTargetData(globalThis); const { unstableFlag, pid, noColor, args } = runtimeStart( internalName ?? name, diff --git a/cli/tests/subdir/worker_globals.ts b/cli/tests/subdir/worker_globals.ts new file mode 100644 index 0000000000..a9e7efd85c --- /dev/null +++ b/cli/tests/subdir/worker_globals.ts @@ -0,0 +1,10 @@ +onmessage = function (): void { + postMessage( + [ + self instanceof DedicatedWorkerGlobalScope, + self instanceof WorkerGlobalScope, + self instanceof EventTarget, + ].join(", "), + ); + close(); +}; diff --git a/cli/tests/unit/globals_test.ts b/cli/tests/unit/globals_test.ts index 6c83b1b444..53fafc5b68 100644 --- a/cli/tests/unit/globals_test.ts +++ b/cli/tests/unit/globals_test.ts @@ -36,6 +36,14 @@ unitTest(function globalThisEqualsSelf(): void { assert(globalThis === self); }); +unitTest(function globalThisInstanceofWindow(): void { + assert(globalThis instanceof Window); +}); + +unitTest(function globalThisInstanceofEventTarget(): void { + assert(globalThis instanceof EventTarget); +}); + unitTest(function DenoNamespaceExists(): void { assert(Deno != null); }); diff --git a/cli/tests/workers_test.ts b/cli/tests/workers_test.ts index 395b1da244..06349efa00 100644 --- a/cli/tests/workers_test.ts +++ b/cli/tests/workers_test.ts @@ -105,6 +105,24 @@ Deno.test({ }, }); +Deno.test({ + name: "worker globals", + fn: async function (): Promise { + const promise = createResolvable(); + const w = new Worker( + new URL("subdir/worker_globals.ts", import.meta.url).href, + { type: "module" }, + ); + w.onmessage = (e): void => { + assertEquals(e.data, "true, true, true"); + promise.resolve(); + }; + w.postMessage("Hello, world!"); + await promise; + w.terminate(); + }, +}); + Deno.test({ name: "worker fetch API", fn: async function (): Promise {