mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-26 17:01:20 -08:00
build(site): [SITE-07] reproduce core outputs and validate localized editing
This commit is contained in:
1 parent
244695e726
commit
0cfdf4a7e3
24 files changed
+10598
-5
No files matched your search
@@ -40,3 +40,5 @@ refactor/baselines/site-vendor/monaco-basic/** -text whitespace=-trailing-space,
|
|||||||
refactor/baselines/monaco-basic-fixtures.json text eol=lf
|
refactor/baselines/monaco-basic-fixtures.json text eol=lf
|
||||||
refactor/baselines/site-vendor/monaco-core-origins/** -text whitespace=-trailing-space,cr-at-eol
|
refactor/baselines/site-vendor/monaco-core-origins/** -text whitespace=-trailing-space,cr-at-eol
|
||||||
docs/licenses/monaco-editor/core-origins/** -text whitespace=-trailing-space,cr-at-eol
|
docs/licenses/monaco-editor/core-origins/** -text whitespace=-trailing-space,cr-at-eol
|
||||||
|
refactor/baselines/site-vendor/monaco-core-build/** -text whitespace=-trailing-space,cr-at-eol
|
||||||
|
refactor/baselines/monaco-core-locales.json text eol=lf
|
||||||
+2
-1
@@ -169,7 +169,8 @@
|
|||||||
"verify:monaco-language-sources": "node scripts/site-vendor/monaco/reproduce-languages.ts",
|
"verify:monaco-language-sources": "node scripts/site-vendor/monaco/reproduce-languages.ts",
|
||||||
"verify:monaco-mode-sources": "node scripts/site-vendor/monaco/reproduce-modes.ts",
|
"verify:monaco-mode-sources": "node scripts/site-vendor/monaco/reproduce-modes.ts",
|
||||||
"verify:monaco-basic-sources": "node scripts/site-vendor/monaco/reproduce-basic.ts",
|
"verify:monaco-basic-sources": "node scripts/site-vendor/monaco/reproduce-basic.ts",
|
||||||
"verify:monaco-core-origins": "node scripts/site-vendor/monaco/reproduce-core-origins.ts"
|
"verify:monaco-core-origins": "node scripts/site-vendor/monaco/reproduce-core-origins.ts",
|
||||||
|
"verify:monaco-core-build": "node scripts/site-vendor/monaco/reproduce-core-build.ts"
|
||||||
},
|
},
|
||||||
"browserslist": "last 1 Chrome version",
|
"browserslist": "last 1 Chrome version",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,72 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"locale": "en",
|
||||||
|
"find": "Find",
|
||||||
|
"next": "Next Match",
|
||||||
|
"close": "Close",
|
||||||
|
"member": "package/dev/vs/editor/editor.main.nls.js"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"locale": "de",
|
||||||
|
"find": "Suchen",
|
||||||
|
"next": "Nächste Übereinstimmung",
|
||||||
|
"close": "Schließen",
|
||||||
|
"member": "package/dev/vs/editor/editor.main.nls.de.js"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"locale": "es",
|
||||||
|
"find": "Buscar",
|
||||||
|
"next": "Coincidencia siguiente",
|
||||||
|
"close": "Cerrar",
|
||||||
|
"member": "package/dev/vs/editor/editor.main.nls.es.js"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"locale": "fr",
|
||||||
|
"find": "Rechercher",
|
||||||
|
"next": "Correspondance suivante",
|
||||||
|
"close": "Fermer",
|
||||||
|
"member": "package/dev/vs/editor/editor.main.nls.fr.js"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"locale": "it",
|
||||||
|
"find": "Trova",
|
||||||
|
"next": "Risultato successivo",
|
||||||
|
"close": "Chiudi",
|
||||||
|
"member": "package/dev/vs/editor/editor.main.nls.it.js"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"locale": "ja",
|
||||||
|
"find": "検索",
|
||||||
|
"next": "次の一致項目",
|
||||||
|
"close": "閉じる",
|
||||||
|
"member": "package/dev/vs/editor/editor.main.nls.ja.js"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"locale": "ko",
|
||||||
|
"find": "찾기",
|
||||||
|
"next": "다음 검색 결과",
|
||||||
|
"close": "닫기",
|
||||||
|
"member": "package/dev/vs/editor/editor.main.nls.ko.js"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"locale": "ru",
|
||||||
|
"find": "Найти",
|
||||||
|
"next": "Следующее совпадение",
|
||||||
|
"close": "Закрыть",
|
||||||
|
"member": "package/dev/vs/editor/editor.main.nls.ru.js"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"locale": "zh-cn",
|
||||||
|
"find": "查找",
|
||||||
|
"next": "下一个匹配项",
|
||||||
|
"close": "关闭",
|
||||||
|
"member": "package/dev/vs/editor/editor.main.nls.zh-cn.js"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"locale": "zh-tw",
|
||||||
|
"find": "尋找",
|
||||||
|
"next": "下一個相符項目",
|
||||||
|
"close": "關閉",
|
||||||
|
"member": "package/dev/vs/editor/editor.main.nls.zh-tw.js"
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,481 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
const gulp = require('gulp');
|
||||||
|
const path = require('path');
|
||||||
|
const util = require('./lib/util');
|
||||||
|
const task = require('./lib/task');
|
||||||
|
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');
|
||||||
|
const compilation = require('./lib/compilation');
|
||||||
|
const monacoapi = require('./lib/monaco-api');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
let root = path.dirname(__dirname);
|
||||||
|
let sha1 = util.getVersion(root);
|
||||||
|
let semver = require('./monaco/package.json').version;
|
||||||
|
let headerVersion = semver + '(' + sha1 + ')';
|
||||||
|
|
||||||
|
// Build
|
||||||
|
|
||||||
|
let editorEntryPoints = [
|
||||||
|
{
|
||||||
|
name: 'vs/editor/editor.main',
|
||||||
|
include: [],
|
||||||
|
exclude: ['vs/css', 'vs/nls'],
|
||||||
|
prepend: ['out-editor-build/vs/css.js', 'out-editor-build/vs/nls.js'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'vs/base/common/worker/simpleWorker',
|
||||||
|
include: ['vs/editor/common/services/editorSimpleWorker'],
|
||||||
|
prepend: ['vs/loader.js'],
|
||||||
|
append: ['vs/base/worker/workerMain'],
|
||||||
|
dest: 'vs/base/worker/workerMain.js'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
let editorResources = [
|
||||||
|
'out-editor-build/vs/base/browser/ui/codicons/**/*.ttf'
|
||||||
|
];
|
||||||
|
|
||||||
|
let BUNDLED_FILE_HEADER = [
|
||||||
|
'/*!-----------------------------------------------------------',
|
||||||
|
' * Copyright (c) Microsoft Corporation. All rights reserved.',
|
||||||
|
' * Version: ' + headerVersion,
|
||||||
|
' * Released under the MIT license',
|
||||||
|
' * https://github.com/microsoft/vscode/blob/main/LICENSE.txt',
|
||||||
|
' *-----------------------------------------------------------*/',
|
||||||
|
''
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
const languages = i18n.defaultLanguages.concat([]); // i18n.defaultLanguages.concat(process.env.VSCODE_QUALITY !== 'stable' ? i18n.extraLanguages : []);
|
||||||
|
|
||||||
|
const extractEditorSrcTask = task.define('extract-editor-src', () => {
|
||||||
|
const apiusages = monacoapi.execute().usageContent;
|
||||||
|
const extrausages = fs.readFileSync(path.join(root, 'build', 'monaco', 'monaco.usage.recipe')).toString();
|
||||||
|
standalone.extractEditor({
|
||||||
|
sourcesRoot: path.join(root, 'src'),
|
||||||
|
entryPoints: [
|
||||||
|
'vs/editor/editor.main',
|
||||||
|
'vs/editor/editor.worker',
|
||||||
|
'vs/base/worker/workerMain',
|
||||||
|
],
|
||||||
|
inlineEntryPoints: [
|
||||||
|
apiusages,
|
||||||
|
extrausages
|
||||||
|
],
|
||||||
|
shakeLevel: 2, // 0-Files, 1-InnerFile, 2-ClassMembers
|
||||||
|
importIgnorePattern: /(^vs\/css!)/,
|
||||||
|
destRoot: path.join(root, 'out-editor-src'),
|
||||||
|
redirects: []
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const compileEditorAMDTask = task.define('compile-editor-amd', compilation.compileTask('out-editor-src', 'out-editor-build', true));
|
||||||
|
|
||||||
|
const optimizeEditorAMDTask = task.define('optimize-editor-amd', common.optimizeTask({
|
||||||
|
src: 'out-editor-build',
|
||||||
|
entryPoints: editorEntryPoints,
|
||||||
|
resources: editorResources,
|
||||||
|
loaderConfig: {
|
||||||
|
paths: {
|
||||||
|
'vs': 'out-editor-build/vs',
|
||||||
|
'vs/css': 'out-editor-build/vs/css.build',
|
||||||
|
'vs/nls': 'out-editor-build/vs/nls.build',
|
||||||
|
'vscode': 'empty:'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bundleLoader: false,
|
||||||
|
header: BUNDLED_FILE_HEADER,
|
||||||
|
bundleInfo: true,
|
||||||
|
out: 'out-editor',
|
||||||
|
languages: languages
|
||||||
|
}));
|
||||||
|
|
||||||
|
const minifyEditorAMDTask = task.define('minify-editor-amd', common.minifyTask('out-editor'));
|
||||||
|
|
||||||
|
const createESMSourcesAndResourcesTask = task.define('extract-editor-esm', () => {
|
||||||
|
standalone.createESMSourcesAndResources2({
|
||||||
|
srcFolder: './out-editor-src',
|
||||||
|
outFolder: './out-editor-esm',
|
||||||
|
outResourcesFolder: './out-monaco-editor-core/esm',
|
||||||
|
ignores: [
|
||||||
|
'inlineEntryPoint:0.ts',
|
||||||
|
'inlineEntryPoint:1.ts',
|
||||||
|
'vs/loader.js',
|
||||||
|
'vs/nls.ts',
|
||||||
|
'vs/nls.build.js',
|
||||||
|
'vs/nls.d.ts',
|
||||||
|
'vs/css.js',
|
||||||
|
'vs/css.build.js',
|
||||||
|
'vs/css.d.ts',
|
||||||
|
'vs/base/worker/workerMain.ts',
|
||||||
|
],
|
||||||
|
renames: {
|
||||||
|
'vs/nls.mock.ts': 'vs/nls.ts'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const compileEditorESMTask = task.define('compile-editor-esm', () => {
|
||||||
|
const KEEP_PREV_ANALYSIS = false;
|
||||||
|
const FAIL_ON_PURPOSE = false;
|
||||||
|
console.log(`Launching the TS compiler at ${path.join(__dirname, '../out-editor-esm')}...`);
|
||||||
|
let result;
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
result = cp.spawnSync(`..\\node_modules\\.bin\\tsc.cmd`, {
|
||||||
|
cwd: path.join(__dirname, '../out-editor-esm')
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
result = cp.spawnSync(`node`, [`../node_modules/.bin/tsc`], {
|
||||||
|
cwd: path.join(__dirname, '../out-editor-esm')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(result.stdout.toString());
|
||||||
|
console.log(result.stderr.toString());
|
||||||
|
|
||||||
|
if (FAIL_ON_PURPOSE || result.status !== 0) {
|
||||||
|
console.log(`The TS Compilation failed, preparing analysis folder...`);
|
||||||
|
const destPath = path.join(__dirname, '../../vscode-monaco-editor-esm-analysis');
|
||||||
|
const keepPrevAnalysis = (KEEP_PREV_ANALYSIS && fs.existsSync(destPath));
|
||||||
|
const cleanDestPath = (keepPrevAnalysis ? Promise.resolve() : util.rimraf(destPath)());
|
||||||
|
return cleanDestPath.then(() => {
|
||||||
|
// build a list of files to copy
|
||||||
|
const files = util.rreddir(path.join(__dirname, '../out-editor-esm'));
|
||||||
|
|
||||||
|
if (!keepPrevAnalysis) {
|
||||||
|
fs.mkdirSync(destPath);
|
||||||
|
|
||||||
|
// initialize a new repository
|
||||||
|
cp.spawnSync(`git`, [`init`], {
|
||||||
|
cwd: destPath
|
||||||
|
});
|
||||||
|
|
||||||
|
// copy files from src
|
||||||
|
for (const file of files) {
|
||||||
|
const srcFilePath = path.join(__dirname, '../src', file);
|
||||||
|
const dstFilePath = path.join(destPath, file);
|
||||||
|
if (fs.existsSync(srcFilePath)) {
|
||||||
|
util.ensureDir(path.dirname(dstFilePath));
|
||||||
|
const contents = fs.readFileSync(srcFilePath).toString().replace(/\r\n|\r|\n/g, '\n');
|
||||||
|
fs.writeFileSync(dstFilePath, contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create an initial commit to diff against
|
||||||
|
cp.spawnSync(`git`, [`add`, `.`], {
|
||||||
|
cwd: destPath
|
||||||
|
});
|
||||||
|
|
||||||
|
// create the commit
|
||||||
|
cp.spawnSync(`git`, [`commit`, `-m`, `"original sources"`, `--no-gpg-sign`], {
|
||||||
|
cwd: destPath
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy files from tree shaken src
|
||||||
|
for (const file of files) {
|
||||||
|
const srcFilePath = path.join(__dirname, '../out-editor-src', file);
|
||||||
|
const dstFilePath = path.join(destPath, file);
|
||||||
|
if (fs.existsSync(srcFilePath)) {
|
||||||
|
util.ensureDir(path.dirname(dstFilePath));
|
||||||
|
const contents = fs.readFileSync(srcFilePath).toString().replace(/\r\n|\r|\n/g, '\n');
|
||||||
|
fs.writeFileSync(dstFilePath, contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Open in VS Code the folder at '${destPath}' and you can analyze the compilation error`);
|
||||||
|
throw new Error('Standalone Editor compilation failed. If this is the build machine, simply launch `yarn run gulp editor-distro` on your machine to further analyze the compilation problem.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function toExternalDTS(contents) {
|
||||||
|
let lines = contents.split(/\r\n|\r|\n/);
|
||||||
|
let killNextCloseCurlyBrace = false;
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
let line = lines[i];
|
||||||
|
|
||||||
|
if (killNextCloseCurlyBrace) {
|
||||||
|
if ('}' === line) {
|
||||||
|
lines[i] = '';
|
||||||
|
killNextCloseCurlyBrace = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.indexOf(' ') === 0) {
|
||||||
|
lines[i] = line.substr(4);
|
||||||
|
} else if (line.charAt(0) === '\t') {
|
||||||
|
lines[i] = line.substr(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('declare namespace monaco {' === line) {
|
||||||
|
lines[i] = '';
|
||||||
|
killNextCloseCurlyBrace = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.indexOf('declare namespace monaco.') === 0) {
|
||||||
|
lines[i] = line.replace('declare namespace monaco.', 'export namespace ');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.indexOf('declare let MonacoEnvironment') === 0) {
|
||||||
|
lines[i] = `declare global {\n let MonacoEnvironment: Environment | undefined;\n}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.indexOf('\tMonacoEnvironment?') === 0) {
|
||||||
|
lines[i] = ` MonacoEnvironment?: Environment | undefined;`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lines.join('\n').replace(/\n\n\n+/g, '\n\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterStream(testFunc) {
|
||||||
|
return es.through(function (data) {
|
||||||
|
if (!testFunc(data.relative)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.emit('data', data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const finalEditorResourcesTask = task.define('final-editor-resources', () => {
|
||||||
|
return es.merge(
|
||||||
|
// other assets
|
||||||
|
es.merge(
|
||||||
|
gulp.src('build/monaco/LICENSE'),
|
||||||
|
gulp.src('build/monaco/ThirdPartyNotices.txt'),
|
||||||
|
gulp.src('src/vs/monaco.d.ts')
|
||||||
|
).pipe(gulp.dest('out-monaco-editor-core')),
|
||||||
|
|
||||||
|
// place the .d.ts in the esm folder
|
||||||
|
gulp.src('src/vs/monaco.d.ts')
|
||||||
|
.pipe(es.through(function (data) {
|
||||||
|
this.emit('data', new File({
|
||||||
|
path: data.path.replace(/monaco\.d\.ts/, 'editor.api.d.ts'),
|
||||||
|
base: data.base,
|
||||||
|
contents: Buffer.from(toExternalDTS(data.contents.toString()))
|
||||||
|
}));
|
||||||
|
}))
|
||||||
|
.pipe(gulp.dest('out-monaco-editor-core/esm/vs/editor')),
|
||||||
|
|
||||||
|
// package.json
|
||||||
|
gulp.src('build/monaco/package.json')
|
||||||
|
.pipe(es.through(function (data) {
|
||||||
|
let json = JSON.parse(data.contents.toString());
|
||||||
|
json.private = false;
|
||||||
|
data.contents = Buffer.from(JSON.stringify(json, null, ' '));
|
||||||
|
this.emit('data', data);
|
||||||
|
}))
|
||||||
|
.pipe(gulp.dest('out-monaco-editor-core')),
|
||||||
|
|
||||||
|
// version.txt
|
||||||
|
gulp.src('build/monaco/version.txt')
|
||||||
|
.pipe(es.through(function (data) {
|
||||||
|
data.contents = Buffer.from(`monaco-editor-core: https://github.com/microsoft/vscode/tree/${sha1}`);
|
||||||
|
this.emit('data', data);
|
||||||
|
}))
|
||||||
|
.pipe(gulp.dest('out-monaco-editor-core')),
|
||||||
|
|
||||||
|
// README.md
|
||||||
|
gulp.src('build/monaco/README-npm.md')
|
||||||
|
.pipe(es.through(function (data) {
|
||||||
|
this.emit('data', new File({
|
||||||
|
path: data.path.replace(/README-npm\.md/, 'README.md'),
|
||||||
|
base: data.base,
|
||||||
|
contents: data.contents
|
||||||
|
}));
|
||||||
|
}))
|
||||||
|
.pipe(gulp.dest('out-monaco-editor-core')),
|
||||||
|
|
||||||
|
// dev folder
|
||||||
|
es.merge(
|
||||||
|
gulp.src('out-editor/**/*')
|
||||||
|
).pipe(gulp.dest('out-monaco-editor-core/dev')),
|
||||||
|
|
||||||
|
// min folder
|
||||||
|
es.merge(
|
||||||
|
gulp.src('out-editor-min/**/*')
|
||||||
|
).pipe(filterStream(function (path) {
|
||||||
|
// no map files
|
||||||
|
return !/(\.js\.map$)|(nls\.metadata\.json$)|(bundleInfo\.json$)/.test(path);
|
||||||
|
})).pipe(es.through(function (data) {
|
||||||
|
// tweak the sourceMappingURL
|
||||||
|
if (!/\.js$/.test(data.path)) {
|
||||||
|
this.emit('data', data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let relativePathToMap = path.relative(path.join(data.relative), path.join('min-maps', data.relative + '.map'));
|
||||||
|
|
||||||
|
let strContents = data.contents.toString();
|
||||||
|
let newStr = '//# sourceMappingURL=' + relativePathToMap.replace(/\\/g, '/');
|
||||||
|
strContents = strContents.replace(/\/\/# sourceMappingURL=[^ ]+$/, newStr);
|
||||||
|
|
||||||
|
data.contents = Buffer.from(strContents);
|
||||||
|
this.emit('data', data);
|
||||||
|
})).pipe(gulp.dest('out-monaco-editor-core/min')),
|
||||||
|
|
||||||
|
// min-maps folder
|
||||||
|
es.merge(
|
||||||
|
gulp.src('out-editor-min/**/*')
|
||||||
|
).pipe(filterStream(function (path) {
|
||||||
|
// no map files
|
||||||
|
return /\.js\.map$/.test(path);
|
||||||
|
})).pipe(gulp.dest('out-monaco-editor-core/min-maps'))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('extract-editor-src',
|
||||||
|
task.series(
|
||||||
|
util.rimraf('out-editor-src'),
|
||||||
|
extractEditorSrcTask
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
gulp.task('editor-distro',
|
||||||
|
task.series(
|
||||||
|
task.parallel(
|
||||||
|
util.rimraf('out-editor-src'),
|
||||||
|
util.rimraf('out-editor-build'),
|
||||||
|
util.rimraf('out-editor-esm'),
|
||||||
|
util.rimraf('out-monaco-editor-core'),
|
||||||
|
util.rimraf('out-editor'),
|
||||||
|
util.rimraf('out-editor-min')
|
||||||
|
),
|
||||||
|
extractEditorSrcTask,
|
||||||
|
task.parallel(
|
||||||
|
task.series(
|
||||||
|
compileEditorAMDTask,
|
||||||
|
optimizeEditorAMDTask,
|
||||||
|
minifyEditorAMDTask
|
||||||
|
),
|
||||||
|
task.series(
|
||||||
|
createESMSourcesAndResourcesTask,
|
||||||
|
compileEditorESMTask
|
||||||
|
)
|
||||||
|
),
|
||||||
|
finalEditorResourcesTask
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const bundleEditorESMTask = task.define('editor-esm-bundle-webpack', () => {
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const webpackGulp = require('webpack-stream');
|
||||||
|
|
||||||
|
const result = es.through();
|
||||||
|
|
||||||
|
const webpackConfigPath = path.join(root, 'build/monaco/monaco.webpack.config.js');
|
||||||
|
|
||||||
|
const webpackConfig = {
|
||||||
|
...require(webpackConfigPath),
|
||||||
|
...{ mode: 'production' }
|
||||||
|
};
|
||||||
|
|
||||||
|
const webpackDone = (err, stats) => {
|
||||||
|
if (err) {
|
||||||
|
result.emit('error', err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { compilation } = stats;
|
||||||
|
if (compilation.errors.length > 0) {
|
||||||
|
result.emit('error', compilation.errors.join('\n'));
|
||||||
|
}
|
||||||
|
if (compilation.warnings.length > 0) {
|
||||||
|
result.emit('data', compilation.warnings.join('\n'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return webpackGulp(webpackConfig, webpack, webpackDone)
|
||||||
|
.pipe(gulp.dest('out-editor-esm-bundle'));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('editor-esm-bundle',
|
||||||
|
task.series(
|
||||||
|
task.parallel(
|
||||||
|
util.rimraf('out-editor-src'),
|
||||||
|
util.rimraf('out-editor-esm'),
|
||||||
|
util.rimraf('out-monaco-editor-core'),
|
||||||
|
util.rimraf('out-editor-esm-bundle'),
|
||||||
|
),
|
||||||
|
extractEditorSrcTask,
|
||||||
|
createESMSourcesAndResourcesTask,
|
||||||
|
compileEditorESMTask,
|
||||||
|
bundleEditorESMTask,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
gulp.task('monacodts', task.define('monacodts', () => {
|
||||||
|
const result = monacoapi.execute();
|
||||||
|
fs.writeFileSync(result.filePath, result.content);
|
||||||
|
fs.writeFileSync(path.join(root, 'src/vs/editor/common/standalone/standaloneEnums.ts'), result.enums);
|
||||||
|
return Promise.resolve(true);
|
||||||
|
}));
|
||||||
|
|
||||||
|
//#region monaco type checking
|
||||||
|
|
||||||
|
function createTscCompileTask(watch) {
|
||||||
|
return () => {
|
||||||
|
const createReporter = require('./lib/reporter').createReporter;
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const args = ['./node_modules/.bin/tsc', '-p', './src/tsconfig.monaco.json', '--noEmit'];
|
||||||
|
if (watch) {
|
||||||
|
args.push('-w');
|
||||||
|
}
|
||||||
|
const child = cp.spawn(`node`, args, {
|
||||||
|
cwd: path.join(__dirname, '..'),
|
||||||
|
// stdio: [null, 'pipe', 'inherit']
|
||||||
|
});
|
||||||
|
let errors = [];
|
||||||
|
let reporter = createReporter('monaco');
|
||||||
|
let report;
|
||||||
|
// eslint-disable-next-line no-control-regex
|
||||||
|
let magic = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g; // https://stackoverflow.com/questions/25245716/remove-all-ansi-colors-styles-from-strings
|
||||||
|
|
||||||
|
child.stdout.on('data', data => {
|
||||||
|
let str = String(data);
|
||||||
|
str = str.replace(magic, '').trim();
|
||||||
|
if (str.indexOf('Starting compilation') >= 0 || str.indexOf('File change detected') >= 0) {
|
||||||
|
errors.length = 0;
|
||||||
|
report = reporter.end(false);
|
||||||
|
|
||||||
|
} else if (str.indexOf('Compilation complete') >= 0) {
|
||||||
|
report.end();
|
||||||
|
|
||||||
|
} else if (str) {
|
||||||
|
let match = /(.*\(\d+,\d+\): )(.*: )(.*)/.exec(str);
|
||||||
|
if (match) {
|
||||||
|
// trying to massage the message so that it matches the gulp-tsb error messages
|
||||||
|
// e.g. src/vs/base/common/strings.ts(663,5): error TS2322: Type '1234' is not assignable to type 'string'.
|
||||||
|
let fullpath = path.join(root, match[1]);
|
||||||
|
let message = match[3];
|
||||||
|
reporter(fullpath + message);
|
||||||
|
} else {
|
||||||
|
reporter(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
child.on('exit', resolve);
|
||||||
|
child.on('error', reject);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const monacoTypecheckWatchTask = task.define('monaco-typecheck-watch', createTscCompileTask(true));
|
||||||
|
exports.monacoTypecheckWatchTask = monacoTypecheckWatchTask;
|
||||||
|
|
||||||
|
const monacoTypecheckTask = task.define('monaco-typecheck', createTscCompileTask(false));
|
||||||
|
exports.monacoTypecheckTask = monacoTypecheckTask;
|
||||||
|
|
||||||
|
//#endregion
|
||||||
@@ -0,0 +1,302 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 * as es from 'event-stream';
|
||||||
|
import * as gulp from 'gulp';
|
||||||
|
import * as concat from 'gulp-concat';
|
||||||
|
import * as filter from 'gulp-filter';
|
||||||
|
import * as fancyLog from 'fancy-log';
|
||||||
|
import * as ansiColors from 'ansi-colors';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as pump from 'pump';
|
||||||
|
import * as VinylFile from 'vinyl';
|
||||||
|
import * as bundle from './bundle';
|
||||||
|
import { Language, processNlsFiles } from './i18n';
|
||||||
|
import { createStatsStream } from './stats';
|
||||||
|
import * as util from './util';
|
||||||
|
|
||||||
|
const REPO_ROOT_PATH = path.join(__dirname, '../..');
|
||||||
|
|
||||||
|
function log(prefix: string, message: string): void {
|
||||||
|
fancyLog(ansiColors.cyan('[' + prefix + ']'), message);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loaderConfig() {
|
||||||
|
const result: any = {
|
||||||
|
paths: {
|
||||||
|
'vs': 'out-build/vs',
|
||||||
|
'vscode': 'empty:'
|
||||||
|
},
|
||||||
|
amdModulesPattern: /^vs\//
|
||||||
|
};
|
||||||
|
|
||||||
|
result['vs/css'] = { inlineResources: true };
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const IS_OUR_COPYRIGHT_REGEXP = /Copyright \(C\) Microsoft Corporation/i;
|
||||||
|
|
||||||
|
function loader(src: string, bundledFileHeader: string, bundleLoader: boolean, externalLoaderInfo?: any): NodeJS.ReadWriteStream {
|
||||||
|
let sources = [
|
||||||
|
`${src}/vs/loader.js`
|
||||||
|
];
|
||||||
|
if (bundleLoader) {
|
||||||
|
sources = sources.concat([
|
||||||
|
`${src}/vs/css.js`,
|
||||||
|
`${src}/vs/nls.js`
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let isFirst = true;
|
||||||
|
return (
|
||||||
|
gulp
|
||||||
|
.src(sources, { base: `${src}` })
|
||||||
|
.pipe(es.through(function (data) {
|
||||||
|
if (isFirst) {
|
||||||
|
isFirst = false;
|
||||||
|
this.emit('data', new VinylFile({
|
||||||
|
path: 'fake',
|
||||||
|
base: '.',
|
||||||
|
contents: Buffer.from(bundledFileHeader)
|
||||||
|
}));
|
||||||
|
this.emit('data', data);
|
||||||
|
} else {
|
||||||
|
this.emit('data', data);
|
||||||
|
}
|
||||||
|
}, function () {
|
||||||
|
if (externalLoaderInfo !== undefined) {
|
||||||
|
this.emit('data', new VinylFile({
|
||||||
|
path: 'fake2',
|
||||||
|
base: '.',
|
||||||
|
contents: Buffer.from(`require.config(${JSON.stringify(externalLoaderInfo, undefined, 2)});`)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
this.emit('end');
|
||||||
|
}))
|
||||||
|
.pipe(concat('vs/loader.js'))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toConcatStream(src: string, bundledFileHeader: string, sources: bundle.IFile[], dest: string, fileContentMapper: (contents: string, path: string) => string): NodeJS.ReadWriteStream {
|
||||||
|
const useSourcemaps = /\.js$/.test(dest) && !/\.nls\.js$/.test(dest);
|
||||||
|
|
||||||
|
// If a bundle ends up including in any of the sources our copyright, then
|
||||||
|
// insert a fake source at the beginning of each bundle with our copyright
|
||||||
|
let containsOurCopyright = false;
|
||||||
|
for (let i = 0, len = sources.length; i < len; i++) {
|
||||||
|
const fileContents = sources[i].contents;
|
||||||
|
if (IS_OUR_COPYRIGHT_REGEXP.test(fileContents)) {
|
||||||
|
containsOurCopyright = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (containsOurCopyright) {
|
||||||
|
sources.unshift({
|
||||||
|
path: null,
|
||||||
|
contents: bundledFileHeader
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const treatedSources = sources.map(function (source) {
|
||||||
|
const root = source.path ? REPO_ROOT_PATH.replace(/\\/g, '/') : '';
|
||||||
|
const base = source.path ? root + `/${src}` : '.';
|
||||||
|
const path = source.path ? root + '/' + source.path.replace(/\\/g, '/') : 'fake';
|
||||||
|
const contents = source.path ? fileContentMapper(source.contents, path) : source.contents;
|
||||||
|
|
||||||
|
return new VinylFile({
|
||||||
|
path: path,
|
||||||
|
base: base,
|
||||||
|
contents: Buffer.from(contents)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return es.readArray(treatedSources)
|
||||||
|
.pipe(useSourcemaps ? util.loadSourcemaps() : es.through())
|
||||||
|
.pipe(concat(dest))
|
||||||
|
.pipe(createStatsStream(dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
function toBundleStream(src: string, bundledFileHeader: string, bundles: bundle.IConcatFile[], fileContentMapper: (contents: string, path: string) => string): NodeJS.ReadWriteStream {
|
||||||
|
return es.merge(bundles.map(function (bundle) {
|
||||||
|
return toConcatStream(src, bundledFileHeader, bundle.sources, bundle.dest, fileContentMapper);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IOptimizeTaskOpts {
|
||||||
|
/**
|
||||||
|
* The folder to read files from.
|
||||||
|
*/
|
||||||
|
src: string;
|
||||||
|
/**
|
||||||
|
* (for AMD files, will get bundled and get Copyright treatment)
|
||||||
|
*/
|
||||||
|
entryPoints: bundle.IEntryPoint[];
|
||||||
|
/**
|
||||||
|
* (svg, etc.)
|
||||||
|
*/
|
||||||
|
resources: string[];
|
||||||
|
loaderConfig: any;
|
||||||
|
/**
|
||||||
|
* Additional info we append to the end of the loader
|
||||||
|
*/
|
||||||
|
externalLoaderInfo?: any;
|
||||||
|
/**
|
||||||
|
* (true by default - append css and nls to loader)
|
||||||
|
*/
|
||||||
|
bundleLoader?: boolean;
|
||||||
|
/**
|
||||||
|
* (basically the Copyright treatment)
|
||||||
|
*/
|
||||||
|
header?: string;
|
||||||
|
/**
|
||||||
|
* (emit bundleInfo.json file)
|
||||||
|
*/
|
||||||
|
bundleInfo: boolean;
|
||||||
|
/**
|
||||||
|
* (out folder name)
|
||||||
|
*/
|
||||||
|
out: string;
|
||||||
|
/**
|
||||||
|
* (out folder name)
|
||||||
|
*/
|
||||||
|
languages?: Language[];
|
||||||
|
/**
|
||||||
|
* File contents interceptor
|
||||||
|
* @param contents The contens of the file
|
||||||
|
* @param path The absolute file path, always using `/`, even on Windows
|
||||||
|
*/
|
||||||
|
fileContentMapper?: (contents: string, path: string) => string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DEFAULT_FILE_HEADER = [
|
||||||
|
'/*!--------------------------------------------------------',
|
||||||
|
' * Copyright (C) Microsoft Corporation. All rights reserved.',
|
||||||
|
' *--------------------------------------------------------*/'
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStream {
|
||||||
|
const src = opts.src;
|
||||||
|
const entryPoints = opts.entryPoints;
|
||||||
|
const resources = opts.resources;
|
||||||
|
const loaderConfig = opts.loaderConfig;
|
||||||
|
const bundledFileHeader = opts.header || DEFAULT_FILE_HEADER;
|
||||||
|
const bundleLoader = (typeof opts.bundleLoader === 'undefined' ? true : opts.bundleLoader);
|
||||||
|
const out = opts.out;
|
||||||
|
const fileContentMapper = opts.fileContentMapper || ((contents: string, _path: string) => contents);
|
||||||
|
|
||||||
|
return function () {
|
||||||
|
const sourcemaps = require('gulp-sourcemaps') as typeof import('gulp-sourcemaps');
|
||||||
|
|
||||||
|
const bundlesStream = es.through(); // this stream will contain the bundled files
|
||||||
|
const resourcesStream = es.through(); // this stream will contain the resources
|
||||||
|
const bundleInfoStream = es.through(); // this stream will contain bundleInfo.json
|
||||||
|
|
||||||
|
bundle.bundle(entryPoints, loaderConfig, function (err, result) {
|
||||||
|
if (err || !result) { return bundlesStream.emit('error', JSON.stringify(err)); }
|
||||||
|
|
||||||
|
toBundleStream(src, bundledFileHeader, result.files, fileContentMapper).pipe(bundlesStream);
|
||||||
|
|
||||||
|
// Remove css inlined resources
|
||||||
|
const filteredResources = resources.slice();
|
||||||
|
result.cssInlinedResources.forEach(function (resource) {
|
||||||
|
if (process.env['VSCODE_BUILD_VERBOSE']) {
|
||||||
|
log('optimizer', 'excluding inlined: ' + resource);
|
||||||
|
}
|
||||||
|
filteredResources.push('!' + resource);
|
||||||
|
});
|
||||||
|
gulp.src(filteredResources, { base: `${src}`, allowEmpty: true }).pipe(resourcesStream);
|
||||||
|
|
||||||
|
const bundleInfoArray: VinylFile[] = [];
|
||||||
|
if (opts.bundleInfo) {
|
||||||
|
bundleInfoArray.push(new VinylFile({
|
||||||
|
path: 'bundleInfo.json',
|
||||||
|
base: '.',
|
||||||
|
contents: Buffer.from(JSON.stringify(result.bundleData, null, '\t'))
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
es.readArray(bundleInfoArray).pipe(bundleInfoStream);
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = es.merge(
|
||||||
|
loader(src, bundledFileHeader, bundleLoader, opts.externalLoaderInfo),
|
||||||
|
bundlesStream,
|
||||||
|
resourcesStream,
|
||||||
|
bundleInfoStream
|
||||||
|
);
|
||||||
|
|
||||||
|
return result
|
||||||
|
.pipe(sourcemaps.write('./', {
|
||||||
|
sourceRoot: undefined,
|
||||||
|
addComment: true,
|
||||||
|
includeContent: true
|
||||||
|
}))
|
||||||
|
.pipe(opts.languages && opts.languages.length ? processNlsFiles({
|
||||||
|
fileHeader: bundledFileHeader,
|
||||||
|
languages: opts.languages
|
||||||
|
}) : es.through())
|
||||||
|
.pipe(gulp.dest(out));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function minifyTask(src: string, sourceMapBaseUrl?: string): (cb: any) => void {
|
||||||
|
const esbuild = require('esbuild') as typeof import('esbuild');
|
||||||
|
const sourceMappingURL = sourceMapBaseUrl ? ((f: any) => `${sourceMapBaseUrl}/${f.relative}.map`) : undefined;
|
||||||
|
|
||||||
|
return cb => {
|
||||||
|
const cssnano = require('cssnano') as typeof import('cssnano');
|
||||||
|
const postcss = require('gulp-postcss') as typeof import('gulp-postcss');
|
||||||
|
const sourcemaps = require('gulp-sourcemaps') as typeof import('gulp-sourcemaps');
|
||||||
|
|
||||||
|
const jsFilter = filter('**/*.js', { restore: true });
|
||||||
|
const cssFilter = filter('**/*.css', { restore: true });
|
||||||
|
|
||||||
|
pump(
|
||||||
|
gulp.src([src + '/**', '!' + src + '/**/*.map']),
|
||||||
|
jsFilter,
|
||||||
|
sourcemaps.init({ loadMaps: true }),
|
||||||
|
es.map((f: any, cb) => {
|
||||||
|
esbuild.build({
|
||||||
|
entryPoints: [f.path],
|
||||||
|
minify: true,
|
||||||
|
sourcemap: 'external',
|
||||||
|
outdir: '.',
|
||||||
|
platform: 'node',
|
||||||
|
target: ['esnext'],
|
||||||
|
write: false
|
||||||
|
}).then(res => {
|
||||||
|
const jsFile = res.outputFiles.find(f => /\.js$/.test(f.path))!;
|
||||||
|
const sourceMapFile = res.outputFiles.find(f => /\.js\.map$/.test(f.path))!;
|
||||||
|
|
||||||
|
f.contents = Buffer.from(jsFile.contents);
|
||||||
|
f.sourceMap = JSON.parse(sourceMapFile.text);
|
||||||
|
|
||||||
|
cb(undefined, f);
|
||||||
|
}, cb);
|
||||||
|
}),
|
||||||
|
jsFilter.restore,
|
||||||
|
cssFilter,
|
||||||
|
postcss([cssnano({ preset: 'default' })]),
|
||||||
|
cssFilter.restore,
|
||||||
|
(<any>sourcemaps).mapSources((sourcePath: string) => {
|
||||||
|
if (sourcePath === 'bootstrap-fork.js') {
|
||||||
|
return 'bootstrap-fork.orig.js';
|
||||||
|
}
|
||||||
|
|
||||||
|
return sourcePath;
|
||||||
|
}),
|
||||||
|
sourcemaps.write('./', {
|
||||||
|
sourceMappingURL,
|
||||||
|
sourceRoot: undefined,
|
||||||
|
includeContent: true,
|
||||||
|
addComment: true
|
||||||
|
} as any),
|
||||||
|
gulp.dest(src + '-min'),
|
||||||
|
(err: any) => cb(err));
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
{
|
||||||
|
"name": "code-oss-dev-build",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"@azure/cosmos": "^3.9.3",
|
||||||
|
"@azure/storage-blob": "^12.4.0",
|
||||||
|
"@electron/get": "^1.12.4",
|
||||||
|
"@types/ansi-colors": "^3.2.0",
|
||||||
|
"@types/azure": "0.9.19",
|
||||||
|
"@types/byline": "^4.2.32",
|
||||||
|
"@types/cssnano": "^4.0.0",
|
||||||
|
"@types/debounce": "^1.0.0",
|
||||||
|
"@types/eslint": "4.16.1",
|
||||||
|
"@types/fancy-log": "^1.3.0",
|
||||||
|
"@types/fs-extra": "^9.0.12",
|
||||||
|
"@types/glob": "^7.1.1",
|
||||||
|
"@types/gulp": "^4.0.5",
|
||||||
|
"@types/gulp-concat": "^0.0.32",
|
||||||
|
"@types/gulp-filter": "^3.0.32",
|
||||||
|
"@types/gulp-gzip": "^0.0.31",
|
||||||
|
"@types/gulp-json-editor": "^2.2.31",
|
||||||
|
"@types/gulp-postcss": "^8.0.0",
|
||||||
|
"@types/gulp-rename": "^0.0.33",
|
||||||
|
"@types/gulp-sourcemaps": "^0.0.32",
|
||||||
|
"@types/mime": "0.0.29",
|
||||||
|
"@types/minimatch": "^3.0.3",
|
||||||
|
"@types/minimist": "^1.2.1",
|
||||||
|
"@types/mkdirp": "^1.0.1",
|
||||||
|
"@types/mocha": "^8.2.0",
|
||||||
|
"@types/node": "14.x",
|
||||||
|
"@types/p-limit": "^2.2.0",
|
||||||
|
"@types/plist": "^3.0.2",
|
||||||
|
"@types/pump": "^1.0.1",
|
||||||
|
"@types/request": "^2.47.0",
|
||||||
|
"@types/rimraf": "^2.0.4",
|
||||||
|
"@types/through": "^0.0.29",
|
||||||
|
"@types/through2": "^2.0.34",
|
||||||
|
"@types/tmp": "^0.2.1",
|
||||||
|
"@types/underscore": "^1.8.9",
|
||||||
|
"@types/webpack": "^4.41.25",
|
||||||
|
"@types/xml2js": "0.0.33",
|
||||||
|
"@typescript-eslint/experimental-utils": "~2.13.0",
|
||||||
|
"@typescript-eslint/parser": "^3.3.0",
|
||||||
|
"applicationinsights": "1.0.8",
|
||||||
|
"azure-storage": "^2.1.0",
|
||||||
|
"byline": "^5.0.0",
|
||||||
|
"colors": "^1.4.0",
|
||||||
|
"commander": "^7.0.0",
|
||||||
|
"debug": "^4.3.2",
|
||||||
|
"electron-osx-sign": "^0.4.16",
|
||||||
|
"esbuild": "^0.12.6",
|
||||||
|
"extract-zip": "^2.0.1",
|
||||||
|
"fs-extra": "^9.1.0",
|
||||||
|
"got": "11.8.1",
|
||||||
|
"gulp-merge-json": "^2.1.1",
|
||||||
|
"iconv-lite-umd": "0.6.8",
|
||||||
|
"jsonc-parser": "^2.3.0",
|
||||||
|
"mime": "^1.4.1",
|
||||||
|
"mkdirp": "^1.0.4",
|
||||||
|
"p-limit": "^3.1.0",
|
||||||
|
"plist": "^3.0.1",
|
||||||
|
"source-map": "0.6.1",
|
||||||
|
"tmp": "^0.2.1",
|
||||||
|
"typescript": "^4.5.0-dev.20211021",
|
||||||
|
"vsce": "^1.100.0",
|
||||||
|
"vscode-universal-bundler": "^0.0.2"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"compile": "tsc -p tsconfig.build.json",
|
||||||
|
"watch": "tsc -p tsconfig.build.json --watch",
|
||||||
|
"npmCheckJs": "tsc --noEmit"
|
||||||
|
},
|
||||||
|
"dependencies": {}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,115 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
* Please make sure to make edits in the .ts file at https://github.com/microsoft/vscode-loader/
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
'use strict';
|
||||||
|
var CSSLoaderPlugin;
|
||||||
|
(function (CSSLoaderPlugin) {
|
||||||
|
/**
|
||||||
|
* Known issue:
|
||||||
|
* - In IE there is no way to know if the CSS file loaded successfully or not.
|
||||||
|
*/
|
||||||
|
var BrowserCSSLoader = /** @class */ (function () {
|
||||||
|
function BrowserCSSLoader() {
|
||||||
|
this._pendingLoads = 0;
|
||||||
|
}
|
||||||
|
BrowserCSSLoader.prototype.attachListeners = function (name, linkNode, callback, errorback) {
|
||||||
|
var unbind = function () {
|
||||||
|
linkNode.removeEventListener('load', loadEventListener);
|
||||||
|
linkNode.removeEventListener('error', errorEventListener);
|
||||||
|
};
|
||||||
|
var loadEventListener = function (e) {
|
||||||
|
unbind();
|
||||||
|
callback();
|
||||||
|
};
|
||||||
|
var errorEventListener = function (e) {
|
||||||
|
unbind();
|
||||||
|
errorback(e);
|
||||||
|
};
|
||||||
|
linkNode.addEventListener('load', loadEventListener);
|
||||||
|
linkNode.addEventListener('error', errorEventListener);
|
||||||
|
};
|
||||||
|
BrowserCSSLoader.prototype._onLoad = function (name, callback) {
|
||||||
|
this._pendingLoads--;
|
||||||
|
callback();
|
||||||
|
};
|
||||||
|
BrowserCSSLoader.prototype._onLoadError = function (name, errorback, err) {
|
||||||
|
this._pendingLoads--;
|
||||||
|
errorback(err);
|
||||||
|
};
|
||||||
|
BrowserCSSLoader.prototype._insertLinkNode = function (linkNode) {
|
||||||
|
this._pendingLoads++;
|
||||||
|
var head = document.head || document.getElementsByTagName('head')[0];
|
||||||
|
head.appendChild(linkNode);
|
||||||
|
};
|
||||||
|
BrowserCSSLoader.prototype.createLinkTag = function (name, cssUrl, externalCallback, externalErrorback) {
|
||||||
|
var _this = this;
|
||||||
|
var linkNode = document.createElement('link');
|
||||||
|
linkNode.setAttribute('rel', 'stylesheet');
|
||||||
|
linkNode.setAttribute('type', 'text/css');
|
||||||
|
linkNode.setAttribute('data-name', name);
|
||||||
|
var callback = function () { return _this._onLoad(name, externalCallback); };
|
||||||
|
var errorback = function (err) { return _this._onLoadError(name, externalErrorback, err); };
|
||||||
|
this.attachListeners(name, linkNode, callback, errorback);
|
||||||
|
linkNode.setAttribute('href', cssUrl);
|
||||||
|
return linkNode;
|
||||||
|
};
|
||||||
|
BrowserCSSLoader.prototype._linkTagExists = function (name, cssUrl) {
|
||||||
|
var i, len, nameAttr, hrefAttr, links = document.getElementsByTagName('link');
|
||||||
|
for (i = 0, len = links.length; i < len; i++) {
|
||||||
|
nameAttr = links[i].getAttribute('data-name');
|
||||||
|
hrefAttr = links[i].getAttribute('href');
|
||||||
|
if (nameAttr === name || hrefAttr === cssUrl) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
BrowserCSSLoader.prototype.load = function (name, cssUrl, externalCallback, externalErrorback) {
|
||||||
|
if (this._linkTagExists(name, cssUrl)) {
|
||||||
|
externalCallback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var linkNode = this.createLinkTag(name, cssUrl, externalCallback, externalErrorback);
|
||||||
|
this._insertLinkNode(linkNode);
|
||||||
|
};
|
||||||
|
return BrowserCSSLoader;
|
||||||
|
}());
|
||||||
|
// ------------------------------ Finally, the plugin
|
||||||
|
var CSSPlugin = /** @class */ (function () {
|
||||||
|
function CSSPlugin() {
|
||||||
|
this._cssLoader = new BrowserCSSLoader();
|
||||||
|
}
|
||||||
|
CSSPlugin.prototype.load = function (name, req, load, config) {
|
||||||
|
config = config || {};
|
||||||
|
var cssConfig = config['vs/css'] || {};
|
||||||
|
if (cssConfig.disabled) {
|
||||||
|
// the plugin is asked to not create any style sheets
|
||||||
|
load({});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var cssUrl = req.toUrl(name + '.css');
|
||||||
|
this._cssLoader.load(name, cssUrl, function (contents) {
|
||||||
|
load({});
|
||||||
|
}, function (err) {
|
||||||
|
if (typeof load.error === 'function') {
|
||||||
|
load.error('Could not find ' + cssUrl + ' or it was empty');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return CSSPlugin;
|
||||||
|
}());
|
||||||
|
CSSLoaderPlugin.CSSPlugin = CSSPlugin;
|
||||||
|
define('vs/css', new CSSPlugin());
|
||||||
|
})(CSSLoaderPlugin || (CSSLoaderPlugin = {}));
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,160 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
* Please make sure to make edits in the .ts file at https://github.com/microsoft/vscode-loader/
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
*---------------------------------------------------------------------------------------------
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
'use strict';
|
||||||
|
var __spreadArrays = (this && this.__spreadArrays) || function () {
|
||||||
|
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
||||||
|
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
||||||
|
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
||||||
|
r[k] = a[j];
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
var NLSLoaderPlugin;
|
||||||
|
(function (NLSLoaderPlugin) {
|
||||||
|
var Environment = /** @class */ (function () {
|
||||||
|
function Environment() {
|
||||||
|
this._detected = false;
|
||||||
|
this._isPseudo = false;
|
||||||
|
}
|
||||||
|
Object.defineProperty(Environment.prototype, "isPseudo", {
|
||||||
|
get: function () {
|
||||||
|
this._detect();
|
||||||
|
return this._isPseudo;
|
||||||
|
},
|
||||||
|
enumerable: false,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
Environment.prototype._detect = function () {
|
||||||
|
if (this._detected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._detected = true;
|
||||||
|
this._isPseudo = (typeof document !== 'undefined' && document.location && document.location.hash.indexOf('pseudo=true') >= 0);
|
||||||
|
};
|
||||||
|
return Environment;
|
||||||
|
}());
|
||||||
|
function _format(message, args, env) {
|
||||||
|
var result;
|
||||||
|
if (args.length === 0) {
|
||||||
|
result = message;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = message.replace(/\{(\d+)\}/g, function (match, rest) {
|
||||||
|
var index = rest[0];
|
||||||
|
var arg = args[index];
|
||||||
|
var result = match;
|
||||||
|
if (typeof arg === 'string') {
|
||||||
|
result = arg;
|
||||||
|
}
|
||||||
|
else if (typeof arg === 'number' || typeof arg === 'boolean' || arg === void 0 || arg === null) {
|
||||||
|
result = String(arg);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (env.isPseudo) {
|
||||||
|
// FF3B and FF3D is the Unicode zenkaku representation for [ and ]
|
||||||
|
result = '\uFF3B' + result.replace(/[aouei]/g, '$&$&') + '\uFF3D';
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
function findLanguageForModule(config, name) {
|
||||||
|
var result = config[name];
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
result = config['*'];
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
function localize(env, data, message) {
|
||||||
|
var args = [];
|
||||||
|
for (var _i = 3; _i < arguments.length; _i++) {
|
||||||
|
args[_i - 3] = arguments[_i];
|
||||||
|
}
|
||||||
|
return _format(message, args, env);
|
||||||
|
}
|
||||||
|
function createScopedLocalize(scope, env) {
|
||||||
|
return function (idx, defaultValue) {
|
||||||
|
var restArgs = Array.prototype.slice.call(arguments, 2);
|
||||||
|
return _format(scope[idx], restArgs, env);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var NLSPlugin = /** @class */ (function () {
|
||||||
|
function NLSPlugin(env) {
|
||||||
|
var _this = this;
|
||||||
|
this._env = env;
|
||||||
|
this.localize = function (data, message) {
|
||||||
|
var args = [];
|
||||||
|
for (var _i = 2; _i < arguments.length; _i++) {
|
||||||
|
args[_i - 2] = arguments[_i];
|
||||||
|
}
|
||||||
|
return localize.apply(void 0, __spreadArrays([_this._env, data, message], args));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
NLSPlugin.prototype.setPseudoTranslation = function (value) {
|
||||||
|
this._env._isPseudo = value;
|
||||||
|
};
|
||||||
|
NLSPlugin.prototype.create = function (key, data) {
|
||||||
|
return {
|
||||||
|
localize: createScopedLocalize(data[key], this._env)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
NLSPlugin.prototype.load = function (name, req, load, config) {
|
||||||
|
var _this = this;
|
||||||
|
config = config || {};
|
||||||
|
if (!name || name.length === 0) {
|
||||||
|
load({
|
||||||
|
localize: this.localize
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var pluginConfig = config['vs/nls'] || {};
|
||||||
|
var language = pluginConfig.availableLanguages ? findLanguageForModule(pluginConfig.availableLanguages, name) : null;
|
||||||
|
var suffix = '.nls';
|
||||||
|
if (language !== null && language !== NLSPlugin.DEFAULT_TAG) {
|
||||||
|
suffix = suffix + '.' + language;
|
||||||
|
}
|
||||||
|
var messagesLoaded_1 = function (messages) {
|
||||||
|
if (Array.isArray(messages)) {
|
||||||
|
messages.localize = createScopedLocalize(messages, _this._env);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
messages.localize = createScopedLocalize(messages[name], _this._env);
|
||||||
|
}
|
||||||
|
load(messages);
|
||||||
|
};
|
||||||
|
if (typeof pluginConfig.loadBundle === 'function') {
|
||||||
|
pluginConfig.loadBundle(name, language, function (err, messages) {
|
||||||
|
// We have an error. Load the English default strings to not fail
|
||||||
|
if (err) {
|
||||||
|
req([name + '.nls'], messagesLoaded_1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
messagesLoaded_1(messages);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
req([name + suffix], messagesLoaded_1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
NLSPlugin.DEFAULT_TAG = 'i-default';
|
||||||
|
return NLSPlugin;
|
||||||
|
}());
|
||||||
|
NLSLoaderPlugin.NLSPlugin = NLSPlugin;
|
||||||
|
define('vs/nls', new NLSPlugin(new Environment()));
|
||||||
|
})(NLSLoaderPlugin || (NLSLoaderPlugin = {}));
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# SITE-07 Monaco 核心压缩、加载器与十语言编辑回归
|
||||||
|
|
||||||
|
修改前 HEAD:244695e7262902c59b522b0a72543f787a442afd。
|
||||||
|
|
||||||
|
## 本批实现
|
||||||
|
|
||||||
|
固定 VS Code 配方/锁文件确认 core 0.30.1 使用 esbuild 0.12.6。新增独立
|
||||||
|
reproduce-core-build.ts,校验 Monaco/core/历史 esbuild 归档和七个 Git 文件,
|
||||||
|
直接从平台归档读取已校验的可执行文件;不执行安装脚本、不改根依赖或 yarn.lock。
|
||||||
|
记录 Windows/Linux x64 两种归档,实际执行证据仅覆盖 Windows x64。
|
||||||
|
|
||||||
|
13 个 core JS 文件(editor、worker、loader、英文及九份翻译)的完整压缩字节
|
||||||
|
均复现。保留 node/esnext/minify 原参数,准确恢复 source-map 注释前的额外换行
|
||||||
|
及相对路径,没有用 trim 忽略差异。12 个文件直接匹配站点;editor.main 核心
|
||||||
|
部分保留原入口改名和追加贡献模块边界,不把该边界检查称为完整后缀重建。
|
||||||
|
|
||||||
|
loader 原始 Git 源码及版本头精确匹配,css/nls loader 固定源码与 source map
|
||||||
|
一致。两个原始 source map 的 584 个条目、549 个不同源码名逐项登记内容哈希
|
||||||
|
和字节数。这些是上游准备后的构建输入,不是完整 VS Code 原始 TS 编译证明。
|
||||||
|
|
||||||
|
core-build.ts 将 NLS 静态解析、source map 清单和末尾注释装配分开。原 NLS
|
||||||
|
包含尾逗号,所以用 TS AST 读取字面量数组;不执行翻译脚本,拒绝动态调用、
|
||||||
|
重复键或额外语句。十种语言查找文案从原归档解析后冻结为浏览器输入,完整
|
||||||
|
复验会重新读取并比较。新命令 yarn verify:monaco-core-build 支持 --fetch。
|
||||||
|
|
||||||
|
## 浏览器与其他验证
|
||||||
|
|
||||||
|
editor-core.spec.js 每种语言执行真实键盘输入、撤销、重做,打开本地化查找框,
|
||||||
|
等待新查询对应的实际选择范围后跳到下一项,退出并销毁 editor/model。
|
||||||
|
初始测试用了不存在的旧 CSS 组合,页面快照表明查找框已经显示;改成实际
|
||||||
|
可访问名称。又修正了旧选区先于查询更新的测试竞态,未增加任意等待或改运行代码。
|
||||||
|
十种语言在三引擎 30/30 通过,另一个真实 diff worker 用例三引擎 3/3 通过:
|
||||||
|
第二行变更被计算出来、输入改成相同内容后差异清空、模型全部释放。
|
||||||
|
|
||||||
|
单元 20/20、严格 docs-tools 类型与本批 lint 通过。归档/Git 联网复验与离线
|
||||||
|
复验通过,13 个压缩产物相等。环境、输出指纹和两次浏览器报告见
|
||||||
|
[验证记录](../baselines/monaco-core-build-validation.json)。未改变运行资产或许可
|
||||||
|
交付,本批没有重复声称播放器/设备/SDK/远程 CI 验收。
|
||||||
|
|
||||||
|
## 后续与范围
|
||||||
|
|
||||||
|
维护入口:[Monaco README](../../scripts/site-vendor/monaco/README.md)。继续 core
|
||||||
|
贡献模块装配、CSS 以及已定位的来源边界:Node path、WinJS 适配、unicode-utils
|
||||||
|
生成数据、HSL 公式引用和 marked 的 Stack Overflow 片段。引用不自动等于许可
|
||||||
|
缺口,后续需按实际表达和来源确认。本批没有替这些条目作完结判断。
|
||||||
|
SITE-07 doing / VENDOR-06 open,199/265;Thumbnail 默认策略仍待用户答复。
|
||||||
|
可独立回退新增脚本、基线和测试。独立本地提交,不推送、部署或发布。
|
||||||
+1
-1
@@ -653,7 +653,7 @@
|
|||||||
- SITE-AI-DOCS-01: [记录](changes/2026-09-14-SITE-AI-DOCS-01-documentation-pipeline.md) [记录](baselines/documentation-pipeline-validation.json)
|
- SITE-AI-DOCS-01: [记录](changes/2026-09-14-SITE-AI-DOCS-01-documentation-pipeline.md) [记录](baselines/documentation-pipeline-validation.json)
|
||||||
- SITE-BUILD-01: [记录](changes/2026-09-14-SITE-BUILD-01-staged-builds.md) [记录](baselines/site-build-validation.json)
|
- SITE-BUILD-01: [记录](changes/2026-09-14-SITE-BUILD-01-staged-builds.md) [记录](baselines/site-build-validation.json)
|
||||||
- SITE-03: [记录](changes/2026-09-14-SITE-03-desktop-editor.md) [记录](baselines/site-editor-validation.json)
|
- SITE-03: [记录](changes/2026-09-14-SITE-03-desktop-editor.md) [记录](baselines/site-editor-validation.json)
|
||||||
- SITE-07: [记录](site-inventory.md) [记录](baselines/site-provenance.json) [记录](changes/2026-09-14-SITE-07-vendor-notices.md) [记录](baselines/site-notices-checkpoint.json) [记录](baselines/site-codicons-provenance.json) [记录](baselines/site-codicons-validation.json) [记录](changes/2026-09-15-SITE-07-codicons.md) [记录](baselines/vconsole-notices-provenance.json) [记录](baselines/vconsole-notices-validation.json) [记录](changes/2026-09-15-SITE-07-vconsole-notices.md) [记录](console-modernization.md) [记录](baselines/site-console-inventory.json) [记录](baselines/site-console-validation.json) [记录](changes/2026-09-15-SITE-07-console-baseline.md) [记录](baselines/console-feed-provenance.json) [记录](changes/2026-09-15-SITE-07-console-feed-source.md) [记录](baselines/console-commonjs-provenance.json) [记录](changes/2026-09-15-SITE-07-console-commonjs.md) [记录](baselines/console-esm-provenance.json) [记录](changes/2026-09-15-SITE-07-console-esm.md) [记录](baselines/console-embedded-notices.json) [记录](baselines/console-notices-validation.json) [记录](changes/2026-09-15-SITE-07-console-notices.md) [记录](baselines/console-embedded-sources.json) [记录](baselines/console-embedded-validation.json) [记录](changes/2026-09-15-SITE-07-console-embedded-sources.md) [记录](baselines/console-derived-attribution.json) [记录](baselines/console-derived-validation.json) [记录](changes/2026-09-15-SITE-07-console-derived-attribution.md) [记录](baselines/console-stackoverflow-provenance.json) [记录](baselines/console-stackoverflow-validation.json) [记录](changes/2026-09-15-SITE-07-console-stackoverflow.md) [记录](baselines/console-shallowequal-validation.json) [记录](changes/2026-09-15-SITE-07-console-shallowequal.md) [记录](console-notice-review.md) [记录](baselines/console-notice-review-validation.json) [记录](changes/2026-09-15-SITE-07-console-notice-review.md) [记录](baselines/monaco-typescript-provenance.json) [记录](baselines/monaco-typescript-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-typescript.md) [记录](baselines/monaco-languages-provenance.json) [记录](baselines/monaco-languages-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-languages.md) [记录](baselines/monaco-language-notices.json) [记录](baselines/monaco-language-notices-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-language-notices.md) [记录](baselines/monaco-modes-provenance.json) [记录](baselines/monaco-modes-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-modes.md) [记录](baselines/monaco-basic-provenance.json) [记录](baselines/monaco-basic-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-basic.md) [记录](baselines/monaco-core-origins-provenance.json) [记录](baselines/monaco-core-origins-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-core-origins.md)
|
- SITE-07: [记录](site-inventory.md) [记录](baselines/site-provenance.json) [记录](changes/2026-09-14-SITE-07-vendor-notices.md) [记录](baselines/site-notices-checkpoint.json) [记录](baselines/site-codicons-provenance.json) [记录](baselines/site-codicons-validation.json) [记录](changes/2026-09-15-SITE-07-codicons.md) [记录](baselines/vconsole-notices-provenance.json) [记录](baselines/vconsole-notices-validation.json) [记录](changes/2026-09-15-SITE-07-vconsole-notices.md) [记录](console-modernization.md) [记录](baselines/site-console-inventory.json) [记录](baselines/site-console-validation.json) [记录](changes/2026-09-15-SITE-07-console-baseline.md) [记录](baselines/console-feed-provenance.json) [记录](changes/2026-09-15-SITE-07-console-feed-source.md) [记录](baselines/console-commonjs-provenance.json) [记录](changes/2026-09-15-SITE-07-console-commonjs.md) [记录](baselines/console-esm-provenance.json) [记录](changes/2026-09-15-SITE-07-console-esm.md) [记录](baselines/console-embedded-notices.json) [记录](baselines/console-notices-validation.json) [记录](changes/2026-09-15-SITE-07-console-notices.md) [记录](baselines/console-embedded-sources.json) [记录](baselines/console-embedded-validation.json) [记录](changes/2026-09-15-SITE-07-console-embedded-sources.md) [记录](baselines/console-derived-attribution.json) [记录](baselines/console-derived-validation.json) [记录](changes/2026-09-15-SITE-07-console-derived-attribution.md) [记录](baselines/console-stackoverflow-provenance.json) [记录](baselines/console-stackoverflow-validation.json) [记录](changes/2026-09-15-SITE-07-console-stackoverflow.md) [记录](baselines/console-shallowequal-validation.json) [记录](changes/2026-09-15-SITE-07-console-shallowequal.md) [记录](console-notice-review.md) [记录](baselines/console-notice-review-validation.json) [记录](changes/2026-09-15-SITE-07-console-notice-review.md) [记录](baselines/monaco-typescript-provenance.json) [记录](baselines/monaco-typescript-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-typescript.md) [记录](baselines/monaco-languages-provenance.json) [记录](baselines/monaco-languages-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-languages.md) [记录](baselines/monaco-language-notices.json) [记录](baselines/monaco-language-notices-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-language-notices.md) [记录](baselines/monaco-modes-provenance.json) [记录](baselines/monaco-modes-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-modes.md) [记录](baselines/monaco-basic-provenance.json) [记录](baselines/monaco-basic-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-basic.md) [记录](baselines/monaco-core-origins-provenance.json) [记录](baselines/monaco-core-origins-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-core-origins.md) [记录](baselines/monaco-core-build-provenance.json) [记录](baselines/monaco-core-build-validation.json) [记录](changes/2026-09-15-SITE-07-monaco-core-build.md)
|
||||||
- EX-01: [记录](changes/2026-09-14-EX-01-react-consumer.md) [记录](baselines/react-consumer-validation.json) [记录](scripts/react-consumer.mjs)
|
- EX-01: [记录](changes/2026-09-14-EX-01-react-consumer.md) [记录](baselines/react-consumer-validation.json) [记录](scripts/react-consumer.mjs)
|
||||||
- EX-02: [记录](changes/2026-09-14-EX-02-vue-consumer.md) [记录](baselines/vue-consumer-validation.json) [记录](scripts/vue-consumer.mjs)
|
- EX-02: [记录](changes/2026-09-14-EX-02-vue-consumer.md) [记录](baselines/vue-consumer-validation.json) [记录](scripts/vue-consumer.mjs)
|
||||||
- MOD-01: [记录](changes/2026-09-15-MOD-01-bun-evaluation.md) [记录](baselines/bun-install-validation.json) [记录](bun-evaluation.md)
|
- MOD-01: [记录](changes/2026-09-15-MOD-01-bun-evaluation.md) [记录](baselines/bun-install-validation.json) [记录](bun-evaluation.md)
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
# 进度与证据
|
# 进度与证据
|
||||||
|
|
||||||
|
## SITE-07 Monaco 核心压缩与编辑操作
|
||||||
|
|
||||||
|
固定 esbuild 0.12.6 精确复现 13 个 core JS 产物,loader 源码/版本头及 css/nls
|
||||||
|
loader 来源匹配;两个 map 登记 584 条目、549 个不同准备源码。十语言真实编辑/
|
||||||
|
撤销重做/查找/销毁 30/30,diff worker 3/3,单元 20/20、类型/lint、联网/离线
|
||||||
|
来源检查通过。见[记录](changes/2026-09-15-SITE-07-monaco-core-build.md)。完整原始
|
||||||
|
TS 编译与余下内嵌来源未被这些检查替代,SITE-07/VENDOR-06 开放、199/265。
|
||||||
|
后续 core 贡献装配/CSS/已定位来源边界;Thumbnail 默认策略仍待答。
|
||||||
|
|
||||||
## SITE-07 Monaco Markdown 来源与遗漏许可
|
## SITE-07 Monaco Markdown 来源与遗漏许可
|
||||||
|
|
||||||
核实 DOMPurify 2.3.1 / marked 3.0.2 的固定来源及完整模块适配,发现并补齐
|
核实 DOMPurify 2.3.1 / marked 3.0.2 的固定来源及完整模块适配,发现并补齐
|
||||||
|
|||||||
+5
-2
@@ -649,11 +649,14 @@
|
|||||||
"refactor/changes/2026-09-15-SITE-07-monaco-basic.md",
|
"refactor/changes/2026-09-15-SITE-07-monaco-basic.md",
|
||||||
"refactor/baselines/monaco-core-origins-provenance.json",
|
"refactor/baselines/monaco-core-origins-provenance.json",
|
||||||
"refactor/baselines/monaco-core-origins-validation.json",
|
"refactor/baselines/monaco-core-origins-validation.json",
|
||||||
"refactor/changes/2026-09-15-SITE-07-monaco-core-origins.md"
|
"refactor/changes/2026-09-15-SITE-07-monaco-core-origins.md",
|
||||||
|
"refactor/baselines/monaco-core-build-provenance.json",
|
||||||
|
"refactor/baselines/monaco-core-build-validation.json",
|
||||||
|
"refactor/changes/2026-09-15-SITE-07-monaco-core-build.md"
|
||||||
],
|
],
|
||||||
"compatibleResolution": "Keep separate from owned TS migration. Verify source/version/diff and license notices before replacement; preserve API/CSS/worker URLs and run owning package tests.",
|
"compatibleResolution": "Keep separate from owned TS migration. Verify source/version/diff and license notices before replacement; preserve API/CSS/worker URLs and run owning package tests.",
|
||||||
"closureCriteria": "固定上游版本/内容差异、完整组件许可与分发 notices,兼容测试通过;仅当前上游许可证名称不足以关闭。",
|
"closureCriteria": "固定上游版本/内容差异、完整组件许可与分发 notices,兼容测试通过;仅当前上游许可证名称不足以关闭。",
|
||||||
"workspaceState": "Monaco 0.30.1 remains byte-pinned (the known CSS newline-only difference is preserved). Codicons 0.0.26 and the actual TypeScript 4.4.4 worker have original notice supplements. CSS/HTML/JSON workers, four mode bundles and all 76 basic-language bundles reproduce exactly; 2511 upstream plus 12 supplemental tokenizer cases pass in three engines. DOMPurify 2.3.1 and marked 3.0.2 now have exact npm-to-Git/source-map/development adaptations; the missing DOMPurify terms and original/legacy marked licenses are delivered. All 85 site notices and attribution links pass three-engine HTTP/mobile playback checks; Markdown formatting/filtering/hook cleanup also passes. Latest unit 18/18, strict type/lint and four-archive/seven-Git offline/network checks pass. The complete core compiler pipeline, other core/loader/localization and further embedded origins remain open; this is not an exhaustive sanitizer audit or release approval."
|
"workspaceState": "Monaco 0.30.1 remains byte-pinned (the known CSS newline-only difference is preserved). Codicons 0.0.26 and the actual TypeScript 4.4.4 worker have original notice supplements. CSS/HTML/JSON workers, four mode bundles and all 76 basic-language bundles reproduce exactly; 2511 upstream plus 12 supplemental tokenizer cases pass in three engines. DOMPurify 2.3.1 and marked 3.0.2 now have exact npm-to-Git/source-map/development adaptations; the missing DOMPurify terms and original/legacy marked licenses are delivered. All 85 site notices and attribution links pass three-engine HTTP/mobile playback checks; Markdown formatting/filtering/hook cleanup also passes. Latest unit 18/18, strict type/lint and four-archive/seven-Git offline/network checks pass. The complete core compiler pipeline, other core/loader/localization and further embedded origins remain open; this is not an exhaustive sanitizer audit or release approval. All 13 core JavaScript minified outputs now reproduce with locked esbuild 0.12.6 on Windows x64; loader source/header and css/nls sources match fixed Git. Two maps inventory 584 prepared-source entries with 549 different names. Ten-locale editing/find checks pass 30/30 and core diff-worker checks pass 3/3; unit 20/20, type/lint and offline/network checks pass. Complete original TS compilation, appended contributions, CSS and remaining embedded origins are not claimed complete."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "VENDOR-07",
|
"id": "VENDOR-07",
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
# 文档站、示例与生成链清单
|
# 文档站、示例与生成链清单
|
||||||
|
|
||||||
|
核心分发后续:13 个 core JavaScript 压缩产物已通过固定 esbuild 0.12.6 精确
|
||||||
|
复现,loader 与 css/nls loader 固定源码匹配;十种语言编辑/查找和核心 diff
|
||||||
|
worker 三引擎 33/33 通过。两个 source map 的 549 份不同准备源码已登记,
|
||||||
|
后续来源边界与完整编译限制见[记录](changes/2026-09-15-SITE-07-monaco-core-build.md)。
|
||||||
|
|
||||||
当前补充:Monaco 四种 mode 与 76 种基础语言的完整产物复现、三引擎语法验证
|
当前补充:Monaco 四种 mode 与 76 种基础语言的完整产物复现、三引擎语法验证
|
||||||
已完成。核心 Markdown 内嵌 DOMPurify 2.3.1 / marked 3.0.2 的固定来源和模块
|
已完成。核心 Markdown 内嵌 DOMPurify 2.3.1 / marked 3.0.2 的固定来源和模块
|
||||||
适配已匹配;补齐四份说明后站点共交付 85 份 notice。核心其余源码与内嵌来源
|
适配已匹配;补齐四份说明后站点共交付 85 份 notice。核心其余源码与内嵌来源
|
||||||
|
|||||||
+4
-1
@@ -4531,7 +4531,10 @@
|
|||||||
"changes/2026-09-15-SITE-07-monaco-basic.md",
|
"changes/2026-09-15-SITE-07-monaco-basic.md",
|
||||||
"baselines/monaco-core-origins-provenance.json",
|
"baselines/monaco-core-origins-provenance.json",
|
||||||
"baselines/monaco-core-origins-validation.json",
|
"baselines/monaco-core-origins-validation.json",
|
||||||
"changes/2026-09-15-SITE-07-monaco-core-origins.md"
|
"changes/2026-09-15-SITE-07-monaco-core-origins.md",
|
||||||
|
"baselines/monaco-core-build-provenance.json",
|
||||||
|
"baselines/monaco-core-build-validation.json",
|
||||||
|
"changes/2026-09-15-SITE-07-monaco-core-build.md"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -195,3 +195,45 @@ temporary sanitizer hooks. The site test checks every delivered notice byte and
|
|||||||
relative attribution link while exercising mobile playback/logging/disposal.
|
relative attribution link while exercising mobile playback/logging/disposal.
|
||||||
Neither is an exhaustive sanitizer audit. Loader, other core modules, localization,
|
Neither is an exhaustive sanitizer audit. Loader, other core modules, localization,
|
||||||
and further embedded-origin details remain under SITE-07/VENDOR-06.
|
and further embedded-origin details remain under SITE-07/VENDOR-06.
|
||||||
|
|
||||||
|
## Core minification, loader and locales
|
||||||
|
|
||||||
|
`reproduce-core-build.ts` verifies all 13 JavaScript outputs in monaco-editor-core
|
||||||
|
0.30.1: editor, worker, loader, English and nine translations. The fixed VS Code
|
||||||
|
recipe and lock identify esbuild 0.12.6. The selected executable is read from a
|
||||||
|
SHA-512/SHA-256-verified archive and run directly in an ignored cache, without
|
||||||
|
install scripts or root dependency changes. Windows/Linux x64 archives are pinned;
|
||||||
|
only Windows execution has been validated. Other hosts fail explicitly.
|
||||||
|
|
||||||
|
The historical build's node platform/esnext target/minify options reproduce every
|
||||||
|
complete output, including the exact extra newline and relative source-map comment.
|
||||||
|
Twelve files copy directly into the site; editor.main has the previously verified
|
||||||
|
entry rename and core prefix before appended language registrations. This command
|
||||||
|
does not claim to reconstruct those registrations or CSS. The loader's full source
|
||||||
|
and release header match fixed Git; css/nls loader sources match their map entries.
|
||||||
|
|
||||||
|
`core-build.ts` contains static NLS parsing, source-map inventory and map-comment
|
||||||
|
assembly. The NLS parser accepts the archived trailing commas but rejects computed
|
||||||
|
values, duplicate keys and extra statements without evaluating downloaded code.
|
||||||
|
Two archived maps contain 584 prepared-source entries, 549 different names, with
|
||||||
|
content hashes and byte lengths. They are prepared build inputs, not proof of a
|
||||||
|
complete original VS Code TypeScript compilation or license review.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
yarn verify:monaco-core-build --fetch
|
||||||
|
yarn verify:monaco-core-build
|
||||||
|
yarn test:browser test/browser/editor-core.spec.js --workers=1
|
||||||
|
```
|
||||||
|
|
||||||
|
Ten locales each exercise actual keyboard edits, undo/redo, localized find UI,
|
||||||
|
next-match navigation and model disposal in all engines. The test waits for the
|
||||||
|
new selected range after changing the query, not a fixed delay or an old cursor
|
||||||
|
position. A separate diff-editor test requires a real worker, checks changed lines,
|
||||||
|
updates the input to equality, and disposes both models.
|
||||||
|
|
||||||
|
Remaining origin review can start from the map inventory: `dom.ts` references WinJS;
|
||||||
|
`strings.ts` names unicode-utils generators; `color.ts` references HSL formulas;
|
||||||
|
marked names a Stack Overflow snippet; `path.ts` identifies Node 14.16.0 while the
|
||||||
|
older supplied notice links a different commit. Reference comments alone do not
|
||||||
|
establish copied expression or a missing license; inspect actual boundaries and
|
||||||
|
original terms before deciding. Core registration assembly and CSS remain separate.
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import assert from 'node:assert/strict'
|
||||||
|
import path from 'node:path'
|
||||||
|
import ts from 'typescript'
|
||||||
|
import { hash } from './archives.ts'
|
||||||
|
|
||||||
|
export interface CoreSourceMap { sources: string[], sourcesContent: string[] }
|
||||||
|
|
||||||
|
export function inventoryCoreMap(map: CoreSourceMap): { source: string, bytes: number, sha256: string }[] {
|
||||||
|
assert.equal(map.sources.length, map.sourcesContent.length, 'Missing mapped source content')
|
||||||
|
assert.equal(new Set(map.sources).size, map.sources.length, 'Repeated mapped source name')
|
||||||
|
return map.sources.map((source, index) => {
|
||||||
|
const content = map.sourcesContent[index]
|
||||||
|
assert(typeof content === 'string', 'Missing mapped source text')
|
||||||
|
const bytes = new TextEncoder().encode(content)
|
||||||
|
return { source, bytes: bytes.length, sha256: hash(bytes) }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function restoreCoreMapComment(minified: string, relative: string): string {
|
||||||
|
assert(/^vs\/[\w./-]+\.js$/.test(relative) && !relative.split('/').includes('..'), 'Invalid core output path')
|
||||||
|
assert(minified.endsWith('\n'), 'Expected esbuild output newline')
|
||||||
|
const url = path.posix.relative(path.posix.dirname(`min/${relative}`), `min-maps/${relative}.map`)
|
||||||
|
return `${minified}\n//# sourceMappingURL=${url}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function readCoreNls(source: string): { id: string, messages: Record<string, string[]> } {
|
||||||
|
const file = ts.createSourceFile('nls.js', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS)
|
||||||
|
assert.equal(file.statements.length, 1, 'Expected one NLS registration')
|
||||||
|
const statement = file.statements[0]!
|
||||||
|
assert(ts.isExpressionStatement(statement) && ts.isCallExpression(statement.expression), 'Expected literal NLS call')
|
||||||
|
const call = statement.expression
|
||||||
|
assert(ts.isIdentifier(call.expression) && call.expression.text === 'define' && call.arguments.length === 2, 'Expected AMD NLS definition')
|
||||||
|
const name = call.arguments[0]!
|
||||||
|
assert(ts.isStringLiteral(name), 'Expected NLS module name')
|
||||||
|
const data = call.arguments[1]!
|
||||||
|
assert(ts.isObjectLiteralExpression(data), 'Expected literal translation object')
|
||||||
|
const entries = data.properties.map((property) => {
|
||||||
|
assert(ts.isPropertyAssignment(property) && ts.isStringLiteral(property.name) && ts.isArrayLiteralExpression(property.initializer), 'Expected literal translation arrays')
|
||||||
|
return [property.name.text, property.initializer.elements.map((item) => {
|
||||||
|
assert(ts.isStringLiteral(item), 'Expected literal translation text')
|
||||||
|
return item.text
|
||||||
|
})] as const
|
||||||
|
})
|
||||||
|
assert.equal(new Set(entries.map(([name]) => name)).size, entries.length, 'Repeated translation module')
|
||||||
|
const messages = Object.fromEntries(entries)
|
||||||
|
return { id: name.text, messages }
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import type { Archive, Member, Remote } from './archives.ts'
|
||||||
|
import type { CoreSourceMap } from './core-build.ts'
|
||||||
|
import assert from 'node:assert/strict'
|
||||||
|
import { execFileSync } from 'node:child_process'
|
||||||
|
import fs from 'node:fs'
|
||||||
|
import path from 'node:path'
|
||||||
|
import process from 'node:process'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import { ArchiveCache, hash } from './archives.ts'
|
||||||
|
import { inventoryCoreMap, readCoreNls, restoreCoreMapComment } from './core-build.ts'
|
||||||
|
|
||||||
|
interface Record {
|
||||||
|
commit: string
|
||||||
|
archives: Archive[]
|
||||||
|
remotes: Remote[]
|
||||||
|
binaries: { [platform: string]: Member }
|
||||||
|
files: { relative: string, development: Member, minified: Member, target: { path: string, sha256: string }, appendedContributions: boolean }[]
|
||||||
|
sourceMaps: (Member & { sources: ReturnType<typeof inventoryCoreMap> })[]
|
||||||
|
locales: { path: string, sha256: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
const root = fileURLToPath(new URL('../../../', import.meta.url))
|
||||||
|
assert(process.argv.slice(2).every(arg => arg === '--fetch'), 'Use reproduce-core-build.ts [--fetch]')
|
||||||
|
assert.equal(process.version, `v${fs.readFileSync(path.join(root, '.node-version'), 'utf8').trim()}`, 'Use canonical Node')
|
||||||
|
const record: Record = JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/monaco-core-build-provenance.json'), 'utf8'))
|
||||||
|
const host = `${process.platform}-${process.arch}`
|
||||||
|
const binary = record.binaries[host]
|
||||||
|
assert(binary, `No frozen esbuild binary for ${host}`)
|
||||||
|
const cache = new ArchiveCache(root, path.join(root, 'refactor/.cache/monaco-review'))
|
||||||
|
const archives = record.archives.filter(item => !item.name.startsWith('esbuild-') || `${item.name}-${item.version}` === binary.archive)
|
||||||
|
await cache.verify(archives, record.remotes, process.argv.includes('--fetch'))
|
||||||
|
const lock = fs.readFileSync(path.join(root, 'refactor/baselines/site-vendor/monaco-core-build/build-yarn.lock.txt'), 'utf8')
|
||||||
|
const esbuild = archives.find(archive => archive.name === 'esbuild')
|
||||||
|
assert(esbuild && lock.includes(`esbuild@^0.12.6:\n version "0.12.6"`) && lock.includes(`integrity ${esbuild.integrity}`), 'Wrong historical minifier')
|
||||||
|
const executable = path.join(cache.directory, process.platform === 'win32' ? 'core-esbuild.exe' : 'core-esbuild')
|
||||||
|
assert(!fs.existsSync(executable) || !fs.lstatSync(executable).isSymbolicLink(), 'Redirected historical executable')
|
||||||
|
fs.writeFileSync(executable, cache.member(binary), { mode: 0o700 })
|
||||||
|
assert.equal(execFileSync(executable, ['--version'], { encoding: 'utf8' }).trim(), '0.12.6')
|
||||||
|
const sourceFile = path.join(cache.directory, 'core-reproduction-input.js')
|
||||||
|
assert(!fs.existsSync(sourceFile) || !fs.lstatSync(sourceFile).isSymbolicLink(), 'Redirected historical input')
|
||||||
|
const archiveFiles = execFileSync('tar', ['-tzf', path.join(cache.directory, 'monaco-editor-core-0.30.1.tgz')], { encoding: 'utf8' }).trim().split(/\r?\n/)
|
||||||
|
assert.deepEqual(record.files.map(file => file.development.member).sort(), archiveFiles.filter(file => file.startsWith('package/dev/') && file.endsWith('.js')).sort(), 'Missing core JavaScript output')
|
||||||
|
assert.equal(record.files.length, 13)
|
||||||
|
const results = []
|
||||||
|
for (const file of record.files) {
|
||||||
|
const development = cache.member(file.development)
|
||||||
|
fs.writeFileSync(sourceFile, development)
|
||||||
|
const output = execFileSync(executable, [sourceFile, '--minify', '--platform=node', '--target=esnext'], { encoding: 'utf8', maxBuffer: 30 * 1024 * 1024 })
|
||||||
|
const minified = cache.member(file.minified).toString('utf8')
|
||||||
|
assert.equal(restoreCoreMapComment(output, file.relative), minified, 'Core minification differs')
|
||||||
|
const shipped = fs.readFileSync(path.join(root, file.target.path))
|
||||||
|
assert.equal(hash(shipped), file.target.sha256, 'Core site asset changed')
|
||||||
|
assert.deepEqual(shipped, cache.read('monaco-editor-0.30.1', `package/min/${file.relative}`), 'Core editor archive differs')
|
||||||
|
if (file.appendedContributions) {
|
||||||
|
assert.equal(file.relative, 'vs/editor/editor.main.js')
|
||||||
|
const renamed = minified.replace('"vs/editor/editor.main"', '"vs/editor/edcore.main"')
|
||||||
|
const offset = renamed.lastIndexOf('//# sourceMappingURL=')
|
||||||
|
assert(shipped.toString('utf8').startsWith(renamed.slice(0, offset)) && shipped.toString('utf8').endsWith(renamed.slice(offset)), 'Editor core boundary differs')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert.equal(shipped.toString('utf8'), minified, 'Core copied output differs')
|
||||||
|
}
|
||||||
|
results.push({ relative: file.relative, exactMinification: true, appendedContributions: file.appendedContributions, sha256: hash(shipped) })
|
||||||
|
}
|
||||||
|
const maps: CoreSourceMap[] = []
|
||||||
|
for (const member of record.sourceMaps) {
|
||||||
|
const map: CoreSourceMap = JSON.parse(cache.member(member).toString('utf8'))
|
||||||
|
assert.deepEqual(inventoryCoreMap(map), member.sources, 'Prepared source inventory differs')
|
||||||
|
maps.push(map)
|
||||||
|
}
|
||||||
|
for (const name of ['loader', 'css', 'nls']) {
|
||||||
|
const remote = record.remotes.find(remote => remote.source.endsWith(`src-vs-${name}.js.txt`))
|
||||||
|
assert(remote)
|
||||||
|
const source = fs.readFileSync(path.join(root, remote.source), 'utf8')
|
||||||
|
const map = maps.find(map => map.sources.includes(`vs/${name}.js`))
|
||||||
|
assert(map)
|
||||||
|
assert.equal(map.sourcesContent[map.sources.indexOf(`vs/${name}.js`)], source, 'Loader source differs')
|
||||||
|
if (name === 'loader') {
|
||||||
|
const header = `/*!-----------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Version: 0.30.1(${record.commit})\n * Released under the MIT license\n * https://github.com/microsoft/vscode/blob/main/LICENSE.txt\n *-----------------------------------------------------------*/\n\n`
|
||||||
|
assert.equal(cache.read('monaco-editor-core-0.30.1', 'package/dev/vs/loader.js').toString('utf8'), header + source, 'Loader release header differs')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const locales = fs.readFileSync(path.join(root, record.locales.path))
|
||||||
|
assert.equal(hash(locales), record.locales.sha256)
|
||||||
|
for (const locale of JSON.parse(locales.toString('utf8'))) {
|
||||||
|
assert(record.files.some(file => file.development.member === locale.member), 'Unverified locale')
|
||||||
|
const { id, messages } = readCoreNls(cache.read('monaco-editor-core-0.30.1', locale.member).toString('utf8'))
|
||||||
|
assert.equal(id, `vs/editor/editor.main.nls${locale.locale === 'en' ? '' : `.${locale.locale}`}`)
|
||||||
|
const labels = messages['vs/editor/contrib/find/findWidget']!
|
||||||
|
assert.deepEqual([locale.find, locale.next, locale.close], [labels[7], labels[10], labels[12]], 'Locale fixture differs')
|
||||||
|
}
|
||||||
|
console.log(JSON.stringify({ host, archives: archives.length, gitSources: record.remotes.length, outputs: results, mappedInstances: maps.reduce((count, map) => count + map.sources.length, 0), uniqueMappedSources: new Set(maps.flatMap(map => map.sources)).size, completeTypeScriptBuild: false, remainingEmbeddedOriginsReviewed: false }))
|
||||||
@@ -1,5 +1,11 @@
|
|||||||
# Browser regression entry
|
# Browser regression entry
|
||||||
|
|
||||||
|
`editor-core.spec.js` checks editing, keyboard undo/redo, find navigation and disposal
|
||||||
|
for all ten bundled locales. Names come from statically parsed frozen NLS inputs;
|
||||||
|
each localized bundle must load over HTTP. A separate case requires the real core
|
||||||
|
diff worker to compute and clear changes after input updates. On Windows the ten
|
||||||
|
locale cases and worker case pass in Chromium/Firefox/WebKit (33 cases total).
|
||||||
|
|
||||||
`editor-markdown.spec.js` runs the bundled DOMPurify/marked renderer, verifies
|
`editor-markdown.spec.js` runs the bundled DOMPurify/marked renderer, verifies
|
||||||
formatting, selected filtering and temporary-hook cleanup. `site-vendor.spec.js`
|
formatting, selected filtering and temporary-hook cleanup. `site-vendor.spec.js`
|
||||||
also checks all 85 notice files and the core-origin attribution links over HTTP.
|
also checks all 85 notice files and the core-origin attribution links over HTTP.
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
import fs from 'node:fs'
|
||||||
|
import { expect, test } from './fixtures.js'
|
||||||
|
|
||||||
|
const locales = JSON.parse(fs.readFileSync(new URL('../../refactor/baselines/monaco-core-locales.json', import.meta.url)))
|
||||||
|
|
||||||
|
test('docs Monaco core diff worker computes changes and updates after edits', async ({ page }, testInfo) => {
|
||||||
|
const workers = []
|
||||||
|
page.on('worker', worker => workers.push(worker.url()))
|
||||||
|
await page.goto('/test/player.html?core=candidate&chapter=published')
|
||||||
|
await page.addScriptTag({ url: '/assets/js/vs/loader.js' })
|
||||||
|
await page.evaluate(async () => {
|
||||||
|
window.require.config({ paths: { vs: '/assets/js/vs' } })
|
||||||
|
await new Promise((resolve, reject) => window.require(['vs/editor/editor.main'], resolve, reject))
|
||||||
|
const host = document.createElement('div')
|
||||||
|
host.style.cssText = 'width:800px;height:400px'
|
||||||
|
document.body.appendChild(host)
|
||||||
|
const api = window.monaco.editor
|
||||||
|
const original = api.createModel('first\nsecond\nthird', 'plaintext')
|
||||||
|
const modified = api.createModel('first\nchanged\nthird', 'plaintext')
|
||||||
|
const editor = api.createDiffEditor(host)
|
||||||
|
editor.setModel({ original, modified })
|
||||||
|
window.diffProbe = { host, editor, original, modified }
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
await expect.poll(() => page.evaluate(() => window.diffProbe.editor.getLineChanges()?.map(change => [change.originalStartLineNumber, change.originalEndLineNumber, change.modifiedStartLineNumber, change.modifiedEndLineNumber]))).toEqual([[2, 2, 2, 2]])
|
||||||
|
expect(workers.length).toBeGreaterThan(0)
|
||||||
|
await page.evaluate(() => window.diffProbe.modified.setValue(window.diffProbe.original.getValue()))
|
||||||
|
await expect.poll(() => page.evaluate(() => window.diffProbe.editor.getLineChanges())).toEqual([])
|
||||||
|
await testInfo.attach('monaco-core-worker', { contentType: 'application/json', body: JSON.stringify({ workers, initialChangedLines: [2, 2, 2, 2], finalChanges: [] }) })
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
await page.evaluate(() => {
|
||||||
|
const { host, editor, original, modified } = window.diffProbe
|
||||||
|
editor.dispose()
|
||||||
|
original.dispose()
|
||||||
|
modified.dispose()
|
||||||
|
host.remove()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
expect(await page.evaluate(() => window.monaco.editor.getModels().length)).toBe(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
for (const locale of locales) {
|
||||||
|
test(`docs Monaco core editing and localized find: ${locale.locale}`, async ({ page }, testInfo) => {
|
||||||
|
const responses = []
|
||||||
|
page.on('response', (response) => {
|
||||||
|
if (/editor\.main\.nls/.test(response.url()))
|
||||||
|
responses.push({ url: response.url(), status: response.status() })
|
||||||
|
})
|
||||||
|
await page.goto('/test/player.html?core=candidate&chapter=published')
|
||||||
|
await page.addScriptTag({ url: '/assets/js/vs/loader.js' })
|
||||||
|
const modifier = await page.evaluate(async (locale) => {
|
||||||
|
window.require.config({ 'paths': { vs: '/assets/js/vs' }, 'vs/nls': { availableLanguages: locale === 'en' ? {} : { '*': locale } } })
|
||||||
|
const load = ids => new Promise((resolve, reject) => window.require(ids, (...modules) => resolve(modules), reject))
|
||||||
|
await load(['vs/editor/editor.main'])
|
||||||
|
const [platform] = await load(['vs/base/common/platform'])
|
||||||
|
const host = document.createElement('div')
|
||||||
|
host.style.cssText = 'width:800px;height:400px'
|
||||||
|
document.body.appendChild(host)
|
||||||
|
const editor = window.monaco.editor.create(host, { value: 'first\nsecond\nfirst', language: 'plaintext', minimap: { enabled: false } })
|
||||||
|
editor.setPosition({ lineNumber: 1, column: 6 })
|
||||||
|
editor.focus()
|
||||||
|
window.coreProbe = { editor, host }
|
||||||
|
return platform.isMacintosh ? 'Meta' : 'Control'
|
||||||
|
}, locale.locale)
|
||||||
|
try {
|
||||||
|
await page.keyboard.insertText(' beta')
|
||||||
|
await expect.poll(() => page.evaluate(() => window.coreProbe.editor.getValue())).toBe('first beta\nsecond\nfirst')
|
||||||
|
await page.keyboard.press(`${modifier}+z`)
|
||||||
|
await expect.poll(() => page.evaluate(() => window.coreProbe.editor.getValue())).toBe('first\nsecond\nfirst')
|
||||||
|
await page.keyboard.press(modifier === 'Meta' ? 'Meta+Shift+z' : 'Control+y')
|
||||||
|
await expect.poll(() => page.evaluate(() => window.coreProbe.editor.getValue())).toBe('first beta\nsecond\nfirst')
|
||||||
|
await page.evaluate(() => {
|
||||||
|
window.coreProbe.editor.setPosition({ lineNumber: 1, column: 1 })
|
||||||
|
return window.coreProbe.editor.getAction('actions.find').run()
|
||||||
|
})
|
||||||
|
const input = page.getByRole('textbox', { name: locale.find, exact: true })
|
||||||
|
await expect(input).toBeVisible()
|
||||||
|
await expect(input).toHaveAttribute('aria-label', locale.find)
|
||||||
|
await input.fill('st')
|
||||||
|
await expect.poll(() => page.evaluate(() => {
|
||||||
|
const selection = window.coreProbe.editor.getSelection()
|
||||||
|
return [selection.startLineNumber, selection.startColumn, selection.endColumn]
|
||||||
|
})).toEqual([1, 4, 6])
|
||||||
|
await input.press('Enter')
|
||||||
|
await expect.poll(() => page.evaluate(() => window.coreProbe.editor.getSelection().startLineNumber)).toBe(3)
|
||||||
|
await input.press('Escape')
|
||||||
|
await expect(input).not.toBeVisible()
|
||||||
|
expect(responses).toHaveLength(1)
|
||||||
|
expect(responses[0].status).toBe(200)
|
||||||
|
expect(responses[0].url).toContain(`editor.main.nls${locale.locale === 'en' ? '' : `.${locale.locale}`}.js`)
|
||||||
|
await testInfo.attach('monaco-core-editing', { contentType: 'application/json', body: JSON.stringify({ locale, modifier, responses }) })
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
await page.evaluate(() => {
|
||||||
|
const { editor, host } = window.coreProbe
|
||||||
|
const model = editor.getModel()
|
||||||
|
editor.dispose()
|
||||||
|
model.dispose()
|
||||||
|
host.remove()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
expect(await page.evaluate(() => window.monaco.editor.getModels().length)).toBe(0)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -4,10 +4,27 @@ import test from 'node:test'
|
|||||||
import ts from 'typescript'
|
import ts from 'typescript'
|
||||||
import { extractBasicFixtures } from '../scripts/site-vendor/monaco/basic-fixtures.ts'
|
import { extractBasicFixtures } from '../scripts/site-vendor/monaco/basic-fixtures.ts'
|
||||||
import { emitAmd } from '../scripts/site-vendor/monaco/compiler.ts'
|
import { emitAmd } from '../scripts/site-vendor/monaco/compiler.ts'
|
||||||
|
import { inventoryCoreMap, readCoreNls, restoreCoreMapComment } from '../scripts/site-vendor/monaco/core-build.ts'
|
||||||
import { adaptCoreOrigin } from '../scripts/site-vendor/monaco/core-origins.ts'
|
import { adaptCoreOrigin } from '../scripts/site-vendor/monaco/core-origins.ts'
|
||||||
import { aliasModule, moduleIds, nameModule, verifyWorkerSources } from '../scripts/site-vendor/monaco/languages.ts'
|
import { aliasModule, moduleIds, nameModule, verifyWorkerSources } from '../scripts/site-vendor/monaco/languages.ts'
|
||||||
import { browserTypeScript, verifyTypeScriptSource } from '../scripts/site-vendor/monaco/typescript.ts'
|
import { browserTypeScript, verifyTypeScriptSource } from '../scripts/site-vendor/monaco/typescript.ts'
|
||||||
|
|
||||||
|
test('Core NLS extraction accepts historical trailing commas without evaluating expressions', () => {
|
||||||
|
assert.deepEqual(readCoreNls('define("nls", { "find": ["Find", "查找",], });'), { id: 'nls', messages: { find: ['Find', '查找'] } })
|
||||||
|
assert.throws(() => readCoreNls('define("nls", { "find": [translate()], });'), /literal translation text/)
|
||||||
|
assert.throws(() => readCoreNls('define("nls", { "find": [], "find": [] });'), /Repeated translation/)
|
||||||
|
assert.throws(() => readCoreNls('run(); define("nls", {});'), /one NLS registration/)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Core source inventories and map comments reject incomplete or ambiguous evidence', () => {
|
||||||
|
assert.equal(inventoryCoreMap({ sources: ['test'], sourcesContent: ['查找'] })[0].bytes, 6)
|
||||||
|
assert.throws(() => inventoryCoreMap({ sources: ['a'], sourcesContent: [] }), /Missing mapped/)
|
||||||
|
assert.throws(() => inventoryCoreMap({ sources: ['a', 'a'], sourcesContent: ['', ''] }), /Repeated mapped/)
|
||||||
|
assert.equal(restoreCoreMapComment('code;\n', 'vs/loader.js'), 'code;\n\n//# sourceMappingURL=../../min-maps/vs/loader.js.map')
|
||||||
|
assert.throws(() => restoreCoreMapComment('code;', 'vs/loader.js'), /newline/)
|
||||||
|
assert.throws(() => restoreCoreMapComment('code;\n', 'vs/../outside.js'), /output path/)
|
||||||
|
})
|
||||||
|
|
||||||
test('Core origin adaptation rejects duplicate boundaries and preserves replacement bytes', () => {
|
test('Core origin adaptation rejects duplicate boundaries and preserves replacement bytes', () => {
|
||||||
const edits = [{ before: 'export default purify;', after: 'define(factory); // $&' }]
|
const edits = [{ before: 'export default purify;', after: 'define(factory); // $&' }]
|
||||||
assert.equal(adaptCoreOrigin('export default purify;', edits), 'define(factory); // $&')
|
assert.equal(adaptCoreOrigin('export default purify;', edits), 'define(factory); // $&')
|
||||||
|
|||||||
Reference in new issue
Block a user