Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adopt globalThis #175381

Merged
merged 1 commit into from Feb 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 12 additions & 8 deletions src/vs/base/browser/defaultWorkerFactory.ts
Expand Up @@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/

import { COI } from 'vs/base/common/network';
import { globals } from 'vs/base/common/platform';
import { IWorker, IWorkerCallback, IWorkerFactory, logOnceWebWorkerWarning } from 'vs/base/common/worker/simpleWorker';

const ttPolicy = window.trustedTypes?.createPolicy('defaultWorkerFactory', { createScriptURL: value => value });
Expand All @@ -18,12 +17,17 @@ export function createBlobWorker(blobUrl: string, options?: WorkerOptions): Work

function getWorker(label: string): Worker | Promise<Worker> {
// Option for hosts to overwrite the worker script (used in the standalone editor)
if (globals.MonacoEnvironment) {
if (typeof globals.MonacoEnvironment.getWorker === 'function') {
return globals.MonacoEnvironment.getWorker('workerMain.js', label);
interface IMonacoEnvironment {
getWorker?(moduleId: string, label: string): Worker | Promise<Worker>;
getWorkerUrl?(moduleId: string, label: string): string;
}
const monacoEnvironment: IMonacoEnvironment | undefined = (globalThis as any).MonacoEnvironment;
if (monacoEnvironment) {
if (typeof monacoEnvironment.getWorker === 'function') {
return monacoEnvironment.getWorker('workerMain.js', label);
}
if (typeof globals.MonacoEnvironment.getWorkerUrl === 'function') {
const workerUrl = <string>globals.MonacoEnvironment.getWorkerUrl('workerMain.js', label);
if (typeof monacoEnvironment.getWorkerUrl === 'function') {
const workerUrl = monacoEnvironment.getWorkerUrl('workerMain.js', label);
return new Worker(ttPolicy ? ttPolicy.createScriptURL(workerUrl) as unknown as string : workerUrl, { name: label });
}
}
Expand All @@ -40,12 +44,12 @@ function getWorker(label: string): Worker | Promise<Worker> {

// ESM-comment-begin
export function getWorkerBootstrapUrl(scriptPath: string, label: string): string {
if (/^((http:)|(https:)|(file:))/.test(scriptPath) && scriptPath.substring(0, self.origin.length) !== self.origin) {
if (/^((http:)|(https:)|(file:))/.test(scriptPath) && scriptPath.substring(0, globalThis.origin.length) !== globalThis.origin) {
// this is the cross-origin case
// i.e. the webpage is running at a different origin than where the scripts are loaded from
const myPath = 'vs/base/worker/defaultWorkerFactory.js';
const workerBaseUrl = require.toUrl(myPath).slice(0, -myPath.length); // explicitly using require.toUrl(), see https://github.com/microsoft/vscode/issues/107440#issuecomment-698982321
const js = `/*${label}*/self.MonacoEnvironment={baseUrl: '${workerBaseUrl}'};const ttPolicy = self.trustedTypes?.createPolicy('defaultWorkerFactory', { createScriptURL: value => value });importScripts(ttPolicy?.createScriptURL('${scriptPath}') ?? '${scriptPath}');/*${label}*/`;
const js = `/*${label}*/globalThis.MonacoEnvironment={baseUrl: '${workerBaseUrl}'};const ttPolicy = globalThis.trustedTypes?.createPolicy('defaultWorkerFactory', { createScriptURL: value => value });importScripts(ttPolicy?.createScriptURL('${scriptPath}') ?? '${scriptPath}');/*${label}*/`;
const blob = new Blob([js], { type: 'application/javascript' });
return URL.createObjectURL(blob);
}
Expand Down
2 changes: 1 addition & 1 deletion src/vs/base/browser/mouseEvent.ts
Expand Up @@ -74,7 +74,7 @@ export class StandardMouseEvent implements IMouseEvent {
}

// Find the position of the iframe this code is executing in relative to the iframe where the event was captured.
const iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(self, e.view);
const iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(window, e.view);
this.posx -= iframeOffsets.left;
this.posy -= iframeOffsets.top;
}
Expand Down
18 changes: 10 additions & 8 deletions src/vs/base/common/worker/simpleWorker.ts
Expand Up @@ -7,7 +7,7 @@ import { transformErrorForSerialization } from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { getAllMethodNames } from 'vs/base/common/objects';
import { globals, isWeb } from 'vs/base/common/platform';
import { isWeb } from 'vs/base/common/platform';
import * as strings from 'vs/base/common/strings';

const INITIALIZE = '$initialize';
Expand Down Expand Up @@ -324,12 +324,14 @@ export class SimpleWorkerClient<W extends object, H extends object> extends Disp

// Gather loader configuration
let loaderConfiguration: any = null;
if (typeof globals.require !== 'undefined' && typeof globals.require.getConfig === 'function') {

const globalRequire: { getConfig?(): object } | undefined = (globalThis as any).require;
if (typeof globalRequire !== 'undefined' && typeof globalRequire.getConfig === 'function') {
// Get the configuration from the Monaco AMD Loader
loaderConfiguration = globals.require.getConfig();
} else if (typeof globals.requirejs !== 'undefined') {
loaderConfiguration = globalRequire.getConfig();
} else if (typeof (globalThis as any).requirejs !== 'undefined') {
// Get the configuration from requirejs
loaderConfiguration = globals.requirejs.s.contexts._.config;
loaderConfiguration = (globalThis as any).requirejs.s.contexts._.config;
}

const hostMethods = getAllMethodNames(host);
Expand Down Expand Up @@ -527,17 +529,17 @@ export class SimpleWorkerServer<H extends object> {

// Since this is in a web worker, enable catching errors
loaderConfig.catchError = true;
globals.require.config(loaderConfig);
globalThis.require.config(loaderConfig);
}

return new Promise<string[]>((resolve, reject) => {
// Use the global require to be sure to get the global config

// ESM-comment-begin
const req = (globals.require || require);
const req = (globalThis.require || require);
// ESM-comment-end
// ESM-uncomment-begin
// const req = globals.require;
// const req = globalThis.require;
// ESM-uncomment-end

req([moduleId], (module: { create: IRequestHandlerFactory<H> }) => {
Expand Down
25 changes: 13 additions & 12 deletions src/vs/base/worker/workerMain.ts
Expand Up @@ -5,7 +5,7 @@

(function () {

const MonacoEnvironment = (<any>self).MonacoEnvironment;
const MonacoEnvironment = (<any>globalThis).MonacoEnvironment;
const monacoBaseUrl = MonacoEnvironment && MonacoEnvironment.baseUrl ? MonacoEnvironment.baseUrl : '../../../';

const trustedTypesPolicy = (
Expand All @@ -29,10 +29,10 @@
try {
const func = (
trustedTypesPolicy
? self.eval(<any>trustedTypesPolicy.createScript('', 'true'))
? globalThis.eval(<any>trustedTypesPolicy.createScript('', 'true'))
: new Function('true')
);
func.call(self);
func.call(globalThis);
return true;
} catch (err) {
return false;
Expand All @@ -41,12 +41,12 @@

function loadAMDLoader() {
return new Promise<void>((resolve, reject) => {
if (typeof (<any>self).define === 'function' && (<any>self).define.amd) {
if (typeof (<any>globalThis).define === 'function' && (<any>globalThis).define.amd) {
return resolve();
}
const loaderSrc: string | TrustedScriptURL = monacoBaseUrl + 'vs/loader.js';

const isCrossOrigin = (/^((http:)|(https:)|(file:))/.test(loaderSrc) && loaderSrc.substring(0, self.origin.length) !== self.origin);
const isCrossOrigin = (/^((http:)|(https:)|(file:))/.test(loaderSrc) && loaderSrc.substring(0, globalThis.origin.length) !== globalThis.origin);
if (!isCrossOrigin && canUseEval()) {
// use `fetch` if possible because `importScripts`
// is synchronous and can lead to deadlocks on Safari
Expand All @@ -59,10 +59,10 @@
text = `${text}\n//# sourceURL=${loaderSrc}`;
const func = (
trustedTypesPolicy
? self.eval(trustedTypesPolicy.createScript('', text) as unknown as string)
? globalThis.eval(trustedTypesPolicy.createScript('', text) as unknown as string)
: new Function(text)
);
func.call(self);
func.call(globalThis);
resolve();
}).then(undefined, reject);
return;
Expand Down Expand Up @@ -92,12 +92,13 @@
require([moduleId], function (ws) {
setTimeout(function () {
const messageHandler = ws.create((msg: any, transfer?: Transferable[]) => {
(<any>self).postMessage(msg, transfer);
(<any>globalThis).postMessage(msg, transfer);
}, null);

self.onmessage = (e: MessageEvent) => messageHandler.onmessage(e.data, e.ports);
globalThis.onmessage = (e: MessageEvent) => messageHandler.onmessage(e.data, e.ports);
while (beforeReadyMessages.length > 0) {
self.onmessage(beforeReadyMessages.shift()!);
const e = beforeReadyMessages.shift()!;
messageHandler.onmessage(e.data, e.ports);
}
}, 0);
});
Expand All @@ -107,13 +108,13 @@
// If the loader is already defined, configure it immediately
// This helps in the bundled case, where we must load nls files
// and they need a correct baseUrl to be loaded.
if (typeof (<any>self).define === 'function' && (<any>self).define.amd) {
if (typeof (<any>globalThis).define === 'function' && (<any>globalThis).define.amd) {
configureAMDLoader();
}

let isFirstMessage = true;
const beforeReadyMessages: MessageEvent[] = [];
self.onmessage = (message: MessageEvent) => {
globalThis.onmessage = (message: MessageEvent) => {
if (!isFirstMessage) {
beforeReadyMessages.push(message);
return;
Expand Down
3 changes: 1 addition & 2 deletions src/vs/editor/common/services/editorSimpleWorker.ts
Expand Up @@ -5,7 +5,6 @@

import { stringDiff } from 'vs/base/common/diff/diff';
import { IDisposable } from 'vs/base/common/lifecycle';
import { globals } from 'vs/base/common/platform';
import { URI } from 'vs/base/common/uri';
import { IRequestHandler } from 'vs/base/common/worker/simpleWorker';
import { IPosition, Position } from 'vs/editor/common/core/position';
Expand Down Expand Up @@ -702,5 +701,5 @@ declare function importScripts(...urls: string[]): void;

if (typeof importScripts === 'function') {
// Running in a web worker
globals.monaco = createMonacoBaseAPI();
globalThis.monaco = createMonacoBaseAPI();
}
13 changes: 8 additions & 5 deletions src/vs/editor/editor.api.ts
Expand Up @@ -7,7 +7,6 @@ import { EditorOptions, WrappingIndent, EditorAutoIndentStrategy } from 'vs/edit
import { createMonacoBaseAPI } from 'vs/editor/common/services/editorBaseApi';
import { createMonacoEditorAPI } from 'vs/editor/standalone/browser/standaloneEditor';
import { createMonacoLanguagesAPI } from 'vs/editor/standalone/browser/standaloneLanguages';
import { globals } from 'vs/base/common/platform';
import { FormattingConflicts } from 'vs/editor/contrib/format/browser/format';

// Set defaults for standalone editor
Expand Down Expand Up @@ -38,12 +37,16 @@ export const Token = api.Token;
export const editor = api.editor;
export const languages = api.languages;

if (globals.MonacoEnvironment?.globalAPI || (typeof define === 'function' && (<any>define).amd)) {
self.monaco = api;
interface IMonacoEnvironment {
globalAPI?: boolean;
}
const monacoEnvironment: IMonacoEnvironment | undefined = (globalThis as any).MonacoEnvironment;
if (monacoEnvironment?.globalAPI || (typeof define === 'function' && (<any>define).amd)) {
globalThis.monaco = api;
}

if (typeof self.require !== 'undefined' && typeof self.require.config === 'function') {
self.require.config({
if (typeof globalThis.require !== 'undefined' && typeof globalThis.require.config === 'function') {
globalThis.require.config({
ignoreDuplicateModules: [
'vscode-languageserver-types',
'vscode-languageserver-types/main',
Expand Down
6 changes: 3 additions & 3 deletions src/vs/editor/editor.worker.ts
Expand Up @@ -16,15 +16,15 @@ export function initialize(foreignModule: any) {
initialized = true;

const simpleWorker = new SimpleWorkerServer((msg) => {
(<any>self).postMessage(msg);
globalThis.postMessage(msg);
}, (host: IEditorWorkerHost) => new EditorSimpleWorker(host, foreignModule));

self.onmessage = (e: MessageEvent) => {
globalThis.onmessage = (e: MessageEvent) => {
simpleWorker.onmessage(e.data);
};
}

self.onmessage = (e: MessageEvent) => {
globalThis.onmessage = (e: MessageEvent) => {
// Ignore first message in this case and initialize if not yet initialized
if (!initialized) {
initialize(null);
Expand Down
Expand Up @@ -13,14 +13,14 @@ const _bootstrapFnSource = (function _bootstrapFn(workerUrl: string) {

const listener: EventListener = (event: Event): void => {
// uninstall handler
self.removeEventListener('message', listener);
globalThis.removeEventListener('message', listener);

// get data
const port = <MessagePort>(<MessageEvent>event).data;

// postMessage
// onmessage
Object.defineProperties(self, {
Object.defineProperties(globalThis, {
'postMessage': {
value(data: any, transferOrOptions?: any) {
port.postMessage(data, transferOrOptions);
Expand All @@ -38,19 +38,19 @@ const _bootstrapFnSource = (function _bootstrapFn(workerUrl: string) {
});

port.addEventListener('message', msg => {
self.dispatchEvent(new MessageEvent('message', { data: msg.data }));
globalThis.dispatchEvent(new MessageEvent('message', { data: msg.data }));
});

port.start();

// fake recursively nested worker
self.Worker = <any>class { constructor() { throw new TypeError('Nested workers from within nested worker are NOT supported.'); } };
globalThis.Worker = <any>class { constructor() { throw new TypeError('Nested workers from within nested worker are NOT supported.'); } };

// load module
importScripts(workerUrl);
};

self.addEventListener('message', listener);
globalThis.addEventListener('message', listener);
}).toString();


Expand Down