Skip to content

Commit

Permalink
fix(cli/rt/main): Add Window and WorkerGlobalScope to globalThis prot…
Browse files Browse the repository at this point in the history
…otypes
  • Loading branch information
nayeemrmn committed Oct 8, 2020
1 parent b5e4b63 commit d6dbd66
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 16 deletions.
3 changes: 2 additions & 1 deletion cli/dts/lib.deno.window.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
/// <reference lib="deno.shared_globals" />
/// <reference lib="esnext" />

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;
Expand Down
25 changes: 15 additions & 10 deletions cli/dts/lib.deno.worker.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,53 @@
/// <reference lib="deno.shared_globals" />
/// <reference lib="esnext" />

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;
Expand Down
47 changes: 42 additions & 5 deletions cli/rt/99_main.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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)
Expand All @@ -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),
Expand All @@ -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) => {
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 10 additions & 0 deletions cli/tests/subdir/worker_globals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
onmessage = function (): void {
postMessage(
[
self instanceof DedicatedWorkerGlobalScope,
self instanceof WorkerGlobalScope,
self instanceof EventTarget,
].join(", "),
);
close();
};
8 changes: 8 additions & 0 deletions cli/tests/unit/globals_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
Expand Down
18 changes: 18 additions & 0 deletions cli/tests/workers_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,24 @@ Deno.test({
},
});

Deno.test({
name: "worker globals",
fn: async function (): Promise<void> {
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<void> {
Expand Down

0 comments on commit d6dbd66

Please sign in to comment.