mirror of
https://github.com/microsoft/monaco-editor.git
synced 2025-12-22 17:25:39 +01:00
Add support for creating a custom webworker subclass
This commit is contained in:
parent
94d92a7181
commit
26d78129fa
6 changed files with 262 additions and 5 deletions
|
|
@ -31,13 +31,15 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.typescript.
|
||||||
private _eagerModelSync: boolean;
|
private _eagerModelSync: boolean;
|
||||||
private _compilerOptions!: monaco.languages.typescript.CompilerOptions;
|
private _compilerOptions!: monaco.languages.typescript.CompilerOptions;
|
||||||
private _diagnosticsOptions!: monaco.languages.typescript.DiagnosticsOptions;
|
private _diagnosticsOptions!: monaco.languages.typescript.DiagnosticsOptions;
|
||||||
|
private _workerOptions!: monaco.languages.typescript.WorkerOptions;
|
||||||
private _onDidExtraLibsChangeTimeout: number;
|
private _onDidExtraLibsChangeTimeout: number;
|
||||||
|
|
||||||
constructor(compilerOptions: monaco.languages.typescript.CompilerOptions, diagnosticsOptions: monaco.languages.typescript.DiagnosticsOptions) {
|
constructor(compilerOptions: monaco.languages.typescript.CompilerOptions, diagnosticsOptions: monaco.languages.typescript.DiagnosticsOptions, workerOptions: monaco.languages.typescript.WorkerOptions) {
|
||||||
this._extraLibs = Object.create(null);
|
this._extraLibs = Object.create(null);
|
||||||
this._eagerModelSync = false;
|
this._eagerModelSync = false;
|
||||||
this.setCompilerOptions(compilerOptions);
|
this.setCompilerOptions(compilerOptions);
|
||||||
this.setDiagnosticsOptions(diagnosticsOptions);
|
this.setDiagnosticsOptions(diagnosticsOptions);
|
||||||
|
this.setWorkerOptions(workerOptions)
|
||||||
this._onDidExtraLibsChangeTimeout = -1;
|
this._onDidExtraLibsChangeTimeout = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,6 +51,10 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.typescript.
|
||||||
return this._onDidExtraLibsChange.event;
|
return this._onDidExtraLibsChange.event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get workerOptions(): monaco.languages.typescript.WorkerOptions {
|
||||||
|
return this._workerOptions
|
||||||
|
}
|
||||||
|
|
||||||
getExtraLibs(): IExtraLibs {
|
getExtraLibs(): IExtraLibs {
|
||||||
return this._extraLibs;
|
return this._extraLibs;
|
||||||
}
|
}
|
||||||
|
|
@ -142,6 +148,11 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.typescript.
|
||||||
this._onDidChange.fire(undefined);
|
this._onDidChange.fire(undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setWorkerOptions(options: monaco.languages.typescript.WorkerOptions): void {
|
||||||
|
this._workerOptions = options || Object.create(null);
|
||||||
|
this._onDidChange.fire(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
setMaximumWorkerIdleTime(value: number): void {
|
setMaximumWorkerIdleTime(value: number): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,11 +213,13 @@ enum ModuleResolutionKind {
|
||||||
|
|
||||||
const typescriptDefaults = new LanguageServiceDefaultsImpl(
|
const typescriptDefaults = new LanguageServiceDefaultsImpl(
|
||||||
{ allowNonTsExtensions: true, target: ScriptTarget.Latest },
|
{ allowNonTsExtensions: true, target: ScriptTarget.Latest },
|
||||||
{ noSemanticValidation: false, noSyntaxValidation: false });
|
{ noSemanticValidation: false, noSyntaxValidation: false },
|
||||||
|
{});
|
||||||
|
|
||||||
const javascriptDefaults = new LanguageServiceDefaultsImpl(
|
const javascriptDefaults = new LanguageServiceDefaultsImpl(
|
||||||
{ allowNonTsExtensions: true, allowJs: true, target: ScriptTarget.Latest },
|
{ allowNonTsExtensions: true, allowJs: true, target: ScriptTarget.Latest },
|
||||||
{ noSemanticValidation: true, noSyntaxValidation: false });
|
{ noSemanticValidation: true, noSyntaxValidation: false },
|
||||||
|
{});
|
||||||
|
|
||||||
function getTypeScriptWorker(): Promise<(...uris: monaco.Uri[]) => Promise<monaco.languages.typescript.TypeScriptWorker>> {
|
function getTypeScriptWorker(): Promise<(...uris: monaco.Uri[]) => Promise<monaco.languages.typescript.TypeScriptWorker>> {
|
||||||
return getMode().then(mode => mode.getTypeScriptWorker());
|
return getMode().then(mode => mode.getTypeScriptWorker());
|
||||||
|
|
|
||||||
4
src/monaco.d.ts
vendored
4
src/monaco.d.ts
vendored
|
|
@ -137,6 +137,10 @@ declare module monaco.languages.typescript {
|
||||||
diagnosticCodesToIgnore?: number[];
|
diagnosticCodesToIgnore?: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface WorkerOptions {
|
||||||
|
customWorkerPath?: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface IExtraLib {
|
interface IExtraLib {
|
||||||
content: string;
|
content: string;
|
||||||
version: number;
|
version: number;
|
||||||
|
|
|
||||||
|
|
@ -238,8 +238,27 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, monaco.language
|
||||||
export interface ICreateData {
|
export interface ICreateData {
|
||||||
compilerOptions: ts.CompilerOptions;
|
compilerOptions: ts.CompilerOptions;
|
||||||
extraLibs: IExtraLibs;
|
extraLibs: IExtraLibs;
|
||||||
|
customWorkerPath?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function create(ctx: IWorkerContext, createData: ICreateData): TypeScriptWorker {
|
export function create(ctx: IWorkerContext, createData: ICreateData): TypeScriptWorker {
|
||||||
return new TypeScriptWorker(ctx, createData);
|
let TSWorkerClass = TypeScriptWorker
|
||||||
|
if (createData.customWorkerPath) {
|
||||||
|
|
||||||
|
// @ts-ignore - This is available in a webworker
|
||||||
|
if (typeof importScripts === "undefined") {
|
||||||
|
console.warn("Monaco is not using webworker workers, and that is needed to support the customWorkerPath flag")
|
||||||
|
} else {
|
||||||
|
// @ts-ignore - This is available in a webworker
|
||||||
|
importScripts(createData.customWorkerPath)
|
||||||
|
// @ts-ignore - This should come from
|
||||||
|
if(!self.extendTSWorkerFactory) {
|
||||||
|
throw new Error(`The script at ${createData.customWorkerPath} does not add extendTSWorkerFactory to self`)
|
||||||
|
}
|
||||||
|
// @ts-ignore - The throw validates this
|
||||||
|
TSWorkerClass = self.extendTSWorkerFactory(TypeScriptWorker)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TSWorkerClass(ctx, createData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,8 @@ export class WorkerManager {
|
||||||
// passed in to the create() method
|
// passed in to the create() method
|
||||||
createData: {
|
createData: {
|
||||||
compilerOptions: this._defaults.getCompilerOptions(),
|
compilerOptions: this._defaults.getCompilerOptions(),
|
||||||
extraLibs: this._defaults.getExtraLibs()
|
extraLibs: this._defaults.getExtraLibs(),
|
||||||
|
customWorkerPath: this._defaults.workerOptions.customWorkerPath
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
211
test/custom-worker.html
Normal file
211
test/custom-worker.html
Normal file
|
|
@ -0,0 +1,211 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||||
|
<link rel="stylesheet" data-name="vs/editor/editor.main" href="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h2>Monaco Editor TypeScript test page</h2>
|
||||||
|
<button id="resetBtn">Reset Sample</button>
|
||||||
|
<div id="container" style="width:800px;height:600px;border:1px solid grey"></div>
|
||||||
|
<h3>Compiler settings</h3>
|
||||||
|
<textarea style="font-family: monospace;" id="compilerOpts" cols="60" rows="30"></textarea><br/>
|
||||||
|
<button id="updateCompilerSettingsBtn">Update compiler settings</button>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var paths = {
|
||||||
|
'vs/basic-languages': '../node_modules/monaco-languages/release/dev',
|
||||||
|
'vs/language/typescript': '../release/dev',
|
||||||
|
'vs': '../node_modules/monaco-editor-core/dev/vs'
|
||||||
|
};
|
||||||
|
if (document.location.protocol === 'http:') {
|
||||||
|
// Add support for running local http server
|
||||||
|
let testIndex = document.location.pathname.indexOf('/test/');
|
||||||
|
if (testIndex !== -1) {
|
||||||
|
let prefix = document.location.pathname.substr(0, testIndex);
|
||||||
|
paths['vs/language/typescript'] = prefix + '/release/dev';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var require = {
|
||||||
|
paths: paths
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script src="../node_modules/monaco-editor-core/dev/vs/loader.js"></script>
|
||||||
|
<script src="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.nls.js"></script>
|
||||||
|
<script src="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function getDefaultCode() {
|
||||||
|
return [
|
||||||
|
'/* Game of Life',
|
||||||
|
' * Implemented in TypeScript',
|
||||||
|
' * To learn more about TypeScript, please visit http://www.typescriptlang.org/',
|
||||||
|
' */',
|
||||||
|
'',
|
||||||
|
'module Conway {',
|
||||||
|
'',
|
||||||
|
' export class Cell {',
|
||||||
|
' public row: number;',
|
||||||
|
' public col: number;',
|
||||||
|
' public live: boolean;',
|
||||||
|
'',
|
||||||
|
' constructor(row: number, col: number, live: boolean) {',
|
||||||
|
' this.row = row;',
|
||||||
|
' this.col = col;',
|
||||||
|
' this.live = live',
|
||||||
|
' }',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' export class GameOfLife {',
|
||||||
|
' private gridSize: number;',
|
||||||
|
' private canvasSize: number;',
|
||||||
|
' private lineColor: string;',
|
||||||
|
' private liveColor: string;',
|
||||||
|
' private deadColor: string;',
|
||||||
|
' private initialLifeProbability: number;',
|
||||||
|
' private animationRate: number;',
|
||||||
|
' private cellSize: number;',
|
||||||
|
' private context: CanvasRenderingContext2D;',
|
||||||
|
' private world;',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
' constructor() {',
|
||||||
|
' this.gridSize = 50;',
|
||||||
|
' this.canvasSize = 600;',
|
||||||
|
' this.lineColor = \'#cdcdcd\';',
|
||||||
|
' this.liveColor = \'#666\';',
|
||||||
|
' this.deadColor = \'#eee\';',
|
||||||
|
' this.initialLifeProbability = 0.5;',
|
||||||
|
' this.animationRate = 60;',
|
||||||
|
' this.cellSize = 0;',
|
||||||
|
' this.world = this.createWorld();',
|
||||||
|
' this.circleOfLife();',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' public createWorld() {',
|
||||||
|
' return this.travelWorld( (cell : Cell) => {',
|
||||||
|
' cell.live = Math.random() < this.initialLifeProbability;',
|
||||||
|
' return cell;',
|
||||||
|
' });',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' public circleOfLife() : void {',
|
||||||
|
' this.world = this.travelWorld( (cell: Cell) => {',
|
||||||
|
' cell = this.world[cell.row][cell.col];',
|
||||||
|
' this.draw(cell);',
|
||||||
|
' return this.resolveNextGeneration(cell);',
|
||||||
|
' });',
|
||||||
|
' setTimeout( () => {this.circleOfLife()}, this.animationRate);',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' public resolveNextGeneration(cell : Cell) {',
|
||||||
|
' var count = this.countNeighbors(cell);',
|
||||||
|
' var newCell = new Cell(cell.row, cell.col, cell.live);',
|
||||||
|
' if(count < 2 || count > 3) newCell.live = false;',
|
||||||
|
' else if(count == 3) newCell.live = true;',
|
||||||
|
' return newCell;',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' public countNeighbors(cell : Cell) {',
|
||||||
|
' var neighbors = 0;',
|
||||||
|
' for(var row = -1; row <=1; row++) {',
|
||||||
|
' for(var col = -1; col <= 1; col++) {',
|
||||||
|
' if(row == 0 && col == 0) continue;',
|
||||||
|
' if(this.isAlive(cell.row + row, cell.col + col)) {',
|
||||||
|
' neighbors++;',
|
||||||
|
' }',
|
||||||
|
' }',
|
||||||
|
' }',
|
||||||
|
' return neighbors;',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' public isAlive(row : number, col : number) {',
|
||||||
|
' if(row < 0 || col < 0 || row >= this.gridSize || col >= this.gridSize) return false;',
|
||||||
|
' return this.world[row][col].live;',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' public travelWorld(callback) {',
|
||||||
|
' var result = [];',
|
||||||
|
' for(var row = 0; row < this.gridSize; row++) {',
|
||||||
|
' var rowData = [];',
|
||||||
|
' for(var col = 0; col < this.gridSize; col++) {',
|
||||||
|
' rowData.push(callback(new Cell(row, col, false)));',
|
||||||
|
' }',
|
||||||
|
' result.push(rowData);',
|
||||||
|
' }',
|
||||||
|
' return result;',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' public draw(cell : Cell) {',
|
||||||
|
' if(this.context == null) this.context = this.createDrawingContext();',
|
||||||
|
' if(this.cellSize == 0) this.cellSize = this.canvasSize/this.gridSize;',
|
||||||
|
'',
|
||||||
|
' this.context.strokeStyle = this.lineColor;',
|
||||||
|
' this.context.strokeRect(cell.row * this.cellSize, cell.col*this.cellSize, this.cellSize, this.cellSize);',
|
||||||
|
' this.context.fillStyle = cell.live ? this.liveColor : this.deadColor;',
|
||||||
|
' this.context.fillRect(cell.row * this.cellSize, cell.col*this.cellSize, this.cellSize, this.cellSize);',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' public createDrawingContext() {',
|
||||||
|
' var canvas = <HTMLCanvasElement> document.getElementById(\'conway-canvas\');',
|
||||||
|
' if(canvas == null) {',
|
||||||
|
' canvas = document.createElement(\'canvas\');',
|
||||||
|
' canvas.id = \'conway-canvas\';',
|
||||||
|
' canvas.width = this.canvasSize;',
|
||||||
|
' canvas.height = this.canvasSize;',
|
||||||
|
' document.body.appendChild(canvas);',
|
||||||
|
' }',
|
||||||
|
' return canvas.getContext(\'2d\');',
|
||||||
|
' }',
|
||||||
|
' }',
|
||||||
|
'}',
|
||||||
|
'',
|
||||||
|
'var game = new Conway.GameOfLife();',
|
||||||
|
].join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefaultComplierOpts() {
|
||||||
|
return { target: 99, jsx: 1, allowNonTsExtensions: true }
|
||||||
|
}
|
||||||
|
require([
|
||||||
|
'vs/basic-languages/monaco.contribution',
|
||||||
|
'vs/language/typescript/monaco.contribution'
|
||||||
|
], () => {
|
||||||
|
|
||||||
|
|
||||||
|
var editor = monaco.editor.create(document.getElementById('container'), {
|
||||||
|
value: localStorage.getItem("code") || getDefaultCode(),
|
||||||
|
language: 'typescript',
|
||||||
|
lightbulb: { enabled: true }
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("OK")
|
||||||
|
|
||||||
|
|
||||||
|
editor.onDidChangeModelContent(() => {
|
||||||
|
const code = editor.getModel().getValue()
|
||||||
|
localStorage.setItem("code", code)
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('resetBtn').onclick = () => {
|
||||||
|
editor.setValue(getDefaultCode());
|
||||||
|
monaco.languages.typescript.typescriptDefaults.setWorkerOptions({ customWorkerPath: "http://localhost:5000/test/custom-worker.js" })
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const optsString = localStorage.getItem("compiler-opts") || JSON.stringify(getDefaultComplierOpts(), null, 4)
|
||||||
|
document.getElementById("compilerOpts").textContent = optsString
|
||||||
|
monaco.languages.typescript.typescriptDefaults.setCompilerOptions(JSON.parse(optsString))
|
||||||
|
|
||||||
|
document.getElementById('updateCompilerSettingsBtn').onclick = () => {
|
||||||
|
const newOpts = document.getElementById('compilerOpts').value
|
||||||
|
monaco.languages.typescript.typescriptDefaults.setCompilerOptions(JSON.parse(newOpts))
|
||||||
|
localStorage.setItem("compiler-opts", newOpts)
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
9
test/custom-worker.js
Normal file
9
test/custom-worker.js
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
/// <reference lib="webworker">
|
||||||
|
|
||||||
|
console.log("worker")
|
||||||
|
|
||||||
|
self.extendTSWorkerFactory = (TypeScriptWorker) => {
|
||||||
|
return class MonacoTSWorker extends TypeScriptWorker {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue