diff --git a/.gitignore b/.gitignore index 3506c9929f5ae..ccf4cca05f539 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ node_modules/ out/ out-build/ out-editor/ +out-editor-esm/ out-editor-min/ out-monaco-editor-core/ out-vscode/ diff --git a/build/gulpfile.editor.js b/build/gulpfile.editor.js index 4fde19e669a8b..eef69c410e2a2 100644 --- a/build/gulpfile.editor.js +++ b/build/gulpfile.editor.js @@ -3,12 +3,15 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -var gulp = require('gulp'); -var path = require('path'); -var util = require('./lib/util'); -var common = require('./lib/optimize'); -var es = require('event-stream'); -var File = require('vinyl'); +const gulp = require('gulp'); +const path = require('path'); +const util = require('./lib/util'); +const common = require('./lib/optimize'); +const es = require('event-stream'); +const File = require('vinyl'); +const i18n = require('./lib/i18n'); +const standalone = require('./lib/standalone'); +const cp = require('child_process'); var root = path.dirname(__dirname); var sha1 = util.getVersion(root); @@ -71,6 +74,8 @@ function editorLoaderConfig() { return result; } +const languages = i18n.defaultLanguages.concat([]); // i18n.defaultLanguages.concat(process.env.VSCODE_QUALITY !== 'stable' ? i18n.extraLanguages : []); + gulp.task('clean-optimized-editor', util.rimraf('out-editor')); gulp.task('optimize-editor', ['clean-optimized-editor', 'compile-client-build'], common.optimizeTask({ entryPoints: editorEntryPoints, @@ -81,14 +86,36 @@ gulp.task('optimize-editor', ['clean-optimized-editor', 'compile-client-build'], header: BUNDLED_FILE_HEADER, bundleInfo: true, out: 'out-editor', - languages: undefined + languages: languages })); gulp.task('clean-minified-editor', util.rimraf('out-editor-min')); gulp.task('minify-editor', ['clean-minified-editor', 'optimize-editor'], common.minifyTask('out-editor')); +gulp.task('clean-editor-esm', util.rimraf('out-editor-esm')); +gulp.task('extract-editor-esm', ['clean-editor-esm'], function() { + standalone.createESMSourcesAndResources({ + entryPoints: [ + 'vs/editor/editor.main', + 'vs/editor/editor.worker' + ], + outFolder: './out-editor-esm/src', + outResourcesFolder: './out-monaco-editor-core/esm', + redirects: { + 'vs/base/browser/ui/octiconLabel/octiconLabel': 'vs/base/browser/ui/octiconLabel/octiconLabel.mock', + 'vs/nls': 'vs/nls.mock', + } + }); +}); +gulp.task('compile-editor-esm', ['extract-editor-esm', 'clean-editor-distro'], function() { + const result = cp.spawnSync(`node`, [`../node_modules/.bin/tsc`], { + cwd: path.join(__dirname, '../out-editor-esm') + }); + console.log(result.stdout.toString()); +}); + gulp.task('clean-editor-distro', util.rimraf('out-monaco-editor-core')); -gulp.task('editor-distro', ['clean-editor-distro', 'minify-editor', 'optimize-editor'], function () { +gulp.task('editor-distro', ['clean-editor-distro', 'compile-editor-esm', 'minify-editor', 'optimize-editor'], function () { return es.merge( // other assets es.merge( diff --git a/build/lib/standalone.js b/build/lib/standalone.js new file mode 100644 index 0000000000000..d0cb2c8c0c38b --- /dev/null +++ b/build/lib/standalone.js @@ -0,0 +1,274 @@ +"use strict"; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +var ts = require("typescript"); +var fs = require("fs"); +var path = require("path"); +var REPO_ROOT = path.join(__dirname, '../../'); +var SRC_DIR = path.join(REPO_ROOT, 'src'); +var OUT_EDITOR = path.join(REPO_ROOT, 'out-editor'); +function createESMSourcesAndResources(options) { + var OUT_FOLDER = path.join(REPO_ROOT, options.outFolder); + var OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder); + var in_queue = Object.create(null); + var queue = []; + var enqueue = function (module) { + if (in_queue[module]) { + return; + } + in_queue[module] = true; + queue.push(module); + }; + var seenDir = {}; + var createDirectoryRecursive = function (dir) { + if (seenDir[dir]) { + return; + } + var lastSlash = dir.lastIndexOf('/'); + if (lastSlash === -1) { + lastSlash = dir.lastIndexOf('\\'); + } + if (lastSlash !== -1) { + createDirectoryRecursive(dir.substring(0, lastSlash)); + } + seenDir[dir] = true; + try { + fs.mkdirSync(dir); + } + catch (err) { } + }; + seenDir[REPO_ROOT] = true; + var toggleComments = function (fileContents) { + var lines = fileContents.split(/\r\n|\r|\n/); + var mode = 0; + for (var i = 0; i < lines.length; i++) { + var line = lines[i]; + if (mode === 0) { + if (/\/\/ ESM-comment-begin/.test(line)) { + mode = 1; + continue; + } + if (/\/\/ ESM-uncomment-begin/.test(line)) { + mode = 2; + continue; + } + continue; + } + if (mode === 1) { + if (/\/\/ ESM-comment-end/.test(line)) { + mode = 0; + continue; + } + lines[i] = '// ' + line; + continue; + } + if (mode === 2) { + if (/\/\/ ESM-uncomment-end/.test(line)) { + mode = 0; + continue; + } + lines[i] = line.replace(/^(\s*)\/\/ ?/, function (_, indent) { + return indent; + }); + } + } + return lines.join('\n'); + }; + var write = function (filePath, contents) { + var absoluteFilePath; + if (/\.ts$/.test(filePath)) { + absoluteFilePath = path.join(OUT_FOLDER, filePath); + } + else { + absoluteFilePath = path.join(OUT_RESOURCES_FOLDER, filePath); + } + createDirectoryRecursive(path.dirname(absoluteFilePath)); + if (/(\.ts$)|(\.js$)/.test(filePath)) { + contents = toggleComments(contents.toString()); + } + fs.writeFileSync(absoluteFilePath, contents); + }; + options.entryPoints.forEach(function (entryPoint) { return enqueue(entryPoint); }); + while (queue.length > 0) { + var module_1 = queue.shift(); + if (transportCSS(options, module_1, enqueue, write)) { + continue; + } + if (transportResource(options, module_1, enqueue, write)) { + continue; + } + if (transportDTS(options, module_1, enqueue, write)) { + continue; + } + var filename = void 0; + if (options.redirects[module_1]) { + filename = path.join(SRC_DIR, options.redirects[module_1] + '.ts'); + } + else { + filename = path.join(SRC_DIR, module_1 + '.ts'); + } + var fileContents = fs.readFileSync(filename).toString(); + var info = ts.preProcessFile(fileContents); + if (info.isLibFile) { + console.log("1. oh no, what does this mean!!!"); + } + if (info.typeReferenceDirectives.length > 0) { + console.log("2. oh no, what does this mean!!!"); + } + if (info.referencedFiles.length > 0) { + console.log("3. oh no, what does this mean!!!"); + } + for (var i = info.importedFiles.length - 1; i >= 0; i--) { + var importedFilename = info.importedFiles[i].fileName; + var pos = info.importedFiles[i].pos; + var end = info.importedFiles[i].end; + var importedFilepath = void 0; + if (/^vs\/css!/.test(importedFilename)) { + importedFilepath = importedFilename.substr('vs/css!'.length) + '.css'; + } + else { + importedFilepath = importedFilename; + } + if (/(^\.\/)|(^\.\.\/)/.test(importedFilepath)) { + importedFilepath = path.join(path.dirname(module_1), importedFilepath); + } + enqueue(importedFilepath); + var relativePath = void 0; + if (importedFilepath === path.dirname(module_1)) { + relativePath = '../' + path.basename(path.dirname(module_1)); + } + else if (importedFilepath === path.dirname(path.dirname(module_1))) { + relativePath = '../../' + path.basename(path.dirname(path.dirname(module_1))); + } + else { + relativePath = path.relative(path.dirname(module_1), importedFilepath); + } + if (!/(^\.\/)|(^\.\.\/)/.test(relativePath)) { + relativePath = './' + relativePath; + } + fileContents = (fileContents.substring(0, pos + 1) + + relativePath + + fileContents.substring(end + 1)); + } + fileContents = fileContents.replace(/import ([a-zA-z0-9]+) = require\(('[^']+')\);/g, function (_, m1, m2) { + return "import * as " + m1 + " from " + m2 + ";"; + }); + fileContents = fileContents.replace(/Thenable/g, 'PromiseLike'); + write(module_1 + '.ts', fileContents); + } + var esm_opts = { + "compilerOptions": { + "outDir": path.relative(path.dirname(OUT_FOLDER), OUT_RESOURCES_FOLDER), + "rootDir": "src", + "module": "es6", + "target": "es5", + "experimentalDecorators": true, + "lib": [ + "dom", + "es5", + "es2015.collection", + "es2015.promise" + ], + "types": [] + } + }; + fs.writeFileSync(path.join(path.dirname(OUT_FOLDER), 'tsconfig.json'), JSON.stringify(esm_opts, null, '\t')); + var monacodts = fs.readFileSync(path.join(SRC_DIR, 'vs/monaco.d.ts')).toString(); + fs.writeFileSync(path.join(OUT_FOLDER, 'vs/monaco.d.ts'), monacodts); +} +exports.createESMSourcesAndResources = createESMSourcesAndResources; +function transportCSS(options, module, enqueue, write) { + if (!/\.css/.test(module)) { + return false; + } + var filename = path.join(SRC_DIR, module); + var fileContents = fs.readFileSync(filename).toString(); + var inlineResources = 'base64'; // see https://github.com/Microsoft/monaco-editor/issues/148 + var inlineResourcesLimit = 300000; //3000; // see https://github.com/Microsoft/monaco-editor/issues/336 + var newContents = _rewriteOrInlineUrls(filename, fileContents, inlineResources === 'base64', inlineResourcesLimit); + write(module, newContents); + return true; + function _rewriteOrInlineUrls(originalFileFSPath, contents, forceBase64, inlineByteLimit) { + return _replaceURL(contents, function (url) { + var imagePath = path.join(path.dirname(module), url); + var fileContents = fs.readFileSync(path.join(SRC_DIR, imagePath)); + if (fileContents.length < inlineByteLimit) { + var MIME = /\.svg$/.test(url) ? 'image/svg+xml' : 'image/png'; + var DATA = ';base64,' + fileContents.toString('base64'); + if (!forceBase64 && /\.svg$/.test(url)) { + // .svg => url encode as explained at https://codepen.io/tigt/post/optimizing-svgs-in-data-uris + var newText = fileContents.toString() + .replace(/"/g, '\'') + .replace(//g, '%3E') + .replace(/&/g, '%26') + .replace(/#/g, '%23') + .replace(/\s+/g, ' '); + var encodedData = ',' + newText; + if (encodedData.length < DATA.length) { + DATA = encodedData; + } + } + return '"data:' + MIME + DATA + '"'; + } + enqueue(imagePath); + return url; + }); + } + function _replaceURL(contents, replacer) { + // Use ")" as the terminator as quotes are oftentimes not used at all + return contents.replace(/url\(\s*([^\)]+)\s*\)?/g, function (_) { + var matches = []; + for (var _i = 1; _i < arguments.length; _i++) { + matches[_i - 1] = arguments[_i]; + } + var url = matches[0]; + // Eliminate starting quotes (the initial whitespace is not captured) + if (url.charAt(0) === '"' || url.charAt(0) === '\'') { + url = url.substring(1); + } + // The ending whitespace is captured + while (url.length > 0 && (url.charAt(url.length - 1) === ' ' || url.charAt(url.length - 1) === '\t')) { + url = url.substring(0, url.length - 1); + } + // Eliminate ending quotes + if (url.charAt(url.length - 1) === '"' || url.charAt(url.length - 1) === '\'') { + url = url.substring(0, url.length - 1); + } + if (!_startsWith(url, 'data:') && !_startsWith(url, 'http://') && !_startsWith(url, 'https://')) { + url = replacer(url); + } + return 'url(' + url + ')'; + }); + } + function _startsWith(haystack, needle) { + return haystack.length >= needle.length && haystack.substr(0, needle.length) === needle; + } +} +function transportResource(options, module, enqueue, write) { + if (!/\.svg/.test(module)) { + return false; + } + write(module, fs.readFileSync(path.join(SRC_DIR, module))); + return true; +} +function transportDTS(options, module, enqueue, write) { + if (options.redirects[module] && fs.existsSync(path.join(SRC_DIR, options.redirects[module] + '.ts'))) { + return false; + } + if (!fs.existsSync(path.join(SRC_DIR, module + '.d.ts'))) { + return false; + } + write(module + '.d.ts', fs.readFileSync(path.join(SRC_DIR, module + '.d.ts'))); + var filename; + if (options.redirects[module]) { + write(module + '.js', fs.readFileSync(path.join(SRC_DIR, options.redirects[module] + '.js'))); + } + else { + write(module + '.js', fs.readFileSync(path.join(SRC_DIR, module + '.js'))); + } + return true; +} diff --git a/build/lib/standalone.ts b/build/lib/standalone.ts new file mode 100644 index 0000000000000..256c309175209 --- /dev/null +++ b/build/lib/standalone.ts @@ -0,0 +1,314 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as ts from 'typescript'; +import * as fs from 'fs'; +import * as path from 'path'; + +const REPO_ROOT = path.join(__dirname, '../../'); +const SRC_DIR = path.join(REPO_ROOT, 'src'); +const OUT_EDITOR = path.join(REPO_ROOT, 'out-editor'); + +export interface IOptions { + entryPoints: string[]; + outFolder: string; + outResourcesFolder: string; + redirects: { [module: string]: string; }; +} + +export function createESMSourcesAndResources(options: IOptions): void { + const OUT_FOLDER = path.join(REPO_ROOT, options.outFolder); + const OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder); + + let in_queue: { [module: string]: boolean; } = Object.create(null); + let queue: string[] = []; + + const enqueue = (module: string) => { + if (in_queue[module]) { + return; + } + in_queue[module] = true; + queue.push(module); + }; + + const seenDir: { [key: string]: boolean; } = {}; + const createDirectoryRecursive = (dir: string) => { + if (seenDir[dir]) { + return; + } + + let lastSlash = dir.lastIndexOf('/'); + if (lastSlash === -1) { + lastSlash = dir.lastIndexOf('\\'); + } + if (lastSlash !== -1) { + createDirectoryRecursive(dir.substring(0, lastSlash)); + } + seenDir[dir] = true; + try { fs.mkdirSync(dir); } catch (err) { } + }; + + seenDir[REPO_ROOT] = true; + + const toggleComments = (fileContents: string) => { + let lines = fileContents.split(/\r\n|\r|\n/); + let mode = 0; + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + + if (mode === 0) { + if (/\/\/ ESM-comment-begin/.test(line)) { + mode = 1; + continue; + } + if (/\/\/ ESM-uncomment-begin/.test(line)) { + mode = 2; + continue; + } + continue; + } + + if (mode === 1) { + if (/\/\/ ESM-comment-end/.test(line)) { + mode = 0; + continue; + } + lines[i] = '// ' + line; + continue; + } + + if (mode === 2) { + if (/\/\/ ESM-uncomment-end/.test(line)) { + mode = 0; + continue; + } + lines[i] = line.replace(/^(\s*)\/\/ ?/, function (_, indent) { + return indent; + }); + } + } + + return lines.join('\n'); + }; + + const write = (filePath: string, contents: string | Buffer) => { + let absoluteFilePath: string; + if (/\.ts$/.test(filePath)) { + absoluteFilePath = path.join(OUT_FOLDER, filePath); + } else { + absoluteFilePath = path.join(OUT_RESOURCES_FOLDER, filePath); + } + createDirectoryRecursive(path.dirname(absoluteFilePath)); + if (/(\.ts$)|(\.js$)/.test(filePath)) { + contents = toggleComments(contents.toString()); + } + fs.writeFileSync(absoluteFilePath, contents); + }; + + options.entryPoints.forEach((entryPoint) => enqueue(entryPoint)); + + while (queue.length > 0) { + const module = queue.shift(); + if (transportCSS(options, module, enqueue, write)) { + continue; + } + if (transportResource(options, module, enqueue, write)) { + continue; + } + if (transportDTS(options, module, enqueue, write)) { + continue; + } + + let filename: string; + if (options.redirects[module]) { + filename = path.join(SRC_DIR, options.redirects[module] + '.ts'); + } else { + filename = path.join(SRC_DIR, module + '.ts'); + } + let fileContents = fs.readFileSync(filename).toString(); + + const info = ts.preProcessFile(fileContents); + if (info.isLibFile) { + console.log(`1. oh no, what does this mean!!!`); + } + if (info.typeReferenceDirectives.length > 0) { + console.log(`2. oh no, what does this mean!!!`); + } + if (info.referencedFiles.length > 0) { + console.log(`3. oh no, what does this mean!!!`); + } + + for (let i = info.importedFiles.length - 1; i >= 0; i--) { + const importedFilename = info.importedFiles[i].fileName; + const pos = info.importedFiles[i].pos; + const end = info.importedFiles[i].end; + + let importedFilepath: string; + if (/^vs\/css!/.test(importedFilename)) { + importedFilepath = importedFilename.substr('vs/css!'.length) + '.css'; + } else { + importedFilepath = importedFilename; + } + if (/(^\.\/)|(^\.\.\/)/.test(importedFilepath)) { + importedFilepath = path.join(path.dirname(module), importedFilepath); + } + + enqueue(importedFilepath); + + let relativePath: string; + if (importedFilepath === path.dirname(module)) { + relativePath = '../' + path.basename(path.dirname(module)); + } else if (importedFilepath === path.dirname(path.dirname(module))) { + relativePath = '../../' + path.basename(path.dirname(path.dirname(module))); + } else { + relativePath = path.relative(path.dirname(module), importedFilepath); + } + if (!/(^\.\/)|(^\.\.\/)/.test(relativePath)) { + relativePath = './' + relativePath; + } + fileContents = ( + fileContents.substring(0, pos + 1) + + relativePath + + fileContents.substring(end + 1) + ); + } + + fileContents = fileContents.replace(/import ([a-zA-z0-9]+) = require\(('[^']+')\);/g, function (_, m1, m2) { + return `import * as ${m1} from ${m2};`; + }); + fileContents = fileContents.replace(/Thenable/g, 'PromiseLike'); + + write(module + '.ts', fileContents); + } + + const esm_opts = { + "compilerOptions": { + "outDir": path.relative(path.dirname(OUT_FOLDER), OUT_RESOURCES_FOLDER), + "rootDir": "src", + "module": "es6", + "target": "es5", + "experimentalDecorators": true, + "lib": [ + "dom", + "es5", + "es2015.collection", + "es2015.promise" + ], + "types": [ + ] + } + }; + fs.writeFileSync(path.join(path.dirname(OUT_FOLDER), 'tsconfig.json'), JSON.stringify(esm_opts, null, '\t')); + + const monacodts = fs.readFileSync(path.join(SRC_DIR, 'vs/monaco.d.ts')).toString(); + fs.writeFileSync(path.join(OUT_FOLDER, 'vs/monaco.d.ts'), monacodts); + +} + +function transportCSS(options: IOptions, module: string, enqueue: (module: string) => void, write: (path: string, contents: string | Buffer) => void): boolean { + + if (!/\.css/.test(module)) { + return false; + } + + const filename = path.join(SRC_DIR, module); + const fileContents = fs.readFileSync(filename).toString(); + const inlineResources = 'base64'; // see https://github.com/Microsoft/monaco-editor/issues/148 + const inlineResourcesLimit = 300000;//3000; // see https://github.com/Microsoft/monaco-editor/issues/336 + + const newContents = _rewriteOrInlineUrls(filename, fileContents, inlineResources === 'base64', inlineResourcesLimit); + write(module, newContents); + return true; + + function _rewriteOrInlineUrls(originalFileFSPath: string, contents: string, forceBase64: boolean, inlineByteLimit: number): string { + return _replaceURL(contents, (url) => { + let imagePath = path.join(path.dirname(module), url); + let fileContents = fs.readFileSync(path.join(SRC_DIR, imagePath)); + + if (fileContents.length < inlineByteLimit) { + const MIME = /\.svg$/.test(url) ? 'image/svg+xml' : 'image/png'; + let DATA = ';base64,' + fileContents.toString('base64'); + + if (!forceBase64 && /\.svg$/.test(url)) { + // .svg => url encode as explained at https://codepen.io/tigt/post/optimizing-svgs-in-data-uris + let newText = fileContents.toString() + .replace(/"/g, '\'') + .replace(//g, '%3E') + .replace(/&/g, '%26') + .replace(/#/g, '%23') + .replace(/\s+/g, ' '); + let encodedData = ',' + newText; + if (encodedData.length < DATA.length) { + DATA = encodedData; + } + } + return '"data:' + MIME + DATA + '"'; + } + + enqueue(imagePath); + return url; + }); + } + + function _replaceURL(contents: string, replacer: (url: string) => string): string { + // Use ")" as the terminator as quotes are oftentimes not used at all + return contents.replace(/url\(\s*([^\)]+)\s*\)?/g, (_: string, ...matches: string[]) => { + var url = matches[0]; + // Eliminate starting quotes (the initial whitespace is not captured) + if (url.charAt(0) === '"' || url.charAt(0) === '\'') { + url = url.substring(1); + } + // The ending whitespace is captured + while (url.length > 0 && (url.charAt(url.length - 1) === ' ' || url.charAt(url.length - 1) === '\t')) { + url = url.substring(0, url.length - 1); + } + // Eliminate ending quotes + if (url.charAt(url.length - 1) === '"' || url.charAt(url.length - 1) === '\'') { + url = url.substring(0, url.length - 1); + } + + if (!_startsWith(url, 'data:') && !_startsWith(url, 'http://') && !_startsWith(url, 'https://')) { + url = replacer(url); + } + + return 'url(' + url + ')'; + }); + } + + function _startsWith(haystack: string, needle: string): boolean { + return haystack.length >= needle.length && haystack.substr(0, needle.length) === needle; + } +} + +function transportResource(options: IOptions, module: string, enqueue: (module: string) => void, write: (path: string, contents: string | Buffer) => void): boolean { + + if (!/\.svg/.test(module)) { + return false; + } + + write(module, fs.readFileSync(path.join(SRC_DIR, module))); + return true; +} + +function transportDTS(options: IOptions, module: string, enqueue: (module: string) => void, write: (path: string, contents: string | Buffer) => void): boolean { + + if (options.redirects[module] && fs.existsSync(path.join(SRC_DIR, options.redirects[module] + '.ts'))) { + return false; + } + + if (!fs.existsSync(path.join(SRC_DIR, module + '.d.ts'))) { + return false; + } + + write(module + '.d.ts', fs.readFileSync(path.join(SRC_DIR, module + '.d.ts'))); + let filename: string; + if (options.redirects[module]) { + write(module + '.js', fs.readFileSync(path.join(SRC_DIR, options.redirects[module] + '.js'))); + } else { + write(module + '.js', fs.readFileSync(path.join(SRC_DIR, module + '.js'))); + } + return true; +} diff --git a/src/vs/base/common/marked/marked.js b/src/vs/base/common/marked/marked.js index 65d0d78654ad8..11d29ced08053 100644 --- a/src/vs/base/common/marked/marked.js +++ b/src/vs/base/common/marked/marked.js @@ -4,9 +4,9 @@ * https://github.com/chjj/marked */ -// TODO MonacoChange: we have our own way of defining modules -// ;(function() { -// END MonacoChange +var __marked_exports; + +(function() { /** * Block-Level Grammar @@ -1370,21 +1370,27 @@ marked.inlineLexer = InlineLexer.output; marked.parse = marked; -// TODO MonacoChange: we have our own way of defining modules +__marked_exports = marked; + +}).call(this); + +// ESM-comment-begin define([], function() { return { - marked: marked + marked: __marked_exports }; }); -//if (typeof module !== 'undefined' && typeof exports === 'object') { -// module.exports = marked; -//} else if (typeof define === 'function' && define.amd) { -// define(function() { return marked; }); -//} else { -// this.marked = marked; -//} -// -//}).call(function() { -// return this || (typeof window !== 'undefined' ? window : global); -//}()); -// END MonacoChange \ No newline at end of file +// ESM-comment-end + +// ESM-uncomment-begin +// export var marked = __marked_exports; +// export var Parser = __marked_exports.Parser; +// export var parser = __marked_exports.parser; +// export var Renderer = __marked_exports.Renderer; +// export var TextRenderer = __marked_exports.TextRenderer; +// export var Lexer = __marked_exports.Lexer; +// export var lexer = __marked_exports.lexer; +// export var InlineLexer = __marked_exports.InlineLexer; +// export var inlineLexer = __marked_exports.inlineLexer; +// export var parse = __marked_exports.parse; +// ESM-uncomment-end diff --git a/src/vs/base/common/platform.ts b/src/vs/base/common/platform.ts index 135f2ac07840f..4e98c088bc9e3 100644 --- a/src/vs/base/common/platform.ts +++ b/src/vs/base/common/platform.ts @@ -42,7 +42,7 @@ declare let self: any; export const LANGUAGE_DEFAULT = 'en'; // OS detection -if (typeof process === 'object' && typeof process.nextTick === 'function') { +if (typeof process === 'object' && typeof process.nextTick === 'function' && typeof process.platform === 'string') { _isWindows = (process.platform === 'win32'); _isMacintosh = (process.platform === 'darwin'); _isLinux = (process.platform === 'linux'); diff --git a/src/vs/base/common/winjs.base.js b/src/vs/base/common/winjs.base.js index 5c6b714bfcb64..49debfc70456a 100644 --- a/src/vs/base/common/winjs.base.js +++ b/src/vs/base/common/winjs.base.js @@ -5,6 +5,8 @@ * All Rights Reserved. * Licensed under the MIT License. */ +var __winjs_exports; + (function() { var _modules = Object.create(null);//{}; @@ -2067,14 +2069,22 @@ _winjs("WinJS/Promise", ["WinJS/Core/_Base","WinJS/Promise/_StateMachine"], func return _StateMachine.Promise; }); -var exported = _modules["WinJS/Core/_WinJS"]; -exported.TPromise = exported.Promise; -exported.PPromise = exported.Promise; +__winjs_exports = _modules["WinJS/Core/_WinJS"]; +__winjs_exports.TPromise = __winjs_exports.Promise; +__winjs_exports.PPromise = __winjs_exports.Promise; +// ESM-comment-begin if (typeof exports === 'undefined' && typeof define === 'function' && define.amd) { - define([], exported); + define([], __winjs_exports); } else { - module.exports = exported; + module.exports = __winjs_exports; } +// ESM-comment-end + +})(); -})(); \ No newline at end of file +// ESM-uncomment-begin +// export var Promise = __winjs_exports.Promise; +// export var TPromise = __winjs_exports.TPromise; +// export var PPromise = __winjs_exports.PPromise; +// ESM-uncomment-end diff --git a/src/vs/base/common/worker/simpleWorker.ts b/src/vs/base/common/worker/simpleWorker.ts index e7ea8490a75b6..0099aac4956a1 100644 --- a/src/vs/base/common/worker/simpleWorker.ts +++ b/src/vs/base/common/worker/simpleWorker.ts @@ -224,10 +224,9 @@ export class SimpleWorkerClient extends Disposable { // Gather loader configuration let loaderConfiguration: any = null; - let globalRequire = (self).require; - if (typeof globalRequire.getConfig === 'function') { + if (typeof (self).require !== 'undefined' && typeof (self).require.getConfig === 'function') { // Get the configuration from the Monaco AMD Loader - loaderConfiguration = globalRequire.getConfig(); + loaderConfiguration = (self).require.getConfig(); } else if (typeof (self).requirejs !== 'undefined') { // Get the configuration from requirejs loaderConfiguration = (self).requirejs.s.contexts._.config; @@ -298,10 +297,11 @@ export interface IRequestHandler { */ export class SimpleWorkerServer { - private _protocol: SimpleWorkerProtocol; private _requestHandler: IRequestHandler; + private _protocol: SimpleWorkerProtocol; - constructor(postSerializedMessage: (msg: string) => void) { + constructor(postSerializedMessage: (msg: string) => void, requestHandler: IRequestHandler) { + this._requestHandler = requestHandler; this._protocol = new SimpleWorkerProtocol({ sendMessage: (msg: string): void => { postSerializedMessage(msg); @@ -333,6 +333,17 @@ export class SimpleWorkerServer { private initialize(workerId: number, moduleId: string, loaderConfig: any): TPromise { this._protocol.setWorkerId(workerId); + if (this._requestHandler) { + // static request handler + let methods: string[] = []; + for (let prop in this._requestHandler) { + if (typeof this._requestHandler[prop] === 'function') { + methods.push(prop); + } + } + return TPromise.as(methods); + } + if (loaderConfig) { // Remove 'baseUrl', handling it is beyond scope for now if (typeof loaderConfig.baseUrl !== 'undefined') { @@ -379,5 +390,5 @@ export class SimpleWorkerServer { * Called on the worker side */ export function create(postMessage: (msg: string) => void): SimpleWorkerServer { - return new SimpleWorkerServer(postMessage); + return new SimpleWorkerServer(postMessage, null); } diff --git a/src/vs/base/worker/defaultWorkerFactory.ts b/src/vs/base/worker/defaultWorkerFactory.ts index 52bca4b7a0532..344588ad9efb7 100644 --- a/src/vs/base/worker/defaultWorkerFactory.ts +++ b/src/vs/base/worker/defaultWorkerFactory.ts @@ -7,21 +7,18 @@ import { globals } from 'vs/base/common/platform'; import { logOnceWebWorkerWarning, IWorker, IWorkerCallback, IWorkerFactory } from 'vs/base/common/worker/simpleWorker'; -// Option for hosts to overwrite the worker script url (used in the standalone editor) -const getCrossOriginWorkerScriptUrl: (workerId: string, label: string) => string = environment('getWorkerUrl', null); - -function environment(name: string, fallback: any = false): any { - if (globals.MonacoEnvironment && globals.MonacoEnvironment.hasOwnProperty(name)) { - return globals.MonacoEnvironment[name]; +function getWorkerUrl(workerId: string, label: string): string { + // Option for hosts to overwrite the worker script url (used in the standalone editor) + if (globals.MonacoEnvironment && typeof globals.MonacoEnvironment.getWorkerUrl === 'function') { + return globals.MonacoEnvironment.getWorkerUrl(workerId, label); } - - return fallback; -} - -function defaultGetWorkerUrl(workerId: string, label: string): string { - return require.toUrl('./' + workerId) + '#' + label; + // ESM-comment-begin + if (typeof require === 'function') { + return require.toUrl('./' + workerId) + '#' + label; + } + // ESM-comment-end + throw new Error(`You must define a function MonacoEnvironment.getWorkerUrl`); } -var getWorkerUrl = getCrossOriginWorkerScriptUrl || defaultGetWorkerUrl; /** * A worker that uses HTML5 web workers so that is has diff --git a/src/vs/editor/common/services/editorSimpleWorker.ts b/src/vs/editor/common/services/editorSimpleWorker.ts index cd669a4a94b4e..846a4fbf5674d 100644 --- a/src/vs/editor/common/services/editorSimpleWorker.ts +++ b/src/vs/editor/common/services/editorSimpleWorker.ts @@ -294,8 +294,8 @@ class MirrorModel extends BaseMirrorModel implements ICommonModel { export abstract class BaseEditorSimpleWorker { private _foreignModule: any; - constructor() { - this._foreignModule = null; + constructor(foreignModule: any) { + this._foreignModule = foreignModule; } protected abstract _getModel(uri: string): ICommonModel; @@ -474,6 +474,16 @@ export abstract class BaseEditorSimpleWorker { // ---- BEGIN foreign module support -------------------------------------------------------------------------- public loadForeignModule(moduleId: string, createData: any): TPromise { + if (this._foreignModule) { + // static foreing module + let methods: string[] = []; + for (let prop in this._foreignModule) { + if (typeof this._foreignModule[prop] === 'function') { + methods.push(prop); + } + } + return TPromise.as(methods); + } return new TPromise((c, e) => { // Use the global require to be sure to get the global config (self).require([moduleId], (foreignModule: { create: (ctx: IWorkerContext, createData: any) => any; }) => { @@ -521,8 +531,8 @@ export class EditorSimpleWorkerImpl extends BaseEditorSimpleWorker implements IR private _models: { [uri: string]: MirrorModel; }; - constructor() { - super(); + constructor(foreignModule: any) { + super(foreignModule); this._models = Object.create(null); } @@ -565,7 +575,7 @@ export class EditorSimpleWorkerImpl extends BaseEditorSimpleWorker implements IR * @internal */ export function create(): IRequestHandler { - return new EditorSimpleWorkerImpl(); + return new EditorSimpleWorkerImpl(null); } if (typeof importScripts === 'function') { diff --git a/src/vs/editor/common/services/editorWorkerServiceImpl.ts b/src/vs/editor/common/services/editorWorkerServiceImpl.ts index 1c84e72264659..86885e233fcc8 100644 --- a/src/vs/editor/common/services/editorWorkerServiceImpl.ts +++ b/src/vs/editor/common/services/editorWorkerServiceImpl.ts @@ -351,7 +351,7 @@ export class EditorWorkerClient extends Disposable { )); } catch (err) { logOnceWebWorkerWarning(err); - this._worker = new SynchronousWorkerClient(new EditorSimpleWorkerImpl()); + this._worker = new SynchronousWorkerClient(new EditorSimpleWorkerImpl(null)); } } return this._worker; @@ -360,7 +360,7 @@ export class EditorWorkerClient extends Disposable { protected _getProxy(): TPromise { return new ShallowCancelThenPromise(this._getOrCreateWorker().getProxyObject().then(null, (err) => { logOnceWebWorkerWarning(err); - this._worker = new SynchronousWorkerClient(new EditorSimpleWorkerImpl()); + this._worker = new SynchronousWorkerClient(new EditorSimpleWorkerImpl(null)); return this._getOrCreateWorker().getProxyObject(); })); } diff --git a/src/vs/editor/editor.worker.ts b/src/vs/editor/editor.worker.ts new file mode 100644 index 0000000000000..61d8c36aea147 --- /dev/null +++ b/src/vs/editor/editor.worker.ts @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { EditorSimpleWorkerImpl } from 'vs/editor/common/services/editorSimpleWorker'; +import { SimpleWorkerServer } from 'vs/base/common/worker/simpleWorker'; + +let initialized = false; + +export function initialize(foreignModule: any) { + if (initialized) { + return; + } + initialized = true; + + const editorWorker = new EditorSimpleWorkerImpl(foreignModule); + const simpleWorker = new SimpleWorkerServer((msg) => { + (self).postMessage(msg); + }, editorWorker); + + self.onmessage = (e) => { + simpleWorker.onmessage(e.data); + }; +} + +self.onmessage = (e) => { + // Ignore first message in this case and initialize if not yet initialized + if (!initialized) { + initialize(null); + } +}; diff --git a/src/vs/editor/test/common/services/editorSimpleWorker.test.ts b/src/vs/editor/test/common/services/editorSimpleWorker.test.ts index 0923605e55d94..0a8b62e8a55e3 100644 --- a/src/vs/editor/test/common/services/editorSimpleWorker.test.ts +++ b/src/vs/editor/test/common/services/editorSimpleWorker.test.ts @@ -32,7 +32,7 @@ suite('EditorSimpleWorker', () => { let model: ICommonModel; setup(() => { - worker = new WorkerWithModels(); + worker = new WorkerWithModels(null); model = worker.addModel([ 'This is line one', //16 'and this is line number two', //27 diff --git a/src/vs/nls.mock.ts b/src/vs/nls.mock.ts new file mode 100644 index 0000000000000..cce948d90bca9 --- /dev/null +++ b/src/vs/nls.mock.ts @@ -0,0 +1,26 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export interface ILocalizeInfo { + key: string; + comment: string[]; +} + +function _format(message: string, args: any[]): string { + let result: string; + if (args.length === 0) { + result = message; + } else { + result = message.replace(/\{(\d+)\}/g, function (match, rest) { + const index = rest[0]; + return typeof args[index] !== 'undefined' ? args[index] : match; + }); + } + return result; +} + +export function localize(data: ILocalizeInfo | string, message: string, ...args: any[]): string { + return _format(message, args); +}