mirror of
https://github.com/Microsoft/vscode
synced 2024-10-30 11:10:48 +00:00
Don't use data:
as the src of the web worker extension host iframe (#108285)
This commit is contained in:
parent
3b95fb5233
commit
b72438c7f3
8 changed files with 192 additions and 92 deletions
|
@ -60,6 +60,7 @@ if (args.help) {
|
||||||
' --host Remote host\n' +
|
' --host Remote host\n' +
|
||||||
' --port Remote/Local port\n' +
|
' --port Remote/Local port\n' +
|
||||||
' --local_port Local port override\n' +
|
' --local_port Local port override\n' +
|
||||||
|
' --secondary-port Secondary port\n' +
|
||||||
' --extension Path of an extension to include\n' +
|
' --extension Path of an extension to include\n' +
|
||||||
' --github-auth Github authentication token\n' +
|
' --github-auth Github authentication token\n' +
|
||||||
' --verbose Print out more information\n' +
|
' --verbose Print out more information\n' +
|
||||||
|
@ -72,6 +73,7 @@ if (args.help) {
|
||||||
|
|
||||||
const PORT = args.port || process.env.PORT || 8080;
|
const PORT = args.port || process.env.PORT || 8080;
|
||||||
const LOCAL_PORT = args.local_port || process.env.LOCAL_PORT || PORT;
|
const LOCAL_PORT = args.local_port || process.env.LOCAL_PORT || PORT;
|
||||||
|
const SECONDARY_PORT = args['secondary-port'] || (parseInt(PORT, 10) + 1);
|
||||||
const SCHEME = args.scheme || process.env.VSCODE_SCHEME || 'http';
|
const SCHEME = args.scheme || process.env.VSCODE_SCHEME || 'http';
|
||||||
const HOST = args.host || 'localhost';
|
const HOST = args.host || 'localhost';
|
||||||
const AUTHORITY = process.env.VSCODE_AUTHORITY || `${HOST}:${PORT}`;
|
const AUTHORITY = process.env.VSCODE_AUTHORITY || `${HOST}:${PORT}`;
|
||||||
|
@ -207,7 +209,11 @@ const commandlineProvidedExtensionsPromise = getCommandlineProvidedExtensionInfo
|
||||||
|
|
||||||
const mapCallbackUriToRequestId = new Map();
|
const mapCallbackUriToRequestId = new Map();
|
||||||
|
|
||||||
const server = http.createServer((req, res) => {
|
/**
|
||||||
|
* @param req {http.IncomingMessage}
|
||||||
|
* @param res {http.ServerResponse}
|
||||||
|
*/
|
||||||
|
const requestHandler = (req, res) => {
|
||||||
const parsedUrl = url.parse(req.url, true);
|
const parsedUrl = url.parse(req.url, true);
|
||||||
const pathname = parsedUrl.pathname;
|
const pathname = parsedUrl.pathname;
|
||||||
|
|
||||||
|
@ -252,20 +258,29 @@ const server = http.createServer((req, res) => {
|
||||||
|
|
||||||
return serveError(req, res, 500, 'Internal Server Error.');
|
return serveError(req, res, 500, 'Internal Server Error.');
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
const server = http.createServer(requestHandler);
|
||||||
server.listen(LOCAL_PORT, () => {
|
server.listen(LOCAL_PORT, () => {
|
||||||
if (LOCAL_PORT !== PORT) {
|
if (LOCAL_PORT !== PORT) {
|
||||||
console.log(`Operating location at http://0.0.0.0:${LOCAL_PORT}`);
|
console.log(`Operating location at http://0.0.0.0:${LOCAL_PORT}`);
|
||||||
}
|
}
|
||||||
console.log(`Web UI available at ${SCHEME}://${AUTHORITY}`);
|
console.log(`Web UI available at ${SCHEME}://${AUTHORITY}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on('error', err => {
|
server.on('error', err => {
|
||||||
console.error(`Error occurred in server:`);
|
console.error(`Error occurred in server:`);
|
||||||
console.error(err);
|
console.error(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const secondaryServer = http.createServer(requestHandler);
|
||||||
|
secondaryServer.listen(SECONDARY_PORT, () => {
|
||||||
|
console.log(`Secondary server available at ${SCHEME}://${HOST}:${SECONDARY_PORT}`);
|
||||||
|
});
|
||||||
|
secondaryServer.on('error', err => {
|
||||||
|
console.error(`Error occurred in server:`);
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import('http').IncomingMessage} req
|
* @param {import('http').IncomingMessage} req
|
||||||
* @param {import('http').ServerResponse} res
|
* @param {import('http').ServerResponse} res
|
||||||
|
@ -366,6 +381,7 @@ async function handleRoot(req, res) {
|
||||||
folderUri: folderUri,
|
folderUri: folderUri,
|
||||||
staticExtensions,
|
staticExtensions,
|
||||||
enableSyncByDefault: args['enable-sync'],
|
enableSyncByDefault: args['enable-sync'],
|
||||||
|
webWorkerExtensionHostIframeSrc: `${SCHEME}://${HOST}:${SECONDARY_PORT}/static/out/vs/workbench/services/extensions/worker/httpWebWorkerExtensionHostIframe.html`
|
||||||
};
|
};
|
||||||
if (args['wrap-iframe']) {
|
if (args['wrap-iframe']) {
|
||||||
webConfigJSON._wrapWebWorkerExtHostInIframe = true;
|
webConfigJSON._wrapWebWorkerExtHostInIframe = true;
|
||||||
|
|
|
@ -51,6 +51,7 @@ export interface IProductConfiguration {
|
||||||
|
|
||||||
readonly downloadUrl?: string;
|
readonly downloadUrl?: string;
|
||||||
readonly updateUrl?: string;
|
readonly updateUrl?: string;
|
||||||
|
readonly webEndpointUrl?: string;
|
||||||
readonly target?: string;
|
readonly target?: string;
|
||||||
|
|
||||||
readonly settingsSearchBuildId?: number;
|
readonly settingsSearchBuildId?: number;
|
||||||
|
|
|
@ -16,7 +16,6 @@ import { ILabelService } from 'vs/platform/label/common/label';
|
||||||
import { ILogService } from 'vs/platform/log/common/log';
|
import { ILogService } from 'vs/platform/log/common/log';
|
||||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||||
import * as platform from 'vs/base/common/platform';
|
import * as platform from 'vs/base/common/platform';
|
||||||
import * as browser from 'vs/base/browser/browser';
|
|
||||||
import * as dom from 'vs/base/browser/dom';
|
import * as dom from 'vs/base/browser/dom';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { IExtensionHost, ExtensionHostLogFileName, ExtensionHostKind } from 'vs/workbench/services/extensions/common/extensions';
|
import { IExtensionHost, ExtensionHostLogFileName, ExtensionHostKind } from 'vs/workbench/services/extensions/common/extensions';
|
||||||
|
@ -28,7 +27,6 @@ import { IOutputChannelRegistry, Extensions } from 'vs/workbench/services/output
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import { generateUuid } from 'vs/base/common/uuid';
|
import { generateUuid } from 'vs/base/common/uuid';
|
||||||
import { canceled, onUnexpectedError } from 'vs/base/common/errors';
|
import { canceled, onUnexpectedError } from 'vs/base/common/errors';
|
||||||
import { WEB_WORKER_IFRAME } from 'vs/workbench/services/extensions/common/webWorkerIframe';
|
|
||||||
import { Barrier } from 'vs/base/common/async';
|
import { Barrier } from 'vs/base/common/async';
|
||||||
import { FileAccess } from 'vs/base/common/network';
|
import { FileAccess } from 'vs/base/common/network';
|
||||||
|
|
||||||
|
@ -81,10 +79,38 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _webWorkerExtensionHostIframeSrc(): string | null {
|
||||||
|
if (this._environmentService.options && this._environmentService.options.webWorkerExtensionHostIframeSrc) {
|
||||||
|
return this._environmentService.options.webWorkerExtensionHostIframeSrc;
|
||||||
|
}
|
||||||
|
if (this._productService.webEndpointUrl) {
|
||||||
|
const forceHTTPS = (location.protocol === 'https:');
|
||||||
|
let baseUrl = this._productService.webEndpointUrl;
|
||||||
|
if (this._productService.quality) {
|
||||||
|
baseUrl += `/${this._productService.quality}`;
|
||||||
|
}
|
||||||
|
if (this._productService.commit) {
|
||||||
|
baseUrl += `/${this._productService.commit}`;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
forceHTTPS
|
||||||
|
? `${baseUrl}/out/vs/workbench/services/extensions/worker/httpsWebWorkerExtensionHostIframe.html`
|
||||||
|
: `${baseUrl}/out/vs/workbench/services/extensions/worker/httpWebWorkerExtensionHostIframe.html`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public async start(): Promise<IMessagePassingProtocol> {
|
public async start(): Promise<IMessagePassingProtocol> {
|
||||||
if (!this._protocolPromise) {
|
if (!this._protocolPromise) {
|
||||||
if (platform.isWeb && !browser.isSafari && this._wrapInIframe()) {
|
if (platform.isWeb) {
|
||||||
this._protocolPromise = this._startInsideIframe();
|
const webWorkerExtensionHostIframeSrc = this._webWorkerExtensionHostIframeSrc();
|
||||||
|
if (webWorkerExtensionHostIframeSrc && this._wrapInIframe()) {
|
||||||
|
this._protocolPromise = this._startInsideIframe(webWorkerExtensionHostIframeSrc);
|
||||||
|
} else {
|
||||||
|
console.warn(`The web worker extension host is started without an iframe sandbox!`);
|
||||||
|
this._protocolPromise = this._startOutsideIframe();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this._protocolPromise = this._startOutsideIframe();
|
this._protocolPromise = this._startOutsideIframe();
|
||||||
}
|
}
|
||||||
|
@ -93,40 +119,41 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
|
||||||
return this._protocolPromise;
|
return this._protocolPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _startInsideIframe(): Promise<IMessagePassingProtocol> {
|
private async _startInsideIframe(webWorkerExtensionHostIframeSrc: string): Promise<IMessagePassingProtocol> {
|
||||||
const emitter = this._register(new Emitter<VSBuffer>());
|
const emitter = this._register(new Emitter<VSBuffer>());
|
||||||
|
|
||||||
const iframe = document.createElement('iframe');
|
const iframe = document.createElement('iframe');
|
||||||
iframe.setAttribute('class', 'web-worker-ext-host-iframe');
|
iframe.setAttribute('class', 'web-worker-ext-host-iframe');
|
||||||
iframe.setAttribute('sandbox', 'allow-scripts');
|
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');
|
||||||
iframe.style.display = 'none';
|
iframe.style.display = 'none';
|
||||||
|
|
||||||
const vscodeWebWorkerExtHostId = generateUuid();
|
const vscodeWebWorkerExtHostId = generateUuid();
|
||||||
const workerUrl = FileAccess.asBrowserUri('../worker/extensionHostWorkerMain.js', require).toString(true);
|
iframe.setAttribute('src', `${webWorkerExtensionHostIframeSrc}?vscodeWebWorkerExtHostId=${vscodeWebWorkerExtHostId}`);
|
||||||
const workerSrc = getWorkerBootstrapUrl(workerUrl, 'WorkerExtensionHost', true);
|
|
||||||
const escapeAttribute = (value: string): string => {
|
|
||||||
return value.replace(/"/g, '"');
|
|
||||||
};
|
|
||||||
const forceHTTPS = (location.protocol === 'https:');
|
|
||||||
const html = `<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'unsafe-eval' '${WEB_WORKER_IFRAME.sha}' ${forceHTTPS ? 'https:' : 'http: https:'}; worker-src data:; connect-src ${forceHTTPS ? 'https:' : 'http: https:'}" />
|
|
||||||
<meta id="vscode-worker-src" data-value="${escapeAttribute(workerSrc)}" />
|
|
||||||
<meta id="vscode-web-worker-ext-host-id" data-value="${escapeAttribute(vscodeWebWorkerExtHostId)}" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<script>${WEB_WORKER_IFRAME.js}</script>
|
|
||||||
</body>
|
|
||||||
</html>`;
|
|
||||||
const iframeContent = `data:text/html;charset=utf-8,${encodeURIComponent(html)}`;
|
|
||||||
iframe.setAttribute('src', iframeContent);
|
|
||||||
const timeout = setTimeout(() => {
|
|
||||||
this._onDidExit.fire([ExtensionHostExitCode.StartTimeout10s, 'The Web Worker Extension Host did not start in 10s']);
|
|
||||||
}, 10000);
|
|
||||||
|
|
||||||
const barrier = new Barrier();
|
const barrier = new Barrier();
|
||||||
let port!: MessagePort;
|
let port!: MessagePort;
|
||||||
|
let barrierError: Error | null = null;
|
||||||
|
let barrierHasError = false;
|
||||||
|
let startTimeout: any = null;
|
||||||
|
|
||||||
|
const rejectBarrier = (exitCode: number, error: Error) => {
|
||||||
|
barrierError = error;
|
||||||
|
barrierHasError = true;
|
||||||
|
onUnexpectedError(barrierError);
|
||||||
|
clearTimeout(startTimeout);
|
||||||
|
this._onDidExit.fire([ExtensionHostExitCode.UnexpectedError, barrierError.message]);
|
||||||
|
barrier.open();
|
||||||
|
};
|
||||||
|
|
||||||
|
const resolveBarrier = (messagePort: MessagePort) => {
|
||||||
|
port = messagePort;
|
||||||
|
clearTimeout(startTimeout);
|
||||||
|
barrier.open();
|
||||||
|
};
|
||||||
|
|
||||||
|
startTimeout = setTimeout(() => {
|
||||||
|
rejectBarrier(ExtensionHostExitCode.StartTimeout10s, new Error('The Web Worker Extension Host did not start in 10s'));
|
||||||
|
}, 10000);
|
||||||
|
|
||||||
this._register(dom.addDisposableListener(window, 'message', (event) => {
|
this._register(dom.addDisposableListener(window, 'message', (event) => {
|
||||||
if (event.source !== iframe.contentWindow) {
|
if (event.source !== iframe.contentWindow) {
|
||||||
|
@ -141,21 +168,15 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
|
||||||
err.message = message;
|
err.message = message;
|
||||||
err.name = name;
|
err.name = name;
|
||||||
err.stack = stack;
|
err.stack = stack;
|
||||||
onUnexpectedError(err);
|
return rejectBarrier(ExtensionHostExitCode.UnexpectedError, err);
|
||||||
clearTimeout(timeout);
|
|
||||||
this._onDidExit.fire([ExtensionHostExitCode.UnexpectedError, err.message]);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
const { data } = event.data;
|
const { data } = event.data;
|
||||||
if (barrier.isOpen() || !(data instanceof MessagePort)) {
|
if (barrier.isOpen() || !(data instanceof MessagePort)) {
|
||||||
console.warn('UNEXPECTED message', event);
|
console.warn('UNEXPECTED message', event);
|
||||||
clearTimeout(timeout);
|
const err = new Error('UNEXPECTED message');
|
||||||
this._onDidExit.fire([ExtensionHostExitCode.UnexpectedError, 'UNEXPECTED message']);
|
return rejectBarrier(ExtensionHostExitCode.UnexpectedError, err);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
port = data;
|
resolveBarrier(data);
|
||||||
clearTimeout(timeout);
|
|
||||||
barrier.open();
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
document.body.appendChild(iframe);
|
document.body.appendChild(iframe);
|
||||||
|
@ -165,6 +186,10 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
|
||||||
// with the worker extension host
|
// with the worker extension host
|
||||||
await barrier.wait();
|
await barrier.wait();
|
||||||
|
|
||||||
|
if (barrierHasError) {
|
||||||
|
throw barrierError;
|
||||||
|
}
|
||||||
|
|
||||||
port.onmessage = (event) => {
|
port.onmessage = (event) => {
|
||||||
const { data } = event;
|
const { data } = event;
|
||||||
if (!(data instanceof ArrayBuffer)) {
|
if (!(data instanceof ArrayBuffer)) {
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
export const WEB_WORKER_IFRAME = {
|
|
||||||
sha: 'sha256-r24mDVsMuFEo8ChaY9ppVJKbY3CUM4I12Aw/yscWZbg=',
|
|
||||||
js: `
|
|
||||||
(function() {
|
|
||||||
const workerSrc = document.getElementById('vscode-worker-src').getAttribute('data-value');
|
|
||||||
const worker = new Worker(workerSrc, { name: 'WorkerExtensionHost' });
|
|
||||||
const vscodeWebWorkerExtHostId = document.getElementById('vscode-web-worker-ext-host-id').getAttribute('data-value');
|
|
||||||
|
|
||||||
worker.onmessage = (event) => {
|
|
||||||
const { data } = event;
|
|
||||||
if (!(data instanceof MessagePort)) {
|
|
||||||
console.warn('Unknown data received', event);
|
|
||||||
window.parent.postMessage({
|
|
||||||
vscodeWebWorkerExtHostId,
|
|
||||||
error: {
|
|
||||||
name: 'Error',
|
|
||||||
message: 'Unknown data received',
|
|
||||||
stack: []
|
|
||||||
}
|
|
||||||
}, '*');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
window.parent.postMessage({
|
|
||||||
vscodeWebWorkerExtHostId,
|
|
||||||
data: data
|
|
||||||
}, '*', [data]);
|
|
||||||
};
|
|
||||||
|
|
||||||
worker.onerror = (event) => {
|
|
||||||
console.error(event.message, event.error);
|
|
||||||
window.parent.postMessage({
|
|
||||||
vscodeWebWorkerExtHostId,
|
|
||||||
error: {
|
|
||||||
name: event.error ? event.error.name : '',
|
|
||||||
message: event.error ? event.error.message : '',
|
|
||||||
stack: event.error ? event.error.stack : []
|
|
||||||
}
|
|
||||||
}, '*');
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
`
|
|
||||||
};
|
|
|
@ -45,9 +45,9 @@ self.addEventListener = () => console.trace(`'addEventListener' has been blocked
|
||||||
(<any>self)['webkitResolveLocalFileSystemSyncURL'] = undefined;
|
(<any>self)['webkitResolveLocalFileSystemSyncURL'] = undefined;
|
||||||
(<any>self)['webkitResolveLocalFileSystemURL'] = undefined;
|
(<any>self)['webkitResolveLocalFileSystemURL'] = undefined;
|
||||||
|
|
||||||
if (location.protocol === 'data:') {
|
if ((<any>self).Worker) {
|
||||||
// make sure new Worker(...) always uses data:
|
// make sure new Worker(...) always uses data:
|
||||||
const _Worker = Worker;
|
const _Worker = (<any>self).Worker;
|
||||||
Worker = <any>function (stringUrl: string | URL, options?: WorkerOptions) {
|
Worker = <any>function (stringUrl: string | URL, options?: WorkerOptions) {
|
||||||
const js = `importScripts('${stringUrl}');`;
|
const js = `importScripts('${stringUrl}');`;
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; child-src 'self' data:; script-src 'unsafe-eval' 'sha256-O98pkmgtvUCQGVoddaGy891K52PVRnySDRxRszVLPNQ=' http: https:; connect-src http: https:" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
const idMatch = document.location.search.match(/\bvscodeWebWorkerExtHostId=([0-9a-f\-]+)/i);
|
||||||
|
const vscodeWebWorkerExtHostId = idMatch ? idMatch[1] : '';
|
||||||
|
|
||||||
|
function sendError(error) {
|
||||||
|
window.parent.postMessage({
|
||||||
|
vscodeWebWorkerExtHostId,
|
||||||
|
error: {
|
||||||
|
name: error ? error.name : '',
|
||||||
|
message: error ? error.message : '',
|
||||||
|
stack: error ? error.stack : []
|
||||||
|
}
|
||||||
|
}, '*');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const worker = new Worker('extensionHostWorkerMain.js', { name: 'WorkerExtensionHost' });
|
||||||
|
|
||||||
|
worker.onmessage = (event) => {
|
||||||
|
const { data } = event;
|
||||||
|
if (!(data instanceof MessagePort)) {
|
||||||
|
console.warn('Unknown data received', event);
|
||||||
|
sendError({ name: 'Error', message: 'Unknown data received', stack: [] });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.parent.postMessage({
|
||||||
|
vscodeWebWorkerExtHostId,
|
||||||
|
data: data
|
||||||
|
}, '*', [data]);
|
||||||
|
};
|
||||||
|
|
||||||
|
worker.onerror = (event) => {
|
||||||
|
console.error(event.message, event.error);
|
||||||
|
sendError(event.error);
|
||||||
|
};
|
||||||
|
} catch(err) {
|
||||||
|
console.error(err);
|
||||||
|
sendError(err);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,50 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; child-src 'self' data:; script-src 'unsafe-eval' 'sha256-O98pkmgtvUCQGVoddaGy891K52PVRnySDRxRszVLPNQ=' https:; connect-src https:" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
const idMatch = document.location.search.match(/\bvscodeWebWorkerExtHostId=([0-9a-f\-]+)/i);
|
||||||
|
const vscodeWebWorkerExtHostId = idMatch ? idMatch[1] : '';
|
||||||
|
|
||||||
|
function sendError(error) {
|
||||||
|
window.parent.postMessage({
|
||||||
|
vscodeWebWorkerExtHostId,
|
||||||
|
error: {
|
||||||
|
name: error ? error.name : '',
|
||||||
|
message: error ? error.message : '',
|
||||||
|
stack: error ? error.stack : []
|
||||||
|
}
|
||||||
|
}, '*');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const worker = new Worker('extensionHostWorkerMain.js', { name: 'WorkerExtensionHost' });
|
||||||
|
|
||||||
|
worker.onmessage = (event) => {
|
||||||
|
const { data } = event;
|
||||||
|
if (!(data instanceof MessagePort)) {
|
||||||
|
console.warn('Unknown data received', event);
|
||||||
|
sendError({ name: 'Error', message: 'Unknown data received', stack: [] });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.parent.postMessage({
|
||||||
|
vscodeWebWorkerExtHostId,
|
||||||
|
data: data
|
||||||
|
}, '*', [data]);
|
||||||
|
};
|
||||||
|
|
||||||
|
worker.onerror = (event) => {
|
||||||
|
console.error(event.message, event.error);
|
||||||
|
sendError(event.error);
|
||||||
|
};
|
||||||
|
} catch(err) {
|
||||||
|
console.error(err);
|
||||||
|
sendError(err);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -277,6 +277,11 @@ interface IWorkbenchConstructionOptions {
|
||||||
*/
|
*/
|
||||||
readonly webviewEndpoint?: string;
|
readonly webviewEndpoint?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An URL pointing to the web worker extension host <iframe> src.
|
||||||
|
*/
|
||||||
|
readonly webWorkerExtensionHostIframeSrc?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A factory for web sockets.
|
* A factory for web sockets.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue