mirror of
https://github.com/Microsoft/vscode
synced 2024-10-05 19:02:54 +00:00
Merge branch 'master' into ben/sqlite
This commit is contained in:
commit
e4b21b6794
|
@ -13,7 +13,6 @@ const es = require('event-stream');
|
|||
const util = require('./lib/util');
|
||||
const remote = require('gulp-remote-src');
|
||||
const zip = require('gulp-vinyl-zip');
|
||||
const assign = require('object-assign');
|
||||
|
||||
const pkg = require('../package.json');
|
||||
|
||||
|
@ -55,7 +54,7 @@ gulp.task('mixin', function () {
|
|||
.pipe(util.rebase(2))
|
||||
.pipe(productJsonFilter)
|
||||
.pipe(buffer())
|
||||
.pipe(json(o => assign({}, require('../product.json'), o)))
|
||||
.pipe(json(o => Object.assign({}, require('../product.json'), o)))
|
||||
.pipe(productJsonFilter.restore);
|
||||
|
||||
all = es.merge(mixin);
|
||||
|
|
|
@ -4,33 +4,33 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var path = require("path");
|
||||
var es = require("event-stream");
|
||||
var pickle = require('chromium-pickle-js');
|
||||
var Filesystem = require('asar/lib/filesystem');
|
||||
var VinylFile = require("vinyl");
|
||||
var minimatch = require("minimatch");
|
||||
const path = require("path");
|
||||
const es = require("event-stream");
|
||||
const pickle = require('chromium-pickle-js');
|
||||
const Filesystem = require('asar/lib/filesystem');
|
||||
const VinylFile = require("vinyl");
|
||||
const minimatch = require("minimatch");
|
||||
function createAsar(folderPath, unpackGlobs, destFilename) {
|
||||
var shouldUnpackFile = function (file) {
|
||||
for (var i = 0; i < unpackGlobs.length; i++) {
|
||||
const shouldUnpackFile = (file) => {
|
||||
for (let i = 0; i < unpackGlobs.length; i++) {
|
||||
if (minimatch(file.relative, unpackGlobs[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
var filesystem = new Filesystem(folderPath);
|
||||
var out = [];
|
||||
const filesystem = new Filesystem(folderPath);
|
||||
const out = [];
|
||||
// Keep track of pending inserts
|
||||
var pendingInserts = 0;
|
||||
var onFileInserted = function () { pendingInserts--; };
|
||||
let pendingInserts = 0;
|
||||
let onFileInserted = () => { pendingInserts--; };
|
||||
// Do not insert twice the same directory
|
||||
var seenDir = {};
|
||||
var insertDirectoryRecursive = function (dir) {
|
||||
const seenDir = {};
|
||||
const insertDirectoryRecursive = (dir) => {
|
||||
if (seenDir[dir]) {
|
||||
return;
|
||||
}
|
||||
var lastSlash = dir.lastIndexOf('/');
|
||||
let lastSlash = dir.lastIndexOf('/');
|
||||
if (lastSlash === -1) {
|
||||
lastSlash = dir.lastIndexOf('\\');
|
||||
}
|
||||
|
@ -40,8 +40,8 @@ function createAsar(folderPath, unpackGlobs, destFilename) {
|
|||
seenDir[dir] = true;
|
||||
filesystem.insertDirectory(dir);
|
||||
};
|
||||
var insertDirectoryForFile = function (file) {
|
||||
var lastSlash = file.lastIndexOf('/');
|
||||
const insertDirectoryForFile = (file) => {
|
||||
let lastSlash = file.lastIndexOf('/');
|
||||
if (lastSlash === -1) {
|
||||
lastSlash = file.lastIndexOf('\\');
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ function createAsar(folderPath, unpackGlobs, destFilename) {
|
|||
insertDirectoryRecursive(file.substring(0, lastSlash));
|
||||
}
|
||||
};
|
||||
var insertFile = function (relativePath, stat, shouldUnpack) {
|
||||
const insertFile = (relativePath, stat, shouldUnpack) => {
|
||||
insertDirectoryForFile(relativePath);
|
||||
pendingInserts++;
|
||||
filesystem.insertFile(relativePath, shouldUnpack, { stat: stat }, {}, onFileInserted);
|
||||
|
@ -59,13 +59,13 @@ function createAsar(folderPath, unpackGlobs, destFilename) {
|
|||
return;
|
||||
}
|
||||
if (!file.stat.isFile()) {
|
||||
throw new Error("unknown item in stream!");
|
||||
throw new Error(`unknown item in stream!`);
|
||||
}
|
||||
var shouldUnpack = shouldUnpackFile(file);
|
||||
const shouldUnpack = shouldUnpackFile(file);
|
||||
insertFile(file.relative, { size: file.contents.length, mode: file.stat.mode }, shouldUnpack);
|
||||
if (shouldUnpack) {
|
||||
// The file goes outside of xx.asar, in a folder xx.asar.unpacked
|
||||
var relative = path.relative(folderPath, file.path);
|
||||
const relative = path.relative(folderPath, file.path);
|
||||
this.queue(new VinylFile({
|
||||
cwd: folderPath,
|
||||
base: folderPath,
|
||||
|
@ -79,34 +79,33 @@ function createAsar(folderPath, unpackGlobs, destFilename) {
|
|||
out.push(file.contents);
|
||||
}
|
||||
}, function () {
|
||||
var _this = this;
|
||||
var finish = function () {
|
||||
let finish = () => {
|
||||
{
|
||||
var headerPickle = pickle.createEmpty();
|
||||
const headerPickle = pickle.createEmpty();
|
||||
headerPickle.writeString(JSON.stringify(filesystem.header));
|
||||
var headerBuf = headerPickle.toBuffer();
|
||||
var sizePickle = pickle.createEmpty();
|
||||
const headerBuf = headerPickle.toBuffer();
|
||||
const sizePickle = pickle.createEmpty();
|
||||
sizePickle.writeUInt32(headerBuf.length);
|
||||
var sizeBuf = sizePickle.toBuffer();
|
||||
const sizeBuf = sizePickle.toBuffer();
|
||||
out.unshift(headerBuf);
|
||||
out.unshift(sizeBuf);
|
||||
}
|
||||
var contents = Buffer.concat(out);
|
||||
const contents = Buffer.concat(out);
|
||||
out.length = 0;
|
||||
_this.queue(new VinylFile({
|
||||
this.queue(new VinylFile({
|
||||
cwd: folderPath,
|
||||
base: folderPath,
|
||||
path: destFilename,
|
||||
contents: contents
|
||||
}));
|
||||
_this.queue(null);
|
||||
this.queue(null);
|
||||
};
|
||||
// Call finish() only when all file inserts have finished...
|
||||
if (pendingInserts === 0) {
|
||||
finish();
|
||||
}
|
||||
else {
|
||||
onFileInserted = function () {
|
||||
onFileInserted = () => {
|
||||
pendingInserts--;
|
||||
if (pendingInserts === 0) {
|
||||
finish();
|
||||
|
|
|
@ -4,19 +4,19 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var vm = require("vm");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const vm = require("vm");
|
||||
/**
|
||||
* Bundle `entryPoints` given config `config`.
|
||||
*/
|
||||
function bundle(entryPoints, config, callback) {
|
||||
var entryPointsMap = {};
|
||||
entryPoints.forEach(function (module) {
|
||||
const entryPointsMap = {};
|
||||
entryPoints.forEach((module) => {
|
||||
entryPointsMap[module.name] = module;
|
||||
});
|
||||
var allMentionedModulesMap = {};
|
||||
entryPoints.forEach(function (module) {
|
||||
const allMentionedModulesMap = {};
|
||||
entryPoints.forEach((module) => {
|
||||
allMentionedModulesMap[module.name] = true;
|
||||
(module.include || []).forEach(function (includedModule) {
|
||||
allMentionedModulesMap[includedModule] = true;
|
||||
|
@ -25,11 +25,11 @@ function bundle(entryPoints, config, callback) {
|
|||
allMentionedModulesMap[excludedModule] = true;
|
||||
});
|
||||
});
|
||||
var code = require('fs').readFileSync(path.join(__dirname, '../../src/vs/loader.js'));
|
||||
var r = vm.runInThisContext('(function(require, module, exports) { ' + code + '\n});');
|
||||
var loaderModule = { exports: {} };
|
||||
const code = require('fs').readFileSync(path.join(__dirname, '../../src/vs/loader.js'));
|
||||
const r = vm.runInThisContext('(function(require, module, exports) { ' + code + '\n});');
|
||||
const loaderModule = { exports: {} };
|
||||
r.call({}, require, loaderModule, loaderModule.exports);
|
||||
var loader = loaderModule.exports;
|
||||
const loader = loaderModule.exports;
|
||||
config.isBuild = true;
|
||||
config.paths = config.paths || {};
|
||||
if (!config.paths['vs/nls']) {
|
||||
|
@ -39,16 +39,16 @@ function bundle(entryPoints, config, callback) {
|
|||
config.paths['vs/css'] = 'out-build/vs/css.build';
|
||||
}
|
||||
loader.config(config);
|
||||
loader(['require'], function (localRequire) {
|
||||
var resolvePath = function (path) {
|
||||
var r = localRequire.toUrl(path);
|
||||
loader(['require'], (localRequire) => {
|
||||
const resolvePath = (path) => {
|
||||
const r = localRequire.toUrl(path);
|
||||
if (!/\.js/.test(r)) {
|
||||
return r + '.js';
|
||||
}
|
||||
return r;
|
||||
};
|
||||
for (var moduleId in entryPointsMap) {
|
||||
var entryPoint = entryPointsMap[moduleId];
|
||||
for (const moduleId in entryPointsMap) {
|
||||
const entryPoint = entryPointsMap[moduleId];
|
||||
if (entryPoint.append) {
|
||||
entryPoint.append = entryPoint.append.map(resolvePath);
|
||||
}
|
||||
|
@ -57,59 +57,59 @@ function bundle(entryPoints, config, callback) {
|
|||
}
|
||||
}
|
||||
});
|
||||
loader(Object.keys(allMentionedModulesMap), function () {
|
||||
var modules = loader.getBuildInfo();
|
||||
var partialResult = emitEntryPoints(modules, entryPointsMap);
|
||||
var cssInlinedResources = loader('vs/css').getInlinedResources();
|
||||
loader(Object.keys(allMentionedModulesMap), () => {
|
||||
const modules = loader.getBuildInfo();
|
||||
const partialResult = emitEntryPoints(modules, entryPointsMap);
|
||||
const cssInlinedResources = loader('vs/css').getInlinedResources();
|
||||
callback(null, {
|
||||
files: partialResult.files,
|
||||
cssInlinedResources: cssInlinedResources,
|
||||
bundleData: partialResult.bundleData
|
||||
});
|
||||
}, function (err) { return callback(err, null); });
|
||||
}, (err) => callback(err, null));
|
||||
}
|
||||
exports.bundle = bundle;
|
||||
function emitEntryPoints(modules, entryPoints) {
|
||||
var modulesMap = {};
|
||||
modules.forEach(function (m) {
|
||||
const modulesMap = {};
|
||||
modules.forEach((m) => {
|
||||
modulesMap[m.id] = m;
|
||||
});
|
||||
var modulesGraph = {};
|
||||
modules.forEach(function (m) {
|
||||
const modulesGraph = {};
|
||||
modules.forEach((m) => {
|
||||
modulesGraph[m.id] = m.dependencies;
|
||||
});
|
||||
var sortedModules = topologicalSort(modulesGraph);
|
||||
var result = [];
|
||||
var usedPlugins = {};
|
||||
var bundleData = {
|
||||
const sortedModules = topologicalSort(modulesGraph);
|
||||
let result = [];
|
||||
const usedPlugins = {};
|
||||
const bundleData = {
|
||||
graph: modulesGraph,
|
||||
bundles: {}
|
||||
};
|
||||
Object.keys(entryPoints).forEach(function (moduleToBundle) {
|
||||
var info = entryPoints[moduleToBundle];
|
||||
var rootNodes = [moduleToBundle].concat(info.include || []);
|
||||
var allDependencies = visit(rootNodes, modulesGraph);
|
||||
var excludes = ['require', 'exports', 'module'].concat(info.exclude || []);
|
||||
excludes.forEach(function (excludeRoot) {
|
||||
var allExcludes = visit([excludeRoot], modulesGraph);
|
||||
Object.keys(allExcludes).forEach(function (exclude) {
|
||||
Object.keys(entryPoints).forEach((moduleToBundle) => {
|
||||
const info = entryPoints[moduleToBundle];
|
||||
const rootNodes = [moduleToBundle].concat(info.include || []);
|
||||
const allDependencies = visit(rootNodes, modulesGraph);
|
||||
const excludes = ['require', 'exports', 'module'].concat(info.exclude || []);
|
||||
excludes.forEach((excludeRoot) => {
|
||||
const allExcludes = visit([excludeRoot], modulesGraph);
|
||||
Object.keys(allExcludes).forEach((exclude) => {
|
||||
delete allDependencies[exclude];
|
||||
});
|
||||
});
|
||||
var includedModules = sortedModules.filter(function (module) {
|
||||
const includedModules = sortedModules.filter((module) => {
|
||||
return allDependencies[module];
|
||||
});
|
||||
bundleData.bundles[moduleToBundle] = includedModules;
|
||||
var res = emitEntryPoint(modulesMap, modulesGraph, moduleToBundle, includedModules, info.prepend || [], info.append || [], info.dest);
|
||||
const res = emitEntryPoint(modulesMap, modulesGraph, moduleToBundle, includedModules, info.prepend || [], info.append || [], info.dest);
|
||||
result = result.concat(res.files);
|
||||
for (var pluginName in res.usedPlugins) {
|
||||
for (const pluginName in res.usedPlugins) {
|
||||
usedPlugins[pluginName] = usedPlugins[pluginName] || res.usedPlugins[pluginName];
|
||||
}
|
||||
});
|
||||
Object.keys(usedPlugins).forEach(function (pluginName) {
|
||||
var plugin = usedPlugins[pluginName];
|
||||
Object.keys(usedPlugins).forEach((pluginName) => {
|
||||
const plugin = usedPlugins[pluginName];
|
||||
if (typeof plugin.finishBuild === 'function') {
|
||||
var write = function (filename, contents) {
|
||||
const write = (filename, contents) => {
|
||||
result.push({
|
||||
dest: filename,
|
||||
sources: [{
|
||||
|
@ -128,16 +128,16 @@ function emitEntryPoints(modules, entryPoints) {
|
|||
};
|
||||
}
|
||||
function extractStrings(destFiles) {
|
||||
var parseDefineCall = function (moduleMatch, depsMatch) {
|
||||
var module = moduleMatch.replace(/^"|"$/g, '');
|
||||
var deps = depsMatch.split(',');
|
||||
deps = deps.map(function (dep) {
|
||||
const parseDefineCall = (moduleMatch, depsMatch) => {
|
||||
const module = moduleMatch.replace(/^"|"$/g, '');
|
||||
let deps = depsMatch.split(',');
|
||||
deps = deps.map((dep) => {
|
||||
dep = dep.trim();
|
||||
dep = dep.replace(/^"|"$/g, '');
|
||||
dep = dep.replace(/^'|'$/g, '');
|
||||
var prefix = null;
|
||||
var _path = null;
|
||||
var pieces = dep.split('!');
|
||||
let prefix = null;
|
||||
let _path = null;
|
||||
const pieces = dep.split('!');
|
||||
if (pieces.length > 1) {
|
||||
prefix = pieces[0] + '!';
|
||||
_path = pieces[1];
|
||||
|
@ -147,7 +147,7 @@ function extractStrings(destFiles) {
|
|||
_path = pieces[0];
|
||||
}
|
||||
if (/^\.\//.test(_path) || /^\.\.\//.test(_path)) {
|
||||
var res = path.join(path.dirname(module), _path).replace(/\\/g, '/');
|
||||
const res = path.join(path.dirname(module), _path).replace(/\\/g, '/');
|
||||
return prefix + res;
|
||||
}
|
||||
return prefix + _path;
|
||||
|
@ -157,7 +157,7 @@ function extractStrings(destFiles) {
|
|||
deps: deps
|
||||
};
|
||||
};
|
||||
destFiles.forEach(function (destFile) {
|
||||
destFiles.forEach((destFile) => {
|
||||
if (!/\.js$/.test(destFile.dest)) {
|
||||
return;
|
||||
}
|
||||
|
@ -165,44 +165,44 @@ function extractStrings(destFiles) {
|
|||
return;
|
||||
}
|
||||
// Do one pass to record the usage counts for each module id
|
||||
var useCounts = {};
|
||||
destFile.sources.forEach(function (source) {
|
||||
var matches = source.contents.match(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/);
|
||||
const useCounts = {};
|
||||
destFile.sources.forEach((source) => {
|
||||
const matches = source.contents.match(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/);
|
||||
if (!matches) {
|
||||
return;
|
||||
}
|
||||
var defineCall = parseDefineCall(matches[1], matches[2]);
|
||||
const defineCall = parseDefineCall(matches[1], matches[2]);
|
||||
useCounts[defineCall.module] = (useCounts[defineCall.module] || 0) + 1;
|
||||
defineCall.deps.forEach(function (dep) {
|
||||
defineCall.deps.forEach((dep) => {
|
||||
useCounts[dep] = (useCounts[dep] || 0) + 1;
|
||||
});
|
||||
});
|
||||
var sortedByUseModules = Object.keys(useCounts);
|
||||
sortedByUseModules.sort(function (a, b) {
|
||||
const sortedByUseModules = Object.keys(useCounts);
|
||||
sortedByUseModules.sort((a, b) => {
|
||||
return useCounts[b] - useCounts[a];
|
||||
});
|
||||
var replacementMap = {};
|
||||
sortedByUseModules.forEach(function (module, index) {
|
||||
const replacementMap = {};
|
||||
sortedByUseModules.forEach((module, index) => {
|
||||
replacementMap[module] = index;
|
||||
});
|
||||
destFile.sources.forEach(function (source) {
|
||||
source.contents = source.contents.replace(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/, function (_, moduleMatch, depsMatch) {
|
||||
var defineCall = parseDefineCall(moduleMatch, depsMatch);
|
||||
return "define(__m[" + replacementMap[defineCall.module] + "/*" + defineCall.module + "*/], __M([" + defineCall.deps.map(function (dep) { return replacementMap[dep] + '/*' + dep + '*/'; }).join(',') + "])";
|
||||
destFile.sources.forEach((source) => {
|
||||
source.contents = source.contents.replace(/define\(("[^"]+"),\s*\[(((, )?("|')[^"']+("|'))+)\]/, (_, moduleMatch, depsMatch) => {
|
||||
const defineCall = parseDefineCall(moduleMatch, depsMatch);
|
||||
return `define(__m[${replacementMap[defineCall.module]}/*${defineCall.module}*/], __M([${defineCall.deps.map(dep => replacementMap[dep] + '/*' + dep + '*/').join(',')}])`;
|
||||
});
|
||||
});
|
||||
destFile.sources.unshift({
|
||||
path: null,
|
||||
contents: [
|
||||
'(function() {',
|
||||
"var __m = " + JSON.stringify(sortedByUseModules) + ";",
|
||||
"var __M = function(deps) {",
|
||||
" var result = [];",
|
||||
" for (var i = 0, len = deps.length; i < len; i++) {",
|
||||
" result[i] = __m[deps[i]];",
|
||||
" }",
|
||||
" return result;",
|
||||
"};"
|
||||
`var __m = ${JSON.stringify(sortedByUseModules)};`,
|
||||
`var __M = function(deps) {`,
|
||||
` var result = [];`,
|
||||
` for (var i = 0, len = deps.length; i < len; i++) {`,
|
||||
` result[i] = __m[deps[i]];`,
|
||||
` }`,
|
||||
` return result;`,
|
||||
`};`
|
||||
].join('\n')
|
||||
});
|
||||
destFile.sources.push({
|
||||
|
@ -214,7 +214,7 @@ function extractStrings(destFiles) {
|
|||
}
|
||||
function removeDuplicateTSBoilerplate(destFiles) {
|
||||
// Taken from typescript compiler => emitFiles
|
||||
var BOILERPLATE = [
|
||||
const BOILERPLATE = [
|
||||
{ start: /^var __extends/, end: /^}\)\(\);$/ },
|
||||
{ start: /^var __assign/, end: /^};$/ },
|
||||
{ start: /^var __decorate/, end: /^};$/ },
|
||||
|
@ -223,14 +223,14 @@ function removeDuplicateTSBoilerplate(destFiles) {
|
|||
{ start: /^var __awaiter/, end: /^};$/ },
|
||||
{ start: /^var __generator/, end: /^};$/ },
|
||||
];
|
||||
destFiles.forEach(function (destFile) {
|
||||
var SEEN_BOILERPLATE = [];
|
||||
destFile.sources.forEach(function (source) {
|
||||
var lines = source.contents.split(/\r\n|\n|\r/);
|
||||
var newLines = [];
|
||||
var IS_REMOVING_BOILERPLATE = false, END_BOILERPLATE;
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var line = lines[i];
|
||||
destFiles.forEach((destFile) => {
|
||||
const SEEN_BOILERPLATE = [];
|
||||
destFile.sources.forEach((source) => {
|
||||
const lines = source.contents.split(/\r\n|\n|\r/);
|
||||
const newLines = [];
|
||||
let IS_REMOVING_BOILERPLATE = false, END_BOILERPLATE;
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
if (IS_REMOVING_BOILERPLATE) {
|
||||
newLines.push('');
|
||||
if (END_BOILERPLATE.test(line)) {
|
||||
|
@ -238,8 +238,8 @@ function removeDuplicateTSBoilerplate(destFiles) {
|
|||
}
|
||||
}
|
||||
else {
|
||||
for (var j = 0; j < BOILERPLATE.length; j++) {
|
||||
var boilerplate = BOILERPLATE[j];
|
||||
for (let j = 0; j < BOILERPLATE.length; j++) {
|
||||
const boilerplate = BOILERPLATE[j];
|
||||
if (boilerplate.start.test(line)) {
|
||||
if (SEEN_BOILERPLATE[j]) {
|
||||
IS_REMOVING_BOILERPLATE = true;
|
||||
|
@ -267,30 +267,30 @@ function emitEntryPoint(modulesMap, deps, entryPoint, includedModules, prepend,
|
|||
if (!dest) {
|
||||
dest = entryPoint + '.js';
|
||||
}
|
||||
var mainResult = {
|
||||
const mainResult = {
|
||||
sources: [],
|
||||
dest: dest
|
||||
}, results = [mainResult];
|
||||
var usedPlugins = {};
|
||||
var getLoaderPlugin = function (pluginName) {
|
||||
const usedPlugins = {};
|
||||
const getLoaderPlugin = (pluginName) => {
|
||||
if (!usedPlugins[pluginName]) {
|
||||
usedPlugins[pluginName] = modulesMap[pluginName].exports;
|
||||
}
|
||||
return usedPlugins[pluginName];
|
||||
};
|
||||
includedModules.forEach(function (c) {
|
||||
var bangIndex = c.indexOf('!');
|
||||
includedModules.forEach((c) => {
|
||||
const bangIndex = c.indexOf('!');
|
||||
if (bangIndex >= 0) {
|
||||
var pluginName = c.substr(0, bangIndex);
|
||||
var plugin = getLoaderPlugin(pluginName);
|
||||
const pluginName = c.substr(0, bangIndex);
|
||||
const plugin = getLoaderPlugin(pluginName);
|
||||
mainResult.sources.push(emitPlugin(entryPoint, plugin, pluginName, c.substr(bangIndex + 1)));
|
||||
return;
|
||||
}
|
||||
var module = modulesMap[c];
|
||||
const module = modulesMap[c];
|
||||
if (module.path === 'empty:') {
|
||||
return;
|
||||
}
|
||||
var contents = readFileAndRemoveBOM(module.path);
|
||||
const contents = readFileAndRemoveBOM(module.path);
|
||||
if (module.shim) {
|
||||
mainResult.sources.push(emitShimmedModule(c, deps[c], module.shim, module.path, contents));
|
||||
}
|
||||
|
@ -298,14 +298,14 @@ function emitEntryPoint(modulesMap, deps, entryPoint, includedModules, prepend,
|
|||
mainResult.sources.push(emitNamedModule(c, module.defineLocation, module.path, contents));
|
||||
}
|
||||
});
|
||||
Object.keys(usedPlugins).forEach(function (pluginName) {
|
||||
var plugin = usedPlugins[pluginName];
|
||||
Object.keys(usedPlugins).forEach((pluginName) => {
|
||||
const plugin = usedPlugins[pluginName];
|
||||
if (typeof plugin.writeFile === 'function') {
|
||||
var req = (function () {
|
||||
const req = (() => {
|
||||
throw new Error('no-no!');
|
||||
});
|
||||
req.toUrl = function (something) { return something; };
|
||||
var write = function (filename, contents) {
|
||||
req.toUrl = something => something;
|
||||
const write = (filename, contents) => {
|
||||
results.push({
|
||||
dest: filename,
|
||||
sources: [{
|
||||
|
@ -317,15 +317,15 @@ function emitEntryPoint(modulesMap, deps, entryPoint, includedModules, prepend,
|
|||
plugin.writeFile(pluginName, entryPoint, req, write, {});
|
||||
}
|
||||
});
|
||||
var toIFile = function (path) {
|
||||
var contents = readFileAndRemoveBOM(path);
|
||||
const toIFile = (path) => {
|
||||
const contents = readFileAndRemoveBOM(path);
|
||||
return {
|
||||
path: path,
|
||||
contents: contents
|
||||
};
|
||||
};
|
||||
var toPrepend = (prepend || []).map(toIFile);
|
||||
var toAppend = (append || []).map(toIFile);
|
||||
const toPrepend = (prepend || []).map(toIFile);
|
||||
const toAppend = (append || []).map(toIFile);
|
||||
mainResult.sources = toPrepend.concat(mainResult.sources).concat(toAppend);
|
||||
return {
|
||||
files: results,
|
||||
|
@ -333,8 +333,8 @@ function emitEntryPoint(modulesMap, deps, entryPoint, includedModules, prepend,
|
|||
};
|
||||
}
|
||||
function readFileAndRemoveBOM(path) {
|
||||
var BOM_CHAR_CODE = 65279;
|
||||
var contents = fs.readFileSync(path, 'utf8');
|
||||
const BOM_CHAR_CODE = 65279;
|
||||
let contents = fs.readFileSync(path, 'utf8');
|
||||
// Remove BOM
|
||||
if (contents.charCodeAt(0) === BOM_CHAR_CODE) {
|
||||
contents = contents.substring(1);
|
||||
|
@ -342,15 +342,15 @@ function readFileAndRemoveBOM(path) {
|
|||
return contents;
|
||||
}
|
||||
function emitPlugin(entryPoint, plugin, pluginName, moduleName) {
|
||||
var result = '';
|
||||
let result = '';
|
||||
if (typeof plugin.write === 'function') {
|
||||
var write = (function (what) {
|
||||
const write = ((what) => {
|
||||
result += what;
|
||||
});
|
||||
write.getEntryPoint = function () {
|
||||
write.getEntryPoint = () => {
|
||||
return entryPoint;
|
||||
};
|
||||
write.asModule = function (moduleId, code) {
|
||||
write.asModule = (moduleId, code) => {
|
||||
code = code.replace(/^define\(/, 'define("' + moduleId + '",');
|
||||
result += code;
|
||||
};
|
||||
|
@ -363,18 +363,18 @@ function emitPlugin(entryPoint, plugin, pluginName, moduleName) {
|
|||
}
|
||||
function emitNamedModule(moduleId, defineCallPosition, path, contents) {
|
||||
// `defineCallPosition` is the position in code: |define()
|
||||
var defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
|
||||
const defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
|
||||
// `parensOffset` is the position in code: define|()
|
||||
var parensOffset = contents.indexOf('(', defineCallOffset);
|
||||
var insertStr = '"' + moduleId + '", ';
|
||||
const parensOffset = contents.indexOf('(', defineCallOffset);
|
||||
const insertStr = '"' + moduleId + '", ';
|
||||
return {
|
||||
path: path,
|
||||
contents: contents.substr(0, parensOffset + 1) + insertStr + contents.substr(parensOffset + 1)
|
||||
};
|
||||
}
|
||||
function emitShimmedModule(moduleId, myDeps, factory, path, contents) {
|
||||
var strDeps = (myDeps.length > 0 ? '"' + myDeps.join('", "') + '"' : '');
|
||||
var strDefine = 'define("' + moduleId + '", [' + strDeps + '], ' + factory + ');';
|
||||
const strDeps = (myDeps.length > 0 ? '"' + myDeps.join('", "') + '"' : '');
|
||||
const strDefine = 'define("' + moduleId + '", [' + strDeps + '], ' + factory + ');';
|
||||
return {
|
||||
path: path,
|
||||
contents: contents + '\n;\n' + strDefine
|
||||
|
@ -387,8 +387,8 @@ function positionToOffset(str, desiredLine, desiredCol) {
|
|||
if (desiredLine === 1) {
|
||||
return desiredCol - 1;
|
||||
}
|
||||
var line = 1;
|
||||
var lastNewLineOffset = -1;
|
||||
let line = 1;
|
||||
let lastNewLineOffset = -1;
|
||||
do {
|
||||
if (desiredLine === line) {
|
||||
return lastNewLineOffset + 1 + desiredCol - 1;
|
||||
|
@ -402,15 +402,15 @@ function positionToOffset(str, desiredLine, desiredCol) {
|
|||
* Return a set of reachable nodes in `graph` starting from `rootNodes`
|
||||
*/
|
||||
function visit(rootNodes, graph) {
|
||||
var result = {};
|
||||
var queue = rootNodes;
|
||||
rootNodes.forEach(function (node) {
|
||||
const result = {};
|
||||
const queue = rootNodes;
|
||||
rootNodes.forEach((node) => {
|
||||
result[node] = true;
|
||||
});
|
||||
while (queue.length > 0) {
|
||||
var el = queue.shift();
|
||||
var myEdges = graph[el] || [];
|
||||
myEdges.forEach(function (toNode) {
|
||||
const el = queue.shift();
|
||||
const myEdges = graph[el] || [];
|
||||
myEdges.forEach((toNode) => {
|
||||
if (!result[toNode]) {
|
||||
result[toNode] = true;
|
||||
queue.push(toNode);
|
||||
|
@ -423,11 +423,11 @@ function visit(rootNodes, graph) {
|
|||
* Perform a topological sort on `graph`
|
||||
*/
|
||||
function topologicalSort(graph) {
|
||||
var allNodes = {}, outgoingEdgeCount = {}, inverseEdges = {};
|
||||
Object.keys(graph).forEach(function (fromNode) {
|
||||
const allNodes = {}, outgoingEdgeCount = {}, inverseEdges = {};
|
||||
Object.keys(graph).forEach((fromNode) => {
|
||||
allNodes[fromNode] = true;
|
||||
outgoingEdgeCount[fromNode] = graph[fromNode].length;
|
||||
graph[fromNode].forEach(function (toNode) {
|
||||
graph[fromNode].forEach((toNode) => {
|
||||
allNodes[toNode] = true;
|
||||
outgoingEdgeCount[toNode] = outgoingEdgeCount[toNode] || 0;
|
||||
inverseEdges[toNode] = inverseEdges[toNode] || [];
|
||||
|
@ -435,8 +435,8 @@ function topologicalSort(graph) {
|
|||
});
|
||||
});
|
||||
// https://en.wikipedia.org/wiki/Topological_sorting
|
||||
var S = [], L = [];
|
||||
Object.keys(allNodes).forEach(function (node) {
|
||||
const S = [], L = [];
|
||||
Object.keys(allNodes).forEach((node) => {
|
||||
if (outgoingEdgeCount[node] === 0) {
|
||||
delete outgoingEdgeCount[node];
|
||||
S.push(node);
|
||||
|
@ -445,10 +445,10 @@ function topologicalSort(graph) {
|
|||
while (S.length > 0) {
|
||||
// Ensure the exact same order all the time with the same inputs
|
||||
S.sort();
|
||||
var n = S.shift();
|
||||
const n = S.shift();
|
||||
L.push(n);
|
||||
var myInverseEdges = inverseEdges[n] || [];
|
||||
myInverseEdges.forEach(function (m) {
|
||||
const myInverseEdges = inverseEdges[n] || [];
|
||||
myInverseEdges.forEach((m) => {
|
||||
outgoingEdgeCount[m]--;
|
||||
if (outgoingEdgeCount[m] === 0) {
|
||||
delete outgoingEdgeCount[m];
|
||||
|
|
|
@ -4,27 +4,26 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var es = require("event-stream");
|
||||
var fs = require("fs");
|
||||
var gulp = require("gulp");
|
||||
var bom = require("gulp-bom");
|
||||
var sourcemaps = require("gulp-sourcemaps");
|
||||
var tsb = require("gulp-tsb");
|
||||
var path = require("path");
|
||||
var _ = require("underscore");
|
||||
var monacodts = require("../monaco/api");
|
||||
var nls = require("./nls");
|
||||
var reporter_1 = require("./reporter");
|
||||
var util = require("./util");
|
||||
var watch = require('./watch');
|
||||
var assign = require("object-assign");
|
||||
var reporter = reporter_1.createReporter();
|
||||
const es = require("event-stream");
|
||||
const fs = require("fs");
|
||||
const gulp = require("gulp");
|
||||
const bom = require("gulp-bom");
|
||||
const sourcemaps = require("gulp-sourcemaps");
|
||||
const tsb = require("gulp-tsb");
|
||||
const path = require("path");
|
||||
const _ = require("underscore");
|
||||
const monacodts = require("../monaco/api");
|
||||
const nls = require("./nls");
|
||||
const reporter_1 = require("./reporter");
|
||||
const util = require("./util");
|
||||
const watch = require('./watch');
|
||||
const reporter = reporter_1.createReporter();
|
||||
function getTypeScriptCompilerOptions(src) {
|
||||
var rootDir = path.join(__dirname, "../../" + src);
|
||||
var tsconfig = require("../../" + src + "/tsconfig.json");
|
||||
var options;
|
||||
const rootDir = path.join(__dirname, `../../${src}`);
|
||||
const tsconfig = require(`../../${src}/tsconfig.json`);
|
||||
let options;
|
||||
if (tsconfig.extends) {
|
||||
options = assign({}, require(path.join(rootDir, tsconfig.extends)).compilerOptions, tsconfig.compilerOptions);
|
||||
options = Object.assign({}, require(path.join(rootDir, tsconfig.extends)).compilerOptions, tsconfig.compilerOptions);
|
||||
}
|
||||
else {
|
||||
options = tsconfig.compilerOptions;
|
||||
|
@ -41,16 +40,16 @@ function getTypeScriptCompilerOptions(src) {
|
|||
return options;
|
||||
}
|
||||
function createCompile(src, build, emitError) {
|
||||
var opts = _.clone(getTypeScriptCompilerOptions(src));
|
||||
const opts = _.clone(getTypeScriptCompilerOptions(src));
|
||||
opts.inlineSources = !!build;
|
||||
opts.noFilesystemLookup = true;
|
||||
var ts = tsb.create(opts, true, undefined, function (err) { return reporter(err.toString()); });
|
||||
const ts = tsb.create(opts, true, undefined, err => reporter(err.toString()));
|
||||
return function (token) {
|
||||
var utf8Filter = util.filter(function (data) { return /(\/|\\)test(\/|\\).*utf8/.test(data.path); });
|
||||
var tsFilter = util.filter(function (data) { return /\.ts$/.test(data.path); });
|
||||
var noDeclarationsFilter = util.filter(function (data) { return !(/\.d\.ts$/.test(data.path)); });
|
||||
var input = es.through();
|
||||
var output = input
|
||||
const utf8Filter = util.filter(data => /(\/|\\)test(\/|\\).*utf8/.test(data.path));
|
||||
const tsFilter = util.filter(data => /\.ts$/.test(data.path));
|
||||
const noDeclarationsFilter = util.filter(data => !(/\.d\.ts$/.test(data.path)));
|
||||
const input = es.through();
|
||||
const output = input
|
||||
.pipe(utf8Filter)
|
||||
.pipe(bom())
|
||||
.pipe(utf8Filter.restore)
|
||||
|
@ -70,7 +69,7 @@ function createCompile(src, build, emitError) {
|
|||
return es.duplex(input, output);
|
||||
};
|
||||
}
|
||||
var typesDts = [
|
||||
const typesDts = [
|
||||
'node_modules/typescript/lib/*.d.ts',
|
||||
'node_modules/@types/**/*.d.ts',
|
||||
'!node_modules/@types/webpack/**/*',
|
||||
|
@ -78,10 +77,10 @@ var typesDts = [
|
|||
];
|
||||
function compileTask(src, out, build) {
|
||||
return function () {
|
||||
var compile = createCompile(src, build, true);
|
||||
var srcPipe = es.merge(gulp.src(src + "/**", { base: "" + src }), gulp.src(typesDts));
|
||||
const compile = createCompile(src, build, true);
|
||||
const srcPipe = es.merge(gulp.src(`${src}/**`, { base: `${src}` }), gulp.src(typesDts));
|
||||
// Do not write .d.ts files to disk, as they are not needed there.
|
||||
var dtsFilter = util.filter(function (data) { return !/\.d\.ts$/.test(data.path); });
|
||||
const dtsFilter = util.filter(data => !/\.d\.ts$/.test(data.path));
|
||||
return srcPipe
|
||||
.pipe(compile())
|
||||
.pipe(dtsFilter)
|
||||
|
@ -93,11 +92,11 @@ function compileTask(src, out, build) {
|
|||
exports.compileTask = compileTask;
|
||||
function watchTask(out, build) {
|
||||
return function () {
|
||||
var compile = createCompile('src', build);
|
||||
var src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src(typesDts));
|
||||
var watchSrc = watch('src/**', { base: 'src' });
|
||||
const compile = createCompile('src', build);
|
||||
const src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src(typesDts));
|
||||
const watchSrc = watch('src/**', { base: 'src' });
|
||||
// Do not write .d.ts files to disk, as they are not needed there.
|
||||
var dtsFilter = util.filter(function (data) { return !/\.d\.ts$/.test(data.path); });
|
||||
const dtsFilter = util.filter(data => !/\.d\.ts$/.test(data.path));
|
||||
return watchSrc
|
||||
.pipe(util.incremental(compile, src, true))
|
||||
.pipe(dtsFilter)
|
||||
|
@ -108,33 +107,33 @@ function watchTask(out, build) {
|
|||
}
|
||||
exports.watchTask = watchTask;
|
||||
function monacodtsTask(out, isWatch) {
|
||||
var basePath = path.resolve(process.cwd(), out);
|
||||
var neededFiles = {};
|
||||
const basePath = path.resolve(process.cwd(), out);
|
||||
const neededFiles = {};
|
||||
monacodts.getFilesToWatch(out).forEach(function (filePath) {
|
||||
filePath = path.normalize(filePath);
|
||||
neededFiles[filePath] = true;
|
||||
});
|
||||
var inputFiles = {};
|
||||
for (var filePath in neededFiles) {
|
||||
const inputFiles = {};
|
||||
for (const filePath in neededFiles) {
|
||||
if (/\bsrc(\/|\\)vs\b/.test(filePath)) {
|
||||
// This file is needed from source => simply read it now
|
||||
inputFiles[filePath] = fs.readFileSync(filePath).toString();
|
||||
}
|
||||
}
|
||||
var setInputFile = function (filePath, contents) {
|
||||
const setInputFile = (filePath, contents) => {
|
||||
if (inputFiles[filePath] === contents) {
|
||||
// no change
|
||||
return;
|
||||
}
|
||||
inputFiles[filePath] = contents;
|
||||
var neededInputFilesCount = Object.keys(neededFiles).length;
|
||||
var availableInputFilesCount = Object.keys(inputFiles).length;
|
||||
const neededInputFilesCount = Object.keys(neededFiles).length;
|
||||
const availableInputFilesCount = Object.keys(inputFiles).length;
|
||||
if (neededInputFilesCount === availableInputFilesCount) {
|
||||
run();
|
||||
}
|
||||
};
|
||||
var run = function () {
|
||||
var result = monacodts.run(out, inputFiles);
|
||||
const run = () => {
|
||||
const result = monacodts.run(out, inputFiles);
|
||||
if (!result.isTheSame) {
|
||||
if (isWatch) {
|
||||
fs.writeFileSync(result.filePath, result.content);
|
||||
|
@ -145,14 +144,14 @@ function monacodtsTask(out, isWatch) {
|
|||
}
|
||||
}
|
||||
};
|
||||
var resultStream;
|
||||
let resultStream;
|
||||
if (isWatch) {
|
||||
watch('build/monaco/*').pipe(es.through(function () {
|
||||
run();
|
||||
}));
|
||||
}
|
||||
resultStream = es.through(function (data) {
|
||||
var filePath = path.normalize(path.resolve(basePath, data.relative));
|
||||
const filePath = path.normalize(path.resolve(basePath, data.relative));
|
||||
if (neededFiles[filePath]) {
|
||||
setInputFile(filePath, data.contents.toString());
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ import * as nls from './nls';
|
|||
import { createReporter } from './reporter';
|
||||
import * as util from './util';
|
||||
const watch = require('./watch');
|
||||
import assign = require('object-assign');
|
||||
|
||||
const reporter = createReporter();
|
||||
|
||||
|
@ -27,7 +26,7 @@ function getTypeScriptCompilerOptions(src: string) {
|
|||
const tsconfig = require(`../../${src}/tsconfig.json`);
|
||||
let options: { [key: string]: any };
|
||||
if (tsconfig.extends) {
|
||||
options = assign({}, require(path.join(rootDir, tsconfig.extends)).compilerOptions, tsconfig.compilerOptions);
|
||||
options = Object.assign({}, require(path.join(rootDir, tsconfig.extends)).compilerOptions, tsconfig.compilerOptions);
|
||||
} else {
|
||||
options = tsconfig.compilerOptions;
|
||||
}
|
||||
|
|
|
@ -3,39 +3,28 @@
|
|||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
var __assign = (this && this.__assign) || function () {
|
||||
__assign = Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var es = require("event-stream");
|
||||
var fs = require("fs");
|
||||
var glob = require("glob");
|
||||
var gulp = require("gulp");
|
||||
var path = require("path");
|
||||
var File = require("vinyl");
|
||||
var vsce = require("vsce");
|
||||
var stats_1 = require("./stats");
|
||||
var util2 = require("./util");
|
||||
var remote = require("gulp-remote-src");
|
||||
var vzip = require('gulp-vinyl-zip');
|
||||
var filter = require("gulp-filter");
|
||||
var rename = require("gulp-rename");
|
||||
var util = require('gulp-util');
|
||||
var buffer = require('gulp-buffer');
|
||||
var json = require("gulp-json-editor");
|
||||
var webpack = require('webpack');
|
||||
var webpackGulp = require('webpack-stream');
|
||||
var root = path.resolve(path.join(__dirname, '..', '..'));
|
||||
const es = require("event-stream");
|
||||
const fs = require("fs");
|
||||
const glob = require("glob");
|
||||
const gulp = require("gulp");
|
||||
const path = require("path");
|
||||
const File = require("vinyl");
|
||||
const vsce = require("vsce");
|
||||
const stats_1 = require("./stats");
|
||||
const util2 = require("./util");
|
||||
const remote = require("gulp-remote-src");
|
||||
const vzip = require('gulp-vinyl-zip');
|
||||
const filter = require("gulp-filter");
|
||||
const rename = require("gulp-rename");
|
||||
const util = require('gulp-util');
|
||||
const buffer = require('gulp-buffer');
|
||||
const json = require("gulp-json-editor");
|
||||
const webpack = require('webpack');
|
||||
const webpackGulp = require('webpack-stream');
|
||||
const root = path.resolve(path.join(__dirname, '..', '..'));
|
||||
function fromLocal(extensionPath, sourceMappingURLBase) {
|
||||
var webpackFilename = path.join(extensionPath, 'extension.webpack.config.js');
|
||||
const webpackFilename = path.join(extensionPath, 'extension.webpack.config.js');
|
||||
if (fs.existsSync(webpackFilename)) {
|
||||
return fromLocalWebpack(extensionPath, sourceMappingURLBase);
|
||||
}
|
||||
|
@ -44,30 +33,30 @@ function fromLocal(extensionPath, sourceMappingURLBase) {
|
|||
}
|
||||
}
|
||||
function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
|
||||
var result = es.through();
|
||||
var packagedDependencies = [];
|
||||
var packageJsonConfig = require(path.join(extensionPath, 'package.json'));
|
||||
var webpackRootConfig = require(path.join(extensionPath, 'extension.webpack.config.js'));
|
||||
for (var key in webpackRootConfig.externals) {
|
||||
const result = es.through();
|
||||
const packagedDependencies = [];
|
||||
const packageJsonConfig = require(path.join(extensionPath, 'package.json'));
|
||||
const webpackRootConfig = require(path.join(extensionPath, 'extension.webpack.config.js'));
|
||||
for (const key in webpackRootConfig.externals) {
|
||||
if (key in packageJsonConfig.dependencies) {
|
||||
packagedDependencies.push(key);
|
||||
}
|
||||
}
|
||||
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn, packagedDependencies: packagedDependencies }).then(function (fileNames) {
|
||||
var files = fileNames
|
||||
.map(function (fileName) { return path.join(extensionPath, fileName); })
|
||||
.map(function (filePath) { return new File({
|
||||
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn, packagedDependencies }).then(fileNames => {
|
||||
const files = fileNames
|
||||
.map(fileName => path.join(extensionPath, fileName))
|
||||
.map(filePath => new File({
|
||||
path: filePath,
|
||||
stat: fs.statSync(filePath),
|
||||
base: extensionPath,
|
||||
contents: fs.createReadStream(filePath)
|
||||
}); });
|
||||
var filesStream = es.readArray(files);
|
||||
}));
|
||||
const filesStream = es.readArray(files);
|
||||
// check for a webpack configuration files, then invoke webpack
|
||||
// and merge its output with the files stream. also rewrite the package.json
|
||||
// file to a new entry point
|
||||
var webpackConfigLocations = glob.sync(path.join(extensionPath, '/**/extension.webpack.config.js'), { ignore: ['**/node_modules'] });
|
||||
var packageJsonFilter = filter(function (f) {
|
||||
const webpackConfigLocations = glob.sync(path.join(extensionPath, '/**/extension.webpack.config.js'), { ignore: ['**/node_modules'] });
|
||||
const packageJsonFilter = filter(f => {
|
||||
if (path.basename(f.path) === 'package.json') {
|
||||
// only modify package.json's next to the webpack file.
|
||||
// to be safe, use existsSync instead of path comparison.
|
||||
|
@ -75,22 +64,22 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
|
|||
}
|
||||
return false;
|
||||
}, { restore: true });
|
||||
var patchFilesStream = filesStream
|
||||
const patchFilesStream = filesStream
|
||||
.pipe(packageJsonFilter)
|
||||
.pipe(buffer())
|
||||
.pipe(json(function (data) {
|
||||
.pipe(json((data) => {
|
||||
// hardcoded entry point directory!
|
||||
data.main = data.main.replace('/out/', /dist/);
|
||||
return data;
|
||||
}))
|
||||
.pipe(packageJsonFilter.restore);
|
||||
var webpackStreams = webpackConfigLocations.map(function (webpackConfigPath) {
|
||||
var webpackDone = function (err, stats) {
|
||||
util.log("Bundled extension: " + util.colors.yellow(path.join(path.basename(extensionPath), path.relative(extensionPath, webpackConfigPath))) + "...");
|
||||
const webpackStreams = webpackConfigLocations.map(webpackConfigPath => {
|
||||
const webpackDone = (err, stats) => {
|
||||
util.log(`Bundled extension: ${util.colors.yellow(path.join(path.basename(extensionPath), path.relative(extensionPath, webpackConfigPath)))}...`);
|
||||
if (err) {
|
||||
result.emit('error', err);
|
||||
}
|
||||
var compilation = stats.compilation;
|
||||
const { compilation } = stats;
|
||||
if (compilation.errors.length > 0) {
|
||||
result.emit('error', compilation.errors.join('\n'));
|
||||
}
|
||||
|
@ -98,8 +87,8 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
|
|||
result.emit('error', compilation.warnings.join('\n'));
|
||||
}
|
||||
};
|
||||
var webpackConfig = __assign({}, require(webpackConfigPath), { mode: 'production' });
|
||||
var relativeOutputPath = path.relative(extensionPath, webpackConfig.output.path);
|
||||
const webpackConfig = Object.assign({}, require(webpackConfigPath), { mode: 'production' });
|
||||
const relativeOutputPath = path.relative(extensionPath, webpackConfig.output.path);
|
||||
return webpackGulp(webpackConfig, webpack, webpackDone)
|
||||
.pipe(es.through(function (data) {
|
||||
data.stat = data.stat || {};
|
||||
|
@ -111,9 +100,9 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
|
|||
// * rewrite sourceMappingURL
|
||||
// * save to disk so that upload-task picks this up
|
||||
if (sourceMappingURLBase) {
|
||||
var contents = data.contents.toString('utf8');
|
||||
const contents = data.contents.toString('utf8');
|
||||
data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) {
|
||||
return "\n//# sourceMappingURL=" + sourceMappingURLBase + "/extensions/" + path.basename(extensionPath) + "/" + relativeOutputPath + "/" + g1;
|
||||
return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/${relativeOutputPath}/${g1}`;
|
||||
}), 'utf8');
|
||||
if (/\.js\.map$/.test(data.path)) {
|
||||
if (!fs.existsSync(path.dirname(data.path))) {
|
||||
|
@ -125,8 +114,14 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
|
|||
this.emit('data', data);
|
||||
}));
|
||||
});
|
||||
es.merge.apply(es, webpackStreams.concat([patchFilesStream])).pipe(result);
|
||||
}).catch(function (err) {
|
||||
es.merge(...webpackStreams, patchFilesStream)
|
||||
// .pipe(es.through(function (data) {
|
||||
// // debug
|
||||
// console.log('out', data.path, data.contents.length);
|
||||
// this.emit('data', data);
|
||||
// }))
|
||||
.pipe(result);
|
||||
}).catch(err => {
|
||||
console.error(extensionPath);
|
||||
console.error(packagedDependencies);
|
||||
result.emit('error', err);
|
||||
|
@ -134,56 +129,56 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
|
|||
return result.pipe(stats_1.createStatsStream(path.basename(extensionPath)));
|
||||
}
|
||||
function fromLocalNormal(extensionPath) {
|
||||
var result = es.through();
|
||||
const result = es.through();
|
||||
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn })
|
||||
.then(function (fileNames) {
|
||||
var files = fileNames
|
||||
.map(function (fileName) { return path.join(extensionPath, fileName); })
|
||||
.map(function (filePath) { return new File({
|
||||
.then(fileNames => {
|
||||
const files = fileNames
|
||||
.map(fileName => path.join(extensionPath, fileName))
|
||||
.map(filePath => new File({
|
||||
path: filePath,
|
||||
stat: fs.statSync(filePath),
|
||||
base: extensionPath,
|
||||
contents: fs.createReadStream(filePath)
|
||||
}); });
|
||||
}));
|
||||
es.readArray(files).pipe(result);
|
||||
})
|
||||
.catch(function (err) { return result.emit('error', err); });
|
||||
.catch(err => result.emit('error', err));
|
||||
return result.pipe(stats_1.createStatsStream(path.basename(extensionPath)));
|
||||
}
|
||||
var baseHeaders = {
|
||||
const baseHeaders = {
|
||||
'X-Market-Client-Id': 'VSCode Build',
|
||||
'User-Agent': 'VSCode Build',
|
||||
'X-Market-User-Id': '291C1CD0-051A-4123-9B4B-30D60EF52EE2',
|
||||
};
|
||||
function fromMarketplace(extensionName, version, metadata) {
|
||||
var _a = extensionName.split('.'), publisher = _a[0], name = _a[1];
|
||||
var url = "https://marketplace.visualstudio.com/_apis/public/gallery/publishers/" + publisher + "/vsextensions/" + name + "/" + version + "/vspackage";
|
||||
util.log('Downloading extension:', util.colors.yellow(extensionName + "@" + version), '...');
|
||||
var options = {
|
||||
const [publisher, name] = extensionName.split('.');
|
||||
const url = `https://marketplace.visualstudio.com/_apis/public/gallery/publishers/${publisher}/vsextensions/${name}/${version}/vspackage`;
|
||||
util.log('Downloading extension:', util.colors.yellow(`${extensionName}@${version}`), '...');
|
||||
const options = {
|
||||
base: url,
|
||||
requestOptions: {
|
||||
gzip: true,
|
||||
headers: baseHeaders
|
||||
}
|
||||
};
|
||||
var packageJsonFilter = filter('package.json', { restore: true });
|
||||
const packageJsonFilter = filter('package.json', { restore: true });
|
||||
return remote('', options)
|
||||
.pipe(vzip.src())
|
||||
.pipe(filter('extension/**'))
|
||||
.pipe(rename(function (p) { return p.dirname = p.dirname.replace(/^extension\/?/, ''); }))
|
||||
.pipe(rename(p => p.dirname = p.dirname.replace(/^extension\/?/, '')))
|
||||
.pipe(packageJsonFilter)
|
||||
.pipe(buffer())
|
||||
.pipe(json({ __metadata: metadata }))
|
||||
.pipe(packageJsonFilter.restore);
|
||||
}
|
||||
exports.fromMarketplace = fromMarketplace;
|
||||
var excludedExtensions = [
|
||||
const excludedExtensions = [
|
||||
'vscode-api-tests',
|
||||
'vscode-colorize-tests',
|
||||
'ms-vscode.node-debug',
|
||||
'ms-vscode.node-debug2',
|
||||
];
|
||||
var builtInExtensions = require('../builtInExtensions.json');
|
||||
const builtInExtensions = require('../builtInExtensions.json');
|
||||
/**
|
||||
* We're doing way too much stuff at once, with webpack et al. So much stuff
|
||||
* that while downloading extensions from the marketplace, node js doesn't get enough
|
||||
|
@ -191,13 +186,13 @@ var builtInExtensions = require('../builtInExtensions.json');
|
|||
* marketplace server cuts off the http request. So, we sequentialize the extensino tasks.
|
||||
*/
|
||||
function sequence(streamProviders) {
|
||||
var result = es.through();
|
||||
const result = es.through();
|
||||
function pop() {
|
||||
if (streamProviders.length === 0) {
|
||||
result.emit('end');
|
||||
}
|
||||
else {
|
||||
var fn = streamProviders.shift();
|
||||
const fn = streamProviders.shift();
|
||||
fn()
|
||||
.on('end', function () { setTimeout(pop, 0); })
|
||||
.pipe(result, { end: false });
|
||||
|
@ -207,39 +202,27 @@ function sequence(streamProviders) {
|
|||
return result;
|
||||
}
|
||||
function packageExtensionsStream(optsIn) {
|
||||
var opts = optsIn || {};
|
||||
var localExtensionDescriptions = glob.sync('extensions/*/package.json')
|
||||
.map(function (manifestPath) {
|
||||
var extensionPath = path.dirname(path.join(root, manifestPath));
|
||||
var extensionName = path.basename(extensionPath);
|
||||
const opts = optsIn || {};
|
||||
const localExtensionDescriptions = glob.sync('extensions/*/package.json')
|
||||
.map(manifestPath => {
|
||||
const extensionPath = path.dirname(path.join(root, manifestPath));
|
||||
const extensionName = path.basename(extensionPath);
|
||||
return { name: extensionName, path: extensionPath };
|
||||
})
|
||||
.filter(function (_a) {
|
||||
var name = _a.name;
|
||||
return excludedExtensions.indexOf(name) === -1;
|
||||
})
|
||||
.filter(function (_a) {
|
||||
var name = _a.name;
|
||||
return opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true;
|
||||
})
|
||||
.filter(function (_a) {
|
||||
var name = _a.name;
|
||||
return builtInExtensions.every(function (b) { return b.name !== name; });
|
||||
});
|
||||
var localExtensions = function () { return es.merge.apply(es, localExtensionDescriptions.map(function (extension) {
|
||||
.filter(({ name }) => excludedExtensions.indexOf(name) === -1)
|
||||
.filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true)
|
||||
.filter(({ name }) => builtInExtensions.every(b => b.name !== name));
|
||||
const localExtensions = () => es.merge(...localExtensionDescriptions.map(extension => {
|
||||
return fromLocal(extension.path, opts.sourceMappingURLBase)
|
||||
.pipe(rename(function (p) { return p.dirname = "extensions/" + extension.name + "/" + p.dirname; }));
|
||||
})); };
|
||||
var localExtensionDependencies = function () { return gulp.src('extensions/node_modules/**', { base: '.' }); };
|
||||
var marketplaceExtensions = function () { return es.merge.apply(es, builtInExtensions
|
||||
.filter(function (_a) {
|
||||
var name = _a.name;
|
||||
return opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true;
|
||||
})
|
||||
.map(function (extension) {
|
||||
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
|
||||
}));
|
||||
const localExtensionDependencies = () => gulp.src('extensions/node_modules/**', { base: '.' });
|
||||
const marketplaceExtensions = () => es.merge(...builtInExtensions
|
||||
.filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true)
|
||||
.map(extension => {
|
||||
return fromMarketplace(extension.name, extension.version, extension.metadata)
|
||||
.pipe(rename(function (p) { return p.dirname = "extensions/" + extension.name + "/" + p.dirname; }));
|
||||
})); };
|
||||
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
|
||||
}));
|
||||
return sequence([localExtensions, localExtensionDependencies, marketplaceExtensions])
|
||||
.pipe(util2.setExecutableBit(['**/*.sh']))
|
||||
.pipe(filter(['**', '!**/*.js.map']));
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
/**
|
||||
* Returns the sha1 commit version of a repository or undefined in case of failure.
|
||||
*/
|
||||
function getVersion(repo) {
|
||||
var git = path.join(repo, '.git');
|
||||
var headPath = path.join(git, 'HEAD');
|
||||
var head;
|
||||
const git = path.join(repo, '.git');
|
||||
const headPath = path.join(git, 'HEAD');
|
||||
let head;
|
||||
try {
|
||||
head = fs.readFileSync(headPath, 'utf8').trim();
|
||||
}
|
||||
|
@ -22,29 +22,29 @@ function getVersion(repo) {
|
|||
if (/^[0-9a-f]{40}$/i.test(head)) {
|
||||
return head;
|
||||
}
|
||||
var refMatch = /^ref: (.*)$/.exec(head);
|
||||
const refMatch = /^ref: (.*)$/.exec(head);
|
||||
if (!refMatch) {
|
||||
return void 0;
|
||||
}
|
||||
var ref = refMatch[1];
|
||||
var refPath = path.join(git, ref);
|
||||
const ref = refMatch[1];
|
||||
const refPath = path.join(git, ref);
|
||||
try {
|
||||
return fs.readFileSync(refPath, 'utf8').trim();
|
||||
}
|
||||
catch (e) {
|
||||
// noop
|
||||
}
|
||||
var packedRefsPath = path.join(git, 'packed-refs');
|
||||
var refsRaw;
|
||||
const packedRefsPath = path.join(git, 'packed-refs');
|
||||
let refsRaw;
|
||||
try {
|
||||
refsRaw = fs.readFileSync(packedRefsPath, 'utf8').trim();
|
||||
}
|
||||
catch (e) {
|
||||
return void 0;
|
||||
}
|
||||
var refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm;
|
||||
var refsMatch;
|
||||
var refs = {};
|
||||
const refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm;
|
||||
let refsMatch;
|
||||
let refs = {};
|
||||
while (refsMatch = refsRegex.exec(refsRaw)) {
|
||||
refs[refsMatch[2]] = refsMatch[1];
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -348,7 +348,7 @@ export interface ITask<T> {
|
|||
|
||||
interface ILimitedTaskFactory<T> {
|
||||
factory: ITask<Promise<T>>;
|
||||
c: (value?: T | Thenable<T>) => void;
|
||||
c: (value?: T | Promise<T>) => void;
|
||||
e: (error?: any) => void;
|
||||
}
|
||||
|
||||
|
|
304
build/lib/nls.js
304
build/lib/nls.js
|
@ -3,13 +3,12 @@
|
|||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
var ts = require("typescript");
|
||||
var lazy = require("lazy.js");
|
||||
var event_stream_1 = require("event-stream");
|
||||
var File = require("vinyl");
|
||||
var sm = require("source-map");
|
||||
var assign = require("object-assign");
|
||||
var path = require("path");
|
||||
const ts = require("typescript");
|
||||
const lazy = require("lazy.js");
|
||||
const event_stream_1 = require("event-stream");
|
||||
const File = require("vinyl");
|
||||
const sm = require("source-map");
|
||||
const path = require("path");
|
||||
var CollectStepResult;
|
||||
(function (CollectStepResult) {
|
||||
CollectStepResult[CollectStepResult["Yes"] = 0] = "Yes";
|
||||
|
@ -18,9 +17,9 @@ var CollectStepResult;
|
|||
CollectStepResult[CollectStepResult["NoAndRecurse"] = 3] = "NoAndRecurse";
|
||||
})(CollectStepResult || (CollectStepResult = {}));
|
||||
function collect(node, fn) {
|
||||
var result = [];
|
||||
const result = [];
|
||||
function loop(node) {
|
||||
var stepResult = fn(node);
|
||||
const stepResult = fn(node);
|
||||
if (stepResult === CollectStepResult.Yes || stepResult === CollectStepResult.YesAndRecurse) {
|
||||
result.push(node);
|
||||
}
|
||||
|
@ -32,43 +31,45 @@ function collect(node, fn) {
|
|||
return result;
|
||||
}
|
||||
function clone(object) {
|
||||
var result = {};
|
||||
for (var id in object) {
|
||||
const result = {};
|
||||
for (const id in object) {
|
||||
result[id] = object[id];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function template(lines) {
|
||||
var indent = '', wrap = '';
|
||||
let indent = '', wrap = '';
|
||||
if (lines.length > 1) {
|
||||
indent = '\t';
|
||||
wrap = '\n';
|
||||
}
|
||||
return "/*---------------------------------------------------------\n * Copyright (C) Microsoft Corporation. All rights reserved.\n *--------------------------------------------------------*/\ndefine([], [" + (wrap + lines.map(function (l) { return indent + l; }).join(',\n') + wrap) + "]);";
|
||||
return `/*---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*--------------------------------------------------------*/
|
||||
define([], [${wrap + lines.map(l => indent + l).join(',\n') + wrap}]);`;
|
||||
}
|
||||
/**
|
||||
* Returns a stream containing the patched JavaScript and source maps.
|
||||
*/
|
||||
function nls() {
|
||||
var input = event_stream_1.through();
|
||||
var output = input.pipe(event_stream_1.through(function (f) {
|
||||
var _this = this;
|
||||
const input = event_stream_1.through();
|
||||
const output = input.pipe(event_stream_1.through(function (f) {
|
||||
if (!f.sourceMap) {
|
||||
return this.emit('error', new Error("File " + f.relative + " does not have sourcemaps."));
|
||||
return this.emit('error', new Error(`File ${f.relative} does not have sourcemaps.`));
|
||||
}
|
||||
var source = f.sourceMap.sources[0];
|
||||
let source = f.sourceMap.sources[0];
|
||||
if (!source) {
|
||||
return this.emit('error', new Error("File " + f.relative + " does not have a source in the source map."));
|
||||
return this.emit('error', new Error(`File ${f.relative} does not have a source in the source map.`));
|
||||
}
|
||||
var root = f.sourceMap.sourceRoot;
|
||||
const root = f.sourceMap.sourceRoot;
|
||||
if (root) {
|
||||
source = path.join(root, source);
|
||||
}
|
||||
var typescript = f.sourceMap.sourcesContent[0];
|
||||
const typescript = f.sourceMap.sourcesContent[0];
|
||||
if (!typescript) {
|
||||
return this.emit('error', new Error("File " + f.relative + " does not have the original content in the source map."));
|
||||
return this.emit('error', new Error(`File ${f.relative} does not have the original content in the source map.`));
|
||||
}
|
||||
nls.patchFiles(f, typescript).forEach(function (f) { return _this.emit('data', f); });
|
||||
nls.patchFiles(f, typescript).forEach(f => this.emit('data', f));
|
||||
}));
|
||||
return event_stream_1.duplex(input, output);
|
||||
}
|
||||
|
@ -76,8 +77,7 @@ function isImportNode(node) {
|
|||
return node.kind === ts.SyntaxKind.ImportDeclaration || node.kind === ts.SyntaxKind.ImportEqualsDeclaration;
|
||||
}
|
||||
(function (nls_1) {
|
||||
function fileFrom(file, contents, path) {
|
||||
if (path === void 0) { path = file.path; }
|
||||
function fileFrom(file, contents, path = file.path) {
|
||||
return new File({
|
||||
contents: Buffer.from(contents),
|
||||
base: file.base,
|
||||
|
@ -87,29 +87,27 @@ function isImportNode(node) {
|
|||
}
|
||||
nls_1.fileFrom = fileFrom;
|
||||
function mappedPositionFrom(source, lc) {
|
||||
return { source: source, line: lc.line + 1, column: lc.character };
|
||||
return { source, line: lc.line + 1, column: lc.character };
|
||||
}
|
||||
nls_1.mappedPositionFrom = mappedPositionFrom;
|
||||
function lcFrom(position) {
|
||||
return { line: position.line - 1, character: position.column };
|
||||
}
|
||||
nls_1.lcFrom = lcFrom;
|
||||
var SingleFileServiceHost = /** @class */ (function () {
|
||||
function SingleFileServiceHost(options, filename, contents) {
|
||||
var _this = this;
|
||||
class SingleFileServiceHost {
|
||||
constructor(options, filename, contents) {
|
||||
this.options = options;
|
||||
this.filename = filename;
|
||||
this.getCompilationSettings = function () { return _this.options; };
|
||||
this.getScriptFileNames = function () { return [_this.filename]; };
|
||||
this.getScriptVersion = function () { return '1'; };
|
||||
this.getScriptSnapshot = function (name) { return name === _this.filename ? _this.file : _this.lib; };
|
||||
this.getCurrentDirectory = function () { return ''; };
|
||||
this.getDefaultLibFileName = function () { return 'lib.d.ts'; };
|
||||
this.getCompilationSettings = () => this.options;
|
||||
this.getScriptFileNames = () => [this.filename];
|
||||
this.getScriptVersion = () => '1';
|
||||
this.getScriptSnapshot = (name) => name === this.filename ? this.file : this.lib;
|
||||
this.getCurrentDirectory = () => '';
|
||||
this.getDefaultLibFileName = () => 'lib.d.ts';
|
||||
this.file = ts.ScriptSnapshot.fromString(contents);
|
||||
this.lib = ts.ScriptSnapshot.fromString('');
|
||||
}
|
||||
return SingleFileServiceHost;
|
||||
}());
|
||||
}
|
||||
nls_1.SingleFileServiceHost = SingleFileServiceHost;
|
||||
function isCallExpressionWithinTextSpanCollectStep(textSpan, node) {
|
||||
if (!ts.textSpanContainsTextSpan({ start: node.pos, length: node.end - node.pos }, textSpan)) {
|
||||
|
@ -117,97 +115,96 @@ function isImportNode(node) {
|
|||
}
|
||||
return node.kind === ts.SyntaxKind.CallExpression ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse;
|
||||
}
|
||||
function analyze(contents, options) {
|
||||
if (options === void 0) { options = {}; }
|
||||
var filename = 'file.ts';
|
||||
var serviceHost = new SingleFileServiceHost(assign(clone(options), { noResolve: true }), filename, contents);
|
||||
var service = ts.createLanguageService(serviceHost);
|
||||
var sourceFile = ts.createSourceFile(filename, contents, ts.ScriptTarget.ES5, true);
|
||||
function analyze(contents, options = {}) {
|
||||
const filename = 'file.ts';
|
||||
const serviceHost = new SingleFileServiceHost(Object.assign(clone(options), { noResolve: true }), filename, contents);
|
||||
const service = ts.createLanguageService(serviceHost);
|
||||
const sourceFile = ts.createSourceFile(filename, contents, ts.ScriptTarget.ES5, true);
|
||||
// all imports
|
||||
var imports = lazy(collect(sourceFile, function (n) { return isImportNode(n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse; }));
|
||||
const imports = lazy(collect(sourceFile, n => isImportNode(n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse));
|
||||
// import nls = require('vs/nls');
|
||||
var importEqualsDeclarations = imports
|
||||
.filter(function (n) { return n.kind === ts.SyntaxKind.ImportEqualsDeclaration; })
|
||||
.map(function (n) { return n; })
|
||||
.filter(function (d) { return d.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference; })
|
||||
.filter(function (d) { return d.moduleReference.expression.getText() === '\'vs/nls\''; });
|
||||
const importEqualsDeclarations = imports
|
||||
.filter(n => n.kind === ts.SyntaxKind.ImportEqualsDeclaration)
|
||||
.map(n => n)
|
||||
.filter(d => d.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference)
|
||||
.filter(d => d.moduleReference.expression.getText() === '\'vs/nls\'');
|
||||
// import ... from 'vs/nls';
|
||||
var importDeclarations = imports
|
||||
.filter(function (n) { return n.kind === ts.SyntaxKind.ImportDeclaration; })
|
||||
.map(function (n) { return n; })
|
||||
.filter(function (d) { return d.moduleSpecifier.kind === ts.SyntaxKind.StringLiteral; })
|
||||
.filter(function (d) { return d.moduleSpecifier.getText() === '\'vs/nls\''; })
|
||||
.filter(function (d) { return !!d.importClause && !!d.importClause.namedBindings; });
|
||||
var nlsExpressions = importEqualsDeclarations
|
||||
.map(function (d) { return d.moduleReference.expression; })
|
||||
.concat(importDeclarations.map(function (d) { return d.moduleSpecifier; }))
|
||||
.map(function (d) { return ({
|
||||
const importDeclarations = imports
|
||||
.filter(n => n.kind === ts.SyntaxKind.ImportDeclaration)
|
||||
.map(n => n)
|
||||
.filter(d => d.moduleSpecifier.kind === ts.SyntaxKind.StringLiteral)
|
||||
.filter(d => d.moduleSpecifier.getText() === '\'vs/nls\'')
|
||||
.filter(d => !!d.importClause && !!d.importClause.namedBindings);
|
||||
const nlsExpressions = importEqualsDeclarations
|
||||
.map(d => d.moduleReference.expression)
|
||||
.concat(importDeclarations.map(d => d.moduleSpecifier))
|
||||
.map(d => ({
|
||||
start: ts.getLineAndCharacterOfPosition(sourceFile, d.getStart()),
|
||||
end: ts.getLineAndCharacterOfPosition(sourceFile, d.getEnd())
|
||||
}); });
|
||||
}));
|
||||
// `nls.localize(...)` calls
|
||||
var nlsLocalizeCallExpressions = importDeclarations
|
||||
.filter(function (d) { return !!(d.importClause && d.importClause.namedBindings && d.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport); })
|
||||
.map(function (d) { return d.importClause.namedBindings.name; })
|
||||
.concat(importEqualsDeclarations.map(function (d) { return d.name; }))
|
||||
const nlsLocalizeCallExpressions = importDeclarations
|
||||
.filter(d => !!(d.importClause && d.importClause.namedBindings && d.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport))
|
||||
.map(d => d.importClause.namedBindings.name)
|
||||
.concat(importEqualsDeclarations.map(d => d.name))
|
||||
// find read-only references to `nls`
|
||||
.map(function (n) { return service.getReferencesAtPosition(filename, n.pos + 1); })
|
||||
.map(n => service.getReferencesAtPosition(filename, n.pos + 1))
|
||||
.flatten()
|
||||
.filter(function (r) { return !r.isWriteAccess; })
|
||||
.filter(r => !r.isWriteAccess)
|
||||
// find the deepest call expressions AST nodes that contain those references
|
||||
.map(function (r) { return collect(sourceFile, function (n) { return isCallExpressionWithinTextSpanCollectStep(r.textSpan, n); }); })
|
||||
.map(function (a) { return lazy(a).last(); })
|
||||
.filter(function (n) { return !!n; })
|
||||
.map(function (n) { return n; })
|
||||
.map(r => collect(sourceFile, n => isCallExpressionWithinTextSpanCollectStep(r.textSpan, n)))
|
||||
.map(a => lazy(a).last())
|
||||
.filter(n => !!n)
|
||||
.map(n => n)
|
||||
// only `localize` calls
|
||||
.filter(function (n) { return n.expression.kind === ts.SyntaxKind.PropertyAccessExpression && n.expression.name.getText() === 'localize'; });
|
||||
.filter(n => n.expression.kind === ts.SyntaxKind.PropertyAccessExpression && n.expression.name.getText() === 'localize');
|
||||
// `localize` named imports
|
||||
var allLocalizeImportDeclarations = importDeclarations
|
||||
.filter(function (d) { return !!(d.importClause && d.importClause.namedBindings && d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports); })
|
||||
.map(function (d) { return [].concat(d.importClause.namedBindings.elements); })
|
||||
const allLocalizeImportDeclarations = importDeclarations
|
||||
.filter(d => !!(d.importClause && d.importClause.namedBindings && d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports))
|
||||
.map(d => [].concat(d.importClause.namedBindings.elements))
|
||||
.flatten();
|
||||
// `localize` read-only references
|
||||
var localizeReferences = allLocalizeImportDeclarations
|
||||
.filter(function (d) { return d.name.getText() === 'localize'; })
|
||||
.map(function (n) { return service.getReferencesAtPosition(filename, n.pos + 1); })
|
||||
const localizeReferences = allLocalizeImportDeclarations
|
||||
.filter(d => d.name.getText() === 'localize')
|
||||
.map(n => service.getReferencesAtPosition(filename, n.pos + 1))
|
||||
.flatten()
|
||||
.filter(function (r) { return !r.isWriteAccess; });
|
||||
.filter(r => !r.isWriteAccess);
|
||||
// custom named `localize` read-only references
|
||||
var namedLocalizeReferences = allLocalizeImportDeclarations
|
||||
.filter(function (d) { return d.propertyName && d.propertyName.getText() === 'localize'; })
|
||||
.map(function (n) { return service.getReferencesAtPosition(filename, n.name.pos + 1); })
|
||||
const namedLocalizeReferences = allLocalizeImportDeclarations
|
||||
.filter(d => d.propertyName && d.propertyName.getText() === 'localize')
|
||||
.map(n => service.getReferencesAtPosition(filename, n.name.pos + 1))
|
||||
.flatten()
|
||||
.filter(function (r) { return !r.isWriteAccess; });
|
||||
.filter(r => !r.isWriteAccess);
|
||||
// find the deepest call expressions AST nodes that contain those references
|
||||
var localizeCallExpressions = localizeReferences
|
||||
const localizeCallExpressions = localizeReferences
|
||||
.concat(namedLocalizeReferences)
|
||||
.map(function (r) { return collect(sourceFile, function (n) { return isCallExpressionWithinTextSpanCollectStep(r.textSpan, n); }); })
|
||||
.map(function (a) { return lazy(a).last(); })
|
||||
.filter(function (n) { return !!n; })
|
||||
.map(function (n) { return n; });
|
||||
.map(r => collect(sourceFile, n => isCallExpressionWithinTextSpanCollectStep(r.textSpan, n)))
|
||||
.map(a => lazy(a).last())
|
||||
.filter(n => !!n)
|
||||
.map(n => n);
|
||||
// collect everything
|
||||
var localizeCalls = nlsLocalizeCallExpressions
|
||||
const localizeCalls = nlsLocalizeCallExpressions
|
||||
.concat(localizeCallExpressions)
|
||||
.map(function (e) { return e.arguments; })
|
||||
.filter(function (a) { return a.length > 1; })
|
||||
.sort(function (a, b) { return a[0].getStart() - b[0].getStart(); })
|
||||
.map(function (a) { return ({
|
||||
.map(e => e.arguments)
|
||||
.filter(a => a.length > 1)
|
||||
.sort((a, b) => a[0].getStart() - b[0].getStart())
|
||||
.map(a => ({
|
||||
keySpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getEnd()) },
|
||||
key: a[0].getText(),
|
||||
valueSpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getEnd()) },
|
||||
value: a[1].getText()
|
||||
}); });
|
||||
}));
|
||||
return {
|
||||
localizeCalls: localizeCalls.toArray(),
|
||||
nlsExpressions: nlsExpressions.toArray()
|
||||
};
|
||||
}
|
||||
nls_1.analyze = analyze;
|
||||
var TextModel = /** @class */ (function () {
|
||||
function TextModel(contents) {
|
||||
var regex = /\r\n|\r|\n/g;
|
||||
var index = 0;
|
||||
var match;
|
||||
class TextModel {
|
||||
constructor(contents) {
|
||||
const regex = /\r\n|\r|\n/g;
|
||||
let index = 0;
|
||||
let match;
|
||||
this.lines = [];
|
||||
this.lineEndings = [];
|
||||
while (match = regex.exec(contents)) {
|
||||
|
@ -220,85 +217,80 @@ function isImportNode(node) {
|
|||
this.lineEndings.push('');
|
||||
}
|
||||
}
|
||||
TextModel.prototype.get = function (index) {
|
||||
get(index) {
|
||||
return this.lines[index];
|
||||
};
|
||||
TextModel.prototype.set = function (index, line) {
|
||||
}
|
||||
set(index, line) {
|
||||
this.lines[index] = line;
|
||||
};
|
||||
Object.defineProperty(TextModel.prototype, "lineCount", {
|
||||
get: function () {
|
||||
return this.lines.length;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
get lineCount() {
|
||||
return this.lines.length;
|
||||
}
|
||||
/**
|
||||
* Applies patch(es) to the model.
|
||||
* Multiple patches must be ordered.
|
||||
* Does not support patches spanning multiple lines.
|
||||
*/
|
||||
TextModel.prototype.apply = function (patch) {
|
||||
var startLineNumber = patch.span.start.line;
|
||||
var endLineNumber = patch.span.end.line;
|
||||
var startLine = this.lines[startLineNumber] || '';
|
||||
var endLine = this.lines[endLineNumber] || '';
|
||||
apply(patch) {
|
||||
const startLineNumber = patch.span.start.line;
|
||||
const endLineNumber = patch.span.end.line;
|
||||
const startLine = this.lines[startLineNumber] || '';
|
||||
const endLine = this.lines[endLineNumber] || '';
|
||||
this.lines[startLineNumber] = [
|
||||
startLine.substring(0, patch.span.start.character),
|
||||
patch.content,
|
||||
endLine.substring(patch.span.end.character)
|
||||
].join('');
|
||||
for (var i = startLineNumber + 1; i <= endLineNumber; i++) {
|
||||
for (let i = startLineNumber + 1; i <= endLineNumber; i++) {
|
||||
this.lines[i] = '';
|
||||
}
|
||||
};
|
||||
TextModel.prototype.toString = function () {
|
||||
}
|
||||
toString() {
|
||||
return lazy(this.lines).zip(this.lineEndings)
|
||||
.flatten().toArray().join('');
|
||||
};
|
||||
return TextModel;
|
||||
}());
|
||||
}
|
||||
}
|
||||
nls_1.TextModel = TextModel;
|
||||
function patchJavascript(patches, contents, moduleId) {
|
||||
var model = new nls.TextModel(contents);
|
||||
const model = new nls.TextModel(contents);
|
||||
// patch the localize calls
|
||||
lazy(patches).reverse().each(function (p) { return model.apply(p); });
|
||||
lazy(patches).reverse().each(p => model.apply(p));
|
||||
// patch the 'vs/nls' imports
|
||||
var firstLine = model.get(0);
|
||||
var patchedFirstLine = firstLine.replace(/(['"])vs\/nls\1/g, "$1vs/nls!" + moduleId + "$1");
|
||||
const firstLine = model.get(0);
|
||||
const patchedFirstLine = firstLine.replace(/(['"])vs\/nls\1/g, `$1vs/nls!${moduleId}$1`);
|
||||
model.set(0, patchedFirstLine);
|
||||
return model.toString();
|
||||
}
|
||||
nls_1.patchJavascript = patchJavascript;
|
||||
function patchSourcemap(patches, rsm, smc) {
|
||||
var smg = new sm.SourceMapGenerator({
|
||||
const smg = new sm.SourceMapGenerator({
|
||||
file: rsm.file,
|
||||
sourceRoot: rsm.sourceRoot
|
||||
});
|
||||
patches = patches.reverse();
|
||||
var currentLine = -1;
|
||||
var currentLineDiff = 0;
|
||||
var source = null;
|
||||
smc.eachMapping(function (m) {
|
||||
var patch = patches[patches.length - 1];
|
||||
var original = { line: m.originalLine, column: m.originalColumn };
|
||||
var generated = { line: m.generatedLine, column: m.generatedColumn };
|
||||
let currentLine = -1;
|
||||
let currentLineDiff = 0;
|
||||
let source = null;
|
||||
smc.eachMapping(m => {
|
||||
const patch = patches[patches.length - 1];
|
||||
const original = { line: m.originalLine, column: m.originalColumn };
|
||||
const generated = { line: m.generatedLine, column: m.generatedColumn };
|
||||
if (currentLine !== generated.line) {
|
||||
currentLineDiff = 0;
|
||||
}
|
||||
currentLine = generated.line;
|
||||
generated.column += currentLineDiff;
|
||||
if (patch && m.generatedLine - 1 === patch.span.end.line && m.generatedColumn === patch.span.end.character) {
|
||||
var originalLength = patch.span.end.character - patch.span.start.character;
|
||||
var modifiedLength = patch.content.length;
|
||||
var lengthDiff = modifiedLength - originalLength;
|
||||
const originalLength = patch.span.end.character - patch.span.start.character;
|
||||
const modifiedLength = patch.content.length;
|
||||
const lengthDiff = modifiedLength - originalLength;
|
||||
currentLineDiff += lengthDiff;
|
||||
generated.column += lengthDiff;
|
||||
patches.pop();
|
||||
}
|
||||
source = rsm.sourceRoot ? path.relative(rsm.sourceRoot, m.source) : m.source;
|
||||
source = source.replace(/\\/g, '/');
|
||||
smg.addMapping({ source: source, name: m.name, original: original, generated: generated });
|
||||
smg.addMapping({ source, name: m.name, original, generated });
|
||||
}, null, sm.SourceMapConsumer.GENERATED_ORDER);
|
||||
if (source) {
|
||||
smg.setSourceContent(source, smc.sourceContentFor(source));
|
||||
|
@ -307,47 +299,47 @@ function isImportNode(node) {
|
|||
}
|
||||
nls_1.patchSourcemap = patchSourcemap;
|
||||
function patch(moduleId, typescript, javascript, sourcemap) {
|
||||
var _a = analyze(typescript), localizeCalls = _a.localizeCalls, nlsExpressions = _a.nlsExpressions;
|
||||
const { localizeCalls, nlsExpressions } = analyze(typescript);
|
||||
if (localizeCalls.length === 0) {
|
||||
return { javascript: javascript, sourcemap: sourcemap };
|
||||
return { javascript, sourcemap };
|
||||
}
|
||||
var nlsKeys = template(localizeCalls.map(function (lc) { return lc.key; }));
|
||||
var nls = template(localizeCalls.map(function (lc) { return lc.value; }));
|
||||
var smc = new sm.SourceMapConsumer(sourcemap);
|
||||
var positionFrom = mappedPositionFrom.bind(null, sourcemap.sources[0]);
|
||||
var i = 0;
|
||||
const nlsKeys = template(localizeCalls.map(lc => lc.key));
|
||||
const nls = template(localizeCalls.map(lc => lc.value));
|
||||
const smc = new sm.SourceMapConsumer(sourcemap);
|
||||
const positionFrom = mappedPositionFrom.bind(null, sourcemap.sources[0]);
|
||||
let i = 0;
|
||||
// build patches
|
||||
var patches = lazy(localizeCalls)
|
||||
.map(function (lc) { return ([
|
||||
const patches = lazy(localizeCalls)
|
||||
.map(lc => ([
|
||||
{ range: lc.keySpan, content: '' + (i++) },
|
||||
{ range: lc.valueSpan, content: 'null' }
|
||||
]); })
|
||||
]))
|
||||
.flatten()
|
||||
.map(function (c) {
|
||||
var start = lcFrom(smc.generatedPositionFor(positionFrom(c.range.start)));
|
||||
var end = lcFrom(smc.generatedPositionFor(positionFrom(c.range.end)));
|
||||
return { span: { start: start, end: end }, content: c.content };
|
||||
.map(c => {
|
||||
const start = lcFrom(smc.generatedPositionFor(positionFrom(c.range.start)));
|
||||
const end = lcFrom(smc.generatedPositionFor(positionFrom(c.range.end)));
|
||||
return { span: { start, end }, content: c.content };
|
||||
})
|
||||
.toArray();
|
||||
javascript = patchJavascript(patches, javascript, moduleId);
|
||||
// since imports are not within the sourcemap information,
|
||||
// we must do this MacGyver style
|
||||
if (nlsExpressions.length) {
|
||||
javascript = javascript.replace(/^define\(.*$/m, function (line) {
|
||||
return line.replace(/(['"])vs\/nls\1/g, "$1vs/nls!" + moduleId + "$1");
|
||||
javascript = javascript.replace(/^define\(.*$/m, line => {
|
||||
return line.replace(/(['"])vs\/nls\1/g, `$1vs/nls!${moduleId}$1`);
|
||||
});
|
||||
}
|
||||
sourcemap = patchSourcemap(patches, sourcemap, smc);
|
||||
return { javascript: javascript, sourcemap: sourcemap, nlsKeys: nlsKeys, nls: nls };
|
||||
return { javascript, sourcemap, nlsKeys, nls };
|
||||
}
|
||||
nls_1.patch = patch;
|
||||
function patchFiles(javascriptFile, typescript) {
|
||||
// hack?
|
||||
var moduleId = javascriptFile.relative
|
||||
const moduleId = javascriptFile.relative
|
||||
.replace(/\.js$/, '')
|
||||
.replace(/\\/g, '/');
|
||||
var _a = patch(moduleId, typescript, javascriptFile.contents.toString(), javascriptFile.sourceMap), javascript = _a.javascript, sourcemap = _a.sourcemap, nlsKeys = _a.nlsKeys, nls = _a.nls;
|
||||
var result = [fileFrom(javascriptFile, javascript)];
|
||||
const { javascript, sourcemap, nlsKeys, nls } = patch(moduleId, typescript, javascriptFile.contents.toString(), javascriptFile.sourceMap);
|
||||
const result = [fileFrom(javascriptFile, javascript)];
|
||||
result[0].sourceMap = sourcemap;
|
||||
if (nlsKeys) {
|
||||
result.push(fileFrom(javascriptFile, nlsKeys, javascriptFile.path.replace(/\.js$/, '.nls.keys.js')));
|
||||
|
|
|
@ -8,7 +8,6 @@ import * as lazy from 'lazy.js';
|
|||
import { duplex, through } from 'event-stream';
|
||||
import * as File from 'vinyl';
|
||||
import * as sm from 'source-map';
|
||||
import assign = require('object-assign');
|
||||
import * as path from 'path';
|
||||
|
||||
declare class FileSourceMap extends File {
|
||||
|
@ -174,7 +173,7 @@ module nls {
|
|||
|
||||
export function analyze(contents: string, options: ts.CompilerOptions = {}): ILocalizeAnalysisResult {
|
||||
const filename = 'file.ts';
|
||||
const serviceHost = new SingleFileServiceHost(assign(clone(options), { noResolve: true }), filename, contents);
|
||||
const serviceHost = new SingleFileServiceHost(Object.assign(clone(options), { noResolve: true }), filename, contents);
|
||||
const service = ts.createLanguageService(serviceHost);
|
||||
const sourceFile = ts.createSourceFile(filename, contents, ts.ScriptTarget.ES5, true);
|
||||
|
||||
|
|
|
@ -4,30 +4,30 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var es = require("event-stream");
|
||||
var gulp = require("gulp");
|
||||
var concat = require("gulp-concat");
|
||||
var minifyCSS = require("gulp-cssnano");
|
||||
var filter = require("gulp-filter");
|
||||
var flatmap = require("gulp-flatmap");
|
||||
var sourcemaps = require("gulp-sourcemaps");
|
||||
var uglify = require("gulp-uglify");
|
||||
var composer = require("gulp-uglify/composer");
|
||||
var gulpUtil = require("gulp-util");
|
||||
var path = require("path");
|
||||
var pump = require("pump");
|
||||
var uglifyes = require("uglify-es");
|
||||
var VinylFile = require("vinyl");
|
||||
var bundle = require("./bundle");
|
||||
var i18n_1 = require("./i18n");
|
||||
var stats_1 = require("./stats");
|
||||
var util = require("./util");
|
||||
var REPO_ROOT_PATH = path.join(__dirname, '../..');
|
||||
const es = require("event-stream");
|
||||
const gulp = require("gulp");
|
||||
const concat = require("gulp-concat");
|
||||
const minifyCSS = require("gulp-cssnano");
|
||||
const filter = require("gulp-filter");
|
||||
const flatmap = require("gulp-flatmap");
|
||||
const sourcemaps = require("gulp-sourcemaps");
|
||||
const uglify = require("gulp-uglify");
|
||||
const composer = require("gulp-uglify/composer");
|
||||
const gulpUtil = require("gulp-util");
|
||||
const path = require("path");
|
||||
const pump = require("pump");
|
||||
const uglifyes = require("uglify-es");
|
||||
const VinylFile = require("vinyl");
|
||||
const bundle = require("./bundle");
|
||||
const i18n_1 = require("./i18n");
|
||||
const stats_1 = require("./stats");
|
||||
const util = require("./util");
|
||||
const REPO_ROOT_PATH = path.join(__dirname, '../..');
|
||||
function log(prefix, message) {
|
||||
gulpUtil.log(gulpUtil.colors.cyan('[' + prefix + ']'), message);
|
||||
}
|
||||
function loaderConfig(emptyPaths) {
|
||||
var result = {
|
||||
const result = {
|
||||
paths: {
|
||||
'vs': 'out-build/vs',
|
||||
'vscode': 'empty:'
|
||||
|
@ -38,20 +38,20 @@ function loaderConfig(emptyPaths) {
|
|||
return result;
|
||||
}
|
||||
exports.loaderConfig = loaderConfig;
|
||||
var IS_OUR_COPYRIGHT_REGEXP = /Copyright \(C\) Microsoft Corporation/i;
|
||||
const IS_OUR_COPYRIGHT_REGEXP = /Copyright \(C\) Microsoft Corporation/i;
|
||||
function loader(src, bundledFileHeader, bundleLoader) {
|
||||
var sources = [
|
||||
src + "/vs/loader.js"
|
||||
let sources = [
|
||||
`${src}/vs/loader.js`
|
||||
];
|
||||
if (bundleLoader) {
|
||||
sources = sources.concat([
|
||||
src + "/vs/css.js",
|
||||
src + "/vs/nls.js"
|
||||
`${src}/vs/css.js`,
|
||||
`${src}/vs/nls.js`
|
||||
]);
|
||||
}
|
||||
var isFirst = true;
|
||||
let isFirst = true;
|
||||
return (gulp
|
||||
.src(sources, { base: "" + src })
|
||||
.src(sources, { base: `${src}` })
|
||||
.pipe(es.through(function (data) {
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
|
@ -74,12 +74,12 @@ function loader(src, bundledFileHeader, bundleLoader) {
|
|||
})));
|
||||
}
|
||||
function toConcatStream(src, bundledFileHeader, sources, dest) {
|
||||
var useSourcemaps = /\.js$/.test(dest) && !/\.nls\.js$/.test(dest);
|
||||
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
|
||||
var containsOurCopyright = false;
|
||||
for (var i = 0, len = sources.length; i < len; i++) {
|
||||
var fileContents = sources[i].contents;
|
||||
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;
|
||||
|
@ -91,9 +91,9 @@ function toConcatStream(src, bundledFileHeader, sources, dest) {
|
|||
contents: bundledFileHeader
|
||||
});
|
||||
}
|
||||
var treatedSources = sources.map(function (source) {
|
||||
var root = source.path ? REPO_ROOT_PATH.replace(/\\/g, '/') : '';
|
||||
var base = source.path ? root + ("/" + src) : '';
|
||||
const treatedSources = sources.map(function (source) {
|
||||
const root = source.path ? REPO_ROOT_PATH.replace(/\\/g, '/') : '';
|
||||
const base = source.path ? root + `/${src}` : '';
|
||||
return new VinylFile({
|
||||
path: source.path ? root + '/' + source.path.replace(/\\/g, '/') : 'fake',
|
||||
base: base,
|
||||
|
@ -111,33 +111,33 @@ function toBundleStream(src, bundledFileHeader, bundles) {
|
|||
}));
|
||||
}
|
||||
function optimizeTask(opts) {
|
||||
var src = opts.src;
|
||||
var entryPoints = opts.entryPoints;
|
||||
var otherSources = opts.otherSources;
|
||||
var resources = opts.resources;
|
||||
var loaderConfig = opts.loaderConfig;
|
||||
var bundledFileHeader = opts.header;
|
||||
var bundleLoader = (typeof opts.bundleLoader === 'undefined' ? true : opts.bundleLoader);
|
||||
var out = opts.out;
|
||||
const src = opts.src;
|
||||
const entryPoints = opts.entryPoints;
|
||||
const otherSources = opts.otherSources;
|
||||
const resources = opts.resources;
|
||||
const loaderConfig = opts.loaderConfig;
|
||||
const bundledFileHeader = opts.header;
|
||||
const bundleLoader = (typeof opts.bundleLoader === 'undefined' ? true : opts.bundleLoader);
|
||||
const out = opts.out;
|
||||
return function () {
|
||||
var bundlesStream = es.through(); // this stream will contain the bundled files
|
||||
var resourcesStream = es.through(); // this stream will contain the resources
|
||||
var bundleInfoStream = es.through(); // this stream will contain bundleInfo.json
|
||||
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).pipe(bundlesStream);
|
||||
// Remove css inlined resources
|
||||
var filteredResources = resources.slice();
|
||||
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 }).pipe(resourcesStream);
|
||||
var bundleInfoArray = [];
|
||||
gulp.src(filteredResources, { base: `${src}` }).pipe(resourcesStream);
|
||||
const bundleInfoArray = [];
|
||||
if (opts.bundleInfo) {
|
||||
bundleInfoArray.push(new VinylFile({
|
||||
path: 'bundleInfo.json',
|
||||
|
@ -147,9 +147,9 @@ function optimizeTask(opts) {
|
|||
}
|
||||
es.readArray(bundleInfoArray).pipe(bundleInfoStream);
|
||||
});
|
||||
var otherSourcesStream = es.through();
|
||||
var otherSourcesStreamArr = [];
|
||||
gulp.src(otherSources, { base: "" + src })
|
||||
const otherSourcesStream = es.through();
|
||||
const otherSourcesStreamArr = [];
|
||||
gulp.src(otherSources, { base: `${src}` })
|
||||
.pipe(es.through(function (data) {
|
||||
otherSourcesStreamArr.push(toConcatStream(src, bundledFileHeader, [data], data.relative));
|
||||
}, function () {
|
||||
|
@ -160,7 +160,7 @@ function optimizeTask(opts) {
|
|||
es.merge(otherSourcesStreamArr).pipe(otherSourcesStream);
|
||||
}
|
||||
}));
|
||||
var result = es.merge(loader(src, bundledFileHeader, bundleLoader), bundlesStream, otherSourcesStream, resourcesStream, bundleInfoStream);
|
||||
const result = es.merge(loader(src, bundledFileHeader, bundleLoader), bundlesStream, otherSourcesStream, resourcesStream, bundleInfoStream);
|
||||
return result
|
||||
.pipe(sourcemaps.write('./', {
|
||||
sourceRoot: undefined,
|
||||
|
@ -180,14 +180,14 @@ exports.optimizeTask = optimizeTask;
|
|||
* to have a file "context" to include our copyright only once per file.
|
||||
*/
|
||||
function uglifyWithCopyrights() {
|
||||
var preserveComments = function (f) {
|
||||
return function (_node, comment) {
|
||||
var text = comment.value;
|
||||
var type = comment.type;
|
||||
const preserveComments = (f) => {
|
||||
return (_node, comment) => {
|
||||
const text = comment.value;
|
||||
const type = comment.type;
|
||||
if (/@minifier_do_not_preserve/.test(text)) {
|
||||
return false;
|
||||
}
|
||||
var isOurCopyright = IS_OUR_COPYRIGHT_REGEXP.test(text);
|
||||
const isOurCopyright = IS_OUR_COPYRIGHT_REGEXP.test(text);
|
||||
if (isOurCopyright) {
|
||||
if (f.__hasOurCopyright) {
|
||||
return false;
|
||||
|
@ -205,10 +205,10 @@ function uglifyWithCopyrights() {
|
|||
return false;
|
||||
};
|
||||
};
|
||||
var minify = composer(uglifyes);
|
||||
var input = es.through();
|
||||
var output = input
|
||||
.pipe(flatmap(function (stream, f) {
|
||||
const minify = composer(uglifyes);
|
||||
const input = es.through();
|
||||
const output = input
|
||||
.pipe(flatmap((stream, f) => {
|
||||
return stream.pipe(minify({
|
||||
output: {
|
||||
comments: preserveComments(f),
|
||||
|
@ -219,18 +219,18 @@ function uglifyWithCopyrights() {
|
|||
return es.duplex(input, output);
|
||||
}
|
||||
function minifyTask(src, sourceMapBaseUrl) {
|
||||
var sourceMappingURL = sourceMapBaseUrl ? (function (f) { return sourceMapBaseUrl + "/" + f.relative + ".map"; }) : undefined;
|
||||
return function (cb) {
|
||||
var jsFilter = filter('**/*.js', { restore: true });
|
||||
var cssFilter = filter('**/*.css', { restore: true });
|
||||
const sourceMappingURL = sourceMapBaseUrl ? ((f) => `${sourceMapBaseUrl}/${f.relative}.map`) : undefined;
|
||||
return cb => {
|
||||
const jsFilter = filter('**/*.js', { restore: true });
|
||||
const cssFilter = filter('**/*.css', { restore: true });
|
||||
pump(gulp.src([src + '/**', '!' + src + '/**/*.map']), jsFilter, sourcemaps.init({ loadMaps: true }), uglifyWithCopyrights(), jsFilter.restore, cssFilter, minifyCSS({ reduceIdents: false }), cssFilter.restore, sourcemaps.write('./', {
|
||||
sourceMappingURL: sourceMappingURL,
|
||||
sourceMappingURL,
|
||||
sourceRoot: undefined,
|
||||
includeContent: true,
|
||||
addComment: true
|
||||
}), gulp.dest(src + '-min'), function (err) {
|
||||
}), gulp.dest(src + '-min'), (err) => {
|
||||
if (err instanceof uglify.GulpUglifyError) {
|
||||
console.error("Uglify error in '" + (err.cause && err.cause.filename) + "'");
|
||||
console.error(`Uglify error in '${err.cause && err.cause.filename}'`);
|
||||
}
|
||||
cb(err);
|
||||
});
|
||||
|
|
|
@ -4,20 +4,20 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var es = require("event-stream");
|
||||
var _ = require("underscore");
|
||||
var util = require("gulp-util");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var allErrors = [];
|
||||
var startTime = null;
|
||||
var count = 0;
|
||||
const es = require("event-stream");
|
||||
const _ = require("underscore");
|
||||
const util = require("gulp-util");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const allErrors = [];
|
||||
let startTime = null;
|
||||
let count = 0;
|
||||
function onStart() {
|
||||
if (count++ > 0) {
|
||||
return;
|
||||
}
|
||||
startTime = new Date().getTime();
|
||||
util.log("Starting " + util.colors.green('compilation') + "...");
|
||||
util.log(`Starting ${util.colors.green('compilation')}...`);
|
||||
}
|
||||
function onEnd() {
|
||||
if (--count > 0) {
|
||||
|
@ -25,7 +25,7 @@ function onEnd() {
|
|||
}
|
||||
log();
|
||||
}
|
||||
var buildLogPath = path.join(path.dirname(path.dirname(__dirname)), '.build', 'log');
|
||||
const buildLogPath = path.join(path.dirname(path.dirname(__dirname)), '.build', 'log');
|
||||
try {
|
||||
fs.mkdirSync(path.dirname(buildLogPath));
|
||||
}
|
||||
|
@ -33,42 +33,39 @@ catch (err) {
|
|||
// ignore
|
||||
}
|
||||
function log() {
|
||||
var errors = _.flatten(allErrors);
|
||||
var seen = new Set();
|
||||
errors.map(function (err) {
|
||||
const errors = _.flatten(allErrors);
|
||||
const seen = new Set();
|
||||
errors.map(err => {
|
||||
if (!seen.has(err)) {
|
||||
seen.add(err);
|
||||
util.log(util.colors.red('Error') + ": " + err);
|
||||
util.log(`${util.colors.red('Error')}: ${err}`);
|
||||
}
|
||||
});
|
||||
var regex = /^([^(]+)\((\d+),(\d+)\): (.*)$/;
|
||||
var messages = errors
|
||||
.map(function (err) { return regex.exec(err); })
|
||||
.filter(function (match) { return !!match; })
|
||||
.map(function (x) { return x; })
|
||||
.map(function (_a) {
|
||||
var path = _a[1], line = _a[2], column = _a[3], message = _a[4];
|
||||
return ({ path: path, line: parseInt(line), column: parseInt(column), message: message });
|
||||
});
|
||||
const regex = /^([^(]+)\((\d+),(\d+)\): (.*)$/;
|
||||
const messages = errors
|
||||
.map(err => regex.exec(err))
|
||||
.filter(match => !!match)
|
||||
.map(x => x)
|
||||
.map(([, path, line, column, message]) => ({ path, line: parseInt(line), column: parseInt(column), message }));
|
||||
try {
|
||||
fs.writeFileSync(buildLogPath, JSON.stringify(messages));
|
||||
}
|
||||
catch (err) {
|
||||
//noop
|
||||
}
|
||||
util.log("Finished " + util.colors.green('compilation') + " with " + errors.length + " errors after " + util.colors.magenta((new Date().getTime() - startTime) + ' ms'));
|
||||
util.log(`Finished ${util.colors.green('compilation')} with ${errors.length} errors after ${util.colors.magenta((new Date().getTime() - startTime) + ' ms')}`);
|
||||
}
|
||||
function createReporter() {
|
||||
var errors = [];
|
||||
const errors = [];
|
||||
allErrors.push(errors);
|
||||
var ReportFunc = /** @class */ (function () {
|
||||
function ReportFunc(err) {
|
||||
class ReportFunc {
|
||||
constructor(err) {
|
||||
errors.push(err);
|
||||
}
|
||||
ReportFunc.hasErrors = function () {
|
||||
static hasErrors() {
|
||||
return errors.length > 0;
|
||||
};
|
||||
ReportFunc.end = function (emitError) {
|
||||
}
|
||||
static end(emitError) {
|
||||
errors.length = 0;
|
||||
onStart();
|
||||
return es.through(undefined, function () {
|
||||
|
@ -78,7 +75,7 @@ function createReporter() {
|
|||
log();
|
||||
}
|
||||
errors.__logged__ = true;
|
||||
var err = new Error("Found " + errors.length + " errors");
|
||||
const err = new Error(`Found ${errors.length} errors`);
|
||||
err.__reporter__ = true;
|
||||
this.emit('error', err);
|
||||
}
|
||||
|
@ -86,9 +83,8 @@ function createReporter() {
|
|||
this.emit('end');
|
||||
}
|
||||
});
|
||||
};
|
||||
return ReportFunc;
|
||||
}());
|
||||
}
|
||||
}
|
||||
return ReportFunc;
|
||||
}
|
||||
exports.createReporter = createReporter;
|
||||
|
|
|
@ -5,25 +5,25 @@
|
|||
'use strict';
|
||||
var snaps;
|
||||
(function (snaps) {
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var os = require('os');
|
||||
var cp = require('child_process');
|
||||
var mksnapshot = path.join(__dirname, "../../node_modules/.bin/" + (process.platform === 'win32' ? 'mksnapshot.cmd' : 'mksnapshot'));
|
||||
var product = require('../../product.json');
|
||||
var arch = (process.argv.join('').match(/--arch=(.*)/) || [])[1];
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
const cp = require('child_process');
|
||||
const mksnapshot = path.join(__dirname, `../../node_modules/.bin/${process.platform === 'win32' ? 'mksnapshot.cmd' : 'mksnapshot'}`);
|
||||
const product = require('../../product.json');
|
||||
const arch = (process.argv.join('').match(/--arch=(.*)/) || [])[1];
|
||||
//
|
||||
var loaderFilepath;
|
||||
var startupBlobFilepath;
|
||||
let loaderFilepath;
|
||||
let startupBlobFilepath;
|
||||
switch (process.platform) {
|
||||
case 'darwin':
|
||||
loaderFilepath = "VSCode-darwin/" + product.nameLong + ".app/Contents/Resources/app/out/vs/loader.js";
|
||||
startupBlobFilepath = "VSCode-darwin/" + product.nameLong + ".app/Contents/Frameworks/Electron Framework.framework/Resources/snapshot_blob.bin";
|
||||
loaderFilepath = `VSCode-darwin/${product.nameLong}.app/Contents/Resources/app/out/vs/loader.js`;
|
||||
startupBlobFilepath = `VSCode-darwin/${product.nameLong}.app/Contents/Frameworks/Electron Framework.framework/Resources/snapshot_blob.bin`;
|
||||
break;
|
||||
case 'win32':
|
||||
case 'linux':
|
||||
loaderFilepath = "VSCode-" + process.platform + "-" + arch + "/resources/app/out/vs/loader.js";
|
||||
startupBlobFilepath = "VSCode-" + process.platform + "-" + arch + "/snapshot_blob.bin";
|
||||
loaderFilepath = `VSCode-${process.platform}-${arch}/resources/app/out/vs/loader.js`;
|
||||
startupBlobFilepath = `VSCode-${process.platform}-${arch}/snapshot_blob.bin`;
|
||||
default:
|
||||
throw new Error('Unknown platform');
|
||||
}
|
||||
|
@ -31,11 +31,24 @@ var snaps;
|
|||
startupBlobFilepath = path.join(__dirname, '../../../', startupBlobFilepath);
|
||||
snapshotLoader(loaderFilepath, startupBlobFilepath);
|
||||
function snapshotLoader(loaderFilepath, startupBlobFilepath) {
|
||||
var inputFile = fs.readFileSync(loaderFilepath);
|
||||
var wrappedInputFile = "\n\t\tvar Monaco_Loader_Init;\n\t\t(function() {\n\t\t\tvar doNotInitLoader = true;\n\t\t\t" + inputFile.toString() + ";\n\t\t\tMonaco_Loader_Init = function() {\n\t\t\t\tAMDLoader.init();\n\t\t\t\tCSSLoaderPlugin.init();\n\t\t\t\tNLSLoaderPlugin.init();\n\n\t\t\t\treturn { define, require };\n\t\t\t}\n\t\t})();\n\t\t";
|
||||
var wrappedInputFilepath = path.join(os.tmpdir(), 'wrapped-loader.js');
|
||||
const inputFile = fs.readFileSync(loaderFilepath);
|
||||
const wrappedInputFile = `
|
||||
var Monaco_Loader_Init;
|
||||
(function() {
|
||||
var doNotInitLoader = true;
|
||||
${inputFile.toString()};
|
||||
Monaco_Loader_Init = function() {
|
||||
AMDLoader.init();
|
||||
CSSLoaderPlugin.init();
|
||||
NLSLoaderPlugin.init();
|
||||
|
||||
return { define, require };
|
||||
}
|
||||
})();
|
||||
`;
|
||||
const wrappedInputFilepath = path.join(os.tmpdir(), 'wrapped-loader.js');
|
||||
console.log(wrappedInputFilepath);
|
||||
fs.writeFileSync(wrappedInputFilepath, wrappedInputFile);
|
||||
cp.execFileSync(mksnapshot, [wrappedInputFilepath, "--startup_blob", startupBlobFilepath]);
|
||||
cp.execFileSync(mksnapshot, [wrappedInputFilepath, `--startup_blob`, startupBlobFilepath]);
|
||||
}
|
||||
})(snaps || (snaps = {}));
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* 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 tss = require("./treeshaking");
|
||||
var REPO_ROOT = path.join(__dirname, '../../');
|
||||
var SRC_DIR = path.join(REPO_ROOT, 'src');
|
||||
var dirCache = {};
|
||||
const ts = require("typescript");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const tss = require("./treeshaking");
|
||||
const REPO_ROOT = path.join(__dirname, '../../');
|
||||
const SRC_DIR = path.join(REPO_ROOT, 'src');
|
||||
let dirCache = {};
|
||||
function writeFile(filePath, contents) {
|
||||
function ensureDirs(dirPath) {
|
||||
if (dirCache[dirPath]) {
|
||||
|
@ -27,39 +27,39 @@ function writeFile(filePath, contents) {
|
|||
fs.writeFileSync(filePath, contents);
|
||||
}
|
||||
function extractEditor(options) {
|
||||
var tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
|
||||
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
|
||||
tsConfig.compilerOptions.noUnusedLocals = false;
|
||||
tsConfig.compilerOptions.preserveConstEnums = false;
|
||||
tsConfig.compilerOptions.declaration = false;
|
||||
delete tsConfig.compilerOptions.types;
|
||||
tsConfig.exclude = [];
|
||||
options.compilerOptions = tsConfig.compilerOptions;
|
||||
var result = tss.shake(options);
|
||||
for (var fileName in result) {
|
||||
let result = tss.shake(options);
|
||||
for (let fileName in result) {
|
||||
if (result.hasOwnProperty(fileName)) {
|
||||
writeFile(path.join(options.destRoot, fileName), result[fileName]);
|
||||
}
|
||||
}
|
||||
var copied = {};
|
||||
var copyFile = function (fileName) {
|
||||
let copied = {};
|
||||
const copyFile = (fileName) => {
|
||||
if (copied[fileName]) {
|
||||
return;
|
||||
}
|
||||
copied[fileName] = true;
|
||||
var srcPath = path.join(options.sourcesRoot, fileName);
|
||||
var dstPath = path.join(options.destRoot, fileName);
|
||||
const srcPath = path.join(options.sourcesRoot, fileName);
|
||||
const dstPath = path.join(options.destRoot, fileName);
|
||||
writeFile(dstPath, fs.readFileSync(srcPath));
|
||||
};
|
||||
var writeOutputFile = function (fileName, contents) {
|
||||
const writeOutputFile = (fileName, contents) => {
|
||||
writeFile(path.join(options.destRoot, fileName), contents);
|
||||
};
|
||||
for (var fileName in result) {
|
||||
for (let fileName in result) {
|
||||
if (result.hasOwnProperty(fileName)) {
|
||||
var fileContents = result[fileName];
|
||||
var info = ts.preProcessFile(fileContents);
|
||||
for (var i = info.importedFiles.length - 1; i >= 0; i--) {
|
||||
var importedFileName = info.importedFiles[i].fileName;
|
||||
var importedFilePath = void 0;
|
||||
const fileContents = result[fileName];
|
||||
const info = ts.preProcessFile(fileContents);
|
||||
for (let i = info.importedFiles.length - 1; i >= 0; i--) {
|
||||
const importedFileName = info.importedFiles[i].fileName;
|
||||
let importedFilePath;
|
||||
if (/^vs\/css!/.test(importedFileName)) {
|
||||
importedFilePath = importedFileName.substr('vs/css!'.length) + '.css';
|
||||
}
|
||||
|
@ -94,27 +94,27 @@ function extractEditor(options) {
|
|||
}
|
||||
exports.extractEditor = extractEditor;
|
||||
function createESMSourcesAndResources2(options) {
|
||||
var SRC_FOLDER = path.join(REPO_ROOT, options.srcFolder);
|
||||
var OUT_FOLDER = path.join(REPO_ROOT, options.outFolder);
|
||||
var OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder);
|
||||
var getDestAbsoluteFilePath = function (file) {
|
||||
var dest = options.renames[file.replace(/\\/g, '/')] || file;
|
||||
const SRC_FOLDER = path.join(REPO_ROOT, options.srcFolder);
|
||||
const OUT_FOLDER = path.join(REPO_ROOT, options.outFolder);
|
||||
const OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder);
|
||||
const getDestAbsoluteFilePath = (file) => {
|
||||
let dest = options.renames[file.replace(/\\/g, '/')] || file;
|
||||
if (dest === 'tsconfig.json') {
|
||||
return path.join(OUT_FOLDER, "tsconfig.json");
|
||||
return path.join(OUT_FOLDER, `tsconfig.json`);
|
||||
}
|
||||
if (/\.ts$/.test(dest)) {
|
||||
return path.join(OUT_FOLDER, dest);
|
||||
}
|
||||
return path.join(OUT_RESOURCES_FOLDER, dest);
|
||||
};
|
||||
var allFiles = walkDirRecursive(SRC_FOLDER);
|
||||
for (var i = 0; i < allFiles.length; i++) {
|
||||
var file = allFiles[i];
|
||||
const allFiles = walkDirRecursive(SRC_FOLDER);
|
||||
for (let i = 0; i < allFiles.length; i++) {
|
||||
const file = allFiles[i];
|
||||
if (options.ignores.indexOf(file.replace(/\\/g, '/')) >= 0) {
|
||||
continue;
|
||||
}
|
||||
if (file === 'tsconfig.json') {
|
||||
var tsConfig = JSON.parse(fs.readFileSync(path.join(SRC_FOLDER, file)).toString());
|
||||
const tsConfig = JSON.parse(fs.readFileSync(path.join(SRC_FOLDER, file)).toString());
|
||||
tsConfig.compilerOptions.module = 'es6';
|
||||
tsConfig.compilerOptions.outDir = path.join(path.relative(OUT_FOLDER, OUT_RESOURCES_FOLDER), 'vs');
|
||||
write(getDestAbsoluteFilePath(file), JSON.stringify(tsConfig, null, '\t'));
|
||||
|
@ -127,13 +127,13 @@ function createESMSourcesAndResources2(options) {
|
|||
}
|
||||
if (/\.ts$/.test(file)) {
|
||||
// Transform the .ts file
|
||||
var fileContents = fs.readFileSync(path.join(SRC_FOLDER, file)).toString();
|
||||
var info = ts.preProcessFile(fileContents);
|
||||
for (var i_1 = info.importedFiles.length - 1; i_1 >= 0; i_1--) {
|
||||
var importedFilename = info.importedFiles[i_1].fileName;
|
||||
var pos = info.importedFiles[i_1].pos;
|
||||
var end = info.importedFiles[i_1].end;
|
||||
var importedFilepath = void 0;
|
||||
let fileContents = fs.readFileSync(path.join(SRC_FOLDER, file)).toString();
|
||||
const info = ts.preProcessFile(fileContents);
|
||||
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;
|
||||
if (/^vs\/css!/.test(importedFilename)) {
|
||||
importedFilepath = importedFilename.substr('vs/css!'.length) + '.css';
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ function createESMSourcesAndResources2(options) {
|
|||
if (/(^\.\/)|(^\.\.\/)/.test(importedFilepath)) {
|
||||
importedFilepath = path.join(path.dirname(file), importedFilepath);
|
||||
}
|
||||
var relativePath = void 0;
|
||||
let relativePath;
|
||||
if (importedFilepath === path.dirname(file)) {
|
||||
relativePath = '../' + path.basename(path.dirname(file));
|
||||
}
|
||||
|
@ -161,25 +161,25 @@ function createESMSourcesAndResources2(options) {
|
|||
+ fileContents.substring(end + 1));
|
||||
}
|
||||
fileContents = fileContents.replace(/import ([a-zA-z0-9]+) = require\(('[^']+')\);/g, function (_, m1, m2) {
|
||||
return "import * as " + m1 + " from " + m2 + ";";
|
||||
return `import * as ${m1} from ${m2};`;
|
||||
});
|
||||
write(getDestAbsoluteFilePath(file), fileContents);
|
||||
continue;
|
||||
}
|
||||
console.log("UNKNOWN FILE: " + file);
|
||||
console.log(`UNKNOWN FILE: ${file}`);
|
||||
}
|
||||
function walkDirRecursive(dir) {
|
||||
if (dir.charAt(dir.length - 1) !== '/' || dir.charAt(dir.length - 1) !== '\\') {
|
||||
dir += '/';
|
||||
}
|
||||
var result = [];
|
||||
let result = [];
|
||||
_walkDirRecursive(dir, result, dir.length);
|
||||
return result;
|
||||
}
|
||||
function _walkDirRecursive(dir, result, trimPos) {
|
||||
var files = fs.readdirSync(dir);
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var file = path.join(dir, files[i]);
|
||||
const files = fs.readdirSync(dir);
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = path.join(dir, files[i]);
|
||||
if (fs.statSync(file).isDirectory()) {
|
||||
_walkDirRecursive(file, result, trimPos);
|
||||
}
|
||||
|
@ -194,10 +194,10 @@ function createESMSourcesAndResources2(options) {
|
|||
}
|
||||
writeFile(absoluteFilePath, contents);
|
||||
function toggleComments(fileContents) {
|
||||
var lines = fileContents.split(/\r\n|\r|\n/);
|
||||
var mode = 0;
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var line = lines[i];
|
||||
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;
|
||||
|
@ -236,30 +236,30 @@ function transportCSS(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(fileContents, inlineResources === 'base64', inlineResourcesLimit);
|
||||
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(fileContents, inlineResources === 'base64', inlineResourcesLimit);
|
||||
write(module, newContents);
|
||||
return true;
|
||||
function _rewriteOrInlineUrls(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));
|
||||
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) {
|
||||
var MIME = /\.svg$/.test(url) ? 'image/svg+xml' : 'image/png';
|
||||
var DATA = ';base64,' + fileContents.toString('base64');
|
||||
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
|
||||
var newText = fileContents.toString()
|
||||
let newText = fileContents.toString()
|
||||
.replace(/"/g, '\'')
|
||||
.replace(/</g, '%3C')
|
||||
.replace(/>/g, '%3E')
|
||||
.replace(/&/g, '%26')
|
||||
.replace(/#/g, '%23')
|
||||
.replace(/\s+/g, ' ');
|
||||
var encodedData = ',' + newText;
|
||||
let encodedData = ',' + newText;
|
||||
if (encodedData.length < DATA.length) {
|
||||
DATA = encodedData;
|
||||
}
|
||||
|
@ -272,12 +272,8 @@ function transportCSS(module, enqueue, write) {
|
|||
}
|
||||
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];
|
||||
return contents.replace(/url\(\s*([^\)]+)\s*\)?/g, (_, ...matches) => {
|
||||
let url = matches[0];
|
||||
// Eliminate starting quotes (the initial whitespace is not captured)
|
||||
if (url.charAt(0) === '"' || url.charAt(0) === '\'') {
|
||||
url = url.substring(1);
|
||||
|
|
|
@ -4,44 +4,43 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var es = require("event-stream");
|
||||
var util = require("gulp-util");
|
||||
var appInsights = require("applicationinsights");
|
||||
var Entry = /** @class */ (function () {
|
||||
function Entry(name, totalCount, totalSize) {
|
||||
const es = require("event-stream");
|
||||
const util = require("gulp-util");
|
||||
const appInsights = require("applicationinsights");
|
||||
class Entry {
|
||||
constructor(name, totalCount, totalSize) {
|
||||
this.name = name;
|
||||
this.totalCount = totalCount;
|
||||
this.totalSize = totalSize;
|
||||
}
|
||||
Entry.prototype.toString = function (pretty) {
|
||||
toString(pretty) {
|
||||
if (!pretty) {
|
||||
if (this.totalCount === 1) {
|
||||
return this.name + ": " + this.totalSize + " bytes";
|
||||
return `${this.name}: ${this.totalSize} bytes`;
|
||||
}
|
||||
else {
|
||||
return this.name + ": " + this.totalCount + " files with " + this.totalSize + " bytes";
|
||||
return `${this.name}: ${this.totalCount} files with ${this.totalSize} bytes`;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.totalCount === 1) {
|
||||
return "Stats for '" + util.colors.grey(this.name) + "': " + Math.round(this.totalSize / 1204) + "KB";
|
||||
return `Stats for '${util.colors.grey(this.name)}': ${Math.round(this.totalSize / 1204)}KB`;
|
||||
}
|
||||
else {
|
||||
var count = this.totalCount < 100
|
||||
const count = this.totalCount < 100
|
||||
? util.colors.green(this.totalCount.toString())
|
||||
: util.colors.red(this.totalCount.toString());
|
||||
return "Stats for '" + util.colors.grey(this.name) + "': " + count + " files, " + Math.round(this.totalSize / 1204) + "KB";
|
||||
return `Stats for '${util.colors.grey(this.name)}': ${count} files, ${Math.round(this.totalSize / 1204)}KB`;
|
||||
}
|
||||
}
|
||||
};
|
||||
return Entry;
|
||||
}());
|
||||
var _entries = new Map();
|
||||
}
|
||||
}
|
||||
const _entries = new Map();
|
||||
function createStatsStream(group, log) {
|
||||
var entry = new Entry(group, 0, 0);
|
||||
const entry = new Entry(group, 0, 0);
|
||||
_entries.set(entry.name, entry);
|
||||
return es.through(function (data) {
|
||||
var file = data;
|
||||
const file = data;
|
||||
if (typeof file.path === 'string') {
|
||||
entry.totalCount += 1;
|
||||
if (Buffer.isBuffer(file.contents)) {
|
||||
|
@ -58,13 +57,13 @@ function createStatsStream(group, log) {
|
|||
}, function () {
|
||||
if (log) {
|
||||
if (entry.totalCount === 1) {
|
||||
util.log("Stats for '" + util.colors.grey(entry.name) + "': " + Math.round(entry.totalSize / 1204) + "KB");
|
||||
util.log(`Stats for '${util.colors.grey(entry.name)}': ${Math.round(entry.totalSize / 1204)}KB`);
|
||||
}
|
||||
else {
|
||||
var count = entry.totalCount < 100
|
||||
const count = entry.totalCount < 100
|
||||
? util.colors.green(entry.totalCount.toString())
|
||||
: util.colors.red(entry.totalCount.toString());
|
||||
util.log("Stats for '" + util.colors.grey(entry.name) + "': " + count + " files, " + Math.round(entry.totalSize / 1204) + "KB");
|
||||
util.log(`Stats for '${util.colors.grey(entry.name)}': ${count} files, ${Math.round(entry.totalSize / 1204)}KB`);
|
||||
}
|
||||
}
|
||||
this.emit('end');
|
||||
|
@ -72,9 +71,9 @@ function createStatsStream(group, log) {
|
|||
}
|
||||
exports.createStatsStream = createStatsStream;
|
||||
function submitAllStats(productJson, commit) {
|
||||
var sorted = [];
|
||||
const sorted = [];
|
||||
// move entries for single files to the front
|
||||
_entries.forEach(function (value) {
|
||||
_entries.forEach(value => {
|
||||
if (value.totalCount === 1) {
|
||||
sorted.unshift(value);
|
||||
}
|
||||
|
@ -83,8 +82,7 @@ function submitAllStats(productJson, commit) {
|
|||
}
|
||||
});
|
||||
// print to console
|
||||
for (var _i = 0, sorted_1 = sorted; _i < sorted_1.length; _i++) {
|
||||
var entry = sorted_1[_i];
|
||||
for (const entry of sorted) {
|
||||
console.log(entry.toString(true));
|
||||
}
|
||||
// send data as telementry event when the
|
||||
|
@ -92,12 +90,11 @@ function submitAllStats(productJson, commit) {
|
|||
if (!productJson || !productJson.aiConfig || typeof productJson.aiConfig.asimovKey !== 'string') {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
return new Promise(function (resolve) {
|
||||
return new Promise(resolve => {
|
||||
try {
|
||||
var sizes = {};
|
||||
var counts = {};
|
||||
for (var _i = 0, sorted_2 = sorted; _i < sorted_2.length; _i++) {
|
||||
var entry = sorted_2[_i];
|
||||
const sizes = {};
|
||||
const counts = {};
|
||||
for (const entry of sorted) {
|
||||
sizes[entry.name] = entry.totalSize;
|
||||
counts[entry.name] = entry.totalCount;
|
||||
}
|
||||
|
@ -119,10 +116,10 @@ function submitAllStats(productJson, commit) {
|
|||
*/
|
||||
appInsights.defaultClient.trackEvent({
|
||||
name: 'monacoworkbench/packagemetrics',
|
||||
properties: { commit: commit, size: JSON.stringify(sizes), count: JSON.stringify(counts) }
|
||||
properties: { commit, size: JSON.stringify(sizes), count: JSON.stringify(counts) }
|
||||
});
|
||||
appInsights.defaultClient.flush({
|
||||
callback: function () {
|
||||
callback: () => {
|
||||
appInsights.dispose();
|
||||
resolve(true);
|
||||
}
|
||||
|
|
|
@ -4,30 +4,30 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var assert = require("assert");
|
||||
var i18n = require("../i18n");
|
||||
suite('XLF Parser Tests', function () {
|
||||
var sampleXlf = '<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file original="vs/base/common/keybinding" source-language="en" datatype="plaintext"><body><trans-unit id="key1"><source xml:lang="en">Key #1</source></trans-unit><trans-unit id="key2"><source xml:lang="en">Key #2 &</source></trans-unit></body></file></xliff>';
|
||||
var sampleTranslatedXlf = '<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file original="vs/base/common/keybinding" source-language="en" target-language="ru" datatype="plaintext"><body><trans-unit id="key1"><source xml:lang="en">Key #1</source><target>Кнопка #1</target></trans-unit><trans-unit id="key2"><source xml:lang="en">Key #2 &</source><target>Кнопка #2 &</target></trans-unit></body></file></xliff>';
|
||||
var originalFilePath = 'vs/base/common/keybinding';
|
||||
var keys = ['key1', 'key2'];
|
||||
var messages = ['Key #1', 'Key #2 &'];
|
||||
var translatedMessages = { key1: 'Кнопка #1', key2: 'Кнопка #2 &' };
|
||||
test('Keys & messages to XLF conversion', function () {
|
||||
var xlf = new i18n.XLF('vscode-workbench');
|
||||
const assert = require("assert");
|
||||
const i18n = require("../i18n");
|
||||
suite('XLF Parser Tests', () => {
|
||||
const sampleXlf = '<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file original="vs/base/common/keybinding" source-language="en" datatype="plaintext"><body><trans-unit id="key1"><source xml:lang="en">Key #1</source></trans-unit><trans-unit id="key2"><source xml:lang="en">Key #2 &</source></trans-unit></body></file></xliff>';
|
||||
const sampleTranslatedXlf = '<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file original="vs/base/common/keybinding" source-language="en" target-language="ru" datatype="plaintext"><body><trans-unit id="key1"><source xml:lang="en">Key #1</source><target>Кнопка #1</target></trans-unit><trans-unit id="key2"><source xml:lang="en">Key #2 &</source><target>Кнопка #2 &</target></trans-unit></body></file></xliff>';
|
||||
const originalFilePath = 'vs/base/common/keybinding';
|
||||
const keys = ['key1', 'key2'];
|
||||
const messages = ['Key #1', 'Key #2 &'];
|
||||
const translatedMessages = { key1: 'Кнопка #1', key2: 'Кнопка #2 &' };
|
||||
test('Keys & messages to XLF conversion', () => {
|
||||
const xlf = new i18n.XLF('vscode-workbench');
|
||||
xlf.addFile(originalFilePath, keys, messages);
|
||||
var xlfString = xlf.toString();
|
||||
const xlfString = xlf.toString();
|
||||
assert.strictEqual(xlfString.replace(/\s{2,}/g, ''), sampleXlf);
|
||||
});
|
||||
test('XLF to keys & messages conversion', function () {
|
||||
test('XLF to keys & messages conversion', () => {
|
||||
i18n.XLF.parse(sampleTranslatedXlf).then(function (resolvedFiles) {
|
||||
assert.deepEqual(resolvedFiles[0].messages, translatedMessages);
|
||||
assert.strictEqual(resolvedFiles[0].originalFilePath, originalFilePath);
|
||||
});
|
||||
});
|
||||
test('JSON file source path to Transifex resource match', function () {
|
||||
var editorProject = 'vscode-editor', workbenchProject = 'vscode-workbench';
|
||||
var platform = { name: 'vs/platform', project: editorProject }, editorContrib = { name: 'vs/editor/contrib', project: editorProject }, editor = { name: 'vs/editor', project: editorProject }, base = { name: 'vs/base', project: editorProject }, code = { name: 'vs/code', project: workbenchProject }, workbenchParts = { name: 'vs/workbench/parts/html', project: workbenchProject }, workbenchServices = { name: 'vs/workbench/services/files', project: workbenchProject }, workbench = { name: 'vs/workbench', project: workbenchProject };
|
||||
test('JSON file source path to Transifex resource match', () => {
|
||||
const editorProject = 'vscode-editor', workbenchProject = 'vscode-workbench';
|
||||
const platform = { name: 'vs/platform', project: editorProject }, editorContrib = { name: 'vs/editor/contrib', project: editorProject }, editor = { name: 'vs/editor', project: editorProject }, base = { name: 'vs/base', project: editorProject }, code = { name: 'vs/code', project: workbenchProject }, workbenchParts = { name: 'vs/workbench/parts/html', project: workbenchProject }, workbenchServices = { name: 'vs/workbench/services/files', project: workbenchProject }, workbench = { name: 'vs/workbench', project: workbenchProject };
|
||||
assert.deepEqual(i18n.getResource('vs/platform/actions/browser/menusExtensionPoint'), platform);
|
||||
assert.deepEqual(i18n.getResource('vs/editor/contrib/clipboard/browser/clipboard'), editorContrib);
|
||||
assert.deepEqual(i18n.getResource('vs/editor/common/modes/modesRegistry'), editor);
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var ts = require("typescript");
|
||||
var TYPESCRIPT_LIB_FOLDER = path.dirname(require.resolve('typescript/lib/lib.d.ts'));
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const ts = require("typescript");
|
||||
const TYPESCRIPT_LIB_FOLDER = path.dirname(require.resolve('typescript/lib/lib.d.ts'));
|
||||
var ShakeLevel;
|
||||
(function (ShakeLevel) {
|
||||
ShakeLevel[ShakeLevel["Files"] = 0] = "Files";
|
||||
|
@ -15,37 +15,37 @@ var ShakeLevel;
|
|||
ShakeLevel[ShakeLevel["ClassMembers"] = 2] = "ClassMembers";
|
||||
})(ShakeLevel = exports.ShakeLevel || (exports.ShakeLevel = {}));
|
||||
function printDiagnostics(diagnostics) {
|
||||
for (var i = 0; i < diagnostics.length; i++) {
|
||||
var diag = diagnostics[i];
|
||||
var result = '';
|
||||
for (let i = 0; i < diagnostics.length; i++) {
|
||||
const diag = diagnostics[i];
|
||||
let result = '';
|
||||
if (diag.file) {
|
||||
result += diag.file.fileName + ": ";
|
||||
result += `${diag.file.fileName}: `;
|
||||
}
|
||||
if (diag.file && diag.start) {
|
||||
var location_1 = diag.file.getLineAndCharacterOfPosition(diag.start);
|
||||
result += "- " + (location_1.line + 1) + "," + location_1.character + " - ";
|
||||
let location = diag.file.getLineAndCharacterOfPosition(diag.start);
|
||||
result += `- ${location.line + 1},${location.character} - `;
|
||||
}
|
||||
result += JSON.stringify(diag.messageText);
|
||||
console.log(result);
|
||||
}
|
||||
}
|
||||
function shake(options) {
|
||||
var languageService = createTypeScriptLanguageService(options);
|
||||
var program = languageService.getProgram();
|
||||
var globalDiagnostics = program.getGlobalDiagnostics();
|
||||
const languageService = createTypeScriptLanguageService(options);
|
||||
const program = languageService.getProgram();
|
||||
const globalDiagnostics = program.getGlobalDiagnostics();
|
||||
if (globalDiagnostics.length > 0) {
|
||||
printDiagnostics(globalDiagnostics);
|
||||
throw new Error("Compilation Errors encountered.");
|
||||
throw new Error(`Compilation Errors encountered.`);
|
||||
}
|
||||
var syntacticDiagnostics = program.getSyntacticDiagnostics();
|
||||
const syntacticDiagnostics = program.getSyntacticDiagnostics();
|
||||
if (syntacticDiagnostics.length > 0) {
|
||||
printDiagnostics(syntacticDiagnostics);
|
||||
throw new Error("Compilation Errors encountered.");
|
||||
throw new Error(`Compilation Errors encountered.`);
|
||||
}
|
||||
var semanticDiagnostics = program.getSemanticDiagnostics();
|
||||
const semanticDiagnostics = program.getSemanticDiagnostics();
|
||||
if (semanticDiagnostics.length > 0) {
|
||||
printDiagnostics(semanticDiagnostics);
|
||||
throw new Error("Compilation Errors encountered.");
|
||||
throw new Error(`Compilation Errors encountered.`);
|
||||
}
|
||||
markNodes(languageService, options);
|
||||
return generateResult(languageService, options.shakeLevel);
|
||||
|
@ -54,98 +54,98 @@ exports.shake = shake;
|
|||
//#region Discovery, LanguageService & Setup
|
||||
function createTypeScriptLanguageService(options) {
|
||||
// Discover referenced files
|
||||
var FILES = discoverAndReadFiles(options);
|
||||
const FILES = discoverAndReadFiles(options);
|
||||
// Add fake usage files
|
||||
options.inlineEntryPoints.forEach(function (inlineEntryPoint, index) {
|
||||
FILES["inlineEntryPoint:" + index + ".ts"] = inlineEntryPoint;
|
||||
options.inlineEntryPoints.forEach((inlineEntryPoint, index) => {
|
||||
FILES[`inlineEntryPoint:${index}.ts`] = inlineEntryPoint;
|
||||
});
|
||||
// Add additional typings
|
||||
options.typings.forEach(function (typing) {
|
||||
var filePath = path.join(options.sourcesRoot, typing);
|
||||
options.typings.forEach((typing) => {
|
||||
const filePath = path.join(options.sourcesRoot, typing);
|
||||
FILES[typing] = fs.readFileSync(filePath).toString();
|
||||
});
|
||||
// Resolve libs
|
||||
var RESOLVED_LIBS = {};
|
||||
options.libs.forEach(function (filename) {
|
||||
var filepath = path.join(TYPESCRIPT_LIB_FOLDER, filename);
|
||||
RESOLVED_LIBS["defaultLib:" + filename] = fs.readFileSync(filepath).toString();
|
||||
const RESOLVED_LIBS = {};
|
||||
options.libs.forEach((filename) => {
|
||||
const filepath = path.join(TYPESCRIPT_LIB_FOLDER, filename);
|
||||
RESOLVED_LIBS[`defaultLib:${filename}`] = fs.readFileSync(filepath).toString();
|
||||
});
|
||||
var host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, ts.convertCompilerOptionsFromJson(options.compilerOptions, "").options);
|
||||
const host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, ts.convertCompilerOptionsFromJson(options.compilerOptions, ``).options);
|
||||
return ts.createLanguageService(host);
|
||||
}
|
||||
/**
|
||||
* Read imports and follow them until all files have been handled
|
||||
*/
|
||||
function discoverAndReadFiles(options) {
|
||||
var FILES = {};
|
||||
var in_queue = Object.create(null);
|
||||
var queue = [];
|
||||
var enqueue = function (moduleId) {
|
||||
const FILES = {};
|
||||
const in_queue = Object.create(null);
|
||||
const queue = [];
|
||||
const enqueue = (moduleId) => {
|
||||
if (in_queue[moduleId]) {
|
||||
return;
|
||||
}
|
||||
in_queue[moduleId] = true;
|
||||
queue.push(moduleId);
|
||||
};
|
||||
options.entryPoints.forEach(function (entryPoint) { return enqueue(entryPoint); });
|
||||
options.entryPoints.forEach((entryPoint) => enqueue(entryPoint));
|
||||
while (queue.length > 0) {
|
||||
var moduleId = queue.shift();
|
||||
var dts_filename = path.join(options.sourcesRoot, moduleId + '.d.ts');
|
||||
const moduleId = queue.shift();
|
||||
const dts_filename = path.join(options.sourcesRoot, moduleId + '.d.ts');
|
||||
if (fs.existsSync(dts_filename)) {
|
||||
var dts_filecontents = fs.readFileSync(dts_filename).toString();
|
||||
FILES[moduleId + ".d.ts"] = dts_filecontents;
|
||||
const dts_filecontents = fs.readFileSync(dts_filename).toString();
|
||||
FILES[`${moduleId}.d.ts`] = dts_filecontents;
|
||||
continue;
|
||||
}
|
||||
var ts_filename = void 0;
|
||||
let ts_filename;
|
||||
if (options.redirects[moduleId]) {
|
||||
ts_filename = path.join(options.sourcesRoot, options.redirects[moduleId] + '.ts');
|
||||
}
|
||||
else {
|
||||
ts_filename = path.join(options.sourcesRoot, moduleId + '.ts');
|
||||
}
|
||||
var ts_filecontents = fs.readFileSync(ts_filename).toString();
|
||||
var info = ts.preProcessFile(ts_filecontents);
|
||||
for (var i = info.importedFiles.length - 1; i >= 0; i--) {
|
||||
var importedFileName = info.importedFiles[i].fileName;
|
||||
const ts_filecontents = fs.readFileSync(ts_filename).toString();
|
||||
const info = ts.preProcessFile(ts_filecontents);
|
||||
for (let i = info.importedFiles.length - 1; i >= 0; i--) {
|
||||
const importedFileName = info.importedFiles[i].fileName;
|
||||
if (options.importIgnorePattern.test(importedFileName)) {
|
||||
// Ignore vs/css! imports
|
||||
continue;
|
||||
}
|
||||
var importedModuleId = importedFileName;
|
||||
let importedModuleId = importedFileName;
|
||||
if (/(^\.\/)|(^\.\.\/)/.test(importedModuleId)) {
|
||||
importedModuleId = path.join(path.dirname(moduleId), importedModuleId);
|
||||
}
|
||||
enqueue(importedModuleId);
|
||||
}
|
||||
FILES[moduleId + ".ts"] = ts_filecontents;
|
||||
FILES[`${moduleId}.ts`] = ts_filecontents;
|
||||
}
|
||||
return FILES;
|
||||
}
|
||||
/**
|
||||
* A TypeScript language service host
|
||||
*/
|
||||
var TypeScriptLanguageServiceHost = /** @class */ (function () {
|
||||
function TypeScriptLanguageServiceHost(libs, files, compilerOptions) {
|
||||
class TypeScriptLanguageServiceHost {
|
||||
constructor(libs, files, compilerOptions) {
|
||||
this._libs = libs;
|
||||
this._files = files;
|
||||
this._compilerOptions = compilerOptions;
|
||||
}
|
||||
// --- language service host ---------------
|
||||
TypeScriptLanguageServiceHost.prototype.getCompilationSettings = function () {
|
||||
getCompilationSettings() {
|
||||
return this._compilerOptions;
|
||||
};
|
||||
TypeScriptLanguageServiceHost.prototype.getScriptFileNames = function () {
|
||||
}
|
||||
getScriptFileNames() {
|
||||
return ([]
|
||||
.concat(Object.keys(this._libs))
|
||||
.concat(Object.keys(this._files)));
|
||||
};
|
||||
TypeScriptLanguageServiceHost.prototype.getScriptVersion = function (_fileName) {
|
||||
}
|
||||
getScriptVersion(_fileName) {
|
||||
return '1';
|
||||
};
|
||||
TypeScriptLanguageServiceHost.prototype.getProjectVersion = function () {
|
||||
}
|
||||
getProjectVersion() {
|
||||
return '1';
|
||||
};
|
||||
TypeScriptLanguageServiceHost.prototype.getScriptSnapshot = function (fileName) {
|
||||
}
|
||||
getScriptSnapshot(fileName) {
|
||||
if (this._files.hasOwnProperty(fileName)) {
|
||||
return ts.ScriptSnapshot.fromString(this._files[fileName]);
|
||||
}
|
||||
|
@ -155,21 +155,20 @@ var TypeScriptLanguageServiceHost = /** @class */ (function () {
|
|||
else {
|
||||
return ts.ScriptSnapshot.fromString('');
|
||||
}
|
||||
};
|
||||
TypeScriptLanguageServiceHost.prototype.getScriptKind = function (_fileName) {
|
||||
}
|
||||
getScriptKind(_fileName) {
|
||||
return ts.ScriptKind.TS;
|
||||
};
|
||||
TypeScriptLanguageServiceHost.prototype.getCurrentDirectory = function () {
|
||||
}
|
||||
getCurrentDirectory() {
|
||||
return '';
|
||||
};
|
||||
TypeScriptLanguageServiceHost.prototype.getDefaultLibFileName = function (_options) {
|
||||
}
|
||||
getDefaultLibFileName(_options) {
|
||||
return 'defaultLib:lib.d.ts';
|
||||
};
|
||||
TypeScriptLanguageServiceHost.prototype.isDefaultLibFileName = function (fileName) {
|
||||
}
|
||||
isDefaultLibFileName(fileName) {
|
||||
return fileName === this.getDefaultLibFileName(this._compilerOptions);
|
||||
};
|
||||
return TypeScriptLanguageServiceHost;
|
||||
}());
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
//#region Tree Shaking
|
||||
var NodeColor;
|
||||
|
@ -186,7 +185,7 @@ function setColor(node, color) {
|
|||
}
|
||||
function nodeOrParentIsBlack(node) {
|
||||
while (node) {
|
||||
var color = getColor(node);
|
||||
const color = getColor(node);
|
||||
if (color === 2 /* Black */) {
|
||||
return true;
|
||||
}
|
||||
|
@ -198,8 +197,7 @@ function nodeOrChildIsBlack(node) {
|
|||
if (getColor(node) === 2 /* Black */) {
|
||||
return true;
|
||||
}
|
||||
for (var _i = 0, _a = node.getChildren(); _i < _a.length; _i++) {
|
||||
var child = _a[_i];
|
||||
for (const child of node.getChildren()) {
|
||||
if (nodeOrChildIsBlack(child)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -207,22 +205,22 @@ function nodeOrChildIsBlack(node) {
|
|||
return false;
|
||||
}
|
||||
function markNodes(languageService, options) {
|
||||
var program = languageService.getProgram();
|
||||
const program = languageService.getProgram();
|
||||
if (!program) {
|
||||
throw new Error('Could not get program from language service');
|
||||
}
|
||||
if (options.shakeLevel === 0 /* Files */) {
|
||||
// Mark all source files Black
|
||||
program.getSourceFiles().forEach(function (sourceFile) {
|
||||
program.getSourceFiles().forEach((sourceFile) => {
|
||||
setColor(sourceFile, 2 /* Black */);
|
||||
});
|
||||
return;
|
||||
}
|
||||
var black_queue = [];
|
||||
var gray_queue = [];
|
||||
var sourceFilesLoaded = {};
|
||||
const black_queue = [];
|
||||
const gray_queue = [];
|
||||
const sourceFilesLoaded = {};
|
||||
function enqueueTopLevelModuleStatements(sourceFile) {
|
||||
sourceFile.forEachChild(function (node) {
|
||||
sourceFile.forEachChild((node) => {
|
||||
if (ts.isImportDeclaration(node)) {
|
||||
if (!node.importClause && ts.isStringLiteral(node.moduleSpecifier)) {
|
||||
setColor(node, 2 /* Black */);
|
||||
|
@ -259,7 +257,7 @@ function markNodes(languageService, options) {
|
|||
gray_queue.push(node);
|
||||
}
|
||||
function enqueue_black(node) {
|
||||
var previousColor = getColor(node);
|
||||
const previousColor = getColor(node);
|
||||
if (previousColor === 2 /* Black */) {
|
||||
return;
|
||||
}
|
||||
|
@ -277,12 +275,12 @@ function markNodes(languageService, options) {
|
|||
if (nodeOrParentIsBlack(node)) {
|
||||
return;
|
||||
}
|
||||
var fileName = node.getSourceFile().fileName;
|
||||
const fileName = node.getSourceFile().fileName;
|
||||
if (/^defaultLib:/.test(fileName) || /\.d\.ts$/.test(fileName)) {
|
||||
setColor(node, 2 /* Black */);
|
||||
return;
|
||||
}
|
||||
var sourceFile = node.getSourceFile();
|
||||
const sourceFile = node.getSourceFile();
|
||||
if (!sourceFilesLoaded[sourceFile.fileName]) {
|
||||
sourceFilesLoaded[sourceFile.fileName] = true;
|
||||
enqueueTopLevelModuleStatements(sourceFile);
|
||||
|
@ -293,15 +291,15 @@ function markNodes(languageService, options) {
|
|||
setColor(node, 2 /* Black */);
|
||||
black_queue.push(node);
|
||||
if (options.shakeLevel === 2 /* ClassMembers */ && (ts.isMethodDeclaration(node) || ts.isMethodSignature(node) || ts.isPropertySignature(node) || ts.isGetAccessor(node) || ts.isSetAccessor(node))) {
|
||||
var references = languageService.getReferencesAtPosition(node.getSourceFile().fileName, node.name.pos + node.name.getLeadingTriviaWidth());
|
||||
const references = languageService.getReferencesAtPosition(node.getSourceFile().fileName, node.name.pos + node.name.getLeadingTriviaWidth());
|
||||
if (references) {
|
||||
for (var i = 0, len = references.length; i < len; i++) {
|
||||
var reference = references[i];
|
||||
var referenceSourceFile = program.getSourceFile(reference.fileName);
|
||||
for (let i = 0, len = references.length; i < len; i++) {
|
||||
const reference = references[i];
|
||||
const referenceSourceFile = program.getSourceFile(reference.fileName);
|
||||
if (!referenceSourceFile) {
|
||||
continue;
|
||||
}
|
||||
var referenceNode = getTokenAtPosition(referenceSourceFile, reference.textSpan.start, false, false);
|
||||
const referenceNode = getTokenAtPosition(referenceSourceFile, reference.textSpan.start, false, false);
|
||||
if (ts.isMethodDeclaration(referenceNode.parent)
|
||||
|| ts.isPropertyDeclaration(referenceNode.parent)
|
||||
|| ts.isGetAccessor(referenceNode.parent)
|
||||
|
@ -313,9 +311,9 @@ function markNodes(languageService, options) {
|
|||
}
|
||||
}
|
||||
function enqueueFile(filename) {
|
||||
var sourceFile = program.getSourceFile(filename);
|
||||
const sourceFile = program.getSourceFile(filename);
|
||||
if (!sourceFile) {
|
||||
console.warn("Cannot find source file " + filename);
|
||||
console.warn(`Cannot find source file ${filename}`);
|
||||
return;
|
||||
}
|
||||
enqueue_black(sourceFile);
|
||||
|
@ -325,8 +323,8 @@ function markNodes(languageService, options) {
|
|||
// this import should be ignored
|
||||
return;
|
||||
}
|
||||
var nodeSourceFile = node.getSourceFile();
|
||||
var fullPath;
|
||||
const nodeSourceFile = node.getSourceFile();
|
||||
let fullPath;
|
||||
if (/(^\.\/)|(^\.\.\/)/.test(importText)) {
|
||||
fullPath = path.join(path.dirname(nodeSourceFile.fileName), importText) + '.ts';
|
||||
}
|
||||
|
@ -335,25 +333,25 @@ function markNodes(languageService, options) {
|
|||
}
|
||||
enqueueFile(fullPath);
|
||||
}
|
||||
options.entryPoints.forEach(function (moduleId) { return enqueueFile(moduleId + '.ts'); });
|
||||
options.entryPoints.forEach(moduleId => enqueueFile(moduleId + '.ts'));
|
||||
// Add fake usage files
|
||||
options.inlineEntryPoints.forEach(function (_, index) { return enqueueFile("inlineEntryPoint:" + index + ".ts"); });
|
||||
var step = 0;
|
||||
var checker = program.getTypeChecker();
|
||||
var _loop_1 = function () {
|
||||
options.inlineEntryPoints.forEach((_, index) => enqueueFile(`inlineEntryPoint:${index}.ts`));
|
||||
let step = 0;
|
||||
const checker = program.getTypeChecker();
|
||||
while (black_queue.length > 0 || gray_queue.length > 0) {
|
||||
++step;
|
||||
var node = void 0;
|
||||
let node;
|
||||
if (step % 100 === 0) {
|
||||
console.log(step + "/" + (step + black_queue.length + gray_queue.length) + " (" + black_queue.length + ", " + gray_queue.length + ")");
|
||||
console.log(`${step}/${step + black_queue.length + gray_queue.length} (${black_queue.length}, ${gray_queue.length})`);
|
||||
}
|
||||
if (black_queue.length === 0) {
|
||||
for (var i = 0; i < gray_queue.length; i++) {
|
||||
var node_1 = gray_queue[i];
|
||||
var nodeParent = node_1.parent;
|
||||
for (let i = 0; i < gray_queue.length; i++) {
|
||||
const node = gray_queue[i];
|
||||
const nodeParent = node.parent;
|
||||
if ((ts.isClassDeclaration(nodeParent) || ts.isInterfaceDeclaration(nodeParent)) && nodeOrChildIsBlack(nodeParent)) {
|
||||
gray_queue.splice(i, 1);
|
||||
black_queue.push(node_1);
|
||||
setColor(node_1, 2 /* Black */);
|
||||
black_queue.push(node);
|
||||
setColor(node, 2 /* Black */);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
@ -362,17 +360,18 @@ function markNodes(languageService, options) {
|
|||
node = black_queue.shift();
|
||||
}
|
||||
else {
|
||||
return "break";
|
||||
// only gray nodes remaining...
|
||||
break;
|
||||
}
|
||||
var nodeSourceFile = node.getSourceFile();
|
||||
var loop = function (node) {
|
||||
var _a = getRealNodeSymbol(checker, node), symbol = _a[0], symbolImportNode = _a[1];
|
||||
const nodeSourceFile = node.getSourceFile();
|
||||
const loop = (node) => {
|
||||
const [symbol, symbolImportNode] = getRealNodeSymbol(checker, node);
|
||||
if (symbolImportNode) {
|
||||
setColor(symbolImportNode, 2 /* Black */);
|
||||
}
|
||||
if (symbol && !nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol)) {
|
||||
for (var i = 0, len = symbol.declarations.length; i < len; i++) {
|
||||
var declaration = symbol.declarations[i];
|
||||
for (let i = 0, len = symbol.declarations.length; i < len; i++) {
|
||||
const declaration = symbol.declarations[i];
|
||||
if (ts.isSourceFile(declaration)) {
|
||||
// Do not enqueue full source files
|
||||
// (they can be the declaration of a module import)
|
||||
|
@ -380,9 +379,9 @@ function markNodes(languageService, options) {
|
|||
}
|
||||
if (options.shakeLevel === 2 /* ClassMembers */ && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration))) {
|
||||
enqueue_black(declaration.name);
|
||||
for (var j = 0; j < declaration.members.length; j++) {
|
||||
var member = declaration.members[j];
|
||||
var memberName = member.name ? member.name.getText() : null;
|
||||
for (let j = 0; j < declaration.members.length; j++) {
|
||||
const member = declaration.members[j];
|
||||
const memberName = member.name ? member.name.getText() : null;
|
||||
if (ts.isConstructorDeclaration(member)
|
||||
|| ts.isConstructSignatureDeclaration(member)
|
||||
|| ts.isIndexSignatureDeclaration(member)
|
||||
|
@ -396,8 +395,7 @@ function markNodes(languageService, options) {
|
|||
}
|
||||
// queue the heritage clauses
|
||||
if (declaration.heritageClauses) {
|
||||
for (var _i = 0, _b = declaration.heritageClauses; _i < _b.length; _i++) {
|
||||
var heritageClause = _b[_i];
|
||||
for (let heritageClause of declaration.heritageClauses) {
|
||||
enqueue_black(heritageClause);
|
||||
}
|
||||
}
|
||||
|
@ -410,17 +408,12 @@ function markNodes(languageService, options) {
|
|||
node.forEachChild(loop);
|
||||
};
|
||||
node.forEachChild(loop);
|
||||
};
|
||||
while (black_queue.length > 0 || gray_queue.length > 0) {
|
||||
var state_1 = _loop_1();
|
||||
if (state_1 === "break")
|
||||
break;
|
||||
}
|
||||
}
|
||||
function nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol) {
|
||||
for (var i = 0, len = symbol.declarations.length; i < len; i++) {
|
||||
var declaration = symbol.declarations[i];
|
||||
var declarationSourceFile = declaration.getSourceFile();
|
||||
for (let i = 0, len = symbol.declarations.length; i < len; i++) {
|
||||
const declaration = symbol.declarations[i];
|
||||
const declarationSourceFile = declaration.getSourceFile();
|
||||
if (nodeSourceFile === declarationSourceFile) {
|
||||
if (declaration.pos <= node.pos && node.end <= declaration.end) {
|
||||
return true;
|
||||
|
@ -430,28 +423,28 @@ function nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol) {
|
|||
return false;
|
||||
}
|
||||
function generateResult(languageService, shakeLevel) {
|
||||
var program = languageService.getProgram();
|
||||
const program = languageService.getProgram();
|
||||
if (!program) {
|
||||
throw new Error('Could not get program from language service');
|
||||
}
|
||||
var result = {};
|
||||
var writeFile = function (filePath, contents) {
|
||||
let result = {};
|
||||
const writeFile = (filePath, contents) => {
|
||||
result[filePath] = contents;
|
||||
};
|
||||
program.getSourceFiles().forEach(function (sourceFile) {
|
||||
var fileName = sourceFile.fileName;
|
||||
program.getSourceFiles().forEach((sourceFile) => {
|
||||
const fileName = sourceFile.fileName;
|
||||
if (/^defaultLib:/.test(fileName)) {
|
||||
return;
|
||||
}
|
||||
var destination = fileName;
|
||||
const destination = fileName;
|
||||
if (/\.d\.ts$/.test(fileName)) {
|
||||
if (nodeOrChildIsBlack(sourceFile)) {
|
||||
writeFile(destination, sourceFile.text);
|
||||
}
|
||||
return;
|
||||
}
|
||||
var text = sourceFile.text;
|
||||
var result = '';
|
||||
let text = sourceFile.text;
|
||||
let result = '';
|
||||
function keep(node) {
|
||||
result += text.substring(node.pos, node.end);
|
||||
}
|
||||
|
@ -480,24 +473,24 @@ function generateResult(languageService, shakeLevel) {
|
|||
}
|
||||
}
|
||||
else {
|
||||
var survivingImports = [];
|
||||
for (var i = 0; i < node.importClause.namedBindings.elements.length; i++) {
|
||||
var importNode = node.importClause.namedBindings.elements[i];
|
||||
let survivingImports = [];
|
||||
for (let i = 0; i < node.importClause.namedBindings.elements.length; i++) {
|
||||
const importNode = node.importClause.namedBindings.elements[i];
|
||||
if (getColor(importNode) === 2 /* Black */) {
|
||||
survivingImports.push(importNode.getFullText(sourceFile));
|
||||
}
|
||||
}
|
||||
var leadingTriviaWidth = node.getLeadingTriviaWidth();
|
||||
var leadingTrivia = sourceFile.text.substr(node.pos, leadingTriviaWidth);
|
||||
const leadingTriviaWidth = node.getLeadingTriviaWidth();
|
||||
const leadingTrivia = sourceFile.text.substr(node.pos, leadingTriviaWidth);
|
||||
if (survivingImports.length > 0) {
|
||||
if (node.importClause && node.importClause.name && getColor(node.importClause) === 2 /* Black */) {
|
||||
return write(leadingTrivia + "import " + node.importClause.name.text + ", {" + survivingImports.join(',') + " } from" + node.moduleSpecifier.getFullText(sourceFile) + ";");
|
||||
return write(`${leadingTrivia}import ${node.importClause.name.text}, {${survivingImports.join(',')} } from${node.moduleSpecifier.getFullText(sourceFile)};`);
|
||||
}
|
||||
return write(leadingTrivia + "import {" + survivingImports.join(',') + " } from" + node.moduleSpecifier.getFullText(sourceFile) + ";");
|
||||
return write(`${leadingTrivia}import {${survivingImports.join(',')} } from${node.moduleSpecifier.getFullText(sourceFile)};`);
|
||||
}
|
||||
else {
|
||||
if (node.importClause && node.importClause.name && getColor(node.importClause) === 2 /* Black */) {
|
||||
return write(leadingTrivia + "import " + node.importClause.name.text + " from" + node.moduleSpecifier.getFullText(sourceFile) + ";");
|
||||
return write(`${leadingTrivia}import ${node.importClause.name.text} from${node.moduleSpecifier.getFullText(sourceFile)};`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -509,9 +502,9 @@ function generateResult(languageService, shakeLevel) {
|
|||
}
|
||||
}
|
||||
if (shakeLevel === 2 /* ClassMembers */ && (ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node)) && nodeOrChildIsBlack(node)) {
|
||||
var toWrite = node.getFullText();
|
||||
for (var i = node.members.length - 1; i >= 0; i--) {
|
||||
var member = node.members[i];
|
||||
let toWrite = node.getFullText();
|
||||
for (let i = node.members.length - 1; i >= 0; i--) {
|
||||
const member = node.members[i];
|
||||
if (getColor(member) === 2 /* Black */ || !member.name) {
|
||||
// keep method
|
||||
continue;
|
||||
|
@ -520,8 +513,8 @@ function generateResult(languageService, shakeLevel) {
|
|||
// TODO: keep all members ending with `Brand`...
|
||||
continue;
|
||||
}
|
||||
var pos = member.pos - node.pos;
|
||||
var end = member.end - node.pos;
|
||||
let pos = member.pos - node.pos;
|
||||
let end = member.end - node.pos;
|
||||
toWrite = toWrite.substring(0, pos) + toWrite.substring(end);
|
||||
}
|
||||
return write(toWrite);
|
||||
|
@ -553,9 +546,9 @@ function generateResult(languageService, shakeLevel) {
|
|||
* Returns the node's symbol and the `import` node (if the symbol resolved from a different module)
|
||||
*/
|
||||
function getRealNodeSymbol(checker, node) {
|
||||
var getPropertySymbolsFromContextualType = ts.getPropertySymbolsFromContextualType;
|
||||
var getContainingObjectLiteralElement = ts.getContainingObjectLiteralElement;
|
||||
var getNameFromPropertyName = ts.getNameFromPropertyName;
|
||||
const getPropertySymbolsFromContextualType = ts.getPropertySymbolsFromContextualType;
|
||||
const getContainingObjectLiteralElement = ts.getContainingObjectLiteralElement;
|
||||
const getNameFromPropertyName = ts.getNameFromPropertyName;
|
||||
// Go to the original declaration for cases:
|
||||
//
|
||||
// (1) when the aliased symbol was declared in the location(parent).
|
||||
|
@ -583,15 +576,15 @@ function getRealNodeSymbol(checker, node) {
|
|||
return [null, null];
|
||||
}
|
||||
}
|
||||
var parent = node.parent;
|
||||
var symbol = checker.getSymbolAtLocation(node);
|
||||
var importNode = null;
|
||||
const { parent } = node;
|
||||
let symbol = checker.getSymbolAtLocation(node);
|
||||
let importNode = null;
|
||||
// If this is an alias, and the request came at the declaration location
|
||||
// get the aliased symbol instead. This allows for goto def on an import e.g.
|
||||
// import {A, B} from "mod";
|
||||
// to jump to the implementation directly.
|
||||
if (symbol && symbol.flags & ts.SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) {
|
||||
var aliased = checker.getAliasedSymbol(symbol);
|
||||
const aliased = checker.getAliasedSymbol(symbol);
|
||||
if (aliased.declarations) {
|
||||
// We should mark the import as visited
|
||||
importNode = symbol.declarations[0];
|
||||
|
@ -620,17 +613,17 @@ function getRealNodeSymbol(checker, node) {
|
|||
// bar<Test>(({pr/*goto*/op1})=>{});
|
||||
if (ts.isPropertyName(node) && ts.isBindingElement(parent) && ts.isObjectBindingPattern(parent.parent) &&
|
||||
(node === (parent.propertyName || parent.name))) {
|
||||
var name_1 = getNameFromPropertyName(node);
|
||||
var type = checker.getTypeAtLocation(parent.parent);
|
||||
if (name_1 && type) {
|
||||
const name = getNameFromPropertyName(node);
|
||||
const type = checker.getTypeAtLocation(parent.parent);
|
||||
if (name && type) {
|
||||
if (type.isUnion()) {
|
||||
var prop = type.types[0].getProperty(name_1);
|
||||
const prop = type.types[0].getProperty(name);
|
||||
if (prop) {
|
||||
symbol = prop;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var prop = type.getProperty(name_1);
|
||||
const prop = type.getProperty(name);
|
||||
if (prop) {
|
||||
symbol = prop;
|
||||
}
|
||||
|
@ -646,11 +639,11 @@ function getRealNodeSymbol(checker, node) {
|
|||
// }
|
||||
// function Foo(arg: Props) {}
|
||||
// Foo( { pr/*1*/op1: 10, prop2: false })
|
||||
var element = getContainingObjectLiteralElement(node);
|
||||
const element = getContainingObjectLiteralElement(node);
|
||||
if (element) {
|
||||
var contextualType = element && checker.getContextualType(element.parent);
|
||||
const contextualType = element && checker.getContextualType(element.parent);
|
||||
if (contextualType) {
|
||||
var propertySymbols = getPropertySymbolsFromContextualType(element, checker, contextualType, /*unionSymbolOk*/ false);
|
||||
const propertySymbols = getPropertySymbolsFromContextualType(element, checker, contextualType, /*unionSymbolOk*/ false);
|
||||
if (propertySymbols) {
|
||||
symbol = propertySymbols[0];
|
||||
}
|
||||
|
@ -664,17 +657,16 @@ function getRealNodeSymbol(checker, node) {
|
|||
}
|
||||
/** Get the token whose text contains the position */
|
||||
function getTokenAtPosition(sourceFile, position, allowPositionInLeadingTrivia, includeEndPosition) {
|
||||
var current = sourceFile;
|
||||
let current = sourceFile;
|
||||
outer: while (true) {
|
||||
// find the child that contains 'position'
|
||||
for (var _i = 0, _a = current.getChildren(); _i < _a.length; _i++) {
|
||||
var child = _a[_i];
|
||||
var start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, /*includeJsDoc*/ true);
|
||||
for (const child of current.getChildren()) {
|
||||
const start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, /*includeJsDoc*/ true);
|
||||
if (start > position) {
|
||||
// If this child begins after position, then all subsequent children will as well.
|
||||
break;
|
||||
}
|
||||
var end = child.getEnd();
|
||||
const end = child.getEnd();
|
||||
if (position < end || (position === end && (child.kind === ts.SyntaxKind.EndOfFileToken || includeEndPosition))) {
|
||||
current = child;
|
||||
continue outer;
|
||||
|
|
|
@ -3,51 +3,30 @@
|
|||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
}
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var path_1 = require("path");
|
||||
var Lint = require("tslint");
|
||||
var Rule = /** @class */ (function (_super) {
|
||||
__extends(Rule, _super);
|
||||
function Rule() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
Rule.prototype.apply = function (sourceFile) {
|
||||
const path_1 = require("path");
|
||||
const Lint = require("tslint");
|
||||
class Rule extends Lint.Rules.AbstractRule {
|
||||
apply(sourceFile) {
|
||||
return this.applyWithWalker(new ImportPatterns(sourceFile, this.getOptions()));
|
||||
};
|
||||
return Rule;
|
||||
}(Lint.Rules.AbstractRule));
|
||||
exports.Rule = Rule;
|
||||
var ImportPatterns = /** @class */ (function (_super) {
|
||||
__extends(ImportPatterns, _super);
|
||||
function ImportPatterns(file, opts) {
|
||||
var _this = _super.call(this, file, opts) || this;
|
||||
_this.imports = Object.create(null);
|
||||
return _this;
|
||||
}
|
||||
ImportPatterns.prototype.visitImportDeclaration = function (node) {
|
||||
var path = node.moduleSpecifier.getText();
|
||||
}
|
||||
exports.Rule = Rule;
|
||||
class ImportPatterns extends Lint.RuleWalker {
|
||||
constructor(file, opts) {
|
||||
super(file, opts);
|
||||
this.imports = Object.create(null);
|
||||
}
|
||||
visitImportDeclaration(node) {
|
||||
let path = node.moduleSpecifier.getText();
|
||||
// remove quotes
|
||||
path = path.slice(1, -1);
|
||||
if (path[0] === '.') {
|
||||
path = path_1.join(path_1.dirname(node.getSourceFile().fileName), path);
|
||||
}
|
||||
if (this.imports[path]) {
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Duplicate imports for '" + path + "'."));
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Duplicate imports for '${path}'.`));
|
||||
}
|
||||
this.imports[path] = true;
|
||||
};
|
||||
return ImportPatterns;
|
||||
}(Lint.RuleWalker));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,82 +3,60 @@
|
|||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
}
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var ts = require("typescript");
|
||||
var Lint = require("tslint");
|
||||
var minimatch = require("minimatch");
|
||||
var path_1 = require("path");
|
||||
var Rule = /** @class */ (function (_super) {
|
||||
__extends(Rule, _super);
|
||||
function Rule() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
Rule.prototype.apply = function (sourceFile) {
|
||||
var configs = this.getOptions().ruleArguments;
|
||||
for (var _i = 0, configs_1 = configs; _i < configs_1.length; _i++) {
|
||||
var config = configs_1[_i];
|
||||
const ts = require("typescript");
|
||||
const Lint = require("tslint");
|
||||
const minimatch = require("minimatch");
|
||||
const path_1 = require("path");
|
||||
class Rule extends Lint.Rules.AbstractRule {
|
||||
apply(sourceFile) {
|
||||
const configs = this.getOptions().ruleArguments;
|
||||
for (const config of configs) {
|
||||
if (minimatch(sourceFile.fileName, config.target)) {
|
||||
return this.applyWithWalker(new ImportPatterns(sourceFile, this.getOptions(), config));
|
||||
}
|
||||
}
|
||||
return [];
|
||||
};
|
||||
return Rule;
|
||||
}(Lint.Rules.AbstractRule));
|
||||
exports.Rule = Rule;
|
||||
var ImportPatterns = /** @class */ (function (_super) {
|
||||
__extends(ImportPatterns, _super);
|
||||
function ImportPatterns(file, opts, _config) {
|
||||
var _this = _super.call(this, file, opts) || this;
|
||||
_this._config = _config;
|
||||
return _this;
|
||||
}
|
||||
ImportPatterns.prototype.visitImportEqualsDeclaration = function (node) {
|
||||
}
|
||||
exports.Rule = Rule;
|
||||
class ImportPatterns extends Lint.RuleWalker {
|
||||
constructor(file, opts, _config) {
|
||||
super(file, opts);
|
||||
this._config = _config;
|
||||
}
|
||||
visitImportEqualsDeclaration(node) {
|
||||
if (node.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) {
|
||||
this._validateImport(node.moduleReference.expression.getText(), node);
|
||||
}
|
||||
};
|
||||
ImportPatterns.prototype.visitImportDeclaration = function (node) {
|
||||
}
|
||||
visitImportDeclaration(node) {
|
||||
this._validateImport(node.moduleSpecifier.getText(), node);
|
||||
};
|
||||
ImportPatterns.prototype.visitCallExpression = function (node) {
|
||||
_super.prototype.visitCallExpression.call(this, node);
|
||||
}
|
||||
visitCallExpression(node) {
|
||||
super.visitCallExpression(node);
|
||||
// import('foo') statements inside the code
|
||||
if (node.expression.kind === ts.SyntaxKind.ImportKeyword) {
|
||||
var path = node.arguments[0];
|
||||
const [path] = node.arguments;
|
||||
this._validateImport(path.getText(), node);
|
||||
}
|
||||
};
|
||||
ImportPatterns.prototype._validateImport = function (path, node) {
|
||||
}
|
||||
_validateImport(path, node) {
|
||||
// remove quotes
|
||||
path = path.slice(1, -1);
|
||||
// resolve relative paths
|
||||
if (path[0] === '.') {
|
||||
path = path_1.join(this.getSourceFile().fileName, path);
|
||||
}
|
||||
var restrictions;
|
||||
let restrictions;
|
||||
if (typeof this._config.restrictions === 'string') {
|
||||
restrictions = [this._config.restrictions];
|
||||
}
|
||||
else {
|
||||
restrictions = this._config.restrictions;
|
||||
}
|
||||
var matched = false;
|
||||
for (var _i = 0, restrictions_1 = restrictions; _i < restrictions_1.length; _i++) {
|
||||
var pattern = restrictions_1[_i];
|
||||
let matched = false;
|
||||
for (const pattern of restrictions) {
|
||||
if (minimatch(path, pattern)) {
|
||||
matched = true;
|
||||
break;
|
||||
|
@ -86,8 +64,7 @@ var ImportPatterns = /** @class */ (function (_super) {
|
|||
}
|
||||
if (!matched) {
|
||||
// None of the restrictions matched
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Imports violates '" + restrictions.join(' or ') + "' restrictions. See https://github.com/Microsoft/vscode/wiki/Code-Organization"));
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Imports violates '${restrictions.join(' or ')}' restrictions. See https://github.com/Microsoft/vscode/wiki/Code-Organization`));
|
||||
}
|
||||
};
|
||||
return ImportPatterns;
|
||||
}(Lint.RuleWalker));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,39 +3,22 @@
|
|||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
}
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var ts = require("typescript");
|
||||
var Lint = require("tslint");
|
||||
var path_1 = require("path");
|
||||
var Rule = /** @class */ (function (_super) {
|
||||
__extends(Rule, _super);
|
||||
function Rule() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
Rule.prototype.apply = function (sourceFile) {
|
||||
var parts = path_1.dirname(sourceFile.fileName).split(/\\|\//);
|
||||
var ruleArgs = this.getOptions().ruleArguments[0];
|
||||
var config;
|
||||
for (var i = parts.length - 1; i >= 0; i--) {
|
||||
const ts = require("typescript");
|
||||
const Lint = require("tslint");
|
||||
const path_1 = require("path");
|
||||
class Rule extends Lint.Rules.AbstractRule {
|
||||
apply(sourceFile) {
|
||||
const parts = path_1.dirname(sourceFile.fileName).split(/\\|\//);
|
||||
const ruleArgs = this.getOptions().ruleArguments[0];
|
||||
let config;
|
||||
for (let i = parts.length - 1; i >= 0; i--) {
|
||||
if (ruleArgs[parts[i]]) {
|
||||
config = {
|
||||
allowed: new Set(ruleArgs[parts[i]]).add(parts[i]),
|
||||
disallowed: new Set()
|
||||
};
|
||||
Object.keys(ruleArgs).forEach(function (key) {
|
||||
Object.keys(ruleArgs).forEach(key => {
|
||||
if (!config.allowed.has(key)) {
|
||||
config.disallowed.add(key);
|
||||
}
|
||||
|
@ -47,58 +30,54 @@ var Rule = /** @class */ (function (_super) {
|
|||
return [];
|
||||
}
|
||||
return this.applyWithWalker(new LayeringRule(sourceFile, config, this.getOptions()));
|
||||
};
|
||||
return Rule;
|
||||
}(Lint.Rules.AbstractRule));
|
||||
exports.Rule = Rule;
|
||||
var LayeringRule = /** @class */ (function (_super) {
|
||||
__extends(LayeringRule, _super);
|
||||
function LayeringRule(file, config, opts) {
|
||||
var _this = _super.call(this, file, opts) || this;
|
||||
_this._config = config;
|
||||
return _this;
|
||||
}
|
||||
LayeringRule.prototype.visitImportEqualsDeclaration = function (node) {
|
||||
}
|
||||
exports.Rule = Rule;
|
||||
class LayeringRule extends Lint.RuleWalker {
|
||||
constructor(file, config, opts) {
|
||||
super(file, opts);
|
||||
this._config = config;
|
||||
}
|
||||
visitImportEqualsDeclaration(node) {
|
||||
if (node.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) {
|
||||
this._validateImport(node.moduleReference.expression.getText(), node);
|
||||
}
|
||||
};
|
||||
LayeringRule.prototype.visitImportDeclaration = function (node) {
|
||||
}
|
||||
visitImportDeclaration(node) {
|
||||
this._validateImport(node.moduleSpecifier.getText(), node);
|
||||
};
|
||||
LayeringRule.prototype.visitCallExpression = function (node) {
|
||||
_super.prototype.visitCallExpression.call(this, node);
|
||||
}
|
||||
visitCallExpression(node) {
|
||||
super.visitCallExpression(node);
|
||||
// import('foo') statements inside the code
|
||||
if (node.expression.kind === ts.SyntaxKind.ImportKeyword) {
|
||||
var path = node.arguments[0];
|
||||
const [path] = node.arguments;
|
||||
this._validateImport(path.getText(), node);
|
||||
}
|
||||
};
|
||||
LayeringRule.prototype._validateImport = function (path, node) {
|
||||
}
|
||||
_validateImport(path, node) {
|
||||
// remove quotes
|
||||
path = path.slice(1, -1);
|
||||
if (path[0] === '.') {
|
||||
path = path_1.join(path_1.dirname(node.getSourceFile().fileName), path);
|
||||
}
|
||||
var parts = path_1.dirname(path).split(/\\|\//);
|
||||
for (var i = parts.length - 1; i >= 0; i--) {
|
||||
var part = parts[i];
|
||||
const parts = path_1.dirname(path).split(/\\|\//);
|
||||
for (let i = parts.length - 1; i >= 0; i--) {
|
||||
const part = parts[i];
|
||||
if (this._config.allowed.has(part)) {
|
||||
// GOOD - same layer
|
||||
return;
|
||||
}
|
||||
if (this._config.disallowed.has(part)) {
|
||||
// BAD - wrong layer
|
||||
var message = "Bad layering. You are not allowed to access '" + part + "' from here, allowed layers are: [" + LayeringRule._print(this._config.allowed) + "]";
|
||||
const message = `Bad layering. You are not allowed to access '${part}' from here, allowed layers are: [${LayeringRule._print(this._config.allowed)}]`;
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), message));
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
LayeringRule._print = function (set) {
|
||||
var r = [];
|
||||
set.forEach(function (e) { return r.push(e); });
|
||||
}
|
||||
static _print(set) {
|
||||
const r = [];
|
||||
set.forEach(e => r.push(e));
|
||||
return r.join(', ');
|
||||
};
|
||||
return LayeringRule;
|
||||
}(Lint.RuleWalker));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,60 +3,41 @@
|
|||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
}
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var ts = require("typescript");
|
||||
var Lint = require("tslint");
|
||||
var path_1 = require("path");
|
||||
var Rule = /** @class */ (function (_super) {
|
||||
__extends(Rule, _super);
|
||||
function Rule() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
Rule.prototype.apply = function (sourceFile) {
|
||||
const ts = require("typescript");
|
||||
const Lint = require("tslint");
|
||||
const path_1 = require("path");
|
||||
class Rule extends Lint.Rules.AbstractRule {
|
||||
apply(sourceFile) {
|
||||
if (/vs(\/|\\)editor/.test(sourceFile.fileName)) {
|
||||
// the vs/editor folder is allowed to use the standalone editor
|
||||
return [];
|
||||
}
|
||||
return this.applyWithWalker(new NoStandaloneEditorRuleWalker(sourceFile, this.getOptions()));
|
||||
};
|
||||
return Rule;
|
||||
}(Lint.Rules.AbstractRule));
|
||||
exports.Rule = Rule;
|
||||
var NoStandaloneEditorRuleWalker = /** @class */ (function (_super) {
|
||||
__extends(NoStandaloneEditorRuleWalker, _super);
|
||||
function NoStandaloneEditorRuleWalker(file, opts) {
|
||||
return _super.call(this, file, opts) || this;
|
||||
}
|
||||
NoStandaloneEditorRuleWalker.prototype.visitImportEqualsDeclaration = function (node) {
|
||||
}
|
||||
exports.Rule = Rule;
|
||||
class NoStandaloneEditorRuleWalker extends Lint.RuleWalker {
|
||||
constructor(file, opts) {
|
||||
super(file, opts);
|
||||
}
|
||||
visitImportEqualsDeclaration(node) {
|
||||
if (node.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) {
|
||||
this._validateImport(node.moduleReference.expression.getText(), node);
|
||||
}
|
||||
};
|
||||
NoStandaloneEditorRuleWalker.prototype.visitImportDeclaration = function (node) {
|
||||
}
|
||||
visitImportDeclaration(node) {
|
||||
this._validateImport(node.moduleSpecifier.getText(), node);
|
||||
};
|
||||
NoStandaloneEditorRuleWalker.prototype.visitCallExpression = function (node) {
|
||||
_super.prototype.visitCallExpression.call(this, node);
|
||||
}
|
||||
visitCallExpression(node) {
|
||||
super.visitCallExpression(node);
|
||||
// import('foo') statements inside the code
|
||||
if (node.expression.kind === ts.SyntaxKind.ImportKeyword) {
|
||||
var path = node.arguments[0];
|
||||
const [path] = node.arguments;
|
||||
this._validateImport(path.getText(), node);
|
||||
}
|
||||
};
|
||||
NoStandaloneEditorRuleWalker.prototype._validateImport = function (path, node) {
|
||||
}
|
||||
_validateImport(path, node) {
|
||||
// remove quotes
|
||||
path = path.slice(1, -1);
|
||||
// resolve relative paths
|
||||
|
@ -68,8 +49,7 @@ var NoStandaloneEditorRuleWalker = /** @class */ (function (_super) {
|
|||
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(path)
|
||||
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(path)) {
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Not allowed to import standalone editor modules. See https://github.com/Microsoft/vscode/wiki/Code-Organization"));
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Not allowed to import standalone editor modules. See https://github.com/Microsoft/vscode/wiki/Code-Organization`));
|
||||
}
|
||||
};
|
||||
return NoStandaloneEditorRuleWalker;
|
||||
}(Lint.RuleWalker));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,35 +3,17 @@
|
|||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
}
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var ts = require("typescript");
|
||||
var Lint = require("tslint");
|
||||
const ts = require("typescript");
|
||||
const Lint = require("tslint");
|
||||
/**
|
||||
* Implementation of the no-unexternalized-strings rule.
|
||||
*/
|
||||
var Rule = /** @class */ (function (_super) {
|
||||
__extends(Rule, _super);
|
||||
function Rule() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
Rule.prototype.apply = function (sourceFile) {
|
||||
class Rule extends Lint.Rules.AbstractRule {
|
||||
apply(sourceFile) {
|
||||
return this.applyWithWalker(new NoUnexternalizedStringsRuleWalker(sourceFile, this.getOptions()));
|
||||
};
|
||||
return Rule;
|
||||
}(Lint.Rules.AbstractRule));
|
||||
}
|
||||
}
|
||||
exports.Rule = Rule;
|
||||
function isStringLiteral(node) {
|
||||
return node && node.kind === ts.SyntaxKind.StringLiteral;
|
||||
|
@ -42,73 +24,70 @@ function isObjectLiteral(node) {
|
|||
function isPropertyAssignment(node) {
|
||||
return node && node.kind === ts.SyntaxKind.PropertyAssignment;
|
||||
}
|
||||
var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
|
||||
__extends(NoUnexternalizedStringsRuleWalker, _super);
|
||||
function NoUnexternalizedStringsRuleWalker(file, opts) {
|
||||
var _this = _super.call(this, file, opts) || this;
|
||||
_this.signatures = Object.create(null);
|
||||
_this.ignores = Object.create(null);
|
||||
_this.messageIndex = undefined;
|
||||
_this.keyIndex = undefined;
|
||||
_this.usedKeys = Object.create(null);
|
||||
var options = _this.getOptions();
|
||||
var first = options && options.length > 0 ? options[0] : null;
|
||||
class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
|
||||
constructor(file, opts) {
|
||||
super(file, opts);
|
||||
this.signatures = Object.create(null);
|
||||
this.ignores = Object.create(null);
|
||||
this.messageIndex = undefined;
|
||||
this.keyIndex = undefined;
|
||||
this.usedKeys = Object.create(null);
|
||||
const options = this.getOptions();
|
||||
const first = options && options.length > 0 ? options[0] : null;
|
||||
if (first) {
|
||||
if (Array.isArray(first.signatures)) {
|
||||
first.signatures.forEach(function (signature) { return _this.signatures[signature] = true; });
|
||||
first.signatures.forEach((signature) => this.signatures[signature] = true);
|
||||
}
|
||||
if (Array.isArray(first.ignores)) {
|
||||
first.ignores.forEach(function (ignore) { return _this.ignores[ignore] = true; });
|
||||
first.ignores.forEach((ignore) => this.ignores[ignore] = true);
|
||||
}
|
||||
if (typeof first.messageIndex !== 'undefined') {
|
||||
_this.messageIndex = first.messageIndex;
|
||||
this.messageIndex = first.messageIndex;
|
||||
}
|
||||
if (typeof first.keyIndex !== 'undefined') {
|
||||
_this.keyIndex = first.keyIndex;
|
||||
this.keyIndex = first.keyIndex;
|
||||
}
|
||||
}
|
||||
return _this;
|
||||
}
|
||||
NoUnexternalizedStringsRuleWalker.prototype.visitSourceFile = function (node) {
|
||||
var _this = this;
|
||||
_super.prototype.visitSourceFile.call(this, node);
|
||||
Object.keys(this.usedKeys).forEach(function (key) {
|
||||
var occurrences = _this.usedKeys[key];
|
||||
visitSourceFile(node) {
|
||||
super.visitSourceFile(node);
|
||||
Object.keys(this.usedKeys).forEach(key => {
|
||||
const occurrences = this.usedKeys[key];
|
||||
if (occurrences.length > 1) {
|
||||
occurrences.forEach(function (occurrence) {
|
||||
_this.addFailure((_this.createFailure(occurrence.key.getStart(), occurrence.key.getWidth(), "Duplicate key " + occurrence.key.getText() + " with different message value.")));
|
||||
occurrences.forEach(occurrence => {
|
||||
this.addFailure((this.createFailure(occurrence.key.getStart(), occurrence.key.getWidth(), `Duplicate key ${occurrence.key.getText()} with different message value.`)));
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
NoUnexternalizedStringsRuleWalker.prototype.visitStringLiteral = function (node) {
|
||||
}
|
||||
visitStringLiteral(node) {
|
||||
this.checkStringLiteral(node);
|
||||
_super.prototype.visitStringLiteral.call(this, node);
|
||||
};
|
||||
NoUnexternalizedStringsRuleWalker.prototype.checkStringLiteral = function (node) {
|
||||
var text = node.getText();
|
||||
var doubleQuoted = text.length >= 2 && text[0] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE && text[text.length - 1] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE;
|
||||
var info = this.findDescribingParent(node);
|
||||
super.visitStringLiteral(node);
|
||||
}
|
||||
checkStringLiteral(node) {
|
||||
const text = node.getText();
|
||||
const doubleQuoted = text.length >= 2 && text[0] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE && text[text.length - 1] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE;
|
||||
const info = this.findDescribingParent(node);
|
||||
// Ignore strings in import and export nodes.
|
||||
if (info && info.isImport && doubleQuoted) {
|
||||
var fix = [
|
||||
const fix = [
|
||||
Lint.Replacement.replaceFromTo(node.getStart(), 1, '\''),
|
||||
Lint.Replacement.replaceFromTo(node.getStart() + text.length - 1, 1, '\''),
|
||||
];
|
||||
this.addFailureAtNode(node, NoUnexternalizedStringsRuleWalker.ImportFailureMessage, fix);
|
||||
return;
|
||||
}
|
||||
var callInfo = info ? info.callInfo : null;
|
||||
var functionName = callInfo ? callInfo.callExpression.expression.getText() : null;
|
||||
const callInfo = info ? info.callInfo : null;
|
||||
const functionName = callInfo ? callInfo.callExpression.expression.getText() : null;
|
||||
if (functionName && this.ignores[functionName]) {
|
||||
return;
|
||||
}
|
||||
if (doubleQuoted && (!callInfo || callInfo.argIndex === -1 || !this.signatures[functionName])) {
|
||||
var s = node.getText();
|
||||
var fix = [
|
||||
Lint.Replacement.replaceFromTo(node.getStart(), node.getWidth(), "nls.localize('KEY-" + s.substring(1, s.length - 1) + "', " + s + ")"),
|
||||
const s = node.getText();
|
||||
const fix = [
|
||||
Lint.Replacement.replaceFromTo(node.getStart(), node.getWidth(), `nls.localize('KEY-${s.substring(1, s.length - 1)}', ${s})`),
|
||||
];
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Unexternalized string found: " + node.getText(), fix));
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Unexternalized string found: ${node.getText()}`, fix));
|
||||
return;
|
||||
}
|
||||
// We have a single quoted string outside a localize function name.
|
||||
|
@ -116,7 +95,7 @@ var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
|
|||
return;
|
||||
}
|
||||
// We have a string that is a direct argument into the localize call.
|
||||
var keyArg = callInfo && callInfo.argIndex === this.keyIndex
|
||||
const keyArg = callInfo && callInfo.argIndex === this.keyIndex
|
||||
? callInfo.callExpression.arguments[this.keyIndex]
|
||||
: null;
|
||||
if (keyArg) {
|
||||
|
@ -124,12 +103,12 @@ var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
|
|||
this.recordKey(keyArg, this.messageIndex && callInfo ? callInfo.callExpression.arguments[this.messageIndex] : undefined);
|
||||
}
|
||||
else if (isObjectLiteral(keyArg)) {
|
||||
for (var i = 0; i < keyArg.properties.length; i++) {
|
||||
var property = keyArg.properties[i];
|
||||
for (let i = 0; i < keyArg.properties.length; i++) {
|
||||
const property = keyArg.properties[i];
|
||||
if (isPropertyAssignment(property)) {
|
||||
var name_1 = property.name.getText();
|
||||
if (name_1 === 'key') {
|
||||
var initializer = property.initializer;
|
||||
const name = property.name.getText();
|
||||
if (name === 'key') {
|
||||
const initializer = property.initializer;
|
||||
if (isStringLiteral(initializer)) {
|
||||
this.recordKey(initializer, this.messageIndex && callInfo ? callInfo.callExpression.arguments[this.messageIndex] : undefined);
|
||||
}
|
||||
|
@ -139,42 +118,42 @@ var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
|
|||
}
|
||||
}
|
||||
}
|
||||
var messageArg = callInfo.callExpression.arguments[this.messageIndex];
|
||||
const messageArg = callInfo.callExpression.arguments[this.messageIndex];
|
||||
if (messageArg && messageArg.kind !== ts.SyntaxKind.StringLiteral) {
|
||||
this.addFailure(this.createFailure(messageArg.getStart(), messageArg.getWidth(), "Message argument to '" + callInfo.callExpression.expression.getText() + "' must be a string literal."));
|
||||
this.addFailure(this.createFailure(messageArg.getStart(), messageArg.getWidth(), `Message argument to '${callInfo.callExpression.expression.getText()}' must be a string literal.`));
|
||||
return;
|
||||
}
|
||||
};
|
||||
NoUnexternalizedStringsRuleWalker.prototype.recordKey = function (keyNode, messageNode) {
|
||||
var text = keyNode.getText();
|
||||
}
|
||||
recordKey(keyNode, messageNode) {
|
||||
const text = keyNode.getText();
|
||||
// We have an empty key
|
||||
if (text.match(/(['"]) *\1/)) {
|
||||
if (messageNode) {
|
||||
this.addFailureAtNode(keyNode, "Key is empty for message: " + messageNode.getText());
|
||||
this.addFailureAtNode(keyNode, `Key is empty for message: ${messageNode.getText()}`);
|
||||
}
|
||||
else {
|
||||
this.addFailureAtNode(keyNode, "Key is empty.");
|
||||
this.addFailureAtNode(keyNode, `Key is empty.`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
var occurrences = this.usedKeys[text];
|
||||
let occurrences = this.usedKeys[text];
|
||||
if (!occurrences) {
|
||||
occurrences = [];
|
||||
this.usedKeys[text] = occurrences;
|
||||
}
|
||||
if (messageNode) {
|
||||
if (occurrences.some(function (pair) { return pair.message ? pair.message.getText() === messageNode.getText() : false; })) {
|
||||
if (occurrences.some(pair => pair.message ? pair.message.getText() === messageNode.getText() : false)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
occurrences.push({ key: keyNode, message: messageNode });
|
||||
};
|
||||
NoUnexternalizedStringsRuleWalker.prototype.findDescribingParent = function (node) {
|
||||
var parent;
|
||||
}
|
||||
findDescribingParent(node) {
|
||||
let parent;
|
||||
while ((parent = node.parent)) {
|
||||
var kind = parent.kind;
|
||||
const kind = parent.kind;
|
||||
if (kind === ts.SyntaxKind.CallExpression) {
|
||||
var callExpression = parent;
|
||||
const callExpression = parent;
|
||||
return { callInfo: { callExpression: callExpression, argIndex: callExpression.arguments.indexOf(node) } };
|
||||
}
|
||||
else if (kind === ts.SyntaxKind.ImportEqualsDeclaration || kind === ts.SyntaxKind.ImportDeclaration || kind === ts.SyntaxKind.ExportDeclaration) {
|
||||
|
@ -189,8 +168,7 @@ var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
|
|||
node = parent;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
NoUnexternalizedStringsRuleWalker.ImportFailureMessage = 'Do not use double quotes for imports.';
|
||||
NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE = '"';
|
||||
return NoUnexternalizedStringsRuleWalker;
|
||||
}(Lint.RuleWalker));
|
||||
}
|
||||
}
|
||||
NoUnexternalizedStringsRuleWalker.ImportFailureMessage = 'Do not use double quotes for imports.';
|
||||
NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE = '"';
|
||||
|
|
|
@ -3,62 +3,43 @@
|
|||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
}
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var Lint = require("tslint");
|
||||
var fs = require("fs");
|
||||
var Rule = /** @class */ (function (_super) {
|
||||
__extends(Rule, _super);
|
||||
function Rule() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
Rule.prototype.apply = function (sourceFile) {
|
||||
const Lint = require("tslint");
|
||||
const fs = require("fs");
|
||||
class Rule extends Lint.Rules.AbstractRule {
|
||||
apply(sourceFile) {
|
||||
return this.applyWithWalker(new TranslationRemindRuleWalker(sourceFile, this.getOptions()));
|
||||
};
|
||||
return Rule;
|
||||
}(Lint.Rules.AbstractRule));
|
||||
exports.Rule = Rule;
|
||||
var TranslationRemindRuleWalker = /** @class */ (function (_super) {
|
||||
__extends(TranslationRemindRuleWalker, _super);
|
||||
function TranslationRemindRuleWalker(file, opts) {
|
||||
return _super.call(this, file, opts) || this;
|
||||
}
|
||||
TranslationRemindRuleWalker.prototype.visitImportDeclaration = function (node) {
|
||||
var declaration = node.moduleSpecifier.getText();
|
||||
if (declaration !== "'" + TranslationRemindRuleWalker.NLS_MODULE + "'") {
|
||||
}
|
||||
exports.Rule = Rule;
|
||||
class TranslationRemindRuleWalker extends Lint.RuleWalker {
|
||||
constructor(file, opts) {
|
||||
super(file, opts);
|
||||
}
|
||||
visitImportDeclaration(node) {
|
||||
const declaration = node.moduleSpecifier.getText();
|
||||
if (declaration !== `'${TranslationRemindRuleWalker.NLS_MODULE}'`) {
|
||||
return;
|
||||
}
|
||||
this.visitImportLikeDeclaration(node);
|
||||
};
|
||||
TranslationRemindRuleWalker.prototype.visitImportEqualsDeclaration = function (node) {
|
||||
var reference = node.moduleReference.getText();
|
||||
if (reference !== "require('" + TranslationRemindRuleWalker.NLS_MODULE + "')") {
|
||||
}
|
||||
visitImportEqualsDeclaration(node) {
|
||||
const reference = node.moduleReference.getText();
|
||||
if (reference !== `require('${TranslationRemindRuleWalker.NLS_MODULE}')`) {
|
||||
return;
|
||||
}
|
||||
this.visitImportLikeDeclaration(node);
|
||||
};
|
||||
TranslationRemindRuleWalker.prototype.visitImportLikeDeclaration = function (node) {
|
||||
var currentFile = node.getSourceFile().fileName;
|
||||
var matchService = currentFile.match(/vs\/workbench\/services\/\w+/);
|
||||
var matchPart = currentFile.match(/vs\/workbench\/parts\/\w+/);
|
||||
}
|
||||
visitImportLikeDeclaration(node) {
|
||||
const currentFile = node.getSourceFile().fileName;
|
||||
const matchService = currentFile.match(/vs\/workbench\/services\/\w+/);
|
||||
const matchPart = currentFile.match(/vs\/workbench\/parts\/\w+/);
|
||||
if (!matchService && !matchPart) {
|
||||
return;
|
||||
}
|
||||
var resource = matchService ? matchService[0] : matchPart[0];
|
||||
var resourceDefined = false;
|
||||
var json;
|
||||
const resource = matchService ? matchService[0] : matchPart[0];
|
||||
let resourceDefined = false;
|
||||
let json;
|
||||
try {
|
||||
json = fs.readFileSync('./build/lib/i18n.resources.json', 'utf8');
|
||||
}
|
||||
|
@ -66,17 +47,16 @@ var TranslationRemindRuleWalker = /** @class */ (function (_super) {
|
|||
console.error('[translation-remind rule]: File with resources to pull from Transifex was not found. Aborting translation resource check for newly defined workbench part/service.');
|
||||
return;
|
||||
}
|
||||
var workbenchResources = JSON.parse(json).workbench;
|
||||
workbenchResources.forEach(function (existingResource) {
|
||||
const workbenchResources = JSON.parse(json).workbench;
|
||||
workbenchResources.forEach((existingResource) => {
|
||||
if (existingResource.name === resource) {
|
||||
resourceDefined = true;
|
||||
return;
|
||||
}
|
||||
});
|
||||
if (!resourceDefined) {
|
||||
this.addFailureAtNode(node, "Please add '" + resource + "' to ./build/lib/i18n.resources.json file to use translations here.");
|
||||
this.addFailureAtNode(node, `Please add '${resource}' to ./build/lib/i18n.resources.json file to use translations here.`);
|
||||
}
|
||||
};
|
||||
TranslationRemindRuleWalker.NLS_MODULE = 'vs/nls';
|
||||
return TranslationRemindRuleWalker;
|
||||
}(Lint.RuleWalker));
|
||||
}
|
||||
}
|
||||
TranslationRemindRuleWalker.NLS_MODULE = 'vs/nls';
|
||||
|
|
4
build/lib/typings/object-assign.d.ts
vendored
4
build/lib/typings/object-assign.d.ts
vendored
|
@ -1,4 +0,0 @@
|
|||
declare module 'object-assign' {
|
||||
function fn(target: any, ...sources: any[]): any;
|
||||
export = fn;
|
||||
}
|
|
@ -4,29 +4,29 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var es = require("event-stream");
|
||||
var debounce = require("debounce");
|
||||
var _filter = require("gulp-filter");
|
||||
var rename = require("gulp-rename");
|
||||
var _ = require("underscore");
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
var _rimraf = require("rimraf");
|
||||
var git = require("./git");
|
||||
var VinylFile = require("vinyl");
|
||||
var NoCancellationToken = { isCancellationRequested: function () { return false; } };
|
||||
const es = require("event-stream");
|
||||
const debounce = require("debounce");
|
||||
const _filter = require("gulp-filter");
|
||||
const rename = require("gulp-rename");
|
||||
const _ = require("underscore");
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const _rimraf = require("rimraf");
|
||||
const git = require("./git");
|
||||
const VinylFile = require("vinyl");
|
||||
const NoCancellationToken = { isCancellationRequested: () => false };
|
||||
function incremental(streamProvider, initial, supportsCancellation) {
|
||||
var input = es.through();
|
||||
var output = es.through();
|
||||
var state = 'idle';
|
||||
var buffer = Object.create(null);
|
||||
var token = !supportsCancellation ? undefined : { isCancellationRequested: function () { return Object.keys(buffer).length > 0; } };
|
||||
var run = function (input, isCancellable) {
|
||||
const input = es.through();
|
||||
const output = es.through();
|
||||
let state = 'idle';
|
||||
let buffer = Object.create(null);
|
||||
const token = !supportsCancellation ? undefined : { isCancellationRequested: () => Object.keys(buffer).length > 0 };
|
||||
const run = (input, isCancellable) => {
|
||||
state = 'running';
|
||||
var stream = !supportsCancellation ? streamProvider() : streamProvider(isCancellable ? token : NoCancellationToken);
|
||||
const stream = !supportsCancellation ? streamProvider() : streamProvider(isCancellable ? token : NoCancellationToken);
|
||||
input
|
||||
.pipe(stream)
|
||||
.pipe(es.through(undefined, function () {
|
||||
.pipe(es.through(undefined, () => {
|
||||
state = 'idle';
|
||||
eventuallyRun();
|
||||
}))
|
||||
|
@ -35,16 +35,16 @@ function incremental(streamProvider, initial, supportsCancellation) {
|
|||
if (initial) {
|
||||
run(initial, false);
|
||||
}
|
||||
var eventuallyRun = debounce(function () {
|
||||
var paths = Object.keys(buffer);
|
||||
const eventuallyRun = debounce(() => {
|
||||
const paths = Object.keys(buffer);
|
||||
if (paths.length === 0) {
|
||||
return;
|
||||
}
|
||||
var data = paths.map(function (path) { return buffer[path]; });
|
||||
const data = paths.map(path => buffer[path]);
|
||||
buffer = Object.create(null);
|
||||
run(es.readArray(data), true);
|
||||
}, 500);
|
||||
input.on('data', function (f) {
|
||||
input.on('data', (f) => {
|
||||
buffer[f.path] = f;
|
||||
if (state === 'idle') {
|
||||
eventuallyRun();
|
||||
|
@ -57,7 +57,7 @@ function fixWin32DirectoryPermissions() {
|
|||
if (!/win32/.test(process.platform)) {
|
||||
return es.through();
|
||||
}
|
||||
return es.mapSync(function (f) {
|
||||
return es.mapSync(f => {
|
||||
if (f.stat && f.stat.isDirectory && f.stat.isDirectory()) {
|
||||
f.stat.mode = 16877;
|
||||
}
|
||||
|
@ -66,16 +66,16 @@ function fixWin32DirectoryPermissions() {
|
|||
}
|
||||
exports.fixWin32DirectoryPermissions = fixWin32DirectoryPermissions;
|
||||
function setExecutableBit(pattern) {
|
||||
var setBit = es.mapSync(function (f) {
|
||||
const setBit = es.mapSync(f => {
|
||||
f.stat.mode = /* 100755 */ 33261;
|
||||
return f;
|
||||
});
|
||||
if (!pattern) {
|
||||
return setBit;
|
||||
}
|
||||
var input = es.through();
|
||||
var filter = _filter(pattern, { restore: true });
|
||||
var output = input
|
||||
const input = es.through();
|
||||
const filter = _filter(pattern, { restore: true });
|
||||
const output = input
|
||||
.pipe(filter)
|
||||
.pipe(setBit)
|
||||
.pipe(filter.restore);
|
||||
|
@ -83,7 +83,7 @@ function setExecutableBit(pattern) {
|
|||
}
|
||||
exports.setExecutableBit = setExecutableBit;
|
||||
function toFileUri(filePath) {
|
||||
var match = filePath.match(/^([a-z])\:(.*)$/i);
|
||||
const match = filePath.match(/^([a-z])\:(.*)$/i);
|
||||
if (match) {
|
||||
filePath = '/' + match[1].toUpperCase() + ':' + match[2];
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ function toFileUri(filePath) {
|
|||
}
|
||||
exports.toFileUri = toFileUri;
|
||||
function skipDirectories() {
|
||||
return es.mapSync(function (f) {
|
||||
return es.mapSync(f => {
|
||||
if (!f.isDirectory()) {
|
||||
return f;
|
||||
}
|
||||
|
@ -99,15 +99,15 @@ function skipDirectories() {
|
|||
}
|
||||
exports.skipDirectories = skipDirectories;
|
||||
function cleanNodeModule(name, excludes, includes) {
|
||||
var toGlob = function (path) { return '**/node_modules/' + name + (path ? '/' + path : ''); };
|
||||
var negate = function (str) { return '!' + str; };
|
||||
var allFilter = _filter(toGlob('**'), { restore: true });
|
||||
var globs = [toGlob('**')].concat(excludes.map(_.compose(negate, toGlob)));
|
||||
var input = es.through();
|
||||
var nodeModuleInput = input.pipe(allFilter);
|
||||
var output = nodeModuleInput.pipe(_filter(globs));
|
||||
const toGlob = (path) => '**/node_modules/' + name + (path ? '/' + path : '');
|
||||
const negate = (str) => '!' + str;
|
||||
const allFilter = _filter(toGlob('**'), { restore: true });
|
||||
const globs = [toGlob('**')].concat(excludes.map(_.compose(negate, toGlob)));
|
||||
const input = es.through();
|
||||
const nodeModuleInput = input.pipe(allFilter);
|
||||
let output = nodeModuleInput.pipe(_filter(globs));
|
||||
if (includes) {
|
||||
var includeGlobs = includes.map(toGlob);
|
||||
const includeGlobs = includes.map(toGlob);
|
||||
output = es.merge(output, nodeModuleInput.pipe(_filter(includeGlobs)));
|
||||
}
|
||||
output = output.pipe(allFilter.restore);
|
||||
|
@ -115,9 +115,9 @@ function cleanNodeModule(name, excludes, includes) {
|
|||
}
|
||||
exports.cleanNodeModule = cleanNodeModule;
|
||||
function loadSourcemaps() {
|
||||
var input = es.through();
|
||||
var output = input
|
||||
.pipe(es.map(function (f, cb) {
|
||||
const input = es.through();
|
||||
const output = input
|
||||
.pipe(es.map((f, cb) => {
|
||||
if (f.sourceMap) {
|
||||
cb(undefined, f);
|
||||
return;
|
||||
|
@ -126,10 +126,10 @@ function loadSourcemaps() {
|
|||
cb(new Error('empty file'));
|
||||
return;
|
||||
}
|
||||
var contents = f.contents.toString('utf8');
|
||||
var reg = /\/\/# sourceMappingURL=(.*)$/g;
|
||||
var lastMatch = null;
|
||||
var match = null;
|
||||
const contents = f.contents.toString('utf8');
|
||||
const reg = /\/\/# sourceMappingURL=(.*)$/g;
|
||||
let lastMatch = null;
|
||||
let match = null;
|
||||
while (match = reg.exec(contents)) {
|
||||
lastMatch = match;
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ function loadSourcemaps() {
|
|||
return;
|
||||
}
|
||||
f.contents = Buffer.from(contents.replace(/\/\/# sourceMappingURL=(.*)$/g, ''), 'utf8');
|
||||
fs.readFile(path.join(path.dirname(f.path), lastMatch[1]), 'utf8', function (err, contents) {
|
||||
fs.readFile(path.join(path.dirname(f.path), lastMatch[1]), 'utf8', (err, contents) => {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
@ -157,10 +157,10 @@ function loadSourcemaps() {
|
|||
}
|
||||
exports.loadSourcemaps = loadSourcemaps;
|
||||
function stripSourceMappingURL() {
|
||||
var input = es.through();
|
||||
var output = input
|
||||
.pipe(es.mapSync(function (f) {
|
||||
var contents = f.contents.toString('utf8');
|
||||
const input = es.through();
|
||||
const output = input
|
||||
.pipe(es.mapSync(f => {
|
||||
const contents = f.contents.toString('utf8');
|
||||
f.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, ''), 'utf8');
|
||||
return f;
|
||||
}));
|
||||
|
@ -168,23 +168,23 @@ function stripSourceMappingURL() {
|
|||
}
|
||||
exports.stripSourceMappingURL = stripSourceMappingURL;
|
||||
function rimraf(dir) {
|
||||
var retries = 0;
|
||||
var retry = function (cb) {
|
||||
_rimraf(dir, { maxBusyTries: 1 }, function (err) {
|
||||
let retries = 0;
|
||||
const retry = (cb) => {
|
||||
_rimraf(dir, { maxBusyTries: 1 }, (err) => {
|
||||
if (!err) {
|
||||
return cb();
|
||||
}
|
||||
if (err.code === 'ENOTEMPTY' && ++retries < 5) {
|
||||
return setTimeout(function () { return retry(cb); }, 10);
|
||||
return setTimeout(() => retry(cb), 10);
|
||||
}
|
||||
return cb(err);
|
||||
});
|
||||
};
|
||||
return function (cb) { return retry(cb); };
|
||||
return cb => retry(cb);
|
||||
}
|
||||
exports.rimraf = rimraf;
|
||||
function getVersion(root) {
|
||||
var version = process.env['BUILD_SOURCEVERSION'];
|
||||
let version = process.env['BUILD_SOURCEVERSION'];
|
||||
if (!version || !/^[0-9a-f]{40}$/i.test(version)) {
|
||||
version = git.getVersion(root);
|
||||
}
|
||||
|
@ -192,14 +192,14 @@ function getVersion(root) {
|
|||
}
|
||||
exports.getVersion = getVersion;
|
||||
function rebase(count) {
|
||||
return rename(function (f) {
|
||||
var parts = f.dirname ? f.dirname.split(/[\/\\]/) : [];
|
||||
return rename(f => {
|
||||
const parts = f.dirname ? f.dirname.split(/[\/\\]/) : [];
|
||||
f.dirname = parts.slice(count).join(path.sep);
|
||||
});
|
||||
}
|
||||
exports.rebase = rebase;
|
||||
function filter(fn) {
|
||||
var result = es.through(function (data) {
|
||||
const result = es.through(function (data) {
|
||||
if (fn(data)) {
|
||||
this.emit('data', data);
|
||||
}
|
||||
|
@ -212,8 +212,8 @@ function filter(fn) {
|
|||
}
|
||||
exports.filter = filter;
|
||||
function versionStringToNumber(versionStr) {
|
||||
var semverRegex = /(\d+)\.(\d+)\.(\d+)/;
|
||||
var match = versionStr.match(semverRegex);
|
||||
const semverRegex = /(\d+)\.(\d+)\.(\d+)/;
|
||||
const match = versionStr.match(semverRegex);
|
||||
if (!match) {
|
||||
throw new Error('Version string is not properly formatted: ' + versionStr);
|
||||
}
|
||||
|
|
|
@ -4,30 +4,22 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var fs = require("fs");
|
||||
var ts = require("typescript");
|
||||
var path = require("path");
|
||||
var util = require("gulp-util");
|
||||
var tsfmt = require('../../tsfmt.json');
|
||||
function log(message) {
|
||||
var rest = [];
|
||||
for (var _i = 1; _i < arguments.length; _i++) {
|
||||
rest[_i - 1] = arguments[_i];
|
||||
}
|
||||
util.log.apply(util, [util.colors.cyan('[monaco.d.ts]'), message].concat(rest));
|
||||
const fs = require("fs");
|
||||
const ts = require("typescript");
|
||||
const path = require("path");
|
||||
const util = require("gulp-util");
|
||||
const tsfmt = require('../../tsfmt.json');
|
||||
function log(message, ...rest) {
|
||||
util.log(util.colors.cyan('[monaco.d.ts]'), message, ...rest);
|
||||
}
|
||||
var SRC = path.join(__dirname, '../../src');
|
||||
var OUT_ROOT = path.join(__dirname, '../../');
|
||||
var RECIPE_PATH = path.join(__dirname, './monaco.d.ts.recipe');
|
||||
var DECLARATION_PATH = path.join(__dirname, '../../src/vs/monaco.d.ts');
|
||||
const SRC = path.join(__dirname, '../../src');
|
||||
const OUT_ROOT = path.join(__dirname, '../../');
|
||||
const RECIPE_PATH = path.join(__dirname, './monaco.d.ts.recipe');
|
||||
const DECLARATION_PATH = path.join(__dirname, '../../src/vs/monaco.d.ts');
|
||||
var CURRENT_PROCESSING_RULE = '';
|
||||
function logErr(message) {
|
||||
var rest = [];
|
||||
for (var _i = 1; _i < arguments.length; _i++) {
|
||||
rest[_i - 1] = arguments[_i];
|
||||
}
|
||||
function logErr(message, ...rest) {
|
||||
util.log(util.colors.red('[monaco.d.ts]'), 'WHILE HANDLING RULE: ', CURRENT_PROCESSING_RULE);
|
||||
util.log.apply(util, [util.colors.red('[monaco.d.ts]'), message].concat(rest));
|
||||
util.log(util.colors.red('[monaco.d.ts]'), message, ...rest);
|
||||
}
|
||||
function moduleIdToPath(out, moduleId) {
|
||||
if (/\.d\.ts/.test(moduleId)) {
|
||||
|
@ -35,16 +27,16 @@ function moduleIdToPath(out, moduleId) {
|
|||
}
|
||||
return path.join(OUT_ROOT, out, moduleId) + '.d.ts';
|
||||
}
|
||||
var SOURCE_FILE_MAP = {};
|
||||
let SOURCE_FILE_MAP = {};
|
||||
function getSourceFile(out, inputFiles, moduleId) {
|
||||
if (!SOURCE_FILE_MAP[moduleId]) {
|
||||
var filePath = path.normalize(moduleIdToPath(out, moduleId));
|
||||
let filePath = path.normalize(moduleIdToPath(out, moduleId));
|
||||
if (!inputFiles.hasOwnProperty(filePath)) {
|
||||
logErr('CANNOT FIND FILE ' + filePath + '. YOU MIGHT NEED TO RESTART gulp');
|
||||
return null;
|
||||
}
|
||||
var fileContents = inputFiles[filePath];
|
||||
var sourceFile = ts.createSourceFile(filePath, fileContents, ts.ScriptTarget.ES5);
|
||||
let fileContents = inputFiles[filePath];
|
||||
let sourceFile = ts.createSourceFile(filePath, fileContents, ts.ScriptTarget.ES5);
|
||||
SOURCE_FILE_MAP[moduleId] = sourceFile;
|
||||
}
|
||||
return SOURCE_FILE_MAP[moduleId];
|
||||
|
@ -58,8 +50,8 @@ function isDeclaration(a) {
|
|||
|| a.kind === ts.SyntaxKind.ModuleDeclaration);
|
||||
}
|
||||
function visitTopLevelDeclarations(sourceFile, visitor) {
|
||||
var stop = false;
|
||||
var visit = function (node) {
|
||||
let stop = false;
|
||||
let visit = (node) => {
|
||||
if (stop) {
|
||||
return;
|
||||
}
|
||||
|
@ -81,19 +73,19 @@ function visitTopLevelDeclarations(sourceFile, visitor) {
|
|||
visit(sourceFile);
|
||||
}
|
||||
function getAllTopLevelDeclarations(sourceFile) {
|
||||
var all = [];
|
||||
visitTopLevelDeclarations(sourceFile, function (node) {
|
||||
let all = [];
|
||||
visitTopLevelDeclarations(sourceFile, (node) => {
|
||||
if (node.kind === ts.SyntaxKind.InterfaceDeclaration || node.kind === ts.SyntaxKind.ClassDeclaration || node.kind === ts.SyntaxKind.ModuleDeclaration) {
|
||||
var interfaceDeclaration = node;
|
||||
var triviaStart = interfaceDeclaration.pos;
|
||||
var triviaEnd = interfaceDeclaration.name.pos;
|
||||
var triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd });
|
||||
let interfaceDeclaration = node;
|
||||
let triviaStart = interfaceDeclaration.pos;
|
||||
let triviaEnd = interfaceDeclaration.name.pos;
|
||||
let triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd });
|
||||
if (triviaText.indexOf('@internal') === -1) {
|
||||
all.push(node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
var nodeText = getNodeText(sourceFile, node);
|
||||
let nodeText = getNodeText(sourceFile, node);
|
||||
if (nodeText.indexOf('@internal') === -1) {
|
||||
all.push(node);
|
||||
}
|
||||
|
@ -103,8 +95,8 @@ function getAllTopLevelDeclarations(sourceFile) {
|
|||
return all;
|
||||
}
|
||||
function getTopLevelDeclaration(sourceFile, typeName) {
|
||||
var result = null;
|
||||
visitTopLevelDeclarations(sourceFile, function (node) {
|
||||
let result = null;
|
||||
visitTopLevelDeclarations(sourceFile, (node) => {
|
||||
if (isDeclaration(node) && node.name) {
|
||||
if (node.name.text === typeName) {
|
||||
result = node;
|
||||
|
@ -126,8 +118,8 @@ function getNodeText(sourceFile, node) {
|
|||
}
|
||||
function hasModifier(modifiers, kind) {
|
||||
if (modifiers) {
|
||||
for (var i = 0; i < modifiers.length; i++) {
|
||||
var mod = modifiers[i];
|
||||
for (let i = 0; i < modifiers.length; i++) {
|
||||
let mod = modifiers[i];
|
||||
if (mod.kind === kind) {
|
||||
return true;
|
||||
}
|
||||
|
@ -143,35 +135,35 @@ function isDefaultExport(declaration) {
|
|||
&& hasModifier(declaration.modifiers, ts.SyntaxKind.ExportKeyword));
|
||||
}
|
||||
function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage) {
|
||||
var result = getNodeText(sourceFile, declaration);
|
||||
let result = getNodeText(sourceFile, declaration);
|
||||
if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) {
|
||||
var interfaceDeclaration = declaration;
|
||||
var staticTypeName_1 = (isDefaultExport(interfaceDeclaration)
|
||||
? importName + ".default"
|
||||
: importName + "." + declaration.name.text);
|
||||
var instanceTypeName_1 = staticTypeName_1;
|
||||
var typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0);
|
||||
let interfaceDeclaration = declaration;
|
||||
const staticTypeName = (isDefaultExport(interfaceDeclaration)
|
||||
? `${importName}.default`
|
||||
: `${importName}.${declaration.name.text}`);
|
||||
let instanceTypeName = staticTypeName;
|
||||
const typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0);
|
||||
if (typeParametersCnt > 0) {
|
||||
var arr = [];
|
||||
for (var i = 0; i < typeParametersCnt; i++) {
|
||||
let arr = [];
|
||||
for (let i = 0; i < typeParametersCnt; i++) {
|
||||
arr.push('any');
|
||||
}
|
||||
instanceTypeName_1 = instanceTypeName_1 + "<" + arr.join(',') + ">";
|
||||
instanceTypeName = `${instanceTypeName}<${arr.join(',')}>`;
|
||||
}
|
||||
var members = interfaceDeclaration.members;
|
||||
members.forEach(function (member) {
|
||||
const members = interfaceDeclaration.members;
|
||||
members.forEach((member) => {
|
||||
try {
|
||||
var memberText = getNodeText(sourceFile, member);
|
||||
let memberText = getNodeText(sourceFile, member);
|
||||
if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) {
|
||||
result = result.replace(memberText, '');
|
||||
}
|
||||
else {
|
||||
var memberName = member.name.text;
|
||||
const memberName = member.name.text;
|
||||
if (isStatic(member)) {
|
||||
usage.push("a = " + staticTypeName_1 + "." + memberName + ";");
|
||||
usage.push(`a = ${staticTypeName}.${memberName};`);
|
||||
}
|
||||
else {
|
||||
usage.push("a = (<" + instanceTypeName_1 + ">b)." + memberName + ";");
|
||||
usage.push(`a = (<${instanceTypeName}>b).${memberName};`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,9 +178,9 @@ function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName,
|
|||
}
|
||||
function format(text) {
|
||||
// Parse the source text
|
||||
var sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true);
|
||||
let sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true);
|
||||
// Get the formatting edits on the input sources
|
||||
var edits = ts.formatting.formatDocument(sourceFile, getRuleProvider(tsfmt), tsfmt);
|
||||
let edits = ts.formatting.formatDocument(sourceFile, getRuleProvider(tsfmt), tsfmt);
|
||||
// Apply the edits on the input code
|
||||
return applyEdits(text, edits);
|
||||
function getRuleProvider(options) {
|
||||
|
@ -198,11 +190,11 @@ function format(text) {
|
|||
}
|
||||
function applyEdits(text, edits) {
|
||||
// Apply edits in reverse on the existing text
|
||||
var result = text;
|
||||
for (var i = edits.length - 1; i >= 0; i--) {
|
||||
var change = edits[i];
|
||||
var head = result.slice(0, change.span.start);
|
||||
var tail = result.slice(change.span.start + change.span.length);
|
||||
let result = text;
|
||||
for (let i = edits.length - 1; i >= 0; i--) {
|
||||
let change = edits[i];
|
||||
let head = result.slice(0, change.span.start);
|
||||
let tail = result.slice(change.span.start + change.span.length);
|
||||
result = head + change.newText + tail;
|
||||
}
|
||||
return result;
|
||||
|
@ -210,131 +202,131 @@ function format(text) {
|
|||
}
|
||||
function createReplacer(data) {
|
||||
data = data || '';
|
||||
var rawDirectives = data.split(';');
|
||||
var directives = [];
|
||||
rawDirectives.forEach(function (rawDirective) {
|
||||
let rawDirectives = data.split(';');
|
||||
let directives = [];
|
||||
rawDirectives.forEach((rawDirective) => {
|
||||
if (rawDirective.length === 0) {
|
||||
return;
|
||||
}
|
||||
var pieces = rawDirective.split('=>');
|
||||
var findStr = pieces[0];
|
||||
var replaceStr = pieces[1];
|
||||
let pieces = rawDirective.split('=>');
|
||||
let findStr = pieces[0];
|
||||
let replaceStr = pieces[1];
|
||||
findStr = findStr.replace(/[\-\\\{\}\*\+\?\|\^\$\.\,\[\]\(\)\#\s]/g, '\\$&');
|
||||
findStr = '\\b' + findStr + '\\b';
|
||||
directives.push([new RegExp(findStr, 'g'), replaceStr]);
|
||||
});
|
||||
return function (str) {
|
||||
for (var i = 0; i < directives.length; i++) {
|
||||
return (str) => {
|
||||
for (let i = 0; i < directives.length; i++) {
|
||||
str = str.replace(directives[i][0], directives[i][1]);
|
||||
}
|
||||
return str;
|
||||
};
|
||||
}
|
||||
function generateDeclarationFile(out, inputFiles, recipe) {
|
||||
var endl = /\r\n/.test(recipe) ? '\r\n' : '\n';
|
||||
var lines = recipe.split(endl);
|
||||
var result = [];
|
||||
var usageCounter = 0;
|
||||
var usageImports = [];
|
||||
var usage = [];
|
||||
usage.push("var a;");
|
||||
usage.push("var b;");
|
||||
var generateUsageImport = function (moduleId) {
|
||||
var importName = 'm' + (++usageCounter);
|
||||
usageImports.push("import * as " + importName + " from './" + moduleId.replace(/\.d\.ts$/, '') + "';");
|
||||
const endl = /\r\n/.test(recipe) ? '\r\n' : '\n';
|
||||
let lines = recipe.split(endl);
|
||||
let result = [];
|
||||
let usageCounter = 0;
|
||||
let usageImports = [];
|
||||
let usage = [];
|
||||
usage.push(`var a;`);
|
||||
usage.push(`var b;`);
|
||||
const generateUsageImport = (moduleId) => {
|
||||
let importName = 'm' + (++usageCounter);
|
||||
usageImports.push(`import * as ${importName} from './${moduleId.replace(/\.d\.ts$/, '')}';`);
|
||||
return importName;
|
||||
};
|
||||
lines.forEach(function (line) {
|
||||
var m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
|
||||
lines.forEach(line => {
|
||||
let m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
|
||||
if (m1) {
|
||||
CURRENT_PROCESSING_RULE = line;
|
||||
var moduleId = m1[1];
|
||||
var sourceFile_1 = getSourceFile(out, inputFiles, moduleId);
|
||||
if (!sourceFile_1) {
|
||||
let moduleId = m1[1];
|
||||
const sourceFile = getSourceFile(out, inputFiles, moduleId);
|
||||
if (!sourceFile) {
|
||||
return;
|
||||
}
|
||||
var importName_1 = generateUsageImport(moduleId);
|
||||
var replacer_1 = createReplacer(m1[2]);
|
||||
var typeNames = m1[3].split(/,/);
|
||||
typeNames.forEach(function (typeName) {
|
||||
const importName = generateUsageImport(moduleId);
|
||||
let replacer = createReplacer(m1[2]);
|
||||
let typeNames = m1[3].split(/,/);
|
||||
typeNames.forEach((typeName) => {
|
||||
typeName = typeName.trim();
|
||||
if (typeName.length === 0) {
|
||||
return;
|
||||
}
|
||||
var declaration = getTopLevelDeclaration(sourceFile_1, typeName);
|
||||
let declaration = getTopLevelDeclaration(sourceFile, typeName);
|
||||
if (!declaration) {
|
||||
logErr('Cannot find type ' + typeName);
|
||||
return;
|
||||
}
|
||||
result.push(replacer_1(getMassagedTopLevelDeclarationText(sourceFile_1, declaration, importName_1, usage)));
|
||||
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage)));
|
||||
});
|
||||
return;
|
||||
}
|
||||
var m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
|
||||
let m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
|
||||
if (m2) {
|
||||
CURRENT_PROCESSING_RULE = line;
|
||||
var moduleId = m2[1];
|
||||
var sourceFile_2 = getSourceFile(out, inputFiles, moduleId);
|
||||
if (!sourceFile_2) {
|
||||
let moduleId = m2[1];
|
||||
const sourceFile = getSourceFile(out, inputFiles, moduleId);
|
||||
if (!sourceFile) {
|
||||
return;
|
||||
}
|
||||
var importName_2 = generateUsageImport(moduleId);
|
||||
var replacer_2 = createReplacer(m2[2]);
|
||||
var typeNames = m2[3].split(/,/);
|
||||
var typesToExcludeMap_1 = {};
|
||||
var typesToExcludeArr_1 = [];
|
||||
typeNames.forEach(function (typeName) {
|
||||
const importName = generateUsageImport(moduleId);
|
||||
let replacer = createReplacer(m2[2]);
|
||||
let typeNames = m2[3].split(/,/);
|
||||
let typesToExcludeMap = {};
|
||||
let typesToExcludeArr = [];
|
||||
typeNames.forEach((typeName) => {
|
||||
typeName = typeName.trim();
|
||||
if (typeName.length === 0) {
|
||||
return;
|
||||
}
|
||||
typesToExcludeMap_1[typeName] = true;
|
||||
typesToExcludeArr_1.push(typeName);
|
||||
typesToExcludeMap[typeName] = true;
|
||||
typesToExcludeArr.push(typeName);
|
||||
});
|
||||
getAllTopLevelDeclarations(sourceFile_2).forEach(function (declaration) {
|
||||
getAllTopLevelDeclarations(sourceFile).forEach((declaration) => {
|
||||
if (isDeclaration(declaration) && declaration.name) {
|
||||
if (typesToExcludeMap_1[declaration.name.text]) {
|
||||
if (typesToExcludeMap[declaration.name.text]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// node is ts.VariableStatement
|
||||
var nodeText = getNodeText(sourceFile_2, declaration);
|
||||
for (var i = 0; i < typesToExcludeArr_1.length; i++) {
|
||||
if (nodeText.indexOf(typesToExcludeArr_1[i]) >= 0) {
|
||||
let nodeText = getNodeText(sourceFile, declaration);
|
||||
for (let i = 0; i < typesToExcludeArr.length; i++) {
|
||||
if (nodeText.indexOf(typesToExcludeArr[i]) >= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
result.push(replacer_2(getMassagedTopLevelDeclarationText(sourceFile_2, declaration, importName_2, usage)));
|
||||
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage)));
|
||||
});
|
||||
return;
|
||||
}
|
||||
result.push(line);
|
||||
});
|
||||
var resultTxt = result.join(endl);
|
||||
let resultTxt = result.join(endl);
|
||||
resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri');
|
||||
resultTxt = resultTxt.replace(/\bEvent</g, 'IEvent<');
|
||||
resultTxt = format(resultTxt);
|
||||
return [
|
||||
resultTxt,
|
||||
usageImports.join('\n') + "\n\n" + usage.join('\n')
|
||||
`${usageImports.join('\n')}\n\n${usage.join('\n')}`
|
||||
];
|
||||
}
|
||||
function getIncludesInRecipe() {
|
||||
var recipe = fs.readFileSync(RECIPE_PATH).toString();
|
||||
var lines = recipe.split(/\r\n|\n|\r/);
|
||||
var result = [];
|
||||
lines.forEach(function (line) {
|
||||
var m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
|
||||
let recipe = fs.readFileSync(RECIPE_PATH).toString();
|
||||
let lines = recipe.split(/\r\n|\n|\r/);
|
||||
let result = [];
|
||||
lines.forEach(line => {
|
||||
let m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
|
||||
if (m1) {
|
||||
var moduleId = m1[1];
|
||||
let moduleId = m1[1];
|
||||
result.push(moduleId);
|
||||
return;
|
||||
}
|
||||
var m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
|
||||
let m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
|
||||
if (m2) {
|
||||
var moduleId = m2[1];
|
||||
let moduleId = m2[1];
|
||||
result.push(moduleId);
|
||||
return;
|
||||
}
|
||||
|
@ -342,24 +334,24 @@ function getIncludesInRecipe() {
|
|||
return result;
|
||||
}
|
||||
function getFilesToWatch(out) {
|
||||
return getIncludesInRecipe().map(function (moduleId) { return moduleIdToPath(out, moduleId); });
|
||||
return getIncludesInRecipe().map((moduleId) => moduleIdToPath(out, moduleId));
|
||||
}
|
||||
exports.getFilesToWatch = getFilesToWatch;
|
||||
function run(out, inputFiles) {
|
||||
log('Starting monaco.d.ts generation');
|
||||
SOURCE_FILE_MAP = {};
|
||||
var recipe = fs.readFileSync(RECIPE_PATH).toString();
|
||||
var _a = generateDeclarationFile(out, inputFiles, recipe), result = _a[0], usageContent = _a[1];
|
||||
var currentContent = fs.readFileSync(DECLARATION_PATH).toString();
|
||||
let recipe = fs.readFileSync(RECIPE_PATH).toString();
|
||||
let [result, usageContent] = generateDeclarationFile(out, inputFiles, recipe);
|
||||
let currentContent = fs.readFileSync(DECLARATION_PATH).toString();
|
||||
log('Finished monaco.d.ts generation');
|
||||
var one = currentContent.replace(/\r\n/gm, '\n');
|
||||
var other = result.replace(/\r\n/gm, '\n');
|
||||
var isTheSame = one === other;
|
||||
const one = currentContent.replace(/\r\n/gm, '\n');
|
||||
const other = result.replace(/\r\n/gm, '\n');
|
||||
const isTheSame = one === other;
|
||||
return {
|
||||
content: result,
|
||||
usageContent: usageContent,
|
||||
filePath: DECLARATION_PATH,
|
||||
isTheSame: isTheSame
|
||||
isTheSame
|
||||
};
|
||||
}
|
||||
exports.run = run;
|
||||
|
@ -367,28 +359,28 @@ function complainErrors() {
|
|||
logErr('Not running monaco.d.ts generation due to compile errors');
|
||||
}
|
||||
exports.complainErrors = complainErrors;
|
||||
var TypeScriptLanguageServiceHost = /** @class */ (function () {
|
||||
function TypeScriptLanguageServiceHost(libs, files, compilerOptions) {
|
||||
class TypeScriptLanguageServiceHost {
|
||||
constructor(libs, files, compilerOptions) {
|
||||
this._libs = libs;
|
||||
this._files = files;
|
||||
this._compilerOptions = compilerOptions;
|
||||
}
|
||||
// --- language service host ---------------
|
||||
TypeScriptLanguageServiceHost.prototype.getCompilationSettings = function () {
|
||||
getCompilationSettings() {
|
||||
return this._compilerOptions;
|
||||
};
|
||||
TypeScriptLanguageServiceHost.prototype.getScriptFileNames = function () {
|
||||
}
|
||||
getScriptFileNames() {
|
||||
return ([]
|
||||
.concat(Object.keys(this._libs))
|
||||
.concat(Object.keys(this._files)));
|
||||
};
|
||||
TypeScriptLanguageServiceHost.prototype.getScriptVersion = function (_fileName) {
|
||||
}
|
||||
getScriptVersion(_fileName) {
|
||||
return '1';
|
||||
};
|
||||
TypeScriptLanguageServiceHost.prototype.getProjectVersion = function () {
|
||||
}
|
||||
getProjectVersion() {
|
||||
return '1';
|
||||
};
|
||||
TypeScriptLanguageServiceHost.prototype.getScriptSnapshot = function (fileName) {
|
||||
}
|
||||
getScriptSnapshot(fileName) {
|
||||
if (this._files.hasOwnProperty(fileName)) {
|
||||
return ts.ScriptSnapshot.fromString(this._files[fileName]);
|
||||
}
|
||||
|
@ -398,42 +390,41 @@ var TypeScriptLanguageServiceHost = /** @class */ (function () {
|
|||
else {
|
||||
return ts.ScriptSnapshot.fromString('');
|
||||
}
|
||||
};
|
||||
TypeScriptLanguageServiceHost.prototype.getScriptKind = function (_fileName) {
|
||||
}
|
||||
getScriptKind(_fileName) {
|
||||
return ts.ScriptKind.TS;
|
||||
};
|
||||
TypeScriptLanguageServiceHost.prototype.getCurrentDirectory = function () {
|
||||
}
|
||||
getCurrentDirectory() {
|
||||
return '';
|
||||
};
|
||||
TypeScriptLanguageServiceHost.prototype.getDefaultLibFileName = function (_options) {
|
||||
}
|
||||
getDefaultLibFileName(_options) {
|
||||
return 'defaultLib:es5';
|
||||
};
|
||||
TypeScriptLanguageServiceHost.prototype.isDefaultLibFileName = function (fileName) {
|
||||
}
|
||||
isDefaultLibFileName(fileName) {
|
||||
return fileName === this.getDefaultLibFileName(this._compilerOptions);
|
||||
};
|
||||
return TypeScriptLanguageServiceHost;
|
||||
}());
|
||||
}
|
||||
}
|
||||
function execute() {
|
||||
var OUTPUT_FILES = {};
|
||||
var SRC_FILES = {};
|
||||
var SRC_FILE_TO_EXPECTED_NAME = {};
|
||||
getIncludesInRecipe().forEach(function (moduleId) {
|
||||
const OUTPUT_FILES = {};
|
||||
const SRC_FILES = {};
|
||||
const SRC_FILE_TO_EXPECTED_NAME = {};
|
||||
getIncludesInRecipe().forEach((moduleId) => {
|
||||
if (/\.d\.ts$/.test(moduleId)) {
|
||||
var fileName_1 = path.join(SRC, moduleId);
|
||||
OUTPUT_FILES[moduleIdToPath('src', moduleId)] = fs.readFileSync(fileName_1).toString();
|
||||
let fileName = path.join(SRC, moduleId);
|
||||
OUTPUT_FILES[moduleIdToPath('src', moduleId)] = fs.readFileSync(fileName).toString();
|
||||
return;
|
||||
}
|
||||
var fileName = path.join(SRC, moduleId) + '.ts';
|
||||
let fileName = path.join(SRC, moduleId) + '.ts';
|
||||
SRC_FILES[fileName] = fs.readFileSync(fileName).toString();
|
||||
SRC_FILE_TO_EXPECTED_NAME[fileName] = moduleIdToPath('src', moduleId);
|
||||
});
|
||||
var languageService = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, SRC_FILES, {}));
|
||||
const languageService = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, SRC_FILES, {}));
|
||||
var t1 = Date.now();
|
||||
Object.keys(SRC_FILES).forEach(function (fileName) {
|
||||
var emitOutput = languageService.getEmitOutput(fileName, true);
|
||||
Object.keys(SRC_FILES).forEach((fileName) => {
|
||||
const emitOutput = languageService.getEmitOutput(fileName, true);
|
||||
OUTPUT_FILES[SRC_FILE_TO_EXPECTED_NAME[fileName]] = emitOutput.outputFiles[0].text;
|
||||
});
|
||||
console.log("Generating .d.ts took " + (Date.now() - t1) + " ms");
|
||||
console.log(`Generating .d.ts took ${Date.now() - t1} ms`);
|
||||
return run('src', OUTPUT_FILES);
|
||||
}
|
||||
exports.execute = execute;
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
"@types/azure": "0.9.19",
|
||||
"@types/debounce": "^1.0.0",
|
||||
"@types/documentdb": "1.10.2",
|
||||
"@types/es6-collections": "0.5.31",
|
||||
"@types/es6-promise": "0.0.33",
|
||||
"@types/glob": "^7.1.1",
|
||||
"@types/gulp": "^4.0.5",
|
||||
"@types/gulp-concat": "^0.0.32",
|
||||
|
|
|
@ -3,70 +3,27 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var child_process_1 = require("child_process");
|
||||
var azure = require("azure-storage");
|
||||
const child_process_1 = require("child_process");
|
||||
const azure = require("azure-storage");
|
||||
function queueSigningRequest(quality, commit) {
|
||||
var retryOperations = new azure.ExponentialRetryPolicyFilter();
|
||||
var queueSvc = azure
|
||||
const retryOperations = new azure.ExponentialRetryPolicyFilter();
|
||||
const queueSvc = azure
|
||||
.createQueueService(process.env['AZURE_STORAGE_ACCOUNT_2'], process.env['AZURE_STORAGE_ACCESS_KEY_2'])
|
||||
.withFilter(retryOperations);
|
||||
queueSvc.messageEncoder = new azure.QueueMessageEncoder.TextBase64QueueMessageEncoder();
|
||||
var message = quality + "/" + commit;
|
||||
return new Promise(function (c, e) { return queueSvc.createMessage('sign-darwin', message, function (err) { return err ? e(err) : c(); }); });
|
||||
const message = `${quality}/${commit}`;
|
||||
return new Promise((c, e) => queueSvc.createMessage('sign-darwin', message, err => err ? e(err) : c()));
|
||||
}
|
||||
function main(quality) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var commit;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
commit = child_process_1.execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim();
|
||||
console.log("Queueing signing request for '" + quality + "/" + commit + "'...");
|
||||
return [4 /*yield*/, queueSigningRequest(quality, commit)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
async function main(quality) {
|
||||
const commit = child_process_1.execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim();
|
||||
console.log(`Queueing signing request for '${quality}/${commit}'...`);
|
||||
await queueSigningRequest(quality, commit);
|
||||
// console.log('Waiting on signed build...');
|
||||
// await waitForSignedBuild(quality, commit);
|
||||
// console.log('Found signed build!');
|
||||
}
|
||||
main(process.argv[2]).catch(function (err) {
|
||||
main(process.argv[2]).catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"target": "es2017",
|
||||
"module": "commonjs",
|
||||
"removeComments": false,
|
||||
"preserveConstEnums": true,
|
||||
|
|
|
@ -42,16 +42,6 @@
|
|||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/es6-collections@0.5.31":
|
||||
version "0.5.31"
|
||||
resolved "https://registry.yarnpkg.com/@types/es6-collections/-/es6-collections-0.5.31.tgz#faad21c930cd0ea7f71f51b9e5b555796c5ab23f"
|
||||
integrity sha512-djEvbdTH5Uw7V0WqdMQLG4NK3+iu/FMZy/ylyhWEFnW5xOsXEWpivo/dhP+cR43Az+ipytza7dTSnpsWCxKYAw==
|
||||
|
||||
"@types/es6-promise@0.0.33":
|
||||
version "0.0.33"
|
||||
resolved "https://registry.yarnpkg.com/@types/es6-promise/-/es6-promise-0.0.33.tgz#280a707e62b1b6bef1a86cc0861ec63cd06c7ff3"
|
||||
integrity sha512-HKJFVLCGrWQ/1unEw8JdaTxu6n3EUxmwTxJ6D0O1x0gD8joCsgoTWxEgevb7fp2XIogNjof3KEd+3bJoGne/nw==
|
||||
|
||||
"@types/events@*":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86"
|
||||
|
|
|
@ -112,7 +112,6 @@
|
|||
"mkdirp": "^0.5.0",
|
||||
"mocha": "^2.2.5",
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"object-assign": "^4.0.1",
|
||||
"optimist": "0.3.5",
|
||||
"p-all": "^1.0.0",
|
||||
"pump": "^1.0.1",
|
||||
|
|
|
@ -5,20 +5,35 @@
|
|||
"strictNullChecks": true
|
||||
},
|
||||
"include": [
|
||||
"./typings",
|
||||
"./typings"
|
||||
],
|
||||
"files": [
|
||||
"./vs/base/browser/browser.ts",
|
||||
"./vs/base/browser/dom.ts",
|
||||
"./vs/base/browser/event.ts",
|
||||
"./vs/base/browser/fastDomNode.ts",
|
||||
"./vs/base/browser/globalMouseMoveMonitor.ts",
|
||||
"./vs/base/browser/history.ts",
|
||||
"./vs/base/browser/iframe.ts",
|
||||
"./vs/base/browser/keyboardEvent.ts",
|
||||
"./vs/base/browser/mouseEvent.ts",
|
||||
"./vs/base/browser/touch.ts",
|
||||
"./vs/base/browser/ui/aria/aria.ts",
|
||||
"./vs/base/browser/ui/contextview/contextview.ts",
|
||||
"./vs/base/browser/ui/list/list.ts",
|
||||
"./vs/base/browser/ui/list/splice.ts",
|
||||
"./vs/base/browser/ui/octiconLabel/octiconLabel.mock.ts",
|
||||
"./vs/base/browser/ui/octiconLabel/octiconLabel.ts",
|
||||
"./vs/base/browser/ui/scrollbar/abstractScrollbar.ts",
|
||||
"./vs/base/browser/ui/scrollbar/horizontalScrollbar.ts",
|
||||
"./vs/base/browser/ui/scrollbar/scrollableElement.ts",
|
||||
"./vs/base/browser/ui/scrollbar/scrollableElementOptions.ts",
|
||||
"./vs/base/browser/ui/scrollbar/scrollbarArrow.ts",
|
||||
"./vs/base/browser/ui/scrollbar/scrollbarState.ts",
|
||||
"./vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts",
|
||||
"./vs/base/browser/ui/scrollbar/verticalScrollbar.ts",
|
||||
"./vs/base/browser/ui/tree/tree.ts",
|
||||
"./vs/base/browser/ui/widget.ts",
|
||||
"./vs/base/common/actions.ts",
|
||||
"./vs/base/common/amd.ts",
|
||||
"./vs/base/common/arrays.ts",
|
||||
|
@ -47,13 +62,14 @@
|
|||
"./vs/base/common/idGenerator.ts",
|
||||
"./vs/base/common/iterator.ts",
|
||||
"./vs/base/common/jsonSchema.ts",
|
||||
"./vs/base/common/keyCodes.ts",
|
||||
"./vs/base/common/keybindingParser.ts",
|
||||
"./vs/base/common/keyCodes.ts",
|
||||
"./vs/base/common/labels.ts",
|
||||
"./vs/base/common/lifecycle.ts",
|
||||
"./vs/base/common/linkedList.ts",
|
||||
"./vs/base/common/map.ts",
|
||||
"./vs/base/common/marshalling.ts",
|
||||
"./vs/base/common/mime.ts",
|
||||
"./vs/base/common/network.ts",
|
||||
"./vs/base/common/normalization.ts",
|
||||
"./vs/base/common/numbers.ts",
|
||||
|
@ -88,21 +104,84 @@
|
|||
"./vs/base/test/node/uri.test.perf.ts",
|
||||
"./vs/base/worker/defaultWorkerFactory.ts",
|
||||
"./vs/base/worker/workerMain.ts",
|
||||
"./vs/code/code.main.ts",
|
||||
"./vs/code/electron-browser/issue/issueReporterPage.ts",
|
||||
"./vs/code/electron-browser/issue/issueReporterUtil.ts",
|
||||
"./vs/code/electron-main/keyboard.ts",
|
||||
"./vs/code/electron-main/theme.ts",
|
||||
"./vs/code/node/shellEnv.ts",
|
||||
"./vs/editor/browser/config/charWidthReader.ts",
|
||||
"./vs/editor/browser/config/configuration.ts",
|
||||
"./vs/editor/browser/config/elementSizeObserver.ts",
|
||||
"./vs/editor/browser/controller/coreCommands.ts",
|
||||
"./vs/editor/browser/controller/mouseHandler.ts",
|
||||
"./vs/editor/browser/controller/mouseTarget.ts",
|
||||
"./vs/editor/browser/controller/pointerHandler.ts",
|
||||
"./vs/editor/browser/controller/textAreaHandler.ts",
|
||||
"./vs/editor/browser/controller/textAreaInput.ts",
|
||||
"./vs/editor/browser/controller/textAreaState.ts",
|
||||
"./vs/editor/browser/core/editorState.ts",
|
||||
"./vs/editor/browser/editorBrowser.ts",
|
||||
"./vs/editor/browser/editorDom.ts",
|
||||
"./vs/editor/browser/editorExtensions.ts",
|
||||
"./vs/editor/browser/editorExtensions",
|
||||
"./vs/editor/browser/services/abstractCodeEditorService.ts",
|
||||
"./vs/editor/browser/services/bulkEditService.ts",
|
||||
"./vs/editor/browser/services/codeEditorService.ts",
|
||||
"./vs/editor/browser/services/codeEditorServiceImpl.ts",
|
||||
"./vs/editor/browser/services/openerService.ts",
|
||||
"./vs/editor/browser/view/dynamicViewOverlay.ts",
|
||||
"./vs/editor/browser/view/viewController.ts",
|
||||
"./vs/editor/browser/view/viewImpl.ts",
|
||||
"./vs/editor/browser/view/viewLayer.ts",
|
||||
"./vs/editor/browser/view/viewOutgoingEvents.ts",
|
||||
"./vs/editor/browser/view/viewOverlays.ts",
|
||||
"./vs/editor/browser/view/viewPart.ts",
|
||||
"./vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts",
|
||||
"./vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.ts",
|
||||
"./vs/editor/browser/viewParts/currentLineMarginHighlight/currentLineMarginHighlight.ts",
|
||||
"./vs/editor/browser/viewParts/decorations/decorations.ts",
|
||||
"./vs/editor/browser/viewParts/editorScrollbar/editorScrollbar.ts",
|
||||
"./vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts",
|
||||
"./vs/editor/browser/viewParts/indentGuides/indentGuides.ts",
|
||||
"./vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts",
|
||||
"./vs/editor/browser/viewParts/lines/rangeUtil.ts",
|
||||
"./vs/editor/browser/viewParts/lines/viewLine.ts",
|
||||
"./vs/editor/browser/viewParts/lines/viewLines.ts",
|
||||
"./vs/editor/browser/viewParts/linesDecorations/linesDecorations.ts",
|
||||
"./vs/editor/browser/viewParts/margin/margin.ts",
|
||||
"./vs/editor/browser/viewParts/marginDecorations/marginDecorations.ts",
|
||||
"./vs/editor/browser/viewParts/minimap/minimap.ts",
|
||||
"./vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts",
|
||||
"./vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts",
|
||||
"./vs/editor/browser/viewParts/overviewRuler/overviewRuler.ts",
|
||||
"./vs/editor/browser/viewParts/rulers/rulers.ts",
|
||||
"./vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts",
|
||||
"./vs/editor/browser/viewParts/selections/selections.ts",
|
||||
"./vs/editor/browser/viewParts/viewCursors/viewCursor.ts",
|
||||
"./vs/editor/browser/viewParts/viewCursors/viewCursors.ts",
|
||||
"./vs/editor/browser/viewParts/viewZones/viewZones.ts",
|
||||
"./vs/editor/browser/widget/codeEditorWidget.ts",
|
||||
"./vs/editor/browser/widget/diffNavigator.ts",
|
||||
"./vs/editor/common/commands/replaceCommand.ts",
|
||||
"./vs/editor/common/commands/shiftCommand.ts",
|
||||
"./vs/editor/common/commands/surroundSelectionCommand.ts",
|
||||
"./vs/editor/common/commands/trimTrailingWhitespaceCommand.ts",
|
||||
"./vs/editor/common/config/commonEditorConfig.ts",
|
||||
"./vs/editor/common/config/editorOptions.ts",
|
||||
"./vs/editor/common/config/editorZoom.ts",
|
||||
"./vs/editor/common/config/fontInfo.ts",
|
||||
"./vs/editor/common/controller/cursor.ts",
|
||||
"./vs/editor/common/controller/cursorCollection.ts",
|
||||
"./vs/editor/common/controller/cursorColumnSelection.ts",
|
||||
"./vs/editor/common/controller/cursorCommon.ts",
|
||||
"./vs/editor/common/controller/cursorDeleteOperations.ts",
|
||||
"./vs/editor/common/controller/cursorEvents.ts",
|
||||
"./vs/editor/common/controller/cursorMoveCommands.ts",
|
||||
"./vs/editor/common/controller/cursorMoveOperations.ts",
|
||||
"./vs/editor/common/controller/cursorTypeOperations.ts",
|
||||
"./vs/editor/common/controller/cursorWordOperations.ts",
|
||||
"./vs/editor/common/controller/oneCursor.ts",
|
||||
"./vs/editor/common/controller/wordCharacterClassifier.ts",
|
||||
"./vs/editor/common/core/characterClassifier.ts",
|
||||
"./vs/editor/common/core/editOperation.ts",
|
||||
|
@ -139,6 +218,7 @@
|
|||
"./vs/editor/common/modes/languageFeatureRegistry.ts",
|
||||
"./vs/editor/common/modes/languageSelector.ts",
|
||||
"./vs/editor/common/modes/linkComputer.ts",
|
||||
"./vs/editor/common/modes/modesRegistry.ts",
|
||||
"./vs/editor/common/modes/nullMode.ts",
|
||||
"./vs/editor/common/modes/supports.ts",
|
||||
"./vs/editor/common/modes/supports/characterPair.ts",
|
||||
|
@ -150,40 +230,95 @@
|
|||
"./vs/editor/common/modes/supports/tokenization.ts",
|
||||
"./vs/editor/common/modes/textToHtmlTokenizer.ts",
|
||||
"./vs/editor/common/modes/tokenizationRegistry.ts",
|
||||
"./vs/editor/common/services/editorSimpleWorker.ts",
|
||||
"./vs/editor/common/services/editorWorkerService.ts",
|
||||
"./vs/editor/common/services/editorWorkerServiceImpl.ts",
|
||||
"./vs/editor/common/services/languagesRegistry.ts",
|
||||
"./vs/editor/common/services/modelService.ts",
|
||||
"./vs/editor/common/services/modelServiceImpl.ts",
|
||||
"./vs/editor/common/services/modeService.ts",
|
||||
"./vs/editor/common/services/modeServiceImpl.ts",
|
||||
"./vs/editor/common/services/resolverService.ts",
|
||||
"./vs/editor/common/services/resourceConfiguration.ts",
|
||||
"./vs/editor/common/services/resourceConfigurationImpl.ts",
|
||||
"./vs/editor/common/services/webWorker.ts",
|
||||
"./vs/editor/common/standalone/standaloneBase.ts",
|
||||
"./vs/editor/common/view/editorColorRegistry.ts",
|
||||
"./vs/editor/common/view/minimapCharRenderer.ts",
|
||||
"./vs/editor/common/view/overviewZoneManager.ts",
|
||||
"./vs/editor/common/view/renderingContext.ts",
|
||||
"./vs/editor/common/view/runtimeMinimapCharRenderer.ts",
|
||||
"./vs/editor/common/view/viewContext.ts",
|
||||
"./vs/editor/common/view/viewEventDispatcher.ts",
|
||||
"./vs/editor/common/view/viewEvents.ts",
|
||||
"./vs/editor/common/viewLayout/lineDecorations.ts",
|
||||
"./vs/editor/common/viewLayout/linesLayout.ts",
|
||||
"./vs/editor/common/viewLayout/viewLayout.ts",
|
||||
"./vs/editor/common/viewLayout/viewLineRenderer.ts",
|
||||
"./vs/editor/common/viewLayout/viewLinesViewportData.ts",
|
||||
"./vs/editor/common/viewLayout/whitespaceComputer.ts",
|
||||
"./vs/editor/common/viewModel/characterHardWrappingLineMapper.ts",
|
||||
"./vs/editor/common/viewModel/prefixSumComputer.ts",
|
||||
"./vs/editor/common/viewModel/splitLinesCollection.ts",
|
||||
"./vs/editor/common/viewModel/viewEventHandler.ts",
|
||||
"./vs/editor/common/viewModel/viewModel.ts",
|
||||
"./vs/editor/common/viewModel/viewModelDecorations.ts",
|
||||
"./vs/editor/common/viewModel/viewModelImpl.ts",
|
||||
"./vs/editor/contrib/bracketMatching/bracketMatching.ts",
|
||||
"./vs/editor/contrib/caretOperations/caretOperations.ts",
|
||||
"./vs/editor/contrib/caretOperations/moveCaretCommand.ts",
|
||||
"./vs/editor/contrib/caretOperations/transpose.ts",
|
||||
"./vs/editor/contrib/clipboard/clipboard.ts",
|
||||
"./vs/editor/contrib/codeAction/codeActionTrigger.ts",
|
||||
"./vs/editor/contrib/colorPicker/colorPickerModel.ts",
|
||||
"./vs/editor/contrib/comment/blockCommentCommand.ts",
|
||||
"./vs/editor/contrib/cursorUndo/cursorUndo.ts",
|
||||
"./vs/editor/contrib/dnd/dragAndDropCommand.ts",
|
||||
"./vs/editor/contrib/find/findState.ts",
|
||||
"./vs/editor/contrib/find/replaceAllCommand.ts",
|
||||
"./vs/editor/contrib/find/replacePattern.ts",
|
||||
"./vs/editor/contrib/fontZoom/fontZoom.ts",
|
||||
"./vs/editor/contrib/goToDefinition/clickLinkGesture.ts",
|
||||
"./vs/editor/contrib/hover/getHover.ts",
|
||||
"./vs/editor/contrib/hover/hoverOperation.ts",
|
||||
"./vs/editor/contrib/hover/hoverWidgets.ts",
|
||||
"./vs/editor/contrib/indentation/indentUtils.ts",
|
||||
"./vs/editor/contrib/inPlaceReplace/inPlaceReplaceCommand.ts",
|
||||
"./vs/editor/contrib/linesOperations/copyLinesCommand.ts",
|
||||
"./vs/editor/contrib/linesOperations/deleteLinesCommand.ts",
|
||||
"./vs/editor/contrib/linesOperations/sortLinesCommand.ts",
|
||||
"./vs/editor/contrib/links/getLinks.ts",
|
||||
"./vs/editor/contrib/quickOpen/quickOpen.ts",
|
||||
"./vs/editor/contrib/toggleTabFocusMode/toggleTabFocusMode.ts",
|
||||
"./vs/editor/contrib/wordOperations/wordOperations.ts",
|
||||
"./vs/editor/editor.worker.ts",
|
||||
"./vs/editor/standalone/browser/iPadShowKeyboard/iPadShowKeyboard.ts",
|
||||
"./vs/editor/standalone/browser/standaloneCodeServiceImpl.ts",
|
||||
"./vs/editor/standalone/common/monarch/monarchCommon.ts",
|
||||
"./vs/editor/standalone/common/monarch/monarchCompile.ts",
|
||||
"./vs/editor/standalone/common/monarch/monarchTypes.ts",
|
||||
"./vs/editor/standalone/common/standaloneThemeService.ts",
|
||||
"./vs/editor/standalone/common/themes.ts",
|
||||
"./vs/editor/test/common/commentMode.ts",
|
||||
"./vs/editor/test/common/core/viewLineToken.ts",
|
||||
"./vs/editor/test/common/editorTestUtils.ts",
|
||||
"./vs/editor/test/common/mocks/mockMode.ts",
|
||||
"./vs/editor/test/common/mocks/testConfiguration.ts",
|
||||
"./vs/editor/test/common/model/benchmark/benchmarkUtils.ts",
|
||||
"./vs/editor/test/common/modes/supports/javascriptOnEnterRules.ts",
|
||||
"./vs/editor/test/common/modesTestUtils.ts",
|
||||
"./vs/editor/test/common/view/minimapCharRendererFactory.ts",
|
||||
"./vs/monaco.d.ts",
|
||||
"./vs/nls.d.ts",
|
||||
"./vs/nls.mock.ts",
|
||||
"./vs/platform/actions/common/actions.ts",
|
||||
"./vs/platform/backup/common/backup.ts",
|
||||
"./vs/platform/broadcast/electron-browser/broadcastService.ts",
|
||||
"./vs/platform/clipboard/common/clipboardService.ts",
|
||||
"./vs/platform/clipboard/electron-browser/clipboardService.ts",
|
||||
"./vs/platform/commands/common/commands.ts",
|
||||
"./vs/platform/configuration/common/configuration.ts",
|
||||
"./vs/platform/configuration/common/configurationRegistry.ts",
|
||||
"./vs/platform/contextkey/common/contextkey.ts",
|
||||
"./vs/platform/download/common/download.ts",
|
||||
"./vs/platform/editor/common/editor.ts",
|
||||
|
@ -199,6 +334,9 @@
|
|||
"./vs/platform/instantiation/common/serviceCollection.ts",
|
||||
"./vs/platform/integrity/common/integrity.ts",
|
||||
"./vs/platform/jsonschemas/common/jsonContributionRegistry.ts",
|
||||
"./vs/platform/keybinding/common/keybindingResolver.ts",
|
||||
"./vs/platform/keybinding/common/keybindingsRegistry.ts",
|
||||
"./vs/platform/keybinding/common/resolvedKeybindingItem.ts",
|
||||
"./vs/platform/lifecycle/common/lifecycle.ts",
|
||||
"./vs/platform/localizations/common/localizations.ts",
|
||||
"./vs/platform/log/common/bufferLog.ts",
|
||||
|
@ -220,37 +358,59 @@
|
|||
"./vs/platform/search/common/search.ts",
|
||||
"./vs/platform/state/common/state.ts",
|
||||
"./vs/platform/statusbar/common/statusbar.ts",
|
||||
"./vs/platform/storage/common/storage.ts",
|
||||
"./vs/platform/telemetry/common/telemetry.ts",
|
||||
"./vs/platform/telemetry/common/telemetryUtils.ts",
|
||||
"./vs/platform/telemetry/node/telemetryNodeUtils.ts",
|
||||
"./vs/platform/theme/common/colorRegistry.ts",
|
||||
"./vs/platform/theme/common/themeService.ts",
|
||||
"./vs/platform/update/common/update.ts",
|
||||
"./vs/platform/update/node/update.config.contribution.ts",
|
||||
"./vs/platform/url/common/url.ts",
|
||||
"./vs/platform/url/common/urlService.ts",
|
||||
"./vs/platform/workbench/common/contextkeys.ts",
|
||||
"./vs/platform/workspace/common/workspace.ts",
|
||||
"./vs/platform/workspace/test/common/testWorkspace.ts",
|
||||
"./vs/platform/workspaces/common/workspaces.ts",
|
||||
"./vs/platform/workspaces/node/workspaces.ts",
|
||||
"./vs/workbench/api/shared/tasks.ts",
|
||||
"./vs/workbench/browser/parts/quickinput/quickInputUtils.ts",
|
||||
"./vs/workbench/browser/parts/statusbar/statusbar.ts",
|
||||
"./vs/workbench/common/activity.ts",
|
||||
"./vs/workbench/common/composite.ts",
|
||||
"./vs/workbench/common/contributions.ts",
|
||||
"./vs/workbench/common/extensionHostProtocol.ts",
|
||||
"./vs/workbench/common/memento.ts",
|
||||
"./vs/workbench/common/panel.ts",
|
||||
"./vs/workbench/common/resources.ts",
|
||||
"./vs/workbench/common/viewlet.ts",
|
||||
"./vs/workbench/parts/codeEditor/browser/menuPreventer.ts",
|
||||
"./vs/workbench/parts/codeEditor/browser/simpleEditorOptions.ts",
|
||||
"./vs/workbench/parts/comments/electron-browser/commentGlyphWidget.ts",
|
||||
"./vs/workbench/parts/execution/common/execution.ts",
|
||||
"./vs/workbench/parts/extensions/common/extensionQuery.ts",
|
||||
"./vs/workbench/parts/logs/common/logConstants.ts",
|
||||
"./vs/workbench/parts/markers/electron-browser/constants.ts",
|
||||
"./vs/workbench/parts/markers/electron-browser/markers.ts",
|
||||
"./vs/workbench/parts/markers/electron-browser/markersModel.ts",
|
||||
"./vs/workbench/parts/markers/electron-browser/messages.ts",
|
||||
"./vs/workbench/parts/outline/electron-browser/outline.ts",
|
||||
"./vs/workbench/parts/output/common/output.ts",
|
||||
"./vs/workbench/parts/performance/electron-browser/stats.ts",
|
||||
"./vs/workbench/parts/scm/electron-browser/scmUtil.ts",
|
||||
"./vs/workbench/parts/search/common/constants.ts",
|
||||
"./vs/workbench/parts/tasks/common/taskTemplates.ts",
|
||||
"./vs/workbench/parts/terminal/browser/terminalWidgetManager.ts",
|
||||
"./vs/workbench/parts/terminal/common/terminal.ts",
|
||||
"./vs/workbench/parts/terminal/node/terminalCommandTracker.ts",
|
||||
"./vs/workbench/parts/webview/electron-browser/webviewProtocols.ts",
|
||||
"./vs/workbench/parts/welcome/gettingStarted/electron-browser/gettingStarted.ts",
|
||||
"./vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page.ts",
|
||||
"./vs/workbench/services/activity/common/activity.ts",
|
||||
"./vs/workbench/services/backup/common/backup.ts",
|
||||
"./vs/workbench/services/configuration/common/configuration.ts",
|
||||
"./vs/workbench/services/configuration/common/jsonEditing.ts",
|
||||
"./vs/workbench/services/configurationResolver/common/configurationResolver.ts",
|
||||
"./vs/workbench/services/decorations/browser/decorations.ts",
|
||||
"./vs/workbench/services/extensions/node/lazyPromise.ts",
|
||||
"./vs/workbench/services/extensions/node/proxyIdentifier.ts",
|
||||
|
@ -264,7 +424,11 @@
|
|||
"./vs/workbench/services/scm/common/scmService.ts",
|
||||
"./vs/workbench/services/search/node/search.ts",
|
||||
"./vs/workbench/services/textMate/electron-browser/textMateService.ts",
|
||||
"./vs/workbench/services/themes/common/colorThemeSchema.ts",
|
||||
"./vs/workbench/services/themes/common/fileIconThemeSchema.ts",
|
||||
"./vs/workbench/services/themes/common/workbenchThemeService.ts",
|
||||
"./vs/workbench/services/title/common/titleService.ts",
|
||||
"./vs/workbench/services/workspace/common/workspaceEditing.ts",
|
||||
"./vs/workbench/test/electron-browser/api/mock.ts"
|
||||
],
|
||||
"exclude": [
|
||||
|
|
12
src/typings/vscode-xterm.d.ts
vendored
12
src/typings/vscode-xterm.d.ts
vendored
|
@ -381,37 +381,37 @@ declare module 'vscode-xterm' {
|
|||
* @param type The type of the event.
|
||||
* @param listener The listener.
|
||||
*/
|
||||
on(type: 'key', listener: (key?: string, event?: KeyboardEvent) => void): void;
|
||||
on(type: 'key', listener: (key: string, event: KeyboardEvent) => void): void;
|
||||
/**
|
||||
* Registers an event listener.
|
||||
* @param type The type of the event.
|
||||
* @param listener The listener.
|
||||
*/
|
||||
on(type: 'keypress' | 'keydown', listener: (event?: KeyboardEvent) => void): void;
|
||||
on(type: 'keypress' | 'keydown', listener: (event: KeyboardEvent) => void): void;
|
||||
/**
|
||||
* Registers an event listener.
|
||||
* @param type The type of the event.
|
||||
* @param listener The listener.
|
||||
*/
|
||||
on(type: 'refresh', listener: (data?: { start: number, end: number }) => void): void;
|
||||
on(type: 'refresh', listener: (data: {start: number, end: number}) => void): void;
|
||||
/**
|
||||
* Registers an event listener.
|
||||
* @param type The type of the event.
|
||||
* @param listener The listener.
|
||||
*/
|
||||
on(type: 'resize', listener: (data?: { cols: number, rows: number }) => void): void;
|
||||
on(type: 'resize', listener: (data: {cols: number, rows: number}) => void): void;
|
||||
/**
|
||||
* Registers an event listener.
|
||||
* @param type The type of the event.
|
||||
* @param listener The listener.
|
||||
*/
|
||||
on(type: 'scroll', listener: (ydisp?: number) => void): void;
|
||||
on(type: 'scroll', listener: (ydisp: number) => void): void;
|
||||
/**
|
||||
* Registers an event listener.
|
||||
* @param type The type of the event.
|
||||
* @param listener The listener.
|
||||
*/
|
||||
on(type: 'title', listener: (title?: string) => void): void;
|
||||
on(type: 'title', listener: (title: string) => void): void;
|
||||
/**
|
||||
* Registers an event listener.
|
||||
* @param type The type of the event.
|
||||
|
|
|
@ -728,7 +728,7 @@ export function getLargestChildWidth(parent: HTMLElement, children: HTMLElement[
|
|||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
export function isAncestor(testChild: Node | null, testAncestor: Node): boolean {
|
||||
export function isAncestor(testChild: Node | null, testAncestor: Node | null): boolean {
|
||||
while (testChild) {
|
||||
if (testChild === testAncestor) {
|
||||
return true;
|
||||
|
|
|
@ -39,9 +39,9 @@ export function standardMouseMoveMerger(lastEvent: IStandardMouseMoveEventData,
|
|||
export class GlobalMouseMoveMonitor<R> extends Disposable {
|
||||
|
||||
private hooks: IDisposable[];
|
||||
private mouseMoveEventMerger: IEventMerger<R>;
|
||||
private mouseMoveCallback: IMouseMoveCallback<R>;
|
||||
private onStopCallback: IOnStopCallback;
|
||||
private mouseMoveEventMerger: IEventMerger<R> | null;
|
||||
private mouseMoveCallback: IMouseMoveCallback<R> | null;
|
||||
private onStopCallback: IOnStopCallback | null;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
@ -69,7 +69,7 @@ export class GlobalMouseMoveMonitor<R> extends Disposable {
|
|||
let onStopCallback = this.onStopCallback;
|
||||
this.onStopCallback = null;
|
||||
|
||||
if (invokeStopCallback) {
|
||||
if (invokeStopCallback && onStopCallback) {
|
||||
onStopCallback();
|
||||
}
|
||||
}
|
||||
|
@ -94,8 +94,8 @@ export class GlobalMouseMoveMonitor<R> extends Disposable {
|
|||
let windowChain = IframeUtils.getSameOriginWindowChain();
|
||||
for (let i = 0; i < windowChain.length; i++) {
|
||||
this.hooks.push(dom.addDisposableThrottledListener(windowChain[i].window.document, 'mousemove',
|
||||
(data: R) => this.mouseMoveCallback(data),
|
||||
(lastEvent: R, currentEvent) => this.mouseMoveEventMerger(lastEvent, currentEvent as MouseEvent)
|
||||
(data: R) => this.mouseMoveCallback!(data),
|
||||
(lastEvent: R, currentEvent) => this.mouseMoveEventMerger!(lastEvent, currentEvent as MouseEvent)
|
||||
));
|
||||
this.hooks.push(dom.addDisposableListener(windowChain[i].window.document, 'mouseup', (e: MouseEvent) => this.stopMonitoring(true)));
|
||||
}
|
||||
|
|
|
@ -127,12 +127,12 @@ interface IGeckoMouseWheelEvent {
|
|||
|
||||
export class StandardMouseWheelEvent {
|
||||
|
||||
public readonly browserEvent: MouseWheelEvent;
|
||||
public readonly browserEvent: MouseWheelEvent | null;
|
||||
public readonly deltaY: number;
|
||||
public readonly deltaX: number;
|
||||
public readonly target: Node;
|
||||
|
||||
constructor(e: MouseWheelEvent, deltaX: number = 0, deltaY: number = 0) {
|
||||
constructor(e: MouseWheelEvent | null, deltaX: number = 0, deltaY: number = 0) {
|
||||
|
||||
this.browserEvent = e || null;
|
||||
this.target = e ? (e.target || (<any>e).targetNode || e.srcElement) : null;
|
||||
|
|
|
@ -28,7 +28,7 @@ interface TouchData {
|
|||
}
|
||||
|
||||
export interface GestureEvent extends MouseEvent {
|
||||
initialTarget: EventTarget;
|
||||
initialTarget: EventTarget | undefined;
|
||||
translationX: number;
|
||||
translationY: number;
|
||||
pageX: number;
|
||||
|
@ -71,7 +71,7 @@ export class Gesture extends Disposable {
|
|||
|
||||
private dispatched: boolean;
|
||||
private targets: HTMLElement[];
|
||||
private handle: IDisposable;
|
||||
private handle: IDisposable | null;
|
||||
|
||||
private activeTouches: { [id: number]: TouchData; };
|
||||
|
||||
|
|
|
@ -99,10 +99,10 @@ export class ContextView extends Disposable {
|
|||
private static readonly BUBBLE_UP_EVENTS = ['click', 'keydown', 'focus', 'blur'];
|
||||
private static readonly BUBBLE_DOWN_EVENTS = ['click'];
|
||||
|
||||
private container: HTMLElement;
|
||||
private container: HTMLElement | null;
|
||||
private view: HTMLElement;
|
||||
private delegate: IDelegate;
|
||||
private toDisposeOnClean: IDisposable;
|
||||
private delegate: IDelegate | null;
|
||||
private toDisposeOnClean: IDisposable | null;
|
||||
private toDisposeOnSetContainer: IDisposable;
|
||||
|
||||
constructor(container: HTMLElement) {
|
||||
|
@ -117,7 +117,7 @@ export class ContextView extends Disposable {
|
|||
this._register(toDisposable(() => this.setContainer(null)));
|
||||
}
|
||||
|
||||
public setContainer(container: HTMLElement): void {
|
||||
public setContainer(container: HTMLElement | null): void {
|
||||
if (this.container) {
|
||||
this.toDisposeOnSetContainer = dispose(this.toDisposeOnSetContainer);
|
||||
this.container.removeChild(this.view);
|
||||
|
@ -130,13 +130,13 @@ export class ContextView extends Disposable {
|
|||
const toDisposeOnSetContainer: IDisposable[] = [];
|
||||
|
||||
ContextView.BUBBLE_UP_EVENTS.forEach(event => {
|
||||
toDisposeOnSetContainer.push(DOM.addStandardDisposableListener(this.container, event, (e: Event) => {
|
||||
toDisposeOnSetContainer.push(DOM.addStandardDisposableListener(this.container!, event, (e: Event) => {
|
||||
this.onDOMEvent(e, <HTMLElement>document.activeElement, false);
|
||||
}));
|
||||
});
|
||||
|
||||
ContextView.BUBBLE_DOWN_EVENTS.forEach(event => {
|
||||
toDisposeOnSetContainer.push(DOM.addStandardDisposableListener(this.container, event, (e: Event) => {
|
||||
toDisposeOnSetContainer.push(DOM.addStandardDisposableListener(this.container!, event, (e: Event) => {
|
||||
this.onDOMEvent(e, <HTMLElement>document.activeElement, true);
|
||||
}, true));
|
||||
});
|
||||
|
@ -172,13 +172,13 @@ export class ContextView extends Disposable {
|
|||
return;
|
||||
}
|
||||
|
||||
if (this.delegate.canRelayout === false) {
|
||||
if (this.delegate!.canRelayout === false) {
|
||||
this.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.delegate.layout) {
|
||||
this.delegate.layout();
|
||||
if (this.delegate!.layout) {
|
||||
this.delegate!.layout!();
|
||||
}
|
||||
|
||||
this.doLayout();
|
||||
|
@ -191,7 +191,7 @@ export class ContextView extends Disposable {
|
|||
}
|
||||
|
||||
// Get anchor
|
||||
let anchor = this.delegate.getAnchor();
|
||||
let anchor = this.delegate!.getAnchor();
|
||||
|
||||
// Compute around
|
||||
let around: IView;
|
||||
|
@ -220,8 +220,8 @@ export class ContextView extends Disposable {
|
|||
const viewSizeWidth = DOM.getTotalWidth(this.view);
|
||||
const viewSizeHeight = DOM.getTotalHeight(this.view);
|
||||
|
||||
const anchorPosition = this.delegate.anchorPosition || AnchorPosition.BELOW;
|
||||
const anchorAlignment = this.delegate.anchorAlignment || AnchorAlignment.LEFT;
|
||||
const anchorPosition = this.delegate!.anchorPosition || AnchorPosition.BELOW;
|
||||
const anchorAlignment = this.delegate!.anchorAlignment || AnchorAlignment.LEFT;
|
||||
|
||||
const verticalAnchor: ILayoutAnchor = { offset: around.top, size: around.height, position: anchorPosition === AnchorPosition.BELOW ? LayoutAnchorPosition.Before : LayoutAnchorPosition.After };
|
||||
|
||||
|
@ -246,7 +246,7 @@ export class ContextView extends Disposable {
|
|||
DOM.addClass(this.view, anchorPosition === AnchorPosition.BELOW ? 'bottom' : 'top');
|
||||
DOM.addClass(this.view, anchorAlignment === AnchorAlignment.LEFT ? 'left' : 'right');
|
||||
|
||||
const containerPosition = DOM.getDomNodePagePosition(this.container);
|
||||
const containerPosition = DOM.getDomNodePagePosition(this.container!);
|
||||
this.view.style.top = `${top - containerPosition.top}px`;
|
||||
this.view.style.left = `${left - containerPosition.left}px`;
|
||||
this.view.style.width = 'initial';
|
||||
|
|
|
@ -5,29 +5,23 @@
|
|||
|
||||
import { GestureEvent } from 'vs/base/browser/touch';
|
||||
|
||||
export interface IVirtualDelegate<T> {
|
||||
export interface IListVirtualDelegate<T> {
|
||||
getHeight(element: T): number;
|
||||
getTemplateId(element: T): string;
|
||||
}
|
||||
|
||||
// TODO@joao rename to IListRenderer
|
||||
export interface IRenderer<TElement, TTemplateData> {
|
||||
export interface IListRenderer<T, TTemplateData> {
|
||||
templateId: string;
|
||||
renderTemplate(container: HTMLElement): TTemplateData;
|
||||
renderElement(element: TElement, index: number, templateData: TTemplateData): void;
|
||||
disposeElement(element: TElement, index: number, templateData: TTemplateData): void;
|
||||
renderElement(element: T, index: number, templateData: TTemplateData): void;
|
||||
disposeElement(element: T, index: number, templateData: TTemplateData): void;
|
||||
disposeTemplate(templateData: TTemplateData): void;
|
||||
}
|
||||
|
||||
export interface IListOpenEvent<T> {
|
||||
elements: T[];
|
||||
indexes: number[];
|
||||
browserEvent?: UIEvent;
|
||||
}
|
||||
|
||||
export interface IListEvent<T> {
|
||||
elements: T[];
|
||||
indexes: number[];
|
||||
browserEvent?: UIEvent;
|
||||
}
|
||||
|
||||
export interface IListMouseEvent<T> {
|
||||
|
@ -49,6 +43,7 @@ export interface IListGestureEvent<T> {
|
|||
}
|
||||
|
||||
export interface IListContextMenuEvent<T> {
|
||||
browserEvent: UIEvent;
|
||||
element: T;
|
||||
index: number;
|
||||
anchor: HTMLElement | { x: number; y: number; };
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
import 'vs/css!./list';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { range } from 'vs/base/common/arrays';
|
||||
import { IVirtualDelegate, IRenderer, IListEvent, IListOpenEvent, IListContextMenuEvent } from './list';
|
||||
import { IListVirtualDelegate, IListRenderer, IListEvent, IListContextMenuEvent } from './list';
|
||||
import { List, IListStyles, IListOptions } from './listWidget';
|
||||
import { IPagedModel } from 'vs/base/common/paging';
|
||||
import { Event, mapEvent } from 'vs/base/common/event';
|
||||
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
|
||||
export interface IPagedRenderer<TElement, TTemplateData> extends IRenderer<TElement, TTemplateData> {
|
||||
export interface IPagedRenderer<TElement, TTemplateData> extends IListRenderer<TElement, TTemplateData> {
|
||||
renderPlaceholder(index: number, templateData: TTemplateData): void;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ export interface ITemplateData<T> {
|
|||
disposable: IDisposable;
|
||||
}
|
||||
|
||||
class PagedRenderer<TElement, TTemplateData> implements IRenderer<number, ITemplateData<TTemplateData>> {
|
||||
class PagedRenderer<TElement, TTemplateData> implements IListRenderer<number, ITemplateData<TTemplateData>> {
|
||||
|
||||
get templateId(): string { return this.renderer.templateId; }
|
||||
|
||||
|
@ -71,7 +71,7 @@ export class PagedList<T> implements IDisposable {
|
|||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
virtualDelegate: IVirtualDelegate<number>,
|
||||
virtualDelegate: IListVirtualDelegate<number>,
|
||||
renderers: IPagedRenderer<T, any>[],
|
||||
options: IListOptions<any> = {}
|
||||
) {
|
||||
|
@ -111,7 +111,7 @@ export class PagedList<T> implements IDisposable {
|
|||
return mapEvent(this.list.onFocusChange, ({ elements, indexes }) => ({ elements: elements.map(e => this._model.get(e)), indexes }));
|
||||
}
|
||||
|
||||
get onOpen(): Event<IListOpenEvent<T>> {
|
||||
get onOpen(): Event<IListEvent<T>> {
|
||||
return mapEvent(this.list.onOpen, ({ elements, indexes, browserEvent }) => ({ elements: elements.map(e => this._model.get(e)), indexes, browserEvent }));
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ export class PagedList<T> implements IDisposable {
|
|||
}
|
||||
|
||||
get onContextMenu(): Event<IListContextMenuEvent<T>> {
|
||||
return mapEvent(this.list.onContextMenu, ({ element, index, anchor }) => ({ element: this._model.get(element), index, anchor }));
|
||||
return mapEvent(this.list.onContextMenu, ({ element, index, anchor, browserEvent }) => ({ element: this._model.get(element), index, anchor, browserEvent }));
|
||||
}
|
||||
|
||||
get model(): IPagedModel<T> {
|
||||
|
@ -164,14 +164,6 @@ export class PagedList<T> implements IDisposable {
|
|||
this.list.focusPrevious(n, loop);
|
||||
}
|
||||
|
||||
selectNext(n?: number, loop?: boolean): void {
|
||||
this.list.selectNext(n, loop);
|
||||
}
|
||||
|
||||
selectPrevious(n?: number, loop?: boolean): void {
|
||||
this.list.selectPrevious(n, loop);
|
||||
}
|
||||
|
||||
focusNextPage(): void {
|
||||
this.list.focusNextPage();
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import { domEvent } from 'vs/base/browser/event';
|
|||
import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
import { ScrollEvent, ScrollbarVisibility } from 'vs/base/common/scrollable';
|
||||
import { RangeMap, shift } from './rangeMap';
|
||||
import { IVirtualDelegate, IRenderer, IListMouseEvent, IListTouchEvent, IListGestureEvent } from './list';
|
||||
import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListTouchEvent, IListGestureEvent } from './list';
|
||||
import { RowCache, IRow } from './rowCache';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
|
@ -60,7 +60,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
private itemId: number;
|
||||
private rangeMap: RangeMap;
|
||||
private cache: RowCache<T>;
|
||||
private renderers = new Map<string, IRenderer<T, any>>();
|
||||
private renderers = new Map<string, IListRenderer<T, any>>();
|
||||
private lastRenderTop: number;
|
||||
private lastRenderHeight: number;
|
||||
private _domNode: HTMLElement;
|
||||
|
@ -78,8 +78,8 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
private virtualDelegate: IVirtualDelegate<T>,
|
||||
renderers: IRenderer<T, any>[],
|
||||
private virtualDelegate: IListVirtualDelegate<T>,
|
||||
renderers: IListRenderer<T, any>[],
|
||||
options: IListViewOptions = DefaultOptions
|
||||
) {
|
||||
this.items = [];
|
||||
|
|
|
@ -16,7 +16,7 @@ import { KeyCode } from 'vs/base/common/keyCodes';
|
|||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { Event, Emitter, EventBufferer, chain, mapEvent, anyEvent } from 'vs/base/common/event';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { IVirtualDelegate, IRenderer, IListEvent, IListContextMenuEvent, IListMouseEvent, IListTouchEvent, IListGestureEvent, IListOpenEvent } from './list';
|
||||
import { IListVirtualDelegate, IListRenderer, IListEvent, IListContextMenuEvent, IListMouseEvent, IListTouchEvent, IListGestureEvent } from './list';
|
||||
import { ListView, IListViewOptions } from './listView';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
|
@ -31,6 +31,7 @@ export interface IIdentityProvider<T> {
|
|||
|
||||
interface ITraitChangeEvent {
|
||||
indexes: number[];
|
||||
browserEvent?: UIEvent;
|
||||
}
|
||||
|
||||
type ITraitTemplateData = HTMLElement;
|
||||
|
@ -40,7 +41,7 @@ interface IRenderedContainer {
|
|||
index: number;
|
||||
}
|
||||
|
||||
class TraitRenderer<T> implements IRenderer<T, ITraitTemplateData>
|
||||
class TraitRenderer<T> implements IListRenderer<T, ITraitTemplateData>
|
||||
{
|
||||
private renderedElements: IRenderedContainer[] = [];
|
||||
|
||||
|
@ -159,14 +160,14 @@ class Trait<T> implements ISpliceable<boolean>, IDisposable {
|
|||
* @param indexes Indexes which should have this trait.
|
||||
* @return The old indexes which had this trait.
|
||||
*/
|
||||
set(indexes: number[]): number[] {
|
||||
set(indexes: number[], browserEvent?: UIEvent): number[] {
|
||||
const result = this.indexes;
|
||||
this.indexes = indexes;
|
||||
|
||||
const toRender = disjunction(result, indexes);
|
||||
this.renderer.renderIndexes(toRender);
|
||||
|
||||
this._onChange.fire({ indexes });
|
||||
this._onChange.fire({ indexes, browserEvent });
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -268,7 +269,7 @@ class KeyboardController<T> implements IDisposable {
|
|||
private onEnter(e: StandardKeyboardEvent): void {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.list.setSelection(this.list.getFocus());
|
||||
this.list.setSelection(this.list.getFocus(), e.browserEvent);
|
||||
|
||||
if (this.openController.shouldOpen(e.browserEvent)) {
|
||||
this.list.open(this.list.getFocus(), e.browserEvent);
|
||||
|
@ -278,7 +279,7 @@ class KeyboardController<T> implements IDisposable {
|
|||
private onUpArrow(e: StandardKeyboardEvent): void {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.list.focusPrevious();
|
||||
this.list.focusPrevious(1, false, e.browserEvent);
|
||||
this.list.reveal(this.list.getFocus()[0]);
|
||||
this.view.domNode.focus();
|
||||
}
|
||||
|
@ -286,7 +287,7 @@ class KeyboardController<T> implements IDisposable {
|
|||
private onDownArrow(e: StandardKeyboardEvent): void {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.list.focusNext();
|
||||
this.list.focusNext(1, false, e.browserEvent);
|
||||
this.list.reveal(this.list.getFocus()[0]);
|
||||
this.view.domNode.focus();
|
||||
}
|
||||
|
@ -294,7 +295,7 @@ class KeyboardController<T> implements IDisposable {
|
|||
private onPageUpArrow(e: StandardKeyboardEvent): void {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.list.focusPreviousPage();
|
||||
this.list.focusPreviousPage(e.browserEvent);
|
||||
this.list.reveal(this.list.getFocus()[0]);
|
||||
this.view.domNode.focus();
|
||||
}
|
||||
|
@ -302,7 +303,7 @@ class KeyboardController<T> implements IDisposable {
|
|||
private onPageDownArrow(e: StandardKeyboardEvent): void {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.list.focusNextPage();
|
||||
this.list.focusNextPage(e.browserEvent);
|
||||
this.list.reveal(this.list.getFocus()[0]);
|
||||
this.view.domNode.focus();
|
||||
}
|
||||
|
@ -310,14 +311,14 @@ class KeyboardController<T> implements IDisposable {
|
|||
private onCtrlA(e: StandardKeyboardEvent): void {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.list.setSelection(range(this.list.length));
|
||||
this.list.setSelection(range(this.list.length), e.browserEvent);
|
||||
this.view.domNode.focus();
|
||||
}
|
||||
|
||||
private onEscape(e: StandardKeyboardEvent): void {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.list.setSelection([]);
|
||||
this.list.setSelection([], e.browserEvent);
|
||||
this.view.domNode.focus();
|
||||
}
|
||||
|
||||
|
@ -417,7 +418,13 @@ class MouseController<T> implements IDisposable {
|
|||
.map(e => new StandardKeyboardEvent(e))
|
||||
.filter(e => this.didJustPressContextMenuKey = e.keyCode === KeyCode.ContextMenu || (e.shiftKey && e.keyCode === KeyCode.F10))
|
||||
.filter(e => { e.preventDefault(); e.stopPropagation(); return false; })
|
||||
.event as Event<any>;
|
||||
.map(event => {
|
||||
const index = this.list.getFocus()[0];
|
||||
const element = this.view.element(index);
|
||||
const anchor = this.view.domElement(index);
|
||||
return { index, element, anchor, browserEvent: event.browserEvent };
|
||||
})
|
||||
.event;
|
||||
|
||||
const fromKeyup = chain(domEvent(this.view.domNode, 'keyup'))
|
||||
.filter(() => {
|
||||
|
@ -426,18 +433,18 @@ class MouseController<T> implements IDisposable {
|
|||
return didJustPressContextMenuKey;
|
||||
})
|
||||
.filter(() => this.list.getFocus().length > 0)
|
||||
.map(() => {
|
||||
.map(browserEvent => {
|
||||
const index = this.list.getFocus()[0];
|
||||
const element = this.view.element(index);
|
||||
const anchor = this.view.domElement(index);
|
||||
return { index, element, anchor };
|
||||
return { index, element, anchor, browserEvent };
|
||||
})
|
||||
.filter(({ anchor }) => !!anchor)
|
||||
.event;
|
||||
|
||||
const fromMouse = chain(this.view.onContextMenu)
|
||||
.filter(() => !this.didJustPressContextMenuKey)
|
||||
.map(({ element, index, browserEvent }) => ({ element, index, anchor: { x: browserEvent.clientX + 1, y: browserEvent.clientY } }))
|
||||
.map(({ element, index, browserEvent }) => ({ element, index, anchor: { x: browserEvent.clientX + 1, y: browserEvent.clientY }, browserEvent }))
|
||||
.event;
|
||||
|
||||
return anyEvent<IListContextMenuEvent<T>>(fromKeydown, fromKeyup, fromMouse);
|
||||
|
@ -502,7 +509,7 @@ class MouseController<T> implements IDisposable {
|
|||
|
||||
const focus = e.index;
|
||||
if (selection.every(s => s !== focus)) {
|
||||
this.list.setFocus([focus]);
|
||||
this.list.setFocus([focus], e.browserEvent);
|
||||
}
|
||||
|
||||
if (this.multipleSelectionSupport && this.isSelectionChangeEvent(e)) {
|
||||
|
@ -510,7 +517,7 @@ class MouseController<T> implements IDisposable {
|
|||
}
|
||||
|
||||
if (this.options.selectOnMouseDown && !isMouseRightClick(e.browserEvent)) {
|
||||
this.list.setSelection([focus]);
|
||||
this.list.setSelection([focus], e.browserEvent);
|
||||
|
||||
if (this.openController.shouldOpen(e.browserEvent)) {
|
||||
this.list.open([focus], e.browserEvent);
|
||||
|
@ -525,7 +532,7 @@ class MouseController<T> implements IDisposable {
|
|||
|
||||
if (!this.options.selectOnMouseDown) {
|
||||
const focus = this.list.getFocus();
|
||||
this.list.setSelection(focus);
|
||||
this.list.setSelection(focus, e.browserEvent);
|
||||
|
||||
if (this.openController.shouldOpen(e.browserEvent)) {
|
||||
this.list.open(focus, e.browserEvent);
|
||||
|
@ -539,7 +546,7 @@ class MouseController<T> implements IDisposable {
|
|||
}
|
||||
|
||||
const focus = this.list.getFocus();
|
||||
this.list.setSelection(focus);
|
||||
this.list.setSelection(focus, e.browserEvent);
|
||||
this.list.pin(focus);
|
||||
}
|
||||
|
||||
|
@ -558,16 +565,16 @@ class MouseController<T> implements IDisposable {
|
|||
}
|
||||
|
||||
const newSelection = disjunction(rangeSelection, relativeComplement(selection, contiguousRange));
|
||||
this.list.setSelection(newSelection);
|
||||
this.list.setSelection(newSelection, e.browserEvent);
|
||||
|
||||
} else if (this.isSelectionSingleChangeEvent(e)) {
|
||||
const selection = this.list.getSelection();
|
||||
const newSelection = selection.filter(i => i !== focus);
|
||||
|
||||
if (selection.length === newSelection.length) {
|
||||
this.list.setSelection([...newSelection, focus]);
|
||||
this.list.setSelection([...newSelection, focus], e.browserEvent);
|
||||
} else {
|
||||
this.list.setSelection(newSelection);
|
||||
this.list.setSelection(newSelection, e.browserEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -800,11 +807,11 @@ function relativeComplement(one: number[], other: number[]): number[] {
|
|||
|
||||
const numericSort = (a: number, b: number) => a - b;
|
||||
|
||||
class PipelineRenderer<T> implements IRenderer<T, any> {
|
||||
class PipelineRenderer<T> implements IListRenderer<T, any> {
|
||||
|
||||
constructor(
|
||||
private _templateId: string,
|
||||
private renderers: IRenderer<T, any>[]
|
||||
private renderers: IListRenderer<T, any>[]
|
||||
) { }
|
||||
|
||||
get templateId(): string {
|
||||
|
@ -865,8 +872,8 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
|||
|
||||
readonly onContextMenu: Event<IListContextMenuEvent<T>> = Event.None;
|
||||
|
||||
private _onOpen = new Emitter<IListOpenEvent<T>>();
|
||||
readonly onOpen: Event<IListOpenEvent<T>> = this._onOpen.event;
|
||||
private _onOpen = new Emitter<IListEvent<T>>();
|
||||
readonly onOpen: Event<IListEvent<T>> = this._onOpen.event;
|
||||
|
||||
private _onPin = new Emitter<number[]>();
|
||||
@memoize get onPin(): Event<IListEvent<T>> {
|
||||
|
@ -896,8 +903,8 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
|||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
virtualDelegate: IVirtualDelegate<T>,
|
||||
renderers: IRenderer<T, any>[],
|
||||
virtualDelegate: IListVirtualDelegate<T>,
|
||||
renderers: IListRenderer<T, any>[],
|
||||
options: IListOptions<T> = DefaultOptions
|
||||
) {
|
||||
this.focus = new FocusTrait(i => this.getElementDomId(i));
|
||||
|
@ -993,7 +1000,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
|||
this.view.layout(height);
|
||||
}
|
||||
|
||||
setSelection(indexes: number[]): void {
|
||||
setSelection(indexes: number[], browserEvent?: UIEvent): void {
|
||||
for (const index of indexes) {
|
||||
if (index < 0 || index >= this.length) {
|
||||
throw new Error(`Invalid index ${index}`);
|
||||
|
@ -1001,24 +1008,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
|||
}
|
||||
|
||||
indexes = indexes.sort(numericSort);
|
||||
this.selection.set(indexes);
|
||||
}
|
||||
|
||||
selectNext(n = 1, loop = false): void {
|
||||
if (this.length === 0) { return; }
|
||||
const selection = this.selection.get();
|
||||
let index = selection.length > 0 ? selection[0] + n : 0;
|
||||
this.setSelection(loop ? [index % this.length] : [Math.min(index, this.length - 1)]);
|
||||
}
|
||||
|
||||
selectPrevious(n = 1, loop = false): void {
|
||||
if (this.length === 0) { return; }
|
||||
const selection = this.selection.get();
|
||||
let index = selection.length > 0 ? selection[0] - n : 0;
|
||||
if (loop && index < 0) {
|
||||
index = this.length + (index % this.length);
|
||||
}
|
||||
this.setSelection([Math.max(index, 0)]);
|
||||
this.selection.set(indexes, browserEvent);
|
||||
}
|
||||
|
||||
getSelection(): number[] {
|
||||
|
@ -1029,7 +1019,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
|||
return this.getSelection().map(i => this.view.element(i));
|
||||
}
|
||||
|
||||
setFocus(indexes: number[]): void {
|
||||
setFocus(indexes: number[], browserEvent?: UIEvent): void {
|
||||
for (const index of indexes) {
|
||||
if (index < 0 || index >= this.length) {
|
||||
throw new Error(`Invalid index ${index}`);
|
||||
|
@ -1037,17 +1027,17 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
|||
}
|
||||
|
||||
indexes = indexes.sort(numericSort);
|
||||
this.focus.set(indexes);
|
||||
this.focus.set(indexes, browserEvent);
|
||||
}
|
||||
|
||||
focusNext(n = 1, loop = false): void {
|
||||
focusNext(n = 1, loop = false, browserEvent?: UIEvent): void {
|
||||
if (this.length === 0) { return; }
|
||||
const focus = this.focus.get();
|
||||
let index = focus.length > 0 ? focus[0] + n : 0;
|
||||
this.setFocus(loop ? [index % this.length] : [Math.min(index, this.length - 1)]);
|
||||
}
|
||||
|
||||
focusPrevious(n = 1, loop = false): void {
|
||||
focusPrevious(n = 1, loop = false, browserEvent?: UIEvent): void {
|
||||
if (this.length === 0) { return; }
|
||||
const focus = this.focus.get();
|
||||
let index = focus.length > 0 ? focus[0] - n : 0;
|
||||
|
@ -1055,7 +1045,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
|||
this.setFocus([Math.max(index, 0)]);
|
||||
}
|
||||
|
||||
focusNextPage(): void {
|
||||
focusNextPage(browserEvent?: UIEvent): void {
|
||||
let lastPageIndex = this.view.indexAt(this.view.getScrollTop() + this.view.renderHeight);
|
||||
lastPageIndex = lastPageIndex === 0 ? 0 : lastPageIndex - 1;
|
||||
const lastPageElement = this.view.element(lastPageIndex);
|
||||
|
@ -1074,7 +1064,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
|||
}
|
||||
}
|
||||
|
||||
focusPreviousPage(): void {
|
||||
focusPreviousPage(browserEvent?: UIEvent): void {
|
||||
let firstPageIndex: number;
|
||||
const scrollTop = this.view.getScrollTop();
|
||||
|
||||
|
@ -1100,12 +1090,12 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
|||
}
|
||||
}
|
||||
|
||||
focusLast(): void {
|
||||
focusLast(browserEvent?: UIEvent): void {
|
||||
if (this.length === 0) { return; }
|
||||
this.setFocus([this.length - 1]);
|
||||
}
|
||||
|
||||
focusFirst(): void {
|
||||
focusFirst(browserEvent?: UIEvent): void {
|
||||
if (this.length === 0) { return; }
|
||||
this.setFocus([0]);
|
||||
}
|
||||
|
@ -1201,8 +1191,8 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
|||
this.styleController.style(styles);
|
||||
}
|
||||
|
||||
private toListEvent({ indexes }: ITraitChangeEvent) {
|
||||
return { indexes, elements: indexes.map(i => this.view.element(i)) };
|
||||
private toListEvent({ indexes, browserEvent }: ITraitChangeEvent) {
|
||||
return { indexes, elements: indexes.map(i => this.view.element(i)), browserEvent };
|
||||
}
|
||||
|
||||
private _onFocusChange(): void {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IRenderer } from './list';
|
||||
import { IListRenderer } from './list';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { $, removeClass } from 'vs/base/browser/dom';
|
||||
|
||||
|
@ -25,7 +25,7 @@ export class RowCache<T> implements IDisposable {
|
|||
|
||||
private cache = new Map<string, IRow[]>();
|
||||
|
||||
constructor(private renderers: Map<string, IRenderer<T, any>>) { }
|
||||
constructor(private renderers: Map<string, IListRenderer<T, any>>) { }
|
||||
|
||||
/**
|
||||
* Returns a row either by creating a new one or reusing
|
||||
|
|
|
@ -86,14 +86,18 @@ export abstract class AbstractScrollbar extends Widget {
|
|||
/**
|
||||
* Creates the slider dom node, adds it to the container & hooks up the events
|
||||
*/
|
||||
protected _createSlider(top: number, left: number, width: number, height: number): void {
|
||||
protected _createSlider(top: number, left: number, width: number | undefined, height: number | undefined): void {
|
||||
this.slider = createFastDomNode(document.createElement('div'));
|
||||
this.slider.setClassName('slider');
|
||||
this.slider.setPosition('absolute');
|
||||
this.slider.setTop(top);
|
||||
this.slider.setLeft(left);
|
||||
this.slider.setWidth(width);
|
||||
this.slider.setHeight(height);
|
||||
if (typeof width === 'number') {
|
||||
this.slider.setWidth(width);
|
||||
}
|
||||
if (typeof height === 'number') {
|
||||
this.slider.setHeight(height);
|
||||
}
|
||||
this.slider.setLayerHinting(true);
|
||||
|
||||
this.domNode.domNode.appendChild(this.slider.domNode);
|
||||
|
|
|
@ -53,7 +53,7 @@ export class HorizontalScrollbar extends AbstractScrollbar {
|
|||
});
|
||||
}
|
||||
|
||||
this._createSlider(Math.floor((options.horizontalScrollbarSize - options.horizontalSliderSize) / 2), 0, null, options.horizontalSliderSize);
|
||||
this._createSlider(Math.floor((options.horizontalScrollbarSize - options.horizontalSliderSize) / 2), 0, undefined, options.horizontalSliderSize);
|
||||
}
|
||||
|
||||
protected _updateSlider(sliderSize: number, sliderPosition: number): void {
|
||||
|
|
|
@ -167,7 +167,7 @@ export abstract class AbstractScrollableElement extends Widget {
|
|||
private readonly _onScroll = this._register(new Emitter<ScrollEvent>());
|
||||
public readonly onScroll: Event<ScrollEvent> = this._onScroll.event;
|
||||
|
||||
protected constructor(element: HTMLElement, options: ScrollableElementCreationOptions, scrollable?: Scrollable) {
|
||||
protected constructor(element: HTMLElement, options: ScrollableElementCreationOptions, scrollable: Scrollable) {
|
||||
super();
|
||||
element.style.overflow = 'hidden';
|
||||
this._options = resolveOptions(options);
|
||||
|
|
|
@ -120,7 +120,7 @@ export interface ScrollableElementResolvedOptions {
|
|||
mouseWheelScrollSensitivity: number;
|
||||
mouseWheelSmoothScroll: boolean;
|
||||
arrowSize: number;
|
||||
listenOnDomNode: HTMLElement;
|
||||
listenOnDomNode: HTMLElement | null;
|
||||
horizontal: ScrollbarVisibility;
|
||||
horizontalScrollbarSize: number;
|
||||
horizontalSliderSize: number;
|
||||
|
|
|
@ -12,7 +12,7 @@ export class ScrollbarVisibilityController extends Disposable {
|
|||
private _visibility: ScrollbarVisibility;
|
||||
private _visibleClassName: string;
|
||||
private _invisibleClassName: string;
|
||||
private _domNode: FastDomNode<HTMLElement>;
|
||||
private _domNode: FastDomNode<HTMLElement> | null;
|
||||
private _shouldBeVisible: boolean;
|
||||
private _isNeeded: boolean;
|
||||
private _isVisible: boolean;
|
||||
|
@ -89,7 +89,9 @@ export class ScrollbarVisibilityController extends Disposable {
|
|||
|
||||
// The CSS animation doesn't play otherwise
|
||||
this._revealTimer.setIfNotSet(() => {
|
||||
this._domNode.setClassName(this._visibleClassName);
|
||||
if (this._domNode) {
|
||||
this._domNode.setClassName(this._visibleClassName);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
|
@ -99,6 +101,8 @@ export class ScrollbarVisibilityController extends Disposable {
|
|||
return;
|
||||
}
|
||||
this._isVisible = false;
|
||||
this._domNode.setClassName(this._invisibleClassName + (withFadeAway ? ' fade' : ''));
|
||||
if (this._domNode) {
|
||||
this._domNode.setClassName(this._invisibleClassName + (withFadeAway ? ' fade' : ''));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -54,7 +54,7 @@ export class VerticalScrollbar extends AbstractScrollbar {
|
|||
});
|
||||
}
|
||||
|
||||
this._createSlider(0, Math.floor((options.verticalScrollbarSize - options.verticalSliderSize) / 2), options.verticalSliderSize, null);
|
||||
this._createSlider(0, Math.floor((options.verticalScrollbarSize - options.verticalSliderSize) / 2), options.verticalSliderSize, undefined);
|
||||
}
|
||||
|
||||
protected _updateSlider(sliderSize: number, sliderPosition: number): void {
|
||||
|
|
|
@ -13,7 +13,7 @@ import * as dom from 'vs/base/browser/dom';
|
|||
import * as arrays from 'vs/base/common/arrays';
|
||||
import { IContextViewProvider, AnchorPosition } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { List } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { IVirtualDelegate, IRenderer, IListEvent } from 'vs/base/browser/ui/list/list';
|
||||
import { IListVirtualDelegate, IListRenderer, IListEvent } from 'vs/base/browser/ui/list/list';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
|
||||
import { ISelectBoxDelegate, ISelectBoxOptions, ISelectBoxStyles, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
|
||||
|
@ -37,7 +37,7 @@ interface ISelectListTemplateData {
|
|||
disposables: IDisposable[];
|
||||
}
|
||||
|
||||
class SelectListRenderer implements IRenderer<ISelectOptionItem, ISelectListTemplateData> {
|
||||
class SelectListRenderer implements IListRenderer<ISelectOptionItem, ISelectListTemplateData> {
|
||||
|
||||
get templateId(): string { return SELECT_OPTION_ENTRY_TEMPLATE_ID; }
|
||||
|
||||
|
@ -86,7 +86,7 @@ class SelectListRenderer implements IRenderer<ISelectOptionItem, ISelectListTemp
|
|||
}
|
||||
}
|
||||
|
||||
export class SelectBoxList implements ISelectBoxDelegate, IVirtualDelegate<ISelectOptionItem> {
|
||||
export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<ISelectOptionItem> {
|
||||
|
||||
private static readonly DEFAULT_DROPDOWN_MINIMUM_BOTTOM_MARGIN = 32;
|
||||
private static readonly DEFAULT_DROPDOWN_MINIMUM_TOP_MARGIN = 2;
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
|
||||
import 'vs/css!./tree';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IListOptions, List, IIdentityProvider, IMultipleSelectionController } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { IVirtualDelegate, IRenderer, IListMouseEvent } from 'vs/base/browser/ui/list/list';
|
||||
import { IListOptions, List, IIdentityProvider, IMultipleSelectionController, IListStyles } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListEvent, IListContextMenuEvent } from 'vs/base/browser/ui/list/list';
|
||||
import { append, $ } from 'vs/base/browser/dom';
|
||||
import { Event, Relay, chain } from 'vs/base/common/event';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { ITreeModel, ITreeNode } from 'vs/base/browser/ui/tree/tree';
|
||||
import { ITreeModel, ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
|
||||
import { ISpliceable } from 'vs/base/common/sequence';
|
||||
import { IIndexTreeModelOptions } from 'vs/base/browser/ui/tree/indexTreeModel';
|
||||
|
||||
|
@ -45,9 +45,9 @@ export function createComposedTreeListOptions<T, N extends { element: T }>(optio
|
|||
};
|
||||
}
|
||||
|
||||
export class ComposedTreeDelegate<T, N extends { element: T }> implements IVirtualDelegate<N> {
|
||||
export class ComposedTreeDelegate<T, N extends { element: T }> implements IListVirtualDelegate<N> {
|
||||
|
||||
constructor(private delegate: IVirtualDelegate<T>) { }
|
||||
constructor(private delegate: IListVirtualDelegate<T>) { }
|
||||
|
||||
getHeight(element: N): number {
|
||||
return this.delegate.getHeight(element.element);
|
||||
|
@ -71,12 +71,7 @@ function renderDefaultTwistie<T>(node: ITreeNode<T, any>, twistie: HTMLElement):
|
|||
}
|
||||
}
|
||||
|
||||
export interface ITreeRenderer<TElement, TTemplateData> extends IRenderer<TElement, TTemplateData> {
|
||||
renderTwistie?(element: TElement, twistieElement: HTMLElement): boolean;
|
||||
onDidChangeTwistieState?: Event<TElement>;
|
||||
}
|
||||
|
||||
class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode<T, TFilterData>, ITreeListTemplateData<TTemplateData>> {
|
||||
class TreeRenderer<T, TFilterData, TTemplateData> implements IListRenderer<ITreeNode<T, TFilterData>, ITreeListTemplateData<TTemplateData>> {
|
||||
|
||||
readonly templateId: string;
|
||||
private renderedElements = new Map<T, ITreeNode<T, TFilterData>>();
|
||||
|
@ -84,7 +79,7 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode
|
|||
private disposables: IDisposable[] = [];
|
||||
|
||||
constructor(
|
||||
private renderer: ITreeRenderer<T, TTemplateData>,
|
||||
private renderer: ITreeRenderer<T, TFilterData, TTemplateData>,
|
||||
onDidChangeCollapseState: Event<ITreeNode<T, TFilterData>>
|
||||
) {
|
||||
this.templateId = renderer.templateId;
|
||||
|
@ -98,8 +93,8 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode
|
|||
|
||||
renderTemplate(container: HTMLElement): ITreeListTemplateData<TTemplateData> {
|
||||
const el = append(container, $('.monaco-tl-row'));
|
||||
const twistie = append(el, $('.tl-twistie'));
|
||||
const contents = append(el, $('.tl-contents'));
|
||||
const twistie = append(el, $('.monaco-tl-twistie'));
|
||||
const contents = append(el, $('.monaco-tl-contents'));
|
||||
const templateData = this.renderer.renderTemplate(contents);
|
||||
|
||||
return { twistie, templateData };
|
||||
|
@ -112,11 +107,11 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode
|
|||
templateData.twistie.style.width = `${10 + node.depth * 10}px`;
|
||||
this.renderTwistie(node, templateData.twistie);
|
||||
|
||||
this.renderer.renderElement(node.element, index, templateData.templateData);
|
||||
this.renderer.renderElement(node, index, templateData.templateData);
|
||||
}
|
||||
|
||||
disposeElement(node: ITreeNode<T, TFilterData>, index: number, templateData: ITreeListTemplateData<TTemplateData>): void {
|
||||
this.renderer.disposeElement(node.element, index, templateData.templateData);
|
||||
this.renderer.disposeElement(node, index, templateData.templateData);
|
||||
this.renderedNodes.delete(node);
|
||||
this.renderedElements.set(node.element);
|
||||
}
|
||||
|
@ -165,6 +160,8 @@ function isInputElement(e: HTMLElement): boolean {
|
|||
}
|
||||
|
||||
export interface ITreeOptions<T, TFilterData = void> extends IListOptions<T>, IIndexTreeModelOptions<T, TFilterData> { }
|
||||
export interface ITreeEvent<T, TFilterData> extends IListEvent<ITreeNode<T, TFilterData>> { }
|
||||
export interface ITreeContextMenuEvent<T, TFilterData> extends IListContextMenuEvent<ITreeNode<T, TFilterData>> { }
|
||||
|
||||
export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable {
|
||||
|
||||
|
@ -173,11 +170,20 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
|
|||
protected disposables: IDisposable[] = [];
|
||||
|
||||
readonly onDidChangeCollapseState: Event<ITreeNode<T, TFilterData>>;
|
||||
readonly onDidChangeRenderNodeCount: Event<ITreeNode<T, TFilterData>>;
|
||||
readonly onDidChangeFocus: Event<ITreeEvent<T, TFilterData>>;
|
||||
readonly onDidChangeSelection: Event<ITreeEvent<T, TFilterData>>;
|
||||
|
||||
readonly onContextMenu: Event<ITreeContextMenuEvent<T, TFilterData>>;
|
||||
|
||||
get onDidFocus(): Event<void> { return this.view.onDidFocus; }
|
||||
get onDidBlur(): Event<void> { return this.view.onDidBlur; }
|
||||
get onDidDispose(): Event<void> { return this.view.onDidDispose; }
|
||||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
delegate: IVirtualDelegate<T>,
|
||||
renderers: ITreeRenderer<T, any>[],
|
||||
delegate: IListVirtualDelegate<T>,
|
||||
renderers: ITreeRenderer<T, TFilterData, any>[],
|
||||
options?: ITreeOptions<T, TFilterData>
|
||||
) {
|
||||
const treeDelegate = new ComposedTreeDelegate<T, ITreeNode<T, TFilterData>>(delegate);
|
||||
|
@ -187,9 +193,14 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
|
|||
this.disposables.push(...treeRenderers);
|
||||
|
||||
this.view = new List(container, treeDelegate, treeRenderers, createComposedTreeListOptions<T, ITreeNode<T, TFilterData>>(options));
|
||||
this.onDidChangeFocus = this.view.onFocusChange;
|
||||
this.onDidChangeSelection = this.view.onSelectionChange;
|
||||
this.onContextMenu = this.view.onContextMenu;
|
||||
|
||||
this.model = this.createModel(this.view, options);
|
||||
onDidChangeCollapseStateRelay.input = this.model.onDidChangeCollapseState;
|
||||
this.onDidChangeCollapseState = this.model.onDidChangeCollapseState;
|
||||
this.onDidChangeRenderNodeCount = this.model.onDidChangeRenderNodeCount;
|
||||
|
||||
this.view.onMouseClick(this.onMouseClick, this, this.disposables);
|
||||
|
||||
|
@ -202,10 +213,42 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
|
|||
onKeyDown.filter(e => e.keyCode === KeyCode.Space).on(this.onSpace, this, this.disposables);
|
||||
}
|
||||
|
||||
protected abstract createModel(view: ISpliceable<ITreeNode<T, TFilterData>>, options: ITreeOptions<T, TFilterData>): ITreeModel<T, TFilterData, TRef>;
|
||||
// Widget
|
||||
|
||||
refilter(): void {
|
||||
this.model.refilter();
|
||||
getHTMLElement(): HTMLElement {
|
||||
return this.view.getHTMLElement();
|
||||
}
|
||||
|
||||
domFocus(): void {
|
||||
this.view.domFocus();
|
||||
}
|
||||
|
||||
layout(height?: number): void {
|
||||
this.view.layout(height);
|
||||
}
|
||||
|
||||
style(styles: IListStyles): void {
|
||||
this.view.style(styles);
|
||||
}
|
||||
|
||||
// Tree navigation
|
||||
|
||||
getParentElement(ref: TRef | null = null): T | null {
|
||||
return this.model.getParentElement(ref);
|
||||
}
|
||||
|
||||
getFirstElementChild(ref: TRef | null = null): T | null {
|
||||
return this.model.getFirstElementChild(ref);
|
||||
}
|
||||
|
||||
getLastElementAncestor(ref: TRef | null = null): T | null {
|
||||
return this.model.getLastElementAncestor(ref);
|
||||
}
|
||||
|
||||
// Tree
|
||||
|
||||
getNode(location?: TRef): ITreeNode<T, TFilterData> {
|
||||
return this.model.getNode(location);
|
||||
}
|
||||
|
||||
collapse(location: TRef): boolean {
|
||||
|
@ -216,6 +259,89 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
|
|||
return this.model.setCollapsed(location, false);
|
||||
}
|
||||
|
||||
toggleCollapsed(ref: TRef): void {
|
||||
this.model.toggleCollapsed(ref);
|
||||
}
|
||||
|
||||
collapseAll(): void {
|
||||
this.model.collapseAll();
|
||||
}
|
||||
|
||||
isCollapsed(ref: TRef): boolean {
|
||||
return this.model.isCollapsed(ref);
|
||||
}
|
||||
|
||||
isExpanded(ref: TRef): boolean {
|
||||
return !this.isCollapsed(ref);
|
||||
}
|
||||
|
||||
refilter(): void {
|
||||
this.model.refilter();
|
||||
}
|
||||
|
||||
setSelection(elements: TRef[], browserEvent?: UIEvent): void {
|
||||
const indexes = elements.map(e => this.model.getListIndex(e));
|
||||
this.view.setSelection(indexes, browserEvent);
|
||||
}
|
||||
|
||||
getSelection(): T[] {
|
||||
const nodes = this.view.getSelectedElements();
|
||||
return nodes.map(n => n.element);
|
||||
}
|
||||
|
||||
setFocus(elements: TRef[]): void {
|
||||
const indexes = elements.map(e => this.model.getListIndex(e));
|
||||
this.view.setFocus(indexes);
|
||||
}
|
||||
|
||||
focusNext(n = 1, loop = false): void {
|
||||
this.view.focusNext(n, loop);
|
||||
}
|
||||
|
||||
focusPrevious(n = 1, loop = false): void {
|
||||
this.view.focusPrevious(n, loop);
|
||||
}
|
||||
|
||||
focusNextPage(): void {
|
||||
this.view.focusNextPage();
|
||||
}
|
||||
|
||||
focusPreviousPage(): void {
|
||||
this.view.focusPreviousPage();
|
||||
}
|
||||
|
||||
focusLast(): void {
|
||||
this.view.focusLast();
|
||||
}
|
||||
|
||||
focusFirst(): void {
|
||||
this.view.focusFirst();
|
||||
}
|
||||
|
||||
getFocus(): T[] {
|
||||
const nodes = this.view.getFocusedElements();
|
||||
return nodes.map(n => n.element);
|
||||
}
|
||||
|
||||
open(elements: TRef[]): void {
|
||||
const indexes = elements.map(e => this.model.getListIndex(e));
|
||||
this.view.open(indexes);
|
||||
}
|
||||
|
||||
reveal(location: TRef, relativeTop?: number): void {
|
||||
const index = this.model.getListIndex(location);
|
||||
this.view.reveal(index, relativeTop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the relative position of an element rendered in the list.
|
||||
* Returns `null` if the element isn't *entirely* in the visible viewport.
|
||||
*/
|
||||
getRelativeTop(location: TRef): number | null {
|
||||
const index = this.model.getListIndex(location);
|
||||
return this.view.getRelativeTop(index);
|
||||
}
|
||||
|
||||
private onMouseClick(e: IListMouseEvent<ITreeNode<T, TFilterData>>): void {
|
||||
const node = e.element;
|
||||
const location = this.model.getNodeLocation(node);
|
||||
|
@ -293,6 +419,8 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
|
|||
this.model.toggleCollapsed(location);
|
||||
}
|
||||
|
||||
protected abstract createModel(view: ISpliceable<ITreeNode<T, TFilterData>>, options: ITreeOptions<T, TFilterData>): ITreeModel<T, TFilterData, TRef>;
|
||||
|
||||
dispose(): void {
|
||||
this.disposables = dispose(this.disposables);
|
||||
this.view.dispose();
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ITreeOptions, ComposedTreeDelegate, createComposedTreeListOptions, ITreeRenderer } from 'vs/base/browser/ui/tree/abstractTree';
|
||||
import { ITreeOptions, ComposedTreeDelegate, createComposedTreeListOptions } from 'vs/base/browser/ui/tree/abstractTree';
|
||||
import { ObjectTree } from 'vs/base/browser/ui/tree/objectTree';
|
||||
import { IVirtualDelegate, IRenderer } from 'vs/base/browser/ui/list/list';
|
||||
import { ITreeElement, ITreeNode } from 'vs/base/browser/ui/tree/tree';
|
||||
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
||||
import { ITreeElement, ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
|
@ -39,14 +39,25 @@ interface IDataTreeListTemplateData<T> {
|
|||
templateData: T;
|
||||
}
|
||||
|
||||
class DataTreeRenderer<T, TTemplateData> implements ITreeRenderer<IDataTreeNode<T>, IDataTreeListTemplateData<TTemplateData>> {
|
||||
function unpack<T, TFilterData>(node: ITreeNode<IDataTreeNode<T>, TFilterData>): ITreeNode<T, TFilterData> {
|
||||
return new Proxy(Object.create(null), {
|
||||
get: (_: any, name: string) => {
|
||||
switch (name) {
|
||||
case 'element': return node.element.element;
|
||||
default: return node[name];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class DataTreeRenderer<T, TFilterData, TTemplateData> implements ITreeRenderer<IDataTreeNode<T>, TFilterData, IDataTreeListTemplateData<TTemplateData>> {
|
||||
|
||||
readonly templateId: string;
|
||||
private renderedNodes = new Map<IDataTreeNode<T>, IDataTreeListTemplateData<TTemplateData>>();
|
||||
private disposables: IDisposable[] = [];
|
||||
|
||||
constructor(
|
||||
private renderer: IRenderer<T, TTemplateData>,
|
||||
private renderer: ITreeRenderer<T, TFilterData, TTemplateData>,
|
||||
readonly onDidChangeTwistieState: Event<IDataTreeNode<T>>
|
||||
) {
|
||||
this.templateId = renderer.templateId;
|
||||
|
@ -57,8 +68,8 @@ class DataTreeRenderer<T, TTemplateData> implements ITreeRenderer<IDataTreeNode<
|
|||
return { templateData };
|
||||
}
|
||||
|
||||
renderElement(node: IDataTreeNode<T>, index: number, templateData: IDataTreeListTemplateData<TTemplateData>): void {
|
||||
this.renderer.renderElement(node.element, index, templateData.templateData);
|
||||
renderElement(element: ITreeNode<IDataTreeNode<T>, TFilterData>, index: number, templateData: IDataTreeListTemplateData<TTemplateData>): void {
|
||||
this.renderer.renderElement(unpack(element), index, templateData.templateData);
|
||||
}
|
||||
|
||||
renderTwistie(element: IDataTreeNode<T>, twistieElement: HTMLElement): boolean {
|
||||
|
@ -70,8 +81,8 @@ class DataTreeRenderer<T, TTemplateData> implements ITreeRenderer<IDataTreeNode<
|
|||
return false;
|
||||
}
|
||||
|
||||
disposeElement(node: IDataTreeNode<T>, index: number, templateData: IDataTreeListTemplateData<TTemplateData>): void {
|
||||
this.renderer.disposeElement(node.element, index, templateData.templateData);
|
||||
disposeElement(element: ITreeNode<IDataTreeNode<T>, TFilterData>, index: number, templateData: IDataTreeListTemplateData<TTemplateData>): void {
|
||||
this.renderer.disposeElement(unpack(element), index, templateData.templateData);
|
||||
}
|
||||
|
||||
disposeTemplate(templateData: IDataTreeListTemplateData<TTemplateData>): void {
|
||||
|
@ -96,8 +107,8 @@ export class DataTree<T extends NonNullable<any>, TFilterData = void> implements
|
|||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
delegate: IVirtualDelegate<T>,
|
||||
renderers: ITreeRenderer<T, any>[],
|
||||
delegate: IListVirtualDelegate<T>,
|
||||
renderers: ITreeRenderer<T, TFilterData, any>[],
|
||||
private dataSource: IDataSource<T>,
|
||||
options?: ITreeOptions<T, TFilterData>
|
||||
) {
|
||||
|
|
|
@ -5,21 +5,21 @@
|
|||
|
||||
import { ISpliceable } from 'vs/base/common/sequence';
|
||||
import { Iterator, ISequence } from 'vs/base/common/iterator';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Emitter, Event, EventBufferer } from 'vs/base/common/event';
|
||||
import { tail2 } from 'vs/base/common/arrays';
|
||||
import { ITreeFilterResult, TreeVisibility, ITreeFilter, ITreeOptions, ITreeModel, ITreeNode, ITreeElement } from 'vs/base/browser/ui/tree/tree';
|
||||
import { ITreeFilterDataResult, TreeVisibility, ITreeFilter, ITreeOptions, ITreeModel, ITreeNode, ITreeElement } from 'vs/base/browser/ui/tree/tree';
|
||||
|
||||
interface IMutableTreeNode<T, TFilterData> extends ITreeNode<T, TFilterData> {
|
||||
readonly parent: IMutableTreeNode<T, TFilterData> | undefined;
|
||||
readonly children: IMutableTreeNode<T, TFilterData>[];
|
||||
collapsible: boolean;
|
||||
collapsed: boolean;
|
||||
revealedCount: number;
|
||||
filterData: TFilterData | undefined;
|
||||
renderNodeCount: number;
|
||||
visible: boolean;
|
||||
filterData: TFilterData | undefined;
|
||||
}
|
||||
|
||||
function isFilterResult<T>(obj: any): obj is ITreeFilterResult<T> {
|
||||
function isFilterResult<T>(obj: any): obj is ITreeFilterDataResult<T> {
|
||||
return typeof obj === 'object' && 'visibility' in obj && 'data' in obj;
|
||||
}
|
||||
|
||||
|
@ -30,8 +30,10 @@ function treeNodeToElement<T>(node: IMutableTreeNode<T, any>): ITreeElement<T> {
|
|||
return { element, children, collapsed };
|
||||
}
|
||||
|
||||
function getVisibleState(visibility: TreeVisibility): boolean | undefined {
|
||||
function getVisibleState(visibility: boolean | TreeVisibility): boolean | undefined {
|
||||
switch (visibility) {
|
||||
case true: return true;
|
||||
case false: return false;
|
||||
case TreeVisibility.Hidden: return false;
|
||||
case TreeVisibility.Visible: return true;
|
||||
case TreeVisibility.Recurse: return undefined;
|
||||
|
@ -49,13 +51,18 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
|
|||
depth: 0,
|
||||
collapsible: false,
|
||||
collapsed: false,
|
||||
revealedCount: 0,
|
||||
renderNodeCount: 0,
|
||||
visible: true,
|
||||
filterData: undefined
|
||||
};
|
||||
|
||||
private eventBufferer = new EventBufferer();
|
||||
|
||||
private _onDidChangeCollapseState = new Emitter<ITreeNode<T, TFilterData>>();
|
||||
readonly onDidChangeCollapseState: Event<ITreeNode<T, TFilterData>> = this._onDidChangeCollapseState.event;
|
||||
readonly onDidChangeCollapseState: Event<ITreeNode<T, TFilterData>> = this.eventBufferer.wrapEvent(this._onDidChangeCollapseState.event);
|
||||
|
||||
private _onDidChangeRenderNodeCount = new Emitter<ITreeNode<T, TFilterData>>();
|
||||
readonly onDidChangeRenderNodeCount: Event<ITreeNode<T, TFilterData>> = this.eventBufferer.wrapEvent(this._onDidChangeRenderNodeCount.event);
|
||||
|
||||
private filter?: ITreeFilter<T, TFilterData>;
|
||||
|
||||
|
@ -74,25 +81,25 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
|
|||
throw new Error('Invalid tree location');
|
||||
}
|
||||
|
||||
const { parentNode, listIndex, revealed } = this.findParentNode(location);
|
||||
const { parentNode, listIndex, revealed } = this.getParentNodeWithListIndex(location);
|
||||
const treeListElementsToInsert: ITreeNode<T, TFilterData>[] = [];
|
||||
const nodesToInsertIterator = Iterator.map(Iterator.from(toInsert), el => this.createTreeNode(el, parentNode, revealed, treeListElementsToInsert, onDidCreateNode));
|
||||
|
||||
const nodesToInsert: IMutableTreeNode<T, TFilterData>[] = [];
|
||||
let revealedCount = 0;
|
||||
let renderNodeCount = 0;
|
||||
|
||||
Iterator.forEach(nodesToInsertIterator, node => {
|
||||
nodesToInsert.push(node);
|
||||
revealedCount += node.revealedCount;
|
||||
renderNodeCount += node.renderNodeCount;
|
||||
});
|
||||
|
||||
const lastIndex = location[location.length - 1];
|
||||
const deletedNodes = parentNode.children.splice(lastIndex, deleteCount, ...nodesToInsert);
|
||||
|
||||
if (revealed) {
|
||||
const visibleDeleteCount = deletedNodes.reduce((r, node) => r + node.revealedCount, 0);
|
||||
const visibleDeleteCount = deletedNodes.reduce((r, node) => r + node.renderNodeCount, 0);
|
||||
|
||||
this._updateAncestorsRevealedCount(parentNode, revealedCount - visibleDeleteCount);
|
||||
this._updateAncestorsRenderNodeCount(parentNode, renderNodeCount - visibleDeleteCount);
|
||||
this.list.splice(listIndex, visibleDeleteCount, treeListElementsToInsert);
|
||||
}
|
||||
|
||||
|
@ -109,44 +116,43 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
|
|||
}
|
||||
|
||||
getListIndex(location: number[]): number {
|
||||
return this.findNode(location).listIndex;
|
||||
return this.getTreeNodeWithListIndex(location).listIndex;
|
||||
}
|
||||
|
||||
setCollapsed(location: number[], collapsed: boolean): boolean {
|
||||
const { node, listIndex, revealed } = this.findNode(location);
|
||||
return this._setCollapsed(node, listIndex, revealed, collapsed);
|
||||
const { node, listIndex, revealed } = this.getTreeNodeWithListIndex(location);
|
||||
return this.eventBufferer.bufferEvents(() => this._setCollapsed(node, listIndex, revealed, collapsed));
|
||||
}
|
||||
|
||||
toggleCollapsed(location: number[]): void {
|
||||
const { node, listIndex, revealed } = this.findNode(location);
|
||||
this._setCollapsed(node, listIndex, revealed);
|
||||
const { node, listIndex, revealed } = this.getTreeNodeWithListIndex(location);
|
||||
this.eventBufferer.bufferEvents(() => this._setCollapsed(node, listIndex, revealed));
|
||||
}
|
||||
|
||||
// // TODO@joao cleanup
|
||||
// setCollapsedAll(collapsed: boolean): void {
|
||||
// if (collapsed) {
|
||||
// const queue = [...this.root.children]; // TODO@joao use a linked list
|
||||
// let listIndex = 0;
|
||||
collapseAll(): void {
|
||||
const queue = [...this.root.children]; // TODO@joao use a linked list
|
||||
let listIndex = 0;
|
||||
|
||||
// while (queue.length > 0) {
|
||||
// const node = queue.shift();
|
||||
// const revealed = listIndex < this.root.children.length;
|
||||
// this._setCollapsed(node, listIndex, revealed, collapsed);
|
||||
this.eventBufferer.bufferEvents(() => {
|
||||
while (queue.length > 0) {
|
||||
const node = queue.shift();
|
||||
const revealed = listIndex < this.root.children.length;
|
||||
this._setCollapsed(node, listIndex, revealed, true);
|
||||
|
||||
// queue.push(...node.children);
|
||||
// listIndex++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
queue.push(...node.children);
|
||||
listIndex++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
isCollapsed(location: number[]): boolean {
|
||||
return this.findNode(location).node.collapsed;
|
||||
return this.getTreeNode(location).collapsed;
|
||||
}
|
||||
|
||||
refilter(): void {
|
||||
const previousRevealedCount = this.root.revealedCount;
|
||||
const previousRenderNodeCount = this.root.renderNodeCount;
|
||||
const toInsert = this.updateNodeAfterFilterChange(this.root);
|
||||
this.list.splice(0, previousRevealedCount, toInsert);
|
||||
this.list.splice(0, previousRenderNodeCount, toInsert);
|
||||
}
|
||||
|
||||
private _setCollapsed(node: IMutableTreeNode<T, TFilterData>, listIndex: number, revealed: boolean, collapsed?: boolean | undefined): boolean {
|
||||
|
@ -165,10 +171,10 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
|
|||
node.collapsed = collapsed;
|
||||
|
||||
if (revealed) {
|
||||
const previousRevealedCount = node.revealedCount;
|
||||
const previousRenderNodeCount = node.renderNodeCount;
|
||||
const toInsert = this.updateNodeAfterCollapseChange(node);
|
||||
|
||||
this.list.splice(listIndex + 1, previousRevealedCount - 1, toInsert.slice(1));
|
||||
this.list.splice(listIndex + 1, previousRenderNodeCount - 1, toInsert.slice(1));
|
||||
this._onDidChangeCollapseState.fire(node);
|
||||
}
|
||||
|
||||
|
@ -189,7 +195,7 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
|
|||
depth: parent.depth + 1,
|
||||
collapsible: typeof treeElement.collapsible === 'boolean' ? treeElement.collapsible : (typeof treeElement.collapsed === 'boolean'),
|
||||
collapsed: !!treeElement.collapsed,
|
||||
revealedCount: 1,
|
||||
renderNodeCount: 1,
|
||||
visible: true,
|
||||
filterData: undefined
|
||||
};
|
||||
|
@ -201,28 +207,29 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
|
|||
}
|
||||
|
||||
const childElements = Iterator.from(treeElement.children);
|
||||
const childNodes = Iterator.map(childElements, el => this.createTreeNode(el, node, revealed && !treeElement.collapsed, treeListElements, onDidCreateNode));
|
||||
const childRevealed = revealed && visible !== false && !node.collapsed;
|
||||
const childNodes = Iterator.map(childElements, el => this.createTreeNode(el, node, childRevealed, treeListElements, onDidCreateNode));
|
||||
|
||||
let hasVisibleDescendants = false;
|
||||
let revealedCount = 1;
|
||||
let renderNodeCount = 1;
|
||||
|
||||
Iterator.forEach(childNodes, child => {
|
||||
node.children.push(child);
|
||||
hasVisibleDescendants = hasVisibleDescendants || child.visible;
|
||||
revealedCount += child.revealedCount;
|
||||
renderNodeCount += child.renderNodeCount;
|
||||
});
|
||||
|
||||
node.collapsible = node.collapsible || node.children.length > 0;
|
||||
node.visible = typeof visible === 'undefined' ? hasVisibleDescendants : visible;
|
||||
|
||||
if (!node.visible) {
|
||||
node.revealedCount = 0;
|
||||
node.renderNodeCount = 0;
|
||||
|
||||
if (revealed) {
|
||||
treeListElements.pop();
|
||||
}
|
||||
} else if (!node.collapsed) {
|
||||
node.revealedCount = revealedCount;
|
||||
node.renderNodeCount = renderNodeCount;
|
||||
}
|
||||
|
||||
if (onDidCreateNode) {
|
||||
|
@ -233,11 +240,11 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
|
|||
}
|
||||
|
||||
private updateNodeAfterCollapseChange(node: IMutableTreeNode<T, TFilterData>): ITreeNode<T, TFilterData>[] {
|
||||
const previousRevealedCount = node.revealedCount;
|
||||
const previousRenderNodeCount = node.renderNodeCount;
|
||||
const result: ITreeNode<T, TFilterData>[] = [];
|
||||
|
||||
this._updateNodeAfterCollapseChange(node, result);
|
||||
this._updateAncestorsRevealedCount(node.parent, result.length - previousRevealedCount);
|
||||
this._updateAncestorsRenderNodeCount(node.parent, result.length - previousRenderNodeCount);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -248,23 +255,24 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
|
|||
}
|
||||
|
||||
result.push(node);
|
||||
node.revealedCount = 1;
|
||||
node.renderNodeCount = 1;
|
||||
|
||||
if (!node.collapsed) {
|
||||
for (const child of node.children) {
|
||||
node.revealedCount += this._updateNodeAfterCollapseChange(child, result);
|
||||
node.renderNodeCount += this._updateNodeAfterCollapseChange(child, result);
|
||||
}
|
||||
}
|
||||
|
||||
return node.revealedCount;
|
||||
this._onDidChangeRenderNodeCount.fire(node);
|
||||
return node.renderNodeCount;
|
||||
}
|
||||
|
||||
private updateNodeAfterFilterChange(node: IMutableTreeNode<T, TFilterData>): ITreeNode<T, TFilterData>[] {
|
||||
const previousRevealedCount = node.revealedCount;
|
||||
const previousRenderNodeCount = node.renderNodeCount;
|
||||
const result: ITreeNode<T, TFilterData>[] = [];
|
||||
|
||||
this._updateNodeAfterFilterChange(node, result);
|
||||
this._updateAncestorsRevealedCount(node.parent, result.length - previousRevealedCount);
|
||||
this._updateAncestorsRenderNodeCount(node.parent, result.length - previousRenderNodeCount);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -286,7 +294,7 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
|
|||
}
|
||||
|
||||
const resultStartLength = result.length;
|
||||
node.revealedCount = node === this.root ? 0 : 1;
|
||||
node.renderNodeCount = node === this.root ? 0 : 1;
|
||||
|
||||
let hasVisibleDescendants = false;
|
||||
if (visible !== false || !node.collapsed) {
|
||||
|
@ -300,25 +308,27 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
|
|||
}
|
||||
|
||||
if (!node.visible) {
|
||||
node.revealedCount = 0;
|
||||
node.renderNodeCount = 0;
|
||||
|
||||
if (revealed) {
|
||||
result.pop();
|
||||
}
|
||||
} else if (!node.collapsed) {
|
||||
node.revealedCount += result.length - resultStartLength;
|
||||
node.renderNodeCount += result.length - resultStartLength;
|
||||
}
|
||||
|
||||
this._onDidChangeRenderNodeCount.fire(node);
|
||||
return node.visible;
|
||||
}
|
||||
|
||||
private _updateAncestorsRevealedCount(node: IMutableTreeNode<T, TFilterData>, diff: number): void {
|
||||
private _updateAncestorsRenderNodeCount(node: IMutableTreeNode<T, TFilterData>, diff: number): void {
|
||||
if (diff === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (node) {
|
||||
node.revealedCount += diff;
|
||||
node.renderNodeCount += diff;
|
||||
this._onDidChangeRenderNodeCount.fire(node);
|
||||
node = node.parent;
|
||||
}
|
||||
}
|
||||
|
@ -338,8 +348,24 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
|
|||
}
|
||||
}
|
||||
|
||||
private findNode(location: number[]): { node: IMutableTreeNode<T, TFilterData>, listIndex: number, revealed: boolean } {
|
||||
const { parentNode, listIndex, revealed } = this.findParentNode(location);
|
||||
// cheap
|
||||
private getTreeNode(location: number[], node: IMutableTreeNode<T, TFilterData> = this.root): IMutableTreeNode<T, TFilterData> {
|
||||
if (location.length === 0) {
|
||||
return node;
|
||||
}
|
||||
|
||||
const [index, ...rest] = location;
|
||||
|
||||
if (index < 0 || index > node.children.length) {
|
||||
throw new Error('Invalid tree location');
|
||||
}
|
||||
|
||||
return this.getTreeNode(rest, node.children[index]);
|
||||
}
|
||||
|
||||
// expensive
|
||||
private getTreeNodeWithListIndex(location: number[]): { node: IMutableTreeNode<T, TFilterData>, listIndex: number, revealed: boolean } {
|
||||
const { parentNode, listIndex, revealed } = this.getParentNodeWithListIndex(location);
|
||||
const index = location[location.length - 1];
|
||||
|
||||
if (index < 0 || index > parentNode.children.length) {
|
||||
|
@ -351,7 +377,7 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
|
|||
return { node, listIndex, revealed };
|
||||
}
|
||||
|
||||
private findParentNode(location: number[], node: IMutableTreeNode<T, TFilterData> = this.root, listIndex: number = 0, revealed = true): { parentNode: IMutableTreeNode<T, TFilterData>; listIndex: number; revealed: boolean; } {
|
||||
private getParentNodeWithListIndex(location: number[], node: IMutableTreeNode<T, TFilterData> = this.root, listIndex: number = 0, revealed = true): { parentNode: IMutableTreeNode<T, TFilterData>; listIndex: number; revealed: boolean; } {
|
||||
const [index, ...rest] = location;
|
||||
|
||||
if (index < 0 || index > node.children.length) {
|
||||
|
@ -360,7 +386,7 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
|
|||
|
||||
// TODO@joao perf!
|
||||
for (let i = 0; i < index; i++) {
|
||||
listIndex += node.children[i].revealedCount;
|
||||
listIndex += node.children[i].renderNodeCount;
|
||||
}
|
||||
|
||||
revealed = revealed && !node.collapsed;
|
||||
|
@ -369,7 +395,11 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
|
|||
return { parentNode: node, listIndex, revealed };
|
||||
}
|
||||
|
||||
return this.findParentNode(rest, node.children[index], listIndex + 1, revealed);
|
||||
return this.getParentNodeWithListIndex(rest, node.children[index], listIndex + 1, revealed);
|
||||
}
|
||||
|
||||
getNode(location: number[] = []): ITreeNode<T, TFilterData> {
|
||||
return this.getTreeNode(location);
|
||||
}
|
||||
|
||||
// TODO@joao perf!
|
||||
|
@ -391,4 +421,38 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
|
|||
|
||||
return tail2(location)[0];
|
||||
}
|
||||
|
||||
getParentElement(location: number[]): T | null {
|
||||
const parentLocation = this.getParentNodeLocation(location);
|
||||
const node = this.getTreeNode(parentLocation);
|
||||
return node === this.root ? null : node.element;
|
||||
}
|
||||
|
||||
getFirstElementChild(location: number[]): T | null {
|
||||
const node = this.getTreeNode(location);
|
||||
|
||||
if (node.children.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return node.children[0].element;
|
||||
}
|
||||
|
||||
getLastElementAncestor(location: number[]): T | null {
|
||||
const node = this.getTreeNode(location);
|
||||
|
||||
if (node.children.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this._getLastElementAncestor(node);
|
||||
}
|
||||
|
||||
private _getLastElementAncestor(node: ITreeNode<T, TFilterData>): T | null {
|
||||
if (node.children.length === 0) {
|
||||
return node.element;
|
||||
}
|
||||
|
||||
return this._getLastElementAncestor(node.children[node.children.length - 1]);
|
||||
}
|
||||
}
|
|
@ -19,12 +19,14 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData = void> imp
|
|||
private nodes = new Map<T, ITreeNode<T, TFilterData>>();
|
||||
|
||||
readonly onDidChangeCollapseState: Event<ITreeNode<T, TFilterData>>;
|
||||
readonly onDidChangeRenderNodeCount: Event<ITreeNode<T, TFilterData>>;
|
||||
|
||||
get size(): number { return this.nodes.size; }
|
||||
|
||||
constructor(list: ISpliceable<ITreeNode<T, TFilterData>>, options: IObjectTreeModelOptions<T, TFilterData> = {}) {
|
||||
this.model = new IndexTreeModel(list, options);
|
||||
this.onDidChangeCollapseState = this.model.onDidChangeCollapseState;
|
||||
this.onDidChangeRenderNodeCount = this.model.onDidChangeRenderNodeCount;
|
||||
}
|
||||
|
||||
setChildren(element: T | null, children?: ISequence<ITreeElement<T>>): Iterator<ITreeElement<T>> {
|
||||
|
@ -45,6 +47,21 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData = void> imp
|
|||
return this.model.splice([...location, 0], Number.MAX_VALUE, children, onDidCreateNode, onDidDeleteNode);
|
||||
}
|
||||
|
||||
getParentElement(ref: T | null = null): T | null {
|
||||
const location = this.getElementLocation(ref);
|
||||
return this.model.getParentElement(location);
|
||||
}
|
||||
|
||||
getFirstElementChild(ref: T | null = null): T | null {
|
||||
const location = this.getElementLocation(ref);
|
||||
return this.model.getFirstElementChild(location);
|
||||
}
|
||||
|
||||
getLastElementAncestor(ref: T | null = null): T | null {
|
||||
const location = this.getElementLocation(ref);
|
||||
return this.model.getLastElementAncestor(location);
|
||||
}
|
||||
|
||||
getListIndex(element: T): number {
|
||||
const location = this.getElementLocation(element);
|
||||
return this.model.getListIndex(location);
|
||||
|
@ -60,6 +77,10 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData = void> imp
|
|||
this.model.toggleCollapsed(location);
|
||||
}
|
||||
|
||||
collapseAll(): void {
|
||||
this.model.collapseAll();
|
||||
}
|
||||
|
||||
isCollapsed(element: T): boolean {
|
||||
const location = this.getElementLocation(element);
|
||||
return this.model.isCollapsed(location);
|
||||
|
@ -69,6 +90,11 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData = void> imp
|
|||
this.model.refilter();
|
||||
}
|
||||
|
||||
getNode(element: T = null): ITreeNode<T, TFilterData> {
|
||||
const location = this.getElementLocation(element);
|
||||
return this.model.getNode(location);
|
||||
}
|
||||
|
||||
getNodeLocation(node: ITreeNode<T, TFilterData>): T {
|
||||
return node.element;
|
||||
}
|
||||
|
|
|
@ -9,13 +9,17 @@
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
.monaco-tl-row > .tl-twistie,
|
||||
.monaco-tl-row > .tl-contents {
|
||||
.monaco-tl-row > .monaco-tl-twistie,
|
||||
.monaco-tl-row > .monaco-tl-contents {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.monaco-tl-row > .tl-twistie {
|
||||
.monaco-tl-row > .monaco-tl-twistie {
|
||||
font-size: 10px;
|
||||
text-align: right;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.monaco-tl-row > .monaco-tl-contents {
|
||||
flex: 1;
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { Iterator } from 'vs/base/common/iterator';
|
||||
import { IListRenderer } from 'vs/base/browser/ui/list/list';
|
||||
|
||||
export const enum TreeVisibility {
|
||||
Hidden,
|
||||
|
@ -12,13 +13,15 @@ export const enum TreeVisibility {
|
|||
Recurse // TODO@joao come up with a better name
|
||||
}
|
||||
|
||||
export interface ITreeFilterResult<TFilterData> {
|
||||
visibility: TreeVisibility;
|
||||
export interface ITreeFilterDataResult<TFilterData> {
|
||||
visibility: boolean | TreeVisibility;
|
||||
data: TFilterData;
|
||||
}
|
||||
|
||||
export type TreeFilterResult<TFilterData> = boolean | TreeVisibility | ITreeFilterDataResult<TFilterData>;
|
||||
|
||||
export interface ITreeFilter<T, TFilterData = void> {
|
||||
filter(element: T): boolean | TreeVisibility | ITreeFilterResult<TFilterData>;
|
||||
filter(element: T): TreeFilterResult<TFilterData>;
|
||||
}
|
||||
|
||||
export interface ITreeOptions<T, TFilterData = void> {
|
||||
|
@ -39,19 +42,32 @@ export interface ITreeNode<T, TFilterData = void> {
|
|||
readonly depth: number;
|
||||
readonly collapsible: boolean;
|
||||
readonly collapsed: boolean;
|
||||
readonly revealedCount: number;
|
||||
readonly renderNodeCount: number;
|
||||
readonly visible: boolean;
|
||||
readonly filterData: TFilterData | undefined;
|
||||
}
|
||||
|
||||
export interface ITreeModel<T, TFilterData, TRef> {
|
||||
readonly onDidChangeCollapseState: Event<ITreeNode<T, TFilterData>>;
|
||||
readonly onDidChangeRenderNodeCount: Event<ITreeNode<T, TFilterData>>;
|
||||
|
||||
getListIndex(ref: TRef): number;
|
||||
setCollapsed(ref: TRef, collapsed: boolean): boolean;
|
||||
toggleCollapsed(ref: TRef): void;
|
||||
collapseAll(): void;
|
||||
isCollapsed(ref: TRef): boolean;
|
||||
refilter(): void;
|
||||
|
||||
getNode(location?: TRef): ITreeNode<T, any>;
|
||||
getNodeLocation(node: ITreeNode<T, any>): TRef;
|
||||
getParentNodeLocation(location: TRef): TRef | null;
|
||||
|
||||
getParentElement(location: TRef): T | null;
|
||||
getFirstElementChild(location: TRef): T | null;
|
||||
getLastElementAncestor(location: TRef): T | null;
|
||||
}
|
||||
|
||||
export interface ITreeRenderer<T, TFilterData, TTemplateData> extends IListRenderer<ITreeNode<T, TFilterData>, TTemplateData> {
|
||||
renderTwistie?(element: T, twistieElement: HTMLElement): boolean;
|
||||
onDidChangeTwistieState?: Event<T>;
|
||||
}
|
|
@ -16,7 +16,7 @@ export interface IAction extends IDisposable {
|
|||
id: string;
|
||||
label: string;
|
||||
tooltip: string;
|
||||
class: string;
|
||||
class: string | undefined;
|
||||
enabled: boolean;
|
||||
checked: boolean;
|
||||
radio: boolean;
|
||||
|
@ -56,7 +56,7 @@ export class Action implements IAction {
|
|||
protected _id: string;
|
||||
protected _label: string;
|
||||
protected _tooltip: string;
|
||||
protected _cssClass: string;
|
||||
protected _cssClass: string | undefined;
|
||||
protected _enabled: boolean;
|
||||
protected _checked: boolean;
|
||||
protected _radio: boolean;
|
||||
|
@ -104,15 +104,15 @@ export class Action implements IAction {
|
|||
}
|
||||
}
|
||||
|
||||
get class(): string {
|
||||
get class(): string | undefined {
|
||||
return this._cssClass;
|
||||
}
|
||||
|
||||
set class(value: string) {
|
||||
set class(value: string | undefined) {
|
||||
this._setClass(value);
|
||||
}
|
||||
|
||||
protected _setClass(value: string): void {
|
||||
protected _setClass(value: string | undefined): void {
|
||||
if (this._cssClass !== value) {
|
||||
this._cssClass = value;
|
||||
this._onDidChange.fire({ class: value });
|
||||
|
|
|
@ -299,16 +299,16 @@ function topStep<T>(array: T[], compare: (a: T, b: T) => number, result: T[], i:
|
|||
/**
|
||||
* @returns a new array with all undefined or null values removed. The original array is not modified at all.
|
||||
*/
|
||||
export function coalesce<T>(array: T[]): T[];
|
||||
export function coalesce<T>(array: T[], inplace: true): void;
|
||||
export function coalesce<T>(array: T[], inplace?: true): void | T[] {
|
||||
export function coalesce<T>(array: (T | undefined | null)[]): T[];
|
||||
export function coalesce<T>(array: (T | undefined | null)[], inplace: true): void;
|
||||
export function coalesce<T>(array: (T | undefined | null)[], inplace?: true): void | T[] {
|
||||
if (!array) {
|
||||
if (!inplace) {
|
||||
return array;
|
||||
}
|
||||
}
|
||||
if (!inplace) {
|
||||
return array.filter(e => !!e);
|
||||
return <T[]>array.filter(e => !!e);
|
||||
|
||||
} else {
|
||||
let to = 0;
|
||||
|
|
|
@ -406,12 +406,13 @@ export class EventBufferer {
|
|||
};
|
||||
}
|
||||
|
||||
bufferEvents(fn: () => void): void {
|
||||
bufferEvents<R = void>(fn: () => R): R {
|
||||
const buffer: Function[] = [];
|
||||
this.buffers.push(buffer);
|
||||
fn();
|
||||
const r = fn();
|
||||
this.buffers.pop();
|
||||
buffer.forEach(flush => flush());
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ export abstract class ReferenceCollection<T> {
|
|||
const { object } = reference;
|
||||
const dispose = once(() => {
|
||||
if (--reference.counter === 0) {
|
||||
this.destroyReferencedObject(reference.object);
|
||||
this.destroyReferencedObject(key, reference.object);
|
||||
delete this.references[key];
|
||||
}
|
||||
});
|
||||
|
@ -91,7 +91,7 @@ export abstract class ReferenceCollection<T> {
|
|||
}
|
||||
|
||||
protected abstract createReferencedObject(key: string): T;
|
||||
protected abstract destroyReferencedObject(object: T): void;
|
||||
protected abstract destroyReferencedObject(key: string, object: T): void;
|
||||
}
|
||||
|
||||
export class ImmortalReference<T> implements IReference<T> {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
import * as paths from 'vs/base/common/paths';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import * as arrays from 'vs/base/common/arrays';
|
||||
import { match } from 'vs/base/common/glob';
|
||||
|
||||
export const MIME_TEXT = 'text/plain';
|
||||
|
@ -136,10 +137,10 @@ export function guessMimeTypes(path: string, firstLine?: string): string[] {
|
|||
return [MIME_UNKNOWN];
|
||||
}
|
||||
|
||||
function guessMimeTypeByPath(path: string, filename: string, associations: ITextMimeAssociationItem[]): string {
|
||||
let filenameMatch: ITextMimeAssociationItem;
|
||||
let patternMatch: ITextMimeAssociationItem;
|
||||
let extensionMatch: ITextMimeAssociationItem;
|
||||
function guessMimeTypeByPath(path: string, filename: string, associations: ITextMimeAssociationItem[]): string | null {
|
||||
let filenameMatch: ITextMimeAssociationItem | null = null;
|
||||
let patternMatch: ITextMimeAssociationItem | null = null;
|
||||
let extensionMatch: ITextMimeAssociationItem | null = null;
|
||||
|
||||
// We want to prioritize associations based on the order they are registered so that the last registered
|
||||
// association wins over all other. This is for https://github.com/Microsoft/vscode/issues/20074
|
||||
|
@ -154,9 +155,9 @@ function guessMimeTypeByPath(path: string, filename: string, associations: IText
|
|||
|
||||
// Longest pattern match
|
||||
if (association.filepattern) {
|
||||
if (!patternMatch || association.filepattern.length > patternMatch.filepattern.length) {
|
||||
if (!patternMatch || association.filepattern.length > patternMatch.filepattern!.length) {
|
||||
const target = association.filepatternOnPath ? path : filename; // match on full path if pattern contains path separator
|
||||
if (match(association.filepatternLowercase, target)) {
|
||||
if (match(association.filepatternLowercase!, target)) {
|
||||
patternMatch = association;
|
||||
}
|
||||
}
|
||||
|
@ -164,8 +165,8 @@ function guessMimeTypeByPath(path: string, filename: string, associations: IText
|
|||
|
||||
// Longest extension match
|
||||
if (association.extension) {
|
||||
if (!extensionMatch || association.extension.length > extensionMatch.extension.length) {
|
||||
if (strings.endsWith(filename, association.extensionLowercase)) {
|
||||
if (!extensionMatch || association.extension.length > extensionMatch.extension!.length) {
|
||||
if (strings.endsWith(filename, association.extensionLowercase!)) {
|
||||
extensionMatch = association;
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +191,7 @@ function guessMimeTypeByPath(path: string, filename: string, associations: IText
|
|||
return null;
|
||||
}
|
||||
|
||||
function guessMimeTypeByFirstline(firstLine: string): string {
|
||||
function guessMimeTypeByFirstline(firstLine: string): string | null {
|
||||
if (strings.startsWithUTF8BOM(firstLine)) {
|
||||
firstLine = firstLine.substr(1);
|
||||
}
|
||||
|
@ -234,7 +235,7 @@ export function suggestFilename(langId: string, prefix: string): string {
|
|||
const extensions = registeredAssociations
|
||||
.filter(assoc => !assoc.userConfigured && assoc.extension && assoc.id === langId)
|
||||
.map(assoc => assoc.extension);
|
||||
const extensionsWithDotFirst = extensions
|
||||
const extensionsWithDotFirst = arrays.coalesce(extensions)
|
||||
.filter(assoc => strings.startsWith(assoc, '.'));
|
||||
|
||||
if (extensionsWithDotFirst.length > 0) {
|
||||
|
|
|
@ -82,14 +82,14 @@ export function isBoolean(obj: any): obj is boolean {
|
|||
/**
|
||||
* @returns whether the provided parameter is undefined.
|
||||
*/
|
||||
export function isUndefined(obj: any): boolean {
|
||||
export function isUndefined(obj: any): obj is undefined {
|
||||
return typeof (obj) === _typeof.undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns whether the provided parameter is undefined or null.
|
||||
*/
|
||||
export function isUndefinedOrNull(obj: any): boolean {
|
||||
export function isUndefinedOrNull(obj: any): obj is undefined | null {
|
||||
return isUndefined(obj) || obj === null;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import * as assert from 'assert';
|
||||
import { ListView } from 'vs/base/browser/ui/list/listView';
|
||||
import { IVirtualDelegate, IRenderer } from 'vs/base/browser/ui/list/list';
|
||||
import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list';
|
||||
import { range } from 'vs/base/common/arrays';
|
||||
|
||||
suite('ListView', function () {
|
||||
|
@ -14,14 +14,14 @@ suite('ListView', function () {
|
|||
element.style.height = '200px';
|
||||
element.style.width = '200px';
|
||||
|
||||
const delegate: IVirtualDelegate<number> = {
|
||||
const delegate: IListVirtualDelegate<number> = {
|
||||
getHeight() { return 20; },
|
||||
getTemplateId() { return 'template'; }
|
||||
};
|
||||
|
||||
let templatesCount = 0;
|
||||
|
||||
const renderer: IRenderer<number, void> = {
|
||||
const renderer: IListRenderer<number, void> = {
|
||||
templateId: 'template',
|
||||
renderTemplate() { templatesCount++; },
|
||||
renderElement() { },
|
||||
|
|
|
@ -54,7 +54,7 @@ suite('Reference Collection', () => {
|
|||
private _count = 0;
|
||||
get count() { return this._count; }
|
||||
protected createReferencedObject(key: string): number { this._count++; return key.length; }
|
||||
protected destroyReferencedObject(object: number): void { this._count--; }
|
||||
protected destroyReferencedObject(key: string, object: number): void { this._count--; }
|
||||
}
|
||||
|
||||
test('simple', () => {
|
||||
|
|
|
@ -67,10 +67,10 @@ export class DefaultWorkerFactory implements IWorkerFactory {
|
|||
|
||||
private static LAST_WORKER_ID = 0;
|
||||
|
||||
private _label: string;
|
||||
private _label: string | undefined;
|
||||
private _webWorkerFailedBeforeError: any;
|
||||
|
||||
constructor(label: string) {
|
||||
constructor(label: string | undefined) {
|
||||
this._label = label;
|
||||
this._webWorkerFailedBeforeError = false;
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ class CSSBasedConfiguration extends Disposable {
|
|||
return this._cache.get(bareFontInfo);
|
||||
}
|
||||
|
||||
private static createRequest(chr: string, type: CharWidthRequestType, all: CharWidthRequest[], monospace: CharWidthRequest[]): CharWidthRequest {
|
||||
private static createRequest(chr: string, type: CharWidthRequestType, all: CharWidthRequest[], monospace: CharWidthRequest[] | null): CharWidthRequest {
|
||||
let result = new CharWidthRequest(chr, type);
|
||||
all.push(result);
|
||||
if (monospace) {
|
||||
|
|
|
@ -8,13 +8,13 @@ import { IDimension } from 'vs/editor/common/editorCommon';
|
|||
|
||||
export class ElementSizeObserver extends Disposable {
|
||||
|
||||
private referenceDomElement: HTMLElement;
|
||||
private referenceDomElement: HTMLElement | null;
|
||||
private measureReferenceDomElementToken: any;
|
||||
private changeCallback: () => void;
|
||||
private width: number;
|
||||
private height: number;
|
||||
|
||||
constructor(referenceDomElement: HTMLElement, changeCallback: () => void) {
|
||||
constructor(referenceDomElement: HTMLElement | null, changeCallback: () => void) {
|
||||
super();
|
||||
this.referenceDomElement = referenceDomElement;
|
||||
this.changeCallback = changeCallback;
|
||||
|
|
|
@ -121,7 +121,7 @@ export namespace EditorScroll_ {
|
|||
select?: boolean;
|
||||
}
|
||||
|
||||
export function parse(args: RawArguments): ParsedArguments {
|
||||
export function parse(args: RawArguments): ParsedArguments | null {
|
||||
let direction: Direction;
|
||||
switch (args.to) {
|
||||
case RawDirection.Up:
|
||||
|
@ -720,11 +720,11 @@ export namespace CoreNavigationCommands {
|
|||
for (let i = 0, len = states.length; i < len; i++) {
|
||||
const state = states[i];
|
||||
|
||||
if (newModelPosition && !state.modelState.selection.containsPosition(newModelPosition)) {
|
||||
if (newModelPosition && !state.modelState!.selection.containsPosition(newModelPosition)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newViewPosition && !state.viewState.selection.containsPosition(newViewPosition)) {
|
||||
if (newViewPosition && !state.viewState!.selection.containsPosition(newViewPosition)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1419,7 +1419,7 @@ export namespace CoreNavigationCommands {
|
|||
|
||||
public runCoreEditorCommand(cursors: ICursors, args: any): void {
|
||||
const revealLineArg = <RevealLine_.RawArguments>args;
|
||||
let lineNumber = revealLineArg.lineNumber + 1;
|
||||
let lineNumber = (revealLineArg.lineNumber || 0) + 1;
|
||||
if (lineNumber < 1) {
|
||||
lineNumber = 1;
|
||||
}
|
||||
|
@ -1499,7 +1499,20 @@ export namespace CoreNavigationCommands {
|
|||
|
||||
export namespace CoreEditingCommands {
|
||||
|
||||
export const LineBreakInsert: EditorCommand = registerEditorCommand(new class extends EditorCommand {
|
||||
export abstract class CoreEditingCommand extends EditorCommand {
|
||||
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
|
||||
const cursors = editor._getCursors();
|
||||
if (!cursors) {
|
||||
// the editor has no view => has no cursors
|
||||
return;
|
||||
}
|
||||
this.runCoreEditingCommand(editor, cursors, args || {});
|
||||
}
|
||||
|
||||
public abstract runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void;
|
||||
}
|
||||
|
||||
export const LineBreakInsert: EditorCommand = registerEditorCommand(new class extends CoreEditingCommand {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'lineBreakInsert',
|
||||
|
@ -1507,19 +1520,19 @@ export namespace CoreEditingCommands {
|
|||
kbOpts: {
|
||||
weight: CORE_WEIGHT,
|
||||
kbExpr: EditorContextKeys.textInputFocus,
|
||||
primary: null,
|
||||
primary: 0,
|
||||
mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_O }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
|
||||
public runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void {
|
||||
editor.pushUndoStop();
|
||||
editor.executeCommands(this.id, TypeOperations.lineBreakInsert(editor._getCursorConfiguration(), editor.getModel(), editor.getSelections()));
|
||||
editor.executeCommands(this.id, TypeOperations.lineBreakInsert(cursors.context.config, cursors.context.model, cursors.getAll().map(s => s.modelState.selection)));
|
||||
}
|
||||
});
|
||||
|
||||
export const Outdent: EditorCommand = registerEditorCommand(new class extends EditorCommand {
|
||||
export const Outdent: EditorCommand = registerEditorCommand(new class extends CoreEditingCommand {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'outdent',
|
||||
|
@ -1535,14 +1548,14 @@ export namespace CoreEditingCommands {
|
|||
});
|
||||
}
|
||||
|
||||
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
|
||||
public runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void {
|
||||
editor.pushUndoStop();
|
||||
editor.executeCommands(this.id, TypeOperations.outdent(editor._getCursorConfiguration(), editor.getModel(), editor.getSelections()));
|
||||
editor.executeCommands(this.id, TypeOperations.outdent(cursors.context.config, cursors.context.model, cursors.getAll().map(s => s.modelState.selection)));
|
||||
editor.pushUndoStop();
|
||||
}
|
||||
});
|
||||
|
||||
export const Tab: EditorCommand = registerEditorCommand(new class extends EditorCommand {
|
||||
export const Tab: EditorCommand = registerEditorCommand(new class extends CoreEditingCommand {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'tab',
|
||||
|
@ -1558,14 +1571,14 @@ export namespace CoreEditingCommands {
|
|||
});
|
||||
}
|
||||
|
||||
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
|
||||
public runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void {
|
||||
editor.pushUndoStop();
|
||||
editor.executeCommands(this.id, TypeOperations.tab(editor._getCursorConfiguration(), editor.getModel(), editor.getSelections()));
|
||||
editor.executeCommands(this.id, TypeOperations.tab(cursors.context.config, cursors.context.model, cursors.getAll().map(s => s.modelState.selection)));
|
||||
editor.pushUndoStop();
|
||||
}
|
||||
});
|
||||
|
||||
export const DeleteLeft: EditorCommand = registerEditorCommand(new class extends EditorCommand {
|
||||
export const DeleteLeft: EditorCommand = registerEditorCommand(new class extends CoreEditingCommand {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'deleteLeft',
|
||||
|
@ -1580,9 +1593,8 @@ export namespace CoreEditingCommands {
|
|||
});
|
||||
}
|
||||
|
||||
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
|
||||
const cursors = editor._getCursors();
|
||||
const [shouldPushStackElementBefore, commands] = DeleteOperations.deleteLeft(cursors.getPrevEditOperationType(), editor._getCursorConfiguration(), editor.getModel(), editor.getSelections());
|
||||
public runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void {
|
||||
const [shouldPushStackElementBefore, commands] = DeleteOperations.deleteLeft(cursors.getPrevEditOperationType(), cursors.context.config, cursors.context.model, cursors.getAll().map(s => s.modelState.selection));
|
||||
if (shouldPushStackElementBefore) {
|
||||
editor.pushUndoStop();
|
||||
}
|
||||
|
@ -1591,7 +1603,7 @@ export namespace CoreEditingCommands {
|
|||
}
|
||||
});
|
||||
|
||||
export const DeleteRight: EditorCommand = registerEditorCommand(new class extends EditorCommand {
|
||||
export const DeleteRight: EditorCommand = registerEditorCommand(new class extends CoreEditingCommand {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'deleteRight',
|
||||
|
@ -1605,9 +1617,8 @@ export namespace CoreEditingCommands {
|
|||
});
|
||||
}
|
||||
|
||||
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
|
||||
const cursors = editor._getCursors();
|
||||
const [shouldPushStackElementBefore, commands] = DeleteOperations.deleteRight(cursors.getPrevEditOperationType(), editor._getCursorConfiguration(), editor.getModel(), editor.getSelections());
|
||||
public runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void {
|
||||
const [shouldPushStackElementBefore, commands] = DeleteOperations.deleteRight(cursors.getPrevEditOperationType(), cursors.context.config, cursors.context.model, cursors.getAll().map(s => s.modelState.selection));
|
||||
if (shouldPushStackElementBefore) {
|
||||
editor.pushUndoStop();
|
||||
}
|
||||
|
@ -1618,10 +1629,6 @@ export namespace CoreEditingCommands {
|
|||
|
||||
}
|
||||
|
||||
function findFocusedEditor(accessor: ServicesAccessor): ICodeEditor {
|
||||
return accessor.get(ICodeEditorService).getFocusedCodeEditor();
|
||||
}
|
||||
|
||||
function registerCommand(command: Command) {
|
||||
command.register();
|
||||
}
|
||||
|
@ -1645,10 +1652,10 @@ class EditorOrNativeTextInputCommand extends Command {
|
|||
|
||||
public runCommand(accessor: ServicesAccessor, args: any): void {
|
||||
|
||||
let focusedEditor = findFocusedEditor(accessor);
|
||||
let focusedEditor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
|
||||
// Only if editor text focus (i.e. not if editor has widget focus).
|
||||
if (focusedEditor && focusedEditor.hasTextFocus()) {
|
||||
return this._runEditorHandler(focusedEditor, args);
|
||||
return this._runEditorHandler(accessor, focusedEditor, args);
|
||||
}
|
||||
|
||||
// Ignore this action when user is focused on an element that allows for entering text
|
||||
|
@ -1662,18 +1669,18 @@ class EditorOrNativeTextInputCommand extends Command {
|
|||
let activeEditor = accessor.get(ICodeEditorService).getActiveCodeEditor();
|
||||
if (activeEditor) {
|
||||
activeEditor.focus();
|
||||
return this._runEditorHandler(activeEditor, args);
|
||||
return this._runEditorHandler(accessor, activeEditor, args);
|
||||
}
|
||||
}
|
||||
|
||||
private _runEditorHandler(editor: ICodeEditor, args: any): void {
|
||||
private _runEditorHandler(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
|
||||
let HANDLER = this._editorHandler;
|
||||
if (typeof HANDLER === 'string') {
|
||||
editor.trigger('keyboard', HANDLER, args);
|
||||
} else {
|
||||
args = args || {};
|
||||
args.source = 'keyboard';
|
||||
HANDLER.runEditorCommand(null, editor, args);
|
||||
HANDLER.runEditorCommand(accessor, editor, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1694,7 +1701,7 @@ class EditorHandlerCommand extends Command {
|
|||
}
|
||||
|
||||
public runCommand(accessor: ServicesAccessor, args: any): void {
|
||||
const editor = findFocusedEditor(accessor);
|
||||
const editor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import { ViewController } from 'vs/editor/browser/view/viewController';
|
|||
/**
|
||||
* Merges mouse events when mouse move events are throttled
|
||||
*/
|
||||
function createMouseMoveEventMerger(mouseTargetFactory: MouseTargetFactory) {
|
||||
function createMouseMoveEventMerger(mouseTargetFactory: MouseTargetFactory | null) {
|
||||
return function (lastEvent: EditorMouseEvent, currentEvent: EditorMouseEvent): EditorMouseEvent {
|
||||
let targetIsWidget = false;
|
||||
if (mouseTargetFactory) {
|
||||
|
@ -55,9 +55,9 @@ export interface IPointerHandlerHelper {
|
|||
/**
|
||||
* Decode a position from a rendered dom node
|
||||
*/
|
||||
getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position;
|
||||
getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position | null;
|
||||
|
||||
visibleRangeForPosition2(lineNumber: number, column: number): HorizontalRange;
|
||||
visibleRangeForPosition2(lineNumber: number, column: number): HorizontalRange | null;
|
||||
getLineWidth(lineNumber: number): number;
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ export class MouseHandler extends ViewEventHandler {
|
|||
return;
|
||||
}
|
||||
let e = new StandardMouseWheelEvent(browserEvent);
|
||||
if (e.browserEvent.ctrlKey || e.browserEvent.metaKey) {
|
||||
if (e.browserEvent!.ctrlKey || e.browserEvent!.metaKey) {
|
||||
let zoomLevel: number = EditorZoom.getZoomLevel();
|
||||
let delta = e.deltaY > 0 ? 1 : -1;
|
||||
EditorZoom.setZoomLevel(zoomLevel + delta);
|
||||
|
@ -148,7 +148,7 @@ export class MouseHandler extends ViewEventHandler {
|
|||
}
|
||||
// --- end event handlers
|
||||
|
||||
public getTargetAtClientPoint(clientX: number, clientY: number): editorBrowser.IMouseTarget {
|
||||
public getTargetAtClientPoint(clientX: number, clientY: number): editorBrowser.IMouseTarget | null {
|
||||
let clientPos = new ClientCoordinates(clientX, clientY);
|
||||
let pos = clientPos.toPageCoordinates();
|
||||
let editorPos = createEditorPagePosition(this.viewHelper.viewDomNode);
|
||||
|
@ -276,7 +276,7 @@ class MouseDownOperation extends Disposable {
|
|||
|
||||
private _currentSelection: Selection;
|
||||
private _isActive: boolean;
|
||||
private _lastMouseEvent: EditorMouseEvent;
|
||||
private _lastMouseEvent: EditorMouseEvent | null;
|
||||
|
||||
constructor(
|
||||
context: ViewContext,
|
||||
|
@ -336,7 +336,7 @@ class MouseDownOperation extends Disposable {
|
|||
this._mouseState.setStartButtons(e);
|
||||
this._mouseState.setModifiers(e);
|
||||
let position = this._findMousePosition(e, true);
|
||||
if (!position) {
|
||||
if (!position || !position.position) {
|
||||
// Ignoring because position is unknown
|
||||
return;
|
||||
}
|
||||
|
@ -353,7 +353,7 @@ class MouseDownOperation extends Disposable {
|
|||
&& !this._isActive // the mouse is not down yet
|
||||
&& !this._currentSelection.isEmpty() // we don't drag single cursor
|
||||
&& (position.type === editorBrowser.MouseTargetType.CONTENT_TEXT) // single click on text
|
||||
&& this._currentSelection.containsPosition(position.position) // single click on a selection
|
||||
&& position.position && this._currentSelection.containsPosition(position.position) // single click on a selection
|
||||
) {
|
||||
this._mouseState.isDragAndDrop = true;
|
||||
this._isActive = true;
|
||||
|
@ -362,11 +362,11 @@ class MouseDownOperation extends Disposable {
|
|||
createMouseMoveEventMerger(null),
|
||||
(e) => this._onMouseDownThenMove(e),
|
||||
() => {
|
||||
let position = this._findMousePosition(this._lastMouseEvent, true);
|
||||
let position = this._findMousePosition(this._lastMouseEvent!, true);
|
||||
|
||||
this._viewController.emitMouseDrop({
|
||||
event: this._lastMouseEvent,
|
||||
target: position ? this._createMouseTarget(this._lastMouseEvent, true) : null // Ignoring because position is unknown, e.g., Content View Zone
|
||||
event: this._lastMouseEvent!,
|
||||
target: (position ? this._createMouseTarget(this._lastMouseEvent!, true) : null) // Ignoring because position is unknown, e.g., Content View Zone
|
||||
});
|
||||
|
||||
this._stop();
|
||||
|
@ -399,6 +399,9 @@ class MouseDownOperation extends Disposable {
|
|||
return;
|
||||
}
|
||||
this._onScrollTimeout.setIfNotSet(() => {
|
||||
if (!this._lastMouseEvent) {
|
||||
return;
|
||||
}
|
||||
let position = this._findMousePosition(this._lastMouseEvent, false);
|
||||
if (!position) {
|
||||
// Ignoring because position is unknown
|
||||
|
@ -416,7 +419,7 @@ class MouseDownOperation extends Disposable {
|
|||
this._currentSelection = e.selections[0];
|
||||
}
|
||||
|
||||
private _getPositionOutsideEditor(e: EditorMouseEvent): MouseTarget {
|
||||
private _getPositionOutsideEditor(e: EditorMouseEvent): MouseTarget | null {
|
||||
const editorContent = e.editorPos;
|
||||
const model = this._context.model;
|
||||
const viewLayout = this._context.viewLayout;
|
||||
|
@ -464,7 +467,7 @@ class MouseDownOperation extends Disposable {
|
|||
return null;
|
||||
}
|
||||
|
||||
private _findMousePosition(e: EditorMouseEvent, testEventTarget: boolean): MouseTarget {
|
||||
private _findMousePosition(e: EditorMouseEvent, testEventTarget: boolean): MouseTarget | null {
|
||||
let positionOutsideEditor = this._getPositionOutsideEditor(e);
|
||||
if (positionOutsideEditor) {
|
||||
return positionOutsideEditor;
|
||||
|
@ -486,7 +489,7 @@ class MouseDownOperation extends Disposable {
|
|||
return t;
|
||||
}
|
||||
|
||||
private _helpPositionJumpOverViewZone(viewZoneData: IViewZoneData): Position {
|
||||
private _helpPositionJumpOverViewZone(viewZoneData: IViewZoneData): Position | null {
|
||||
// Force position on view zones to go above or below depending on where selection started from
|
||||
let selectionStart = new Position(this._currentSelection.selectionStartLineNumber, this._currentSelection.selectionStartColumn);
|
||||
let positionBefore = viewZoneData.positionBefore;
|
||||
|
@ -503,6 +506,9 @@ class MouseDownOperation extends Disposable {
|
|||
}
|
||||
|
||||
private _dispatchMouse(position: MouseTarget, inSelectionMode: boolean): void {
|
||||
if (!position.position) {
|
||||
return;
|
||||
}
|
||||
this._viewController.dispatchMouse({
|
||||
position: position.position,
|
||||
mouseColumn: position.mouseColumn,
|
||||
|
@ -546,7 +552,7 @@ class MouseDownState {
|
|||
private _startedOnLineNumbers: boolean;
|
||||
public get startedOnLineNumbers(): boolean { return this._startedOnLineNumbers; }
|
||||
|
||||
private _lastMouseDownPosition: Position;
|
||||
private _lastMouseDownPosition: Position | null;
|
||||
private _lastMouseDownPositionEqualCount: number;
|
||||
private _lastMouseDownCount: number;
|
||||
private _lastSetMouseDownCountTime: number;
|
||||
|
|
|
@ -19,8 +19,8 @@ import { HorizontalRange } from 'vs/editor/common/view/renderingContext';
|
|||
|
||||
export interface IViewZoneData {
|
||||
viewZoneId: number;
|
||||
positionBefore: Position;
|
||||
positionAfter: Position;
|
||||
positionBefore: Position | null;
|
||||
positionAfter: Position | null;
|
||||
position: Position;
|
||||
afterLineNumber: number;
|
||||
}
|
||||
|
@ -84,20 +84,20 @@ declare var IETextRange: {
|
|||
};
|
||||
|
||||
interface IHitTestResult {
|
||||
position: Position;
|
||||
hitTarget: Element;
|
||||
position: Position | null;
|
||||
hitTarget: Element | null;
|
||||
}
|
||||
|
||||
export class MouseTarget implements IMouseTarget {
|
||||
|
||||
public readonly element: Element;
|
||||
public readonly element: Element | null;
|
||||
public readonly type: MouseTargetType;
|
||||
public readonly mouseColumn: number;
|
||||
public readonly position: Position;
|
||||
public readonly range: EditorRange;
|
||||
public readonly position: Position | null;
|
||||
public readonly range: EditorRange | null;
|
||||
public readonly detail: any;
|
||||
|
||||
constructor(element: Element, type: MouseTargetType, mouseColumn: number = 0, position: Position | null = null, range: EditorRange | null = null, detail: any = null) {
|
||||
constructor(element: Element | null, type: MouseTargetType, mouseColumn: number = 0, position: Position | null = null, range: EditorRange | null = null, detail: any = null) {
|
||||
this.element = element;
|
||||
this.type = type;
|
||||
this.mouseColumn = mouseColumn;
|
||||
|
@ -247,11 +247,11 @@ export class HitTestContext {
|
|||
this._viewHelper = viewHelper;
|
||||
}
|
||||
|
||||
public getZoneAtCoord(mouseVerticalOffset: number): IViewZoneData {
|
||||
public getZoneAtCoord(mouseVerticalOffset: number): IViewZoneData | null {
|
||||
return HitTestContext.getZoneAtCoord(this._context, mouseVerticalOffset);
|
||||
}
|
||||
|
||||
public static getZoneAtCoord(context: ViewContext, mouseVerticalOffset: number): IViewZoneData {
|
||||
public static getZoneAtCoord(context: ViewContext, mouseVerticalOffset: number): IViewZoneData | null {
|
||||
// The target is either a view zone or the empty space after the last view-line
|
||||
let viewZoneWhitespace = context.viewLayout.getWhitespaceAtVerticalOffset(mouseVerticalOffset);
|
||||
|
||||
|
@ -259,7 +259,7 @@ export class HitTestContext {
|
|||
let viewZoneMiddle = viewZoneWhitespace.verticalOffset + viewZoneWhitespace.height / 2,
|
||||
lineCount = context.model.getLineCount(),
|
||||
positionBefore: Position | null = null,
|
||||
position: Position,
|
||||
position: Position | null,
|
||||
positionAfter: Position | null = null;
|
||||
|
||||
if (viewZoneWhitespace.afterLineNumber !== lineCount) {
|
||||
|
@ -286,7 +286,7 @@ export class HitTestContext {
|
|||
afterLineNumber: viewZoneWhitespace.afterLineNumber,
|
||||
positionBefore: positionBefore,
|
||||
positionAfter: positionAfter,
|
||||
position: position
|
||||
position: position!
|
||||
};
|
||||
}
|
||||
return null;
|
||||
|
@ -323,11 +323,11 @@ export class HitTestContext {
|
|||
return this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber);
|
||||
}
|
||||
|
||||
public findAttribute(element: Element, attr: string): string {
|
||||
public findAttribute(element: Element, attr: string): string | null {
|
||||
return HitTestContext._findAttribute(element, attr, this._viewHelper.viewDomNode);
|
||||
}
|
||||
|
||||
private static _findAttribute(element: Element, attr: string, stopAt: Element): string {
|
||||
private static _findAttribute(element: Element, attr: string, stopAt: Element): string | null {
|
||||
while (element && element !== document.body) {
|
||||
if (element.hasAttribute && element.hasAttribute(attr)) {
|
||||
return element.getAttribute(attr);
|
||||
|
@ -344,11 +344,11 @@ export class HitTestContext {
|
|||
return this._viewHelper.getLineWidth(lineNumber);
|
||||
}
|
||||
|
||||
public visibleRangeForPosition2(lineNumber: number, column: number): HorizontalRange {
|
||||
public visibleRangeForPosition2(lineNumber: number, column: number): HorizontalRange | null {
|
||||
return this._viewHelper.visibleRangeForPosition2(lineNumber, column);
|
||||
}
|
||||
|
||||
public getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position {
|
||||
public getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position | null {
|
||||
return this._viewHelper.getPositionFromDOMInfo(spanNode, offset);
|
||||
}
|
||||
|
||||
|
@ -386,10 +386,10 @@ abstract class BareHitTestRequest {
|
|||
|
||||
class HitTestRequest extends BareHitTestRequest {
|
||||
private readonly _ctx: HitTestContext;
|
||||
public readonly target: Element;
|
||||
public readonly target: Element | null;
|
||||
public readonly targetPath: Uint8Array;
|
||||
|
||||
constructor(ctx: HitTestContext, editorPos: EditorPagePosition, pos: PageCoordinates, target: Element) {
|
||||
constructor(ctx: HitTestContext, editorPos: EditorPagePosition, pos: PageCoordinates, target: Element | null) {
|
||||
super(ctx, editorPos, pos);
|
||||
this._ctx = ctx;
|
||||
|
||||
|
@ -410,11 +410,15 @@ class HitTestRequest extends BareHitTestRequest {
|
|||
return new MouseTarget(this.target, type, this.mouseColumn, position, range, detail);
|
||||
}
|
||||
|
||||
public withTarget(target: Element): HitTestRequest {
|
||||
public withTarget(target: Element | null): HitTestRequest {
|
||||
return new HitTestRequest(this._ctx, this.editorPos, this.pos, target);
|
||||
}
|
||||
}
|
||||
|
||||
interface ResolvedHitTestRequest extends HitTestRequest {
|
||||
readonly target: Element;
|
||||
}
|
||||
|
||||
const EMPTY_CONTENT_AFTER_LINES: IEmptyContentData = { isAfterLines: true };
|
||||
|
||||
function createEmptyContentDataInLines(horizontalDistanceToText: number): IEmptyContentData {
|
||||
|
@ -451,7 +455,7 @@ export class MouseTargetFactory {
|
|||
return false;
|
||||
}
|
||||
|
||||
public createMouseTarget(lastViewCursorsRenderData: IViewCursorRenderData[], editorPos: EditorPagePosition, pos: PageCoordinates, target: HTMLElement): IMouseTarget {
|
||||
public createMouseTarget(lastViewCursorsRenderData: IViewCursorRenderData[], editorPos: EditorPagePosition, pos: PageCoordinates, target: HTMLElement | null): IMouseTarget {
|
||||
const ctx = new HitTestContext(this._context, this._viewHelper, lastViewCursorsRenderData);
|
||||
const request = new HitTestRequest(ctx, editorPos, pos, target);
|
||||
try {
|
||||
|
@ -484,23 +488,26 @@ export class MouseTargetFactory {
|
|||
return this._createMouseTarget(ctx, request.withTarget(hitTestResult.hitTarget), true);
|
||||
}
|
||||
|
||||
// we know for a fact that request.target is not null
|
||||
const resolvedRequest = <ResolvedHitTestRequest>request;
|
||||
|
||||
let result: MouseTarget | null = null;
|
||||
|
||||
result = result || MouseTargetFactory._hitTestContentWidget(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestOverlayWidget(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestMinimap(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestScrollbarSlider(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestViewZone(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestMargin(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestViewCursor(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestTextArea(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestViewLines(ctx, request, domHitTestExecuted);
|
||||
result = result || MouseTargetFactory._hitTestScrollbar(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestContentWidget(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestOverlayWidget(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestMinimap(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestScrollbarSlider(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestViewZone(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestMargin(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestViewCursor(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestTextArea(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestViewLines(ctx, resolvedRequest, domHitTestExecuted);
|
||||
result = result || MouseTargetFactory._hitTestScrollbar(ctx, resolvedRequest);
|
||||
|
||||
return (result || request.fulfill(MouseTargetType.UNKNOWN));
|
||||
}
|
||||
|
||||
private static _hitTestContentWidget(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestContentWidget(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
// Is it a content widget?
|
||||
if (ElementPath.isChildOfContentWidgets(request.targetPath) || ElementPath.isChildOfOverflowingContentWidgets(request.targetPath)) {
|
||||
let widgetId = ctx.findAttribute(request.target, 'widgetId');
|
||||
|
@ -513,7 +520,7 @@ export class MouseTargetFactory {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestOverlayWidget(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestOverlayWidget(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
// Is it an overlay widget?
|
||||
if (ElementPath.isChildOfOverlayWidgets(request.targetPath)) {
|
||||
let widgetId = ctx.findAttribute(request.target, 'widgetId');
|
||||
|
@ -526,7 +533,7 @@ export class MouseTargetFactory {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestViewCursor(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestViewCursor(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
|
||||
if (request.target) {
|
||||
// Check if we've hit a painted cursor
|
||||
|
@ -577,7 +584,7 @@ export class MouseTargetFactory {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestViewZone(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestViewZone(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
let viewZoneData = ctx.getZoneAtCoord(request.mouseVerticalOffset);
|
||||
if (viewZoneData) {
|
||||
let mouseTargetType = (request.isInContentArea ? MouseTargetType.CONTENT_VIEW_ZONE : MouseTargetType.GUTTER_VIEW_ZONE);
|
||||
|
@ -587,7 +594,7 @@ export class MouseTargetFactory {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestTextArea(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestTextArea(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
// Is it the textarea?
|
||||
if (ElementPath.isTextArea(request.targetPath)) {
|
||||
return request.fulfill(MouseTargetType.TEXTAREA);
|
||||
|
@ -595,7 +602,7 @@ export class MouseTargetFactory {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestMargin(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestMargin(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
if (request.isInMarginArea) {
|
||||
let res = ctx.getFullLineRangeAtCoord(request.mouseVerticalOffset);
|
||||
let pos = res.range.getStartPosition();
|
||||
|
@ -628,7 +635,7 @@ export class MouseTargetFactory {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestViewLines(ctx: HitTestContext, request: HitTestRequest, domHitTestExecuted: boolean): MouseTarget {
|
||||
private static _hitTestViewLines(ctx: HitTestContext, request: ResolvedHitTestRequest, domHitTestExecuted: boolean): MouseTarget | null {
|
||||
if (!ElementPath.isChildOfViewLines(request.targetPath)) {
|
||||
return null;
|
||||
}
|
||||
|
@ -666,7 +673,7 @@ export class MouseTargetFactory {
|
|||
return this._createMouseTarget(ctx, request.withTarget(hitTestResult.hitTarget), true);
|
||||
}
|
||||
|
||||
private static _hitTestMinimap(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestMinimap(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
if (ElementPath.isChildOfMinimap(request.targetPath)) {
|
||||
const possibleLineNumber = ctx.getLineNumberAtVerticalOffset(request.mouseVerticalOffset);
|
||||
const maxColumn = ctx.model.getLineMaxColumn(possibleLineNumber);
|
||||
|
@ -675,7 +682,7 @@ export class MouseTargetFactory {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestScrollbarSlider(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestScrollbarSlider(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
if (ElementPath.isChildOfScrollableElement(request.targetPath)) {
|
||||
if (request.target && request.target.nodeType === 1) {
|
||||
let className = request.target.className;
|
||||
|
@ -689,7 +696,7 @@ export class MouseTargetFactory {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestScrollbar(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestScrollbar(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
// Is it the overview ruler?
|
||||
// Is it a child of the scrollable element?
|
||||
if (ElementPath.isChildOfScrollableElement(request.targetPath)) {
|
||||
|
@ -817,7 +824,7 @@ export class MouseTargetFactory {
|
|||
|
||||
// Chrome always hits a TEXT_NODE, while Edge sometimes hits a token span
|
||||
let startContainer = range.startContainer;
|
||||
let hitTarget: HTMLElement;
|
||||
let hitTarget: HTMLElement | null = null;
|
||||
|
||||
if (startContainer.nodeType === startContainer.TEXT_NODE) {
|
||||
// startContainer is expected to be the token text
|
||||
|
@ -842,7 +849,7 @@ export class MouseTargetFactory {
|
|||
let parent2ClassName = parent2 && parent2.nodeType === parent2.ELEMENT_NODE ? (<HTMLElement>parent2).className : null;
|
||||
|
||||
if (parent2ClassName === ViewLine.CLASS_NAME) {
|
||||
let p = ctx.getPositionFromDOMInfo(<HTMLElement>startContainer, (<HTMLElement>startContainer).textContent.length);
|
||||
let p = ctx.getPositionFromDOMInfo(<HTMLElement>startContainer, (<HTMLElement>startContainer).textContent!.length);
|
||||
return {
|
||||
position: p,
|
||||
hitTarget: null
|
||||
|
@ -919,7 +926,7 @@ export class MouseTargetFactory {
|
|||
|
||||
if (parent2ClassName === ViewLine.CLASS_NAME) {
|
||||
let rangeToContainEntireSpan = textRange.duplicate();
|
||||
rangeToContainEntireSpan.moveToElementText(parentElement);
|
||||
rangeToContainEntireSpan.moveToElementText(parentElement!);
|
||||
rangeToContainEntireSpan.setEndPoint('EndToStart', textRange);
|
||||
|
||||
resultPosition = ctx.getPositionFromDOMInfo(<HTMLElement>parentElement, rangeToContainEntireSpan.text.length);
|
||||
|
|
|
@ -234,7 +234,7 @@ export class PointerHandler implements IDisposable {
|
|||
}
|
||||
}
|
||||
|
||||
public getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget {
|
||||
public getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget | null {
|
||||
return this.handler.getTargetAtClientPoint(clientX, clientY);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ import { EndOfLinePreference } from 'vs/editor/common/model';
|
|||
import { getMapForWordSeparators, WordCharacterClass } from 'vs/editor/common/controller/wordCharacterClassifier';
|
||||
|
||||
export interface ITextAreaHandlerHelper {
|
||||
visibleRangeForPositionRelativeToEditor(lineNumber: number, column: number): HorizontalRange;
|
||||
visibleRangeForPositionRelativeToEditor(lineNumber: number, column: number): HorizontalRange | null;
|
||||
}
|
||||
|
||||
class VisibleTextAreaData {
|
||||
|
@ -55,7 +55,7 @@ const canUseZeroSizeTextarea = (browser.isEdgeOrIE || browser.isFirefox);
|
|||
interface LocalClipboardMetadata {
|
||||
lastCopiedValue: string;
|
||||
isFromEmptySelection: boolean;
|
||||
multicursorText: string[];
|
||||
multicursorText: string[] | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,17 +66,17 @@ interface LocalClipboardMetadata {
|
|||
class LocalClipboardMetadataManager {
|
||||
public static INSTANCE = new LocalClipboardMetadataManager();
|
||||
|
||||
private _lastState: LocalClipboardMetadata;
|
||||
private _lastState: LocalClipboardMetadata | null;
|
||||
|
||||
constructor() {
|
||||
this._lastState = null;
|
||||
}
|
||||
|
||||
public set(state: LocalClipboardMetadata): void {
|
||||
public set(state: LocalClipboardMetadata | null): void {
|
||||
this._lastState = state;
|
||||
}
|
||||
|
||||
public get(pastedText: string): LocalClipboardMetadata {
|
||||
public get(pastedText: string): LocalClipboardMetadata | null {
|
||||
if (this._lastState && this._lastState.lastCopiedValue === pastedText) {
|
||||
// match!
|
||||
return this._lastState;
|
||||
|
@ -104,7 +104,7 @@ export class TextAreaHandler extends ViewPart {
|
|||
/**
|
||||
* Defined only when the text area is visible (composition case).
|
||||
*/
|
||||
private _visibleTextArea: VisibleTextAreaData;
|
||||
private _visibleTextArea: VisibleTextAreaData | null;
|
||||
private _selections: Selection[];
|
||||
|
||||
public readonly textArea: FastDomNode<HTMLTextAreaElement>;
|
||||
|
@ -191,7 +191,7 @@ export class TextAreaHandler extends ViewPart {
|
|||
return whatToCopy;
|
||||
},
|
||||
|
||||
getHTMLToCopy: (): string => {
|
||||
getHTMLToCopy: (): string | null => {
|
||||
if (!this._copyWithSyntaxHighlighting && !CopyOptions.forceCopyWithSyntaxHighlighting) {
|
||||
return null;
|
||||
}
|
||||
|
@ -307,10 +307,10 @@ export class TextAreaHandler extends ViewPart {
|
|||
if (browser.isEdgeOrIE) {
|
||||
// Due to isEdgeOrIE (where the textarea was not cleared initially)
|
||||
// we cannot assume the text consists only of the composited text
|
||||
this._visibleTextArea = this._visibleTextArea.setWidth(0);
|
||||
this._visibleTextArea = this._visibleTextArea!.setWidth(0);
|
||||
} else {
|
||||
// adjust width by its size
|
||||
this._visibleTextArea = this._visibleTextArea.setWidth(measureText(e.data, this._fontInfo));
|
||||
this._visibleTextArea = this._visibleTextArea!.setWidth(measureText(e.data, this._fontInfo));
|
||||
}
|
||||
this._render();
|
||||
}));
|
||||
|
@ -564,7 +564,7 @@ export class TextAreaHandler extends ViewPart {
|
|||
function measureText(text: string, fontInfo: BareFontInfo): number {
|
||||
// adjust width by its size
|
||||
const canvasElem = <HTMLCanvasElement>document.createElement('canvas');
|
||||
const context = canvasElem.getContext('2d');
|
||||
const context = canvasElem.getContext('2d')!;
|
||||
context.font = createFontString(fontInfo);
|
||||
const metrics = context.measureText(text);
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ export interface IPasteData {
|
|||
|
||||
export interface ITextAreaInputHost {
|
||||
getPlainTextToCopy(): string;
|
||||
getHTMLToCopy(): string;
|
||||
getHTMLToCopy(): string | null;
|
||||
getScreenReaderContent(currentState: TextAreaState): TextAreaState;
|
||||
deduceModelPosition(viewAnchorPosition: Position, deltaOffset: number, lineFeedCnt: number): Position;
|
||||
}
|
||||
|
@ -400,10 +400,10 @@ export class TextAreaInput extends Disposable {
|
|||
}
|
||||
|
||||
const _newSelectionStartPosition = this._textAreaState.deduceEditorPosition(newSelectionStart);
|
||||
const newSelectionStartPosition = this._host.deduceModelPosition(_newSelectionStartPosition[0], _newSelectionStartPosition[1], _newSelectionStartPosition[2]);
|
||||
const newSelectionStartPosition = this._host.deduceModelPosition(_newSelectionStartPosition[0]!, _newSelectionStartPosition[1], _newSelectionStartPosition[2]);
|
||||
|
||||
const _newSelectionEndPosition = this._textAreaState.deduceEditorPosition(newSelectionEnd);
|
||||
const newSelectionEndPosition = this._host.deduceModelPosition(_newSelectionEndPosition[0], _newSelectionEndPosition[1], _newSelectionEndPosition[2]);
|
||||
const newSelectionEndPosition = this._host.deduceModelPosition(_newSelectionEndPosition[0]!, _newSelectionEndPosition[1], _newSelectionEndPosition[2]);
|
||||
|
||||
const newSelection = new Selection(
|
||||
newSelectionStartPosition.lineNumber, newSelectionStartPosition.column,
|
||||
|
@ -513,7 +513,7 @@ class ClipboardEventUtils {
|
|||
throw new Error('ClipboardEventUtils.getTextData: Cannot use text data!');
|
||||
}
|
||||
|
||||
public static setTextData(e: ClipboardEvent, text: string, richText: string): void {
|
||||
public static setTextData(e: ClipboardEvent, text: string, richText: string | null): void {
|
||||
if (e.clipboardData) {
|
||||
e.clipboardData.setData('text/plain', text);
|
||||
if (richText !== null) {
|
||||
|
|
|
@ -19,9 +19,9 @@ export class EditorState {
|
|||
|
||||
private readonly flags: number;
|
||||
|
||||
private readonly position: Position;
|
||||
private readonly selection: Range;
|
||||
private readonly modelVersionId: string;
|
||||
private readonly position: Position | null;
|
||||
private readonly selection: Range | null;
|
||||
private readonly modelVersionId: string | null;
|
||||
private readonly scrollLeft: number;
|
||||
private readonly scrollTop: number;
|
||||
|
||||
|
@ -88,7 +88,7 @@ export class StableEditorScrollState {
|
|||
}
|
||||
|
||||
constructor(
|
||||
private readonly _visiblePosition: Position,
|
||||
private readonly _visiblePosition: Position | null,
|
||||
private readonly _visiblePositionScrollDelta: number
|
||||
) {
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import { OverviewRulerZone } from 'vs/editor/common/view/overviewZoneManager';
|
|||
import { IModelContentChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelOptionsChangedEvent, IModelDecorationsChangedEvent } from 'vs/editor/common/model/textModelEvents';
|
||||
import { ICursorPositionChangedEvent, ICursorSelectionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ICursors, CursorConfiguration } from 'vs/editor/common/controller/cursorCommon';
|
||||
import { ICursors } from 'vs/editor/common/controller/cursorCommon';
|
||||
import { IEditorWhitespace } from 'vs/editor/common/viewLayout/whitespaceComputer';
|
||||
import { ITextModel, IIdentifiedSingleEditOperation, IModelDecoration, IModelDeltaDecoration } from 'vs/editor/common/model';
|
||||
|
||||
|
@ -64,7 +64,7 @@ export interface IViewZone {
|
|||
/**
|
||||
* An optional dom node for the view zone that will be placed in the margin area.
|
||||
*/
|
||||
marginDomNode?: HTMLElement;
|
||||
marginDomNode?: HTMLElement | null;
|
||||
/**
|
||||
* Callback which gives the relative top of the view zone as it appears (taking scrolling into account).
|
||||
*/
|
||||
|
@ -121,12 +121,12 @@ export interface IContentWidgetPosition {
|
|||
* Desired position for the content widget.
|
||||
* `preference` will also affect the placement.
|
||||
*/
|
||||
position: IPosition;
|
||||
position: IPosition | null;
|
||||
/**
|
||||
* Optionally, a range can be provided to further
|
||||
* define the position of the content widget.
|
||||
*/
|
||||
range?: IRange;
|
||||
range?: IRange | null;
|
||||
/**
|
||||
* Placement preference for position, in order of preference.
|
||||
*/
|
||||
|
@ -154,7 +154,7 @@ export interface IContentWidget {
|
|||
* Get the placement of the content widget.
|
||||
* If null is returned, the content widget will be placed off screen.
|
||||
*/
|
||||
getPosition(): IContentWidgetPosition;
|
||||
getPosition(): IContentWidgetPosition | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -201,7 +201,7 @@ export interface IOverlayWidget {
|
|||
* Get the placement of the overlay widget.
|
||||
* If null is returned, the overlay widget is responsible to place itself.
|
||||
*/
|
||||
getPosition(): IOverlayWidgetPosition;
|
||||
getPosition(): IOverlayWidgetPosition | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -273,7 +273,7 @@ export interface IMouseTarget {
|
|||
/**
|
||||
* The target element
|
||||
*/
|
||||
readonly element: Element;
|
||||
readonly element: Element | null;
|
||||
/**
|
||||
* The target type
|
||||
*/
|
||||
|
@ -281,7 +281,7 @@ export interface IMouseTarget {
|
|||
/**
|
||||
* The 'approximate' editor position
|
||||
*/
|
||||
readonly position: Position;
|
||||
readonly position: Position | null;
|
||||
/**
|
||||
* Desired mouse column (e.g. when position.column gets clamped to text length -- clicking after text on a line).
|
||||
*/
|
||||
|
@ -289,7 +289,7 @@ export interface IMouseTarget {
|
|||
/**
|
||||
* The 'approximate' editor range
|
||||
*/
|
||||
readonly range: Range;
|
||||
readonly range: Range | null;
|
||||
/**
|
||||
* Some extra detail.
|
||||
*/
|
||||
|
@ -300,7 +300,7 @@ export interface IMouseTarget {
|
|||
*/
|
||||
export interface IEditorMouseEvent {
|
||||
readonly event: IMouseEvent;
|
||||
readonly target: IMouseTarget;
|
||||
readonly target: IMouseTarget | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -481,7 +481,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
|||
/**
|
||||
* Saves current view state of the editor in a serializable object.
|
||||
*/
|
||||
saveViewState(): editorCommon.ICodeEditorViewState;
|
||||
saveViewState(): editorCommon.ICodeEditorViewState | null;
|
||||
|
||||
/**
|
||||
* Restores the view state of the editor from a serializable object generated by `saveViewState`.
|
||||
|
@ -509,7 +509,17 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
|||
/**
|
||||
* Type the getModel() of IEditor.
|
||||
*/
|
||||
getModel(): ITextModel;
|
||||
getModel(): ITextModel | null;
|
||||
|
||||
/**
|
||||
* Sets the current model attached to this editor.
|
||||
* If the previous model was created by the editor via the value key in the options
|
||||
* literal object, it will be destroyed. Otherwise, if the previous model was set
|
||||
* via setModel, or the model key in the options literal object, the previous model
|
||||
* will not be destroyed.
|
||||
* It is safe to call setModel(null) to simply detach the current model from the editor.
|
||||
*/
|
||||
setModel(model: ITextModel | null): void;
|
||||
|
||||
/**
|
||||
* Returns the current editor's configuration
|
||||
|
@ -599,22 +609,17 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
|||
* @param source The source of the call.
|
||||
* @param command The commands to execute
|
||||
*/
|
||||
executeCommands(source: string, commands: editorCommon.ICommand[]): void;
|
||||
executeCommands(source: string, commands: (editorCommon.ICommand | null)[]): void;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_getCursors(): ICursors;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_getCursorConfiguration(): CursorConfiguration;
|
||||
_getCursors(): ICursors | null;
|
||||
|
||||
/**
|
||||
* Get all the decorations on a line (filtering out decorations from other editors).
|
||||
*/
|
||||
getLineDecorations(lineNumber: number): IModelDecoration[];
|
||||
getLineDecorations(lineNumber: number): IModelDecoration[] | null;
|
||||
|
||||
/**
|
||||
* All decorations added through this call will get the ownerId of this editor.
|
||||
|
@ -673,12 +678,12 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
|||
/**
|
||||
* @internal
|
||||
*/
|
||||
getTelemetryData(): { [key: string]: any; };
|
||||
getTelemetryData(): { [key: string]: any; } | null;
|
||||
|
||||
/**
|
||||
* Returns the editor's dom node
|
||||
*/
|
||||
getDomNode(): HTMLElement;
|
||||
getDomNode(): HTMLElement | null;
|
||||
|
||||
/**
|
||||
* Add a content widget. Widgets must have unique ids, otherwise they will be overwritten.
|
||||
|
@ -725,6 +730,79 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
|||
*/
|
||||
render(): void;
|
||||
|
||||
/**
|
||||
* Get the hit test target at coordinates `clientX` and `clientY`.
|
||||
* The coordinates are relative to the top-left of the viewport.
|
||||
*
|
||||
* @returns Hit test target or null if the coordinates fall outside the editor or the editor has no model.
|
||||
*/
|
||||
getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget | null;
|
||||
|
||||
/**
|
||||
* Get the visible position for `position`.
|
||||
* The result position takes scrolling into account and is relative to the top left corner of the editor.
|
||||
* Explanation 1: the results of this method will change for the same `position` if the user scrolls the editor.
|
||||
* Explanation 2: the results of this method will not change if the container of the editor gets repositioned.
|
||||
* Warning: the results of this method are innacurate for positions that are outside the current editor viewport.
|
||||
*/
|
||||
getScrolledVisiblePosition(position: IPosition): { top: number; left: number; height: number; } | null;
|
||||
|
||||
/**
|
||||
* Apply the same font settings as the editor to `target`.
|
||||
*/
|
||||
applyFontInfo(target: HTMLElement): void;
|
||||
|
||||
/**
|
||||
* Check if the current instance has a model attached.
|
||||
* @internal
|
||||
*/
|
||||
hasModel(): this is IActiveCodeEditor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface IActiveCodeEditor extends ICodeEditor {
|
||||
/**
|
||||
* Returns the primary position of the cursor.
|
||||
*/
|
||||
getPosition(): Position;
|
||||
|
||||
/**
|
||||
* Returns the primary selection of the editor.
|
||||
*/
|
||||
getSelection(): Selection;
|
||||
|
||||
/**
|
||||
* Returns all the selections of the editor.
|
||||
*/
|
||||
getSelections(): Selection[];
|
||||
|
||||
/**
|
||||
* Saves current view state of the editor in a serializable object.
|
||||
*/
|
||||
saveViewState(): editorCommon.ICodeEditorViewState;
|
||||
|
||||
/**
|
||||
* Type the getModel() of IEditor.
|
||||
*/
|
||||
getModel(): ITextModel;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_getCursors(): ICursors;
|
||||
|
||||
/**
|
||||
* Get all the decorations on a line (filtering out decorations from other editors).
|
||||
*/
|
||||
getLineDecorations(lineNumber: number): IModelDecoration[];
|
||||
|
||||
/**
|
||||
* Returns the editor's dom node
|
||||
*/
|
||||
getDomNode(): HTMLElement;
|
||||
|
||||
/**
|
||||
* Get the hit test target at coordinates `clientX` and `clientY`.
|
||||
* The coordinates are relative to the top-left of the viewport.
|
||||
|
@ -741,11 +819,6 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
|||
* Warning: the results of this method are innacurate for positions that are outside the current editor viewport.
|
||||
*/
|
||||
getScrolledVisiblePosition(position: IPosition): { top: number; left: number; height: number; };
|
||||
|
||||
/**
|
||||
* Apply the same font settings as the editor to `target`.
|
||||
*/
|
||||
applyFontInfo(target: HTMLElement): void;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -790,7 +863,7 @@ export interface IDiffEditor extends editorCommon.IEditor {
|
|||
/**
|
||||
* Saves current view state of the editor in a serializable object.
|
||||
*/
|
||||
saveViewState(): editorCommon.IDiffEditorViewState;
|
||||
saveViewState(): editorCommon.IDiffEditorViewState | null;
|
||||
|
||||
/**
|
||||
* Restores the view state of the editor from a serializable object generated by `saveViewState`.
|
||||
|
@ -800,7 +873,17 @@ export interface IDiffEditor extends editorCommon.IEditor {
|
|||
/**
|
||||
* Type the getModel() of IEditor.
|
||||
*/
|
||||
getModel(): editorCommon.IDiffEditorModel;
|
||||
getModel(): editorCommon.IDiffEditorModel | null;
|
||||
|
||||
/**
|
||||
* Sets the current model attached to this editor.
|
||||
* If the previous model was created by the editor via the value key in the options
|
||||
* literal object, it will be destroyed. Otherwise, if the previous model was set
|
||||
* via setModel, or the model key in the options literal object, the previous model
|
||||
* will not be destroyed.
|
||||
* It is safe to call setModel(null) to simply detach the current model from the editor.
|
||||
*/
|
||||
setModel(model: editorCommon.IDiffEditorModel | null): void;
|
||||
|
||||
/**
|
||||
* Get the `original` editor.
|
||||
|
@ -815,19 +898,19 @@ export interface IDiffEditor extends editorCommon.IEditor {
|
|||
/**
|
||||
* Get the computed diff information.
|
||||
*/
|
||||
getLineChanges(): editorCommon.ILineChange[];
|
||||
getLineChanges(): editorCommon.ILineChange[] | null;
|
||||
|
||||
/**
|
||||
* Get information based on computed diff about a line number from the original model.
|
||||
* If the diff computation is not finished or the model is missing, will return null.
|
||||
*/
|
||||
getDiffLineInformationForOriginal(lineNumber: number): IDiffLineInformation;
|
||||
getDiffLineInformationForOriginal(lineNumber: number): IDiffLineInformation | null;
|
||||
|
||||
/**
|
||||
* Get information based on computed diff about a line number from the modified model.
|
||||
* If the diff computation is not finished or the model is missing, will return null.
|
||||
*/
|
||||
getDiffLineInformationForModified(lineNumber: number): IDiffLineInformation;
|
||||
getDiffLineInformationForModified(lineNumber: number): IDiffLineInformation | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -855,7 +938,7 @@ export function isDiffEditor(thing: any): thing is IDiffEditor {
|
|||
/**
|
||||
*@internal
|
||||
*/
|
||||
export function getCodeEditor(thing: any): ICodeEditor {
|
||||
export function getCodeEditor(thing: any): ICodeEditor | null {
|
||||
if (isCodeEditor(thing)) {
|
||||
return thing;
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ export class GlobalEditorMouseMoveMonitor extends Disposable {
|
|||
|
||||
private _editorViewDomNode: HTMLElement;
|
||||
private _globalMouseMoveMonitor: GlobalMouseMoveMonitor<EditorMouseEvent>;
|
||||
private _keydownListener: IDisposable;
|
||||
private _keydownListener: IDisposable | null;
|
||||
|
||||
constructor(editorViewDomNode: HTMLElement) {
|
||||
super();
|
||||
|
@ -162,7 +162,7 @@ export class GlobalEditorMouseMoveMonitor extends Disposable {
|
|||
};
|
||||
|
||||
this._globalMouseMoveMonitor.startMonitoring(myMerger, mouseMoveCallback, () => {
|
||||
this._keydownListener.dispose();
|
||||
this._keydownListener!.dispose();
|
||||
onStopCallback();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ export type IEditorContributionCtor = IConstructorSignature1<ICodeEditor, editor
|
|||
//#region Command
|
||||
|
||||
export interface ICommandKeybindingsOptions extends IKeybindings {
|
||||
kbExpr?: ContextKeyExpr;
|
||||
kbExpr?: ContextKeyExpr | null;
|
||||
weight: number;
|
||||
}
|
||||
export interface ICommandMenubarOptions {
|
||||
|
@ -38,17 +38,17 @@ export interface ICommandMenubarOptions {
|
|||
}
|
||||
export interface ICommandOptions {
|
||||
id: string;
|
||||
precondition: ContextKeyExpr;
|
||||
kbOpts?: ICommandKeybindingsOptions;
|
||||
precondition: ContextKeyExpr | null;
|
||||
kbOpts?: ICommandKeybindingsOptions | null;
|
||||
description?: ICommandHandlerDescription;
|
||||
menubarOpts?: ICommandMenubarOptions;
|
||||
}
|
||||
export abstract class Command {
|
||||
public readonly id: string;
|
||||
public readonly precondition: ContextKeyExpr;
|
||||
private readonly _kbOpts: ICommandKeybindingsOptions;
|
||||
private readonly _menubarOpts: ICommandMenubarOptions;
|
||||
private readonly _description: ICommandHandlerDescription;
|
||||
public readonly precondition: ContextKeyExpr | null;
|
||||
private readonly _kbOpts: ICommandKeybindingsOptions | null | undefined;
|
||||
private readonly _menubarOpts: ICommandMenubarOptions | null | undefined;
|
||||
private readonly _description: ICommandHandlerDescription | null | undefined;
|
||||
|
||||
constructor(opts: ICommandOptions) {
|
||||
this.id = opts.id;
|
||||
|
@ -87,7 +87,7 @@ export abstract class Command {
|
|||
id: this.id,
|
||||
handler: (accessor, args) => this.runCommand(accessor, args),
|
||||
weight: this._kbOpts.weight,
|
||||
when: kbWhen,
|
||||
when: kbWhen || null,
|
||||
primary: this._kbOpts.primary,
|
||||
secondary: this._kbOpts.secondary,
|
||||
win: this._kbOpts.win,
|
||||
|
@ -160,7 +160,7 @@ export abstract class EditorCommand extends Command {
|
|||
return;
|
||||
}
|
||||
|
||||
return this.runEditorCommand(editorAccessor, editor, args);
|
||||
return this.runEditorCommand(editorAccessor, editor!, args);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -185,7 +185,7 @@ export abstract class EditorAction extends EditorCommand {
|
|||
|
||||
public label: string;
|
||||
public alias: string;
|
||||
private menuOpts: IEditorCommandMenuOptions;
|
||||
private menuOpts: IEditorCommandMenuOptions | undefined;
|
||||
|
||||
constructor(opts: IActionOptions) {
|
||||
super(opts);
|
||||
|
|
|
@ -70,7 +70,7 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC
|
|||
return Object.keys(this._diffEditors).map(id => this._diffEditors[id]);
|
||||
}
|
||||
|
||||
getFocusedCodeEditor(): ICodeEditor {
|
||||
getFocusedCodeEditor(): ICodeEditor | null {
|
||||
let editorWithWidgetFocus: ICodeEditor | null = null;
|
||||
|
||||
let editors = this.listCodeEditors();
|
||||
|
@ -92,7 +92,7 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC
|
|||
|
||||
abstract registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string): void;
|
||||
abstract removeDecorationType(key: string): void;
|
||||
abstract resolveDecorationOptions(decorationTypeKey: string, writable: boolean): IModelDecorationOptions;
|
||||
abstract resolveDecorationOptions(decorationTypeKey: string | undefined, writable: boolean): IModelDecorationOptions;
|
||||
|
||||
private _transientWatchers: { [uri: string]: ModelTransientSettingWatcher; } = {};
|
||||
|
||||
|
@ -125,8 +125,8 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC
|
|||
delete this._transientWatchers[w.uri];
|
||||
}
|
||||
|
||||
abstract getActiveCodeEditor(): ICodeEditor;
|
||||
abstract openCodeEditor(input: IResourceInput, source: ICodeEditor, sideBySide?: boolean): Thenable<ICodeEditor>;
|
||||
abstract getActiveCodeEditor(): ICodeEditor | null;
|
||||
abstract openCodeEditor(input: IResourceInput, source: ICodeEditor | null, sideBySide?: boolean): Thenable<ICodeEditor | null>;
|
||||
}
|
||||
|
||||
export class ModelTransientSettingWatcher {
|
||||
|
|
|
@ -35,7 +35,7 @@ export interface ICodeEditorService {
|
|||
/**
|
||||
* Returns the current focused code editor (if the focus is in the editor or in an editor widget) or null.
|
||||
*/
|
||||
getFocusedCodeEditor(): ICodeEditor;
|
||||
getFocusedCodeEditor(): ICodeEditor | null;
|
||||
|
||||
registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string): void;
|
||||
removeDecorationType(key: string): void;
|
||||
|
@ -44,6 +44,6 @@ export interface ICodeEditorService {
|
|||
setTransientModelProperty(model: ITextModel, key: string, value: any): void;
|
||||
getTransientModelProperty(model: ITextModel, key: string): any;
|
||||
|
||||
getActiveCodeEditor(): ICodeEditor;
|
||||
openCodeEditor(input: IResourceInput, source: ICodeEditor, sideBySide?: boolean): Thenable<ICodeEditor>;
|
||||
getActiveCodeEditor(): ICodeEditor | null;
|
||||
openCodeEditor(input: IResourceInput, source: ICodeEditor | null, sideBySide?: boolean): Thenable<ICodeEditor | null>;
|
||||
}
|
||||
|
|
|
@ -66,8 +66,8 @@ export abstract class CodeEditorServiceImpl extends AbstractCodeEditorService {
|
|||
return provider.getOptions(this, writable);
|
||||
}
|
||||
|
||||
abstract getActiveCodeEditor(): ICodeEditor;
|
||||
abstract openCodeEditor(input: IResourceInput, source: ICodeEditor, sideBySide?: boolean): Thenable<ICodeEditor>;
|
||||
abstract getActiveCodeEditor(): ICodeEditor | null;
|
||||
abstract openCodeEditor(input: IResourceInput, source: ICodeEditor | null, sideBySide?: boolean): Thenable<ICodeEditor | null>;
|
||||
}
|
||||
|
||||
interface IModelDecorationOptionsProvider extends IDisposable {
|
||||
|
@ -79,9 +79,9 @@ class DecorationSubTypeOptionsProvider implements IModelDecorationOptionsProvide
|
|||
|
||||
public refCount: number;
|
||||
|
||||
private _parentTypeKey: string;
|
||||
private _beforeContentRules: DecorationCSSRules;
|
||||
private _afterContentRules: DecorationCSSRules;
|
||||
private _parentTypeKey: string | undefined;
|
||||
private _beforeContentRules: DecorationCSSRules | null;
|
||||
private _afterContentRules: DecorationCSSRules | null;
|
||||
|
||||
constructor(themeService: IThemeService, providerArgs: ProviderArguments) {
|
||||
this._parentTypeKey = providerArgs.parentTypeKey;
|
||||
|
@ -127,15 +127,15 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
|
|||
private _disposables: IDisposable[];
|
||||
public refCount: number;
|
||||
|
||||
public className: string;
|
||||
public className: string | undefined;
|
||||
public inlineClassName: string;
|
||||
public inlineClassNameAffectsLetterSpacing: boolean;
|
||||
public beforeContentClassName: string;
|
||||
public afterContentClassName: string;
|
||||
public glyphMarginClassName: string;
|
||||
public beforeContentClassName: string | undefined;
|
||||
public afterContentClassName: string | undefined;
|
||||
public glyphMarginClassName: string | undefined;
|
||||
public isWholeLine: boolean;
|
||||
public overviewRuler: IModelDecorationOverviewRulerOptions;
|
||||
public stickiness: TrackedRangeStickiness;
|
||||
public stickiness: TrackedRangeStickiness | undefined;
|
||||
|
||||
constructor(themeService: IThemeService, providerArgs: ProviderArguments) {
|
||||
this.refCount = 0;
|
||||
|
@ -250,7 +250,7 @@ class DecorationCSSRules {
|
|||
private _hasContent: boolean;
|
||||
private _hasLetterSpacing: boolean;
|
||||
private _ruleType: ModelDecorationCSSRuleType;
|
||||
private _themeListener: IDisposable;
|
||||
private _themeListener: IDisposable | null;
|
||||
private _providerArgs: ProviderArguments;
|
||||
private _usesThemeColors: boolean;
|
||||
|
||||
|
@ -278,6 +278,8 @@ class DecorationCSSRules {
|
|||
this._removeCSS();
|
||||
this._buildCSS();
|
||||
});
|
||||
} else {
|
||||
this._themeListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -361,7 +363,7 @@ class DecorationCSSRules {
|
|||
/**
|
||||
* Build the CSS for decorations styled via `className`.
|
||||
*/
|
||||
private getCSSTextForModelDecorationClassName(opts: IThemeDecorationRenderOptions): string {
|
||||
private getCSSTextForModelDecorationClassName(opts: IThemeDecorationRenderOptions | undefined): string {
|
||||
if (!opts) {
|
||||
return '';
|
||||
}
|
||||
|
@ -375,7 +377,7 @@ class DecorationCSSRules {
|
|||
/**
|
||||
* Build the CSS for decorations styled via `inlineClassName`.
|
||||
*/
|
||||
private getCSSTextForModelDecorationInlineClassName(opts: IThemeDecorationRenderOptions): string {
|
||||
private getCSSTextForModelDecorationInlineClassName(opts: IThemeDecorationRenderOptions | undefined): string {
|
||||
if (!opts) {
|
||||
return '';
|
||||
}
|
||||
|
@ -390,7 +392,7 @@ class DecorationCSSRules {
|
|||
/**
|
||||
* Build the CSS for decorations styled before or after content.
|
||||
*/
|
||||
private getCSSTextForModelDecorationContentClassName(opts: IContentDecorationRenderOptions): string {
|
||||
private getCSSTextForModelDecorationContentClassName(opts: IContentDecorationRenderOptions | undefined): string {
|
||||
if (!opts) {
|
||||
return '';
|
||||
}
|
||||
|
@ -406,7 +408,7 @@ class DecorationCSSRules {
|
|||
}
|
||||
}
|
||||
if (typeof opts.contentText === 'string') {
|
||||
const truncated = opts.contentText.match(/^.*$/m)[0]; // only take first line
|
||||
const truncated = opts.contentText.match(/^.*$/m)![0]; // only take first line
|
||||
const escaped = truncated.replace(/['\\]/g, '\\$&');
|
||||
|
||||
cssTextArr.push(strings.format(_CSS_MAP.contentText, escaped));
|
||||
|
@ -423,11 +425,11 @@ class DecorationCSSRules {
|
|||
/**
|
||||
* Build the CSS for decorations styled via `glpyhMarginClassName`.
|
||||
*/
|
||||
private getCSSTextForModelDecorationGlyphMarginClassName(opts: IThemeDecorationRenderOptions): string {
|
||||
private getCSSTextForModelDecorationGlyphMarginClassName(opts: IThemeDecorationRenderOptions | undefined): string {
|
||||
if (!opts) {
|
||||
return '';
|
||||
}
|
||||
let cssTextArr = [];
|
||||
let cssTextArr: string[] = [];
|
||||
|
||||
if (typeof opts.gutterIconPath !== 'undefined') {
|
||||
if (typeof opts.gutterIconPath === 'string') {
|
||||
|
@ -489,7 +491,7 @@ class CSSNameHelper {
|
|||
return 'ced-' + key + '-' + type;
|
||||
}
|
||||
|
||||
public static getSelector(key: string, parentKey: string, ruleType: ModelDecorationCSSRuleType): string {
|
||||
public static getSelector(key: string, parentKey: string | undefined, ruleType: ModelDecorationCSSRuleType): string {
|
||||
let selector = '.monaco-editor .' + this.getClassName(key, ruleType);
|
||||
if (parentKey) {
|
||||
selector = selector + '.' + this.getClassName(parentKey, ruleType);
|
||||
|
|
|
@ -29,15 +29,17 @@ export class OpenerService implements IOpenerService {
|
|||
|
||||
open(resource: URI, options?: { openToSide?: boolean }): Promise<any> {
|
||||
|
||||
/* __GDPR__
|
||||
"openerService" : {
|
||||
"scheme" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
this._telemetryService.publicLog('openerService', { scheme: resource.scheme });
|
||||
if (this._telemetryService) {
|
||||
/* __GDPR__
|
||||
"openerService" : {
|
||||
"scheme" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
this._telemetryService.publicLog('openerService', { scheme: resource.scheme });
|
||||
}
|
||||
|
||||
const { scheme, path, query, fragment } = resource;
|
||||
let promise: Thenable<any>;
|
||||
let promise: Thenable<any> | undefined = undefined;
|
||||
|
||||
if (scheme === Schemas.http || scheme === Schemas.https || scheme === Schemas.mailto) {
|
||||
// open http or default mail application
|
||||
|
@ -59,7 +61,7 @@ export class OpenerService implements IOpenerService {
|
|||
let selection: {
|
||||
startLineNumber: number;
|
||||
startColumn: number;
|
||||
};
|
||||
} | undefined = undefined;
|
||||
const match = /^L?(\d+)(?:,(\d+))?/.exec(fragment);
|
||||
if (match) {
|
||||
// support file:///some/file.js#73,84
|
||||
|
|
|
@ -12,10 +12,6 @@ import { ViewOutgoingEvents } from 'vs/editor/browser/view/viewOutgoingEvents';
|
|||
import { CoreNavigationCommands, CoreEditorCommand } from 'vs/editor/browser/controller/coreCommands';
|
||||
import { IConfiguration } from 'vs/editor/common/editorCommon';
|
||||
|
||||
export interface ExecCoreEditorCommandFunc {
|
||||
(editorCommand: CoreEditorCommand, args: any): void;
|
||||
}
|
||||
|
||||
export interface IMouseDispatchData {
|
||||
position: Position;
|
||||
/**
|
||||
|
@ -36,7 +32,9 @@ export interface IMouseDispatchData {
|
|||
}
|
||||
|
||||
export interface ICommandDelegate {
|
||||
paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[]): void;
|
||||
executeEditorCommand(editorCommand: CoreEditorCommand, args: any): void;
|
||||
|
||||
paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[] | null): void;
|
||||
type(source: string, text: string): void;
|
||||
replacePreviousChar(source: string, text: string, replaceCharCnt: number): void;
|
||||
compositionStart(source: string): void;
|
||||
|
@ -48,30 +46,27 @@ export class ViewController {
|
|||
|
||||
private readonly configuration: IConfiguration;
|
||||
private readonly viewModel: IViewModel;
|
||||
private readonly _execCoreEditorCommandFunc: ExecCoreEditorCommandFunc;
|
||||
private readonly outgoingEvents: ViewOutgoingEvents;
|
||||
private readonly commandDelegate: ICommandDelegate;
|
||||
|
||||
constructor(
|
||||
configuration: IConfiguration,
|
||||
viewModel: IViewModel,
|
||||
execCommandFunc: ExecCoreEditorCommandFunc,
|
||||
outgoingEvents: ViewOutgoingEvents,
|
||||
commandDelegate: ICommandDelegate
|
||||
) {
|
||||
this.configuration = configuration;
|
||||
this.viewModel = viewModel;
|
||||
this._execCoreEditorCommandFunc = execCommandFunc;
|
||||
this.outgoingEvents = outgoingEvents;
|
||||
this.commandDelegate = commandDelegate;
|
||||
}
|
||||
|
||||
private _execMouseCommand(editorCommand: CoreEditorCommand, args: any): void {
|
||||
args.source = 'mouse';
|
||||
this._execCoreEditorCommandFunc(editorCommand, args);
|
||||
this.commandDelegate.executeEditorCommand(editorCommand, args);
|
||||
}
|
||||
|
||||
public paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[]): void {
|
||||
public paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[] | null): void {
|
||||
this.commandDelegate.paste(source, text, pasteOnNewLine, multicursorText);
|
||||
}
|
||||
|
||||
|
@ -96,7 +91,7 @@ export class ViewController {
|
|||
}
|
||||
|
||||
public setSelection(source: string, modelSelection: Selection): void {
|
||||
this._execCoreEditorCommandFunc(CoreNavigationCommands.SetSelection, {
|
||||
this.commandDelegate.executeEditorCommand(CoreNavigationCommands.SetSelection, {
|
||||
source: source,
|
||||
selection: modelSelection
|
||||
});
|
||||
|
|
|
@ -13,7 +13,7 @@ import { IConfiguration } from 'vs/editor/common/editorCommon';
|
|||
import { TextAreaHandler, ITextAreaHandlerHelper } from 'vs/editor/browser/controller/textAreaHandler';
|
||||
import { PointerHandler } from 'vs/editor/browser/controller/pointerHandler';
|
||||
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
|
||||
import { ViewController, ExecCoreEditorCommandFunc, ICommandDelegate } from 'vs/editor/browser/view/viewController';
|
||||
import { ViewController, ICommandDelegate } from 'vs/editor/browser/view/viewController';
|
||||
import { ViewEventDispatcher } from 'vs/editor/common/view/viewEventDispatcher';
|
||||
import { ContentViewOverlays, MarginViewOverlays } from 'vs/editor/browser/view/viewOverlays';
|
||||
import { ViewContentWidgets } from 'vs/editor/browser/viewParts/contentWidgets/contentWidgets';
|
||||
|
@ -51,14 +51,16 @@ import { IMouseEvent } from 'vs/base/browser/mouseEvent';
|
|||
|
||||
export interface IContentWidgetData {
|
||||
widget: editorBrowser.IContentWidget;
|
||||
position: editorBrowser.IContentWidgetPosition;
|
||||
position: editorBrowser.IContentWidgetPosition | null;
|
||||
}
|
||||
|
||||
export interface IOverlayWidgetData {
|
||||
widget: editorBrowser.IOverlayWidget;
|
||||
position: editorBrowser.IOverlayWidgetPosition;
|
||||
position: editorBrowser.IOverlayWidgetPosition | null;
|
||||
}
|
||||
|
||||
const invalidFunc = () => { throw new Error(`Invalid change accessor`); };
|
||||
|
||||
export class View extends ViewEventHandler {
|
||||
|
||||
private eventDispatcher: ViewEventDispatcher;
|
||||
|
@ -88,7 +90,7 @@ export class View extends ViewEventHandler {
|
|||
private overflowGuardContainer: FastDomNode<HTMLElement>;
|
||||
|
||||
// Actual mutable state
|
||||
private _renderAnimationFrame: IDisposable;
|
||||
private _renderAnimationFrame: IDisposable | null;
|
||||
|
||||
constructor(
|
||||
commandDelegate: ICommandDelegate,
|
||||
|
@ -96,14 +98,14 @@ export class View extends ViewEventHandler {
|
|||
themeService: IThemeService,
|
||||
model: IViewModel,
|
||||
cursor: Cursor,
|
||||
execCoreEditorCommandFunc: ExecCoreEditorCommandFunc
|
||||
outgoingEvents: ViewOutgoingEvents
|
||||
) {
|
||||
super();
|
||||
this._cursor = cursor;
|
||||
this._renderAnimationFrame = null;
|
||||
this.outgoingEvents = new ViewOutgoingEvents(model);
|
||||
this.outgoingEvents = outgoingEvents;
|
||||
|
||||
let viewController = new ViewController(configuration, model, execCoreEditorCommandFunc, this.outgoingEvents, commandDelegate);
|
||||
let viewController = new ViewController(configuration, model, this.outgoingEvents, commandDelegate);
|
||||
|
||||
// The event dispatcher will always go through _renderOnce before dispatching any events
|
||||
this.eventDispatcher = new ViewEventDispatcher((callback: () => void) => this._renderOnce(callback));
|
||||
|
@ -462,14 +464,10 @@ export class View extends ViewEventHandler {
|
|||
return visibleRange.left;
|
||||
}
|
||||
|
||||
public getTargetAtClientPoint(clientX: number, clientY: number): editorBrowser.IMouseTarget {
|
||||
public getTargetAtClientPoint(clientX: number, clientY: number): editorBrowser.IMouseTarget | null {
|
||||
return this.pointerHandler.getTargetAtClientPoint(clientX, clientY);
|
||||
}
|
||||
|
||||
public getInternalEventBus(): ViewOutgoingEvents {
|
||||
return this.outgoingEvents;
|
||||
}
|
||||
|
||||
public createOverviewRuler(cssClassName: string): OverviewRuler {
|
||||
return new OverviewRuler(this._context, cssClassName);
|
||||
}
|
||||
|
@ -500,8 +498,9 @@ export class View extends ViewEventHandler {
|
|||
safeInvoke1Arg(callback, changeAccessor);
|
||||
|
||||
// Invalidate changeAccessor
|
||||
changeAccessor.addZone = null;
|
||||
changeAccessor.removeZone = null;
|
||||
changeAccessor.addZone = invalidFunc;
|
||||
changeAccessor.removeZone = invalidFunc;
|
||||
changeAccessor.layoutZone = invalidFunc;
|
||||
|
||||
if (zonesHaveChanged) {
|
||||
this._context.viewLayout.onHeightMaybeChanged();
|
||||
|
|
|
@ -12,7 +12,7 @@ import { createStringBuilder, IStringBuilder } from 'vs/editor/common/core/strin
|
|||
* Represents a visible line
|
||||
*/
|
||||
export interface IVisibleLine extends ILine {
|
||||
getDomNode(): HTMLElement;
|
||||
getDomNode(): HTMLElement | null;
|
||||
setDomNode(domNode: HTMLElement): void;
|
||||
|
||||
/**
|
||||
|
@ -87,7 +87,7 @@ export class RenderedLinesCollection<T extends ILine> {
|
|||
/**
|
||||
* @returns Lines that were removed from this collection
|
||||
*/
|
||||
public onLinesDeleted(deleteFromLineNumber: number, deleteToLineNumber: number): T[] {
|
||||
public onLinesDeleted(deleteFromLineNumber: number, deleteToLineNumber: number): T[] | null {
|
||||
if (this.getCount() === 0) {
|
||||
// no lines
|
||||
return null;
|
||||
|
@ -167,7 +167,7 @@ export class RenderedLinesCollection<T extends ILine> {
|
|||
return someoneNotified;
|
||||
}
|
||||
|
||||
public onLinesInserted(insertFromLineNumber: number, insertToLineNumber: number): T[] {
|
||||
public onLinesInserted(insertFromLineNumber: number, insertToLineNumber: number): T[] | null {
|
||||
if (this.getCount() === 0) {
|
||||
// no lines
|
||||
return null;
|
||||
|
@ -527,8 +527,8 @@ class ViewLayerRenderer<T extends IVisibleLine> {
|
|||
let line = ctx.lines[i];
|
||||
if (wasInvalid[i]) {
|
||||
let source = <HTMLElement>hugeDomNode.firstChild;
|
||||
let lineDomNode = line.getDomNode();
|
||||
lineDomNode.parentNode.replaceChild(source, lineDomNode);
|
||||
let lineDomNode = line.getDomNode()!;
|
||||
lineDomNode.parentNode!.replaceChild(source, lineDomNode);
|
||||
line.setDomNode(source);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,14 +143,14 @@ export class ViewOutgoingEvents extends Disposable {
|
|||
|
||||
class ExternalMouseTarget implements IMouseTarget {
|
||||
|
||||
public readonly element: Element;
|
||||
public readonly element: Element | null;
|
||||
public readonly type: MouseTargetType;
|
||||
public readonly mouseColumn: number;
|
||||
public readonly position: Position;
|
||||
public readonly range: Range;
|
||||
public readonly position: Position | null;
|
||||
public readonly range: Range | null;
|
||||
public readonly detail: any;
|
||||
|
||||
constructor(element: Element, type: MouseTargetType, mouseColumn: number, position: Position, range: Range, detail: any) {
|
||||
constructor(element: Element | null, type: MouseTargetType, mouseColumn: number, position: Position | null, range: Range | null, detail: any) {
|
||||
this.element = element;
|
||||
this.type = type;
|
||||
this.mouseColumn = mouseColumn;
|
||||
|
|
|
@ -56,7 +56,7 @@ export class ViewOverlays extends ViewPart implements IVisibleLinesHost<ViewOver
|
|||
let dynamicOverlay = this._dynamicOverlays[i];
|
||||
dynamicOverlay.dispose();
|
||||
}
|
||||
this._dynamicOverlays = null;
|
||||
this._dynamicOverlays = [];
|
||||
}
|
||||
|
||||
public getDomNode(): FastDomNode<HTMLElement> {
|
||||
|
@ -123,8 +123,6 @@ export class ViewOverlays extends ViewPart implements IVisibleLinesHost<ViewOver
|
|||
dynamicOverlay.prepareRender(ctx);
|
||||
dynamicOverlay.onDidRender();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public render(ctx: RestrictedRenderingContext): void {
|
||||
|
@ -143,8 +141,8 @@ export class ViewOverlayLine implements IVisibleLine {
|
|||
|
||||
private _configuration: IConfiguration;
|
||||
private _dynamicOverlays: DynamicViewOverlay[];
|
||||
private _domNode: FastDomNode<HTMLElement>;
|
||||
private _renderedContent: string;
|
||||
private _domNode: FastDomNode<HTMLElement> | null;
|
||||
private _renderedContent: string | null;
|
||||
private _lineHeight: number;
|
||||
|
||||
constructor(configuration: IConfiguration, dynamicOverlays: DynamicViewOverlay[]) {
|
||||
|
@ -156,7 +154,7 @@ export class ViewOverlayLine implements IVisibleLine {
|
|||
this._renderedContent = null;
|
||||
}
|
||||
|
||||
public getDomNode(): HTMLElement {
|
||||
public getDomNode(): HTMLElement | null {
|
||||
if (!this._domNode) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ export abstract class ViewPart extends ViewEventHandler {
|
|||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
@ -58,7 +57,7 @@ export class PartFingerprints {
|
|||
return parseInt(r, 10);
|
||||
}
|
||||
|
||||
public static collect(child: Element, stopAt: Element): Uint8Array {
|
||||
public static collect(child: Element | null, stopAt: Element): Uint8Array {
|
||||
let result: PartFingerprint[] = [], resultLen = 0;
|
||||
|
||||
while (child && child !== document.body) {
|
||||
|
|
|
@ -53,8 +53,7 @@ export class ViewContentWidgets extends ViewPart {
|
|||
|
||||
public dispose(): void {
|
||||
super.dispose();
|
||||
this._widgets = null;
|
||||
this.domNode = null;
|
||||
this._widgets = {};
|
||||
}
|
||||
|
||||
// --- begin event handlers
|
||||
|
@ -113,7 +112,7 @@ export class ViewContentWidgets extends ViewPart {
|
|||
this.setShouldRender();
|
||||
}
|
||||
|
||||
public setWidgetPosition(widget: IContentWidget, position: IPosition, range: IRange, preference: ContentWidgetPositionPreference[]): void {
|
||||
public setWidgetPosition(widget: IContentWidget, position: IPosition | null | undefined, range: IRange | null | undefined, preference: ContentWidgetPositionPreference[] | null | undefined): void {
|
||||
const myWidget = this._widgets[widget.getId()];
|
||||
myWidget.setPosition(position, range, preference);
|
||||
|
||||
|
@ -127,7 +126,7 @@ export class ViewContentWidgets extends ViewPart {
|
|||
delete this._widgets[widgetId];
|
||||
|
||||
const domNode = myWidget.domNode.domNode;
|
||||
domNode.parentNode.removeChild(domNode);
|
||||
domNode.parentNode!.removeChild(domNode);
|
||||
domNode.removeAttribute('monaco-visible-content-widget');
|
||||
|
||||
this.setShouldRender();
|
||||
|
@ -191,17 +190,17 @@ class Widget {
|
|||
private _contentLeft: number;
|
||||
private _lineHeight: number;
|
||||
|
||||
private _position: IPosition;
|
||||
private _viewPosition: Position;
|
||||
private _range: IRange;
|
||||
private _viewRange: Range;
|
||||
private _preference: ContentWidgetPositionPreference[];
|
||||
private _position: IPosition | null;
|
||||
private _viewPosition: Position | null;
|
||||
private _range: IRange | null;
|
||||
private _viewRange: Range | null;
|
||||
private _preference: ContentWidgetPositionPreference[] | null;
|
||||
private _cachedDomNodeClientWidth: number;
|
||||
private _cachedDomNodeClientHeight: number;
|
||||
private _maxWidth: number;
|
||||
private _isVisible: boolean;
|
||||
|
||||
private _renderData: Coordinate;
|
||||
private _renderData: Coordinate | null;
|
||||
|
||||
constructor(context: ViewContext, viewDomNode: FastDomNode<HTMLElement>, actual: IContentWidget) {
|
||||
this._context = context;
|
||||
|
@ -219,7 +218,7 @@ class Widget {
|
|||
this._lineHeight = this._context.configuration.editor.lineHeight;
|
||||
|
||||
this._setPosition(null, null);
|
||||
this._preference = null;
|
||||
this._preference = [];
|
||||
this._cachedDomNodeClientWidth = -1;
|
||||
this._cachedDomNodeClientHeight = -1;
|
||||
this._maxWidth = this._getMaxWidth();
|
||||
|
@ -247,9 +246,9 @@ class Widget {
|
|||
this._setPosition(this._position, this._range);
|
||||
}
|
||||
|
||||
private _setPosition(position: IPosition, range: IRange): void {
|
||||
this._position = position;
|
||||
this._range = range;
|
||||
private _setPosition(position: IPosition | null | undefined, range: IRange | null | undefined): void {
|
||||
this._position = position || null;
|
||||
this._range = range || null;
|
||||
this._viewPosition = null;
|
||||
this._viewRange = null;
|
||||
|
||||
|
@ -270,14 +269,14 @@ class Widget {
|
|||
private _getMaxWidth(): number {
|
||||
return (
|
||||
this.allowEditorOverflow
|
||||
? window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
|
||||
? window.innerWidth || document.documentElement!.clientWidth || document.body.clientWidth
|
||||
: this._contentWidth
|
||||
);
|
||||
}
|
||||
|
||||
public setPosition(position: IPosition, range: IRange, preference: ContentWidgetPositionPreference[]): void {
|
||||
public setPosition(position: IPosition | null | undefined, range: IRange | null | undefined, preference: ContentWidgetPositionPreference[] | null | undefined): void {
|
||||
this._setPosition(position, range);
|
||||
this._preference = preference;
|
||||
this._preference = preference || null;
|
||||
this._cachedDomNodeClientWidth = -1;
|
||||
this._cachedDomNodeClientHeight = -1;
|
||||
}
|
||||
|
@ -325,7 +324,7 @@ class Widget {
|
|||
};
|
||||
}
|
||||
|
||||
private _layoutBoxInPage(topLeft: Coordinate, bottomLeft: Coordinate, width: number, height: number, ctx: RenderingContext): IBoxLayoutResult {
|
||||
private _layoutBoxInPage(topLeft: Coordinate, bottomLeft: Coordinate, width: number, height: number, ctx: RenderingContext): IBoxLayoutResult | null {
|
||||
let aboveLeft0 = topLeft.left - ctx.scrollLeft;
|
||||
let belowLeft0 = bottomLeft.left - ctx.scrollLeft;
|
||||
|
||||
|
@ -345,8 +344,8 @@ class Widget {
|
|||
let absoluteAboveLeft = domNodePosition.left + aboveLeft - dom.StandardWindow.scrollX;
|
||||
let absoluteBelowLeft = domNodePosition.left + belowLeft - dom.StandardWindow.scrollX;
|
||||
|
||||
let INNER_WIDTH = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
|
||||
let INNER_HEIGHT = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
|
||||
let INNER_WIDTH = window.innerWidth || document.documentElement!.clientWidth || document.body.clientWidth;
|
||||
let INNER_HEIGHT = window.innerHeight || document.documentElement!.clientHeight || document.body.clientHeight;
|
||||
|
||||
// Leave some clearance to the bottom
|
||||
let TOP_PADDING = 22;
|
||||
|
@ -393,7 +392,7 @@ class Widget {
|
|||
/**
|
||||
* Compute `this._topLeft`
|
||||
*/
|
||||
private _getTopAndBottomLeft(ctx: RenderingContext): [Coordinate, Coordinate] {
|
||||
private _getTopAndBottomLeft(ctx: RenderingContext): [Coordinate, Coordinate] | [null, null] {
|
||||
if (!this._viewPosition) {
|
||||
return [null, null];
|
||||
}
|
||||
|
@ -437,58 +436,53 @@ class Widget {
|
|||
return [topLeft, bottomLeft];
|
||||
}
|
||||
|
||||
private _prepareRenderWidget(ctx: RenderingContext): Coordinate {
|
||||
private _prepareRenderWidget(ctx: RenderingContext): Coordinate | null {
|
||||
const [topLeft, bottomLeft] = this._getTopAndBottomLeft(ctx);
|
||||
if (!topLeft) {
|
||||
if (!topLeft || !bottomLeft) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let placement: IBoxLayoutResult | null = null;
|
||||
let fetchPlacement = (): void => {
|
||||
if (placement) {
|
||||
return;
|
||||
}
|
||||
if (this._cachedDomNodeClientWidth === -1 || this._cachedDomNodeClientHeight === -1) {
|
||||
const domNode = this.domNode.domNode;
|
||||
this._cachedDomNodeClientWidth = domNode.clientWidth;
|
||||
this._cachedDomNodeClientHeight = domNode.clientHeight;
|
||||
}
|
||||
|
||||
if (this._cachedDomNodeClientWidth === -1 || this._cachedDomNodeClientHeight === -1) {
|
||||
const domNode = this.domNode.domNode;
|
||||
this._cachedDomNodeClientWidth = domNode.clientWidth;
|
||||
this._cachedDomNodeClientHeight = domNode.clientHeight;
|
||||
}
|
||||
|
||||
if (this.allowEditorOverflow) {
|
||||
placement = this._layoutBoxInPage(topLeft, bottomLeft, this._cachedDomNodeClientWidth, this._cachedDomNodeClientHeight, ctx);
|
||||
} else {
|
||||
placement = this._layoutBoxInViewport(topLeft, bottomLeft, this._cachedDomNodeClientWidth, this._cachedDomNodeClientHeight, ctx);
|
||||
}
|
||||
};
|
||||
let placement: IBoxLayoutResult | null;
|
||||
if (this.allowEditorOverflow) {
|
||||
placement = this._layoutBoxInPage(topLeft, bottomLeft, this._cachedDomNodeClientWidth, this._cachedDomNodeClientHeight, ctx);
|
||||
} else {
|
||||
placement = this._layoutBoxInViewport(topLeft, bottomLeft, this._cachedDomNodeClientWidth, this._cachedDomNodeClientHeight, ctx);
|
||||
}
|
||||
|
||||
// Do two passes, first for perfect fit, second picks first option
|
||||
for (let pass = 1; pass <= 2; pass++) {
|
||||
for (let i = 0; i < this._preference.length; i++) {
|
||||
let pref = this._preference[i];
|
||||
if (pref === ContentWidgetPositionPreference.ABOVE) {
|
||||
fetchPlacement();
|
||||
if (!placement) {
|
||||
// Widget outside of viewport
|
||||
return null;
|
||||
}
|
||||
if (pass === 2 || placement.fitsAbove) {
|
||||
return new Coordinate(placement.aboveTop, placement.aboveLeft);
|
||||
}
|
||||
} else if (pref === ContentWidgetPositionPreference.BELOW) {
|
||||
fetchPlacement();
|
||||
if (!placement) {
|
||||
// Widget outside of viewport
|
||||
return null;
|
||||
}
|
||||
if (pass === 2 || placement.fitsBelow) {
|
||||
return new Coordinate(placement.belowTop, placement.belowLeft);
|
||||
}
|
||||
} else {
|
||||
if (this.allowEditorOverflow) {
|
||||
return this._prepareRenderWidgetAtExactPositionOverflowing(topLeft);
|
||||
if (this._preference) {
|
||||
for (let pass = 1; pass <= 2; pass++) {
|
||||
for (let i = 0; i < this._preference.length; i++) {
|
||||
// placement
|
||||
let pref = this._preference[i];
|
||||
if (pref === ContentWidgetPositionPreference.ABOVE) {
|
||||
if (!placement) {
|
||||
// Widget outside of viewport
|
||||
return null;
|
||||
}
|
||||
if (pass === 2 || placement.fitsAbove) {
|
||||
return new Coordinate(placement.aboveTop, placement.aboveLeft);
|
||||
}
|
||||
} else if (pref === ContentWidgetPositionPreference.BELOW) {
|
||||
if (!placement) {
|
||||
// Widget outside of viewport
|
||||
return null;
|
||||
}
|
||||
if (pass === 2 || placement.fitsBelow) {
|
||||
return new Coordinate(placement.belowTop, placement.belowLeft);
|
||||
}
|
||||
} else {
|
||||
return topLeft;
|
||||
if (this.allowEditorOverflow) {
|
||||
return this._prepareRenderWidgetAtExactPositionOverflowing(topLeft);
|
||||
} else {
|
||||
return topLeft;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@ export class CurrentLineHighlightOverlay extends DynamicViewOverlay {
|
|||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@ export class CurrentLineMarginHighlightOverlay extends DynamicViewOverlay {
|
|||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ export class DecorationsOverlay extends DynamicViewOverlay {
|
|||
private _context: ViewContext;
|
||||
private _lineHeight: number;
|
||||
private _typicalHalfwidthCharacterWidth: number;
|
||||
private _renderResult: string[];
|
||||
private _renderResult: string[] | null;
|
||||
|
||||
constructor(context: ViewContext) {
|
||||
super();
|
||||
|
@ -30,7 +30,6 @@ export class DecorationsOverlay extends DynamicViewOverlay {
|
|||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
this._renderResult = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
@ -83,14 +82,14 @@ export class DecorationsOverlay extends DynamicViewOverlay {
|
|||
|
||||
// Sort decorations for consistent render output
|
||||
decorations = decorations.sort((a, b) => {
|
||||
if (a.options.zIndex < b.options.zIndex) {
|
||||
if (a.options.zIndex! < b.options.zIndex!) {
|
||||
return -1;
|
||||
}
|
||||
if (a.options.zIndex > b.options.zIndex) {
|
||||
if (a.options.zIndex! > b.options.zIndex!) {
|
||||
return 1;
|
||||
}
|
||||
const aClassName = a.options.className;
|
||||
const bClassName = b.options.className;
|
||||
const aClassName = a.options.className!;
|
||||
const bClassName = b.options.className!;
|
||||
|
||||
if (aClassName < bClassName) {
|
||||
return -1;
|
||||
|
@ -160,23 +159,23 @@ export class DecorationsOverlay extends DynamicViewOverlay {
|
|||
continue;
|
||||
}
|
||||
|
||||
const className = d.options.className;
|
||||
const showIfCollapsed = d.options.showIfCollapsed;
|
||||
const className = d.options.className!;
|
||||
const showIfCollapsed = Boolean(d.options.showIfCollapsed);
|
||||
|
||||
let range = d.range;
|
||||
if (showIfCollapsed && range.endColumn === 1 && range.endLineNumber !== range.startLineNumber) {
|
||||
range = new Range(range.startLineNumber, range.startColumn, range.endLineNumber - 1, this._context.model.getLineMaxColumn(range.endLineNumber - 1));
|
||||
}
|
||||
|
||||
if (prevClassName === className && prevShowIfCollapsed === showIfCollapsed && Range.areIntersectingOrTouching(prevRange, range)) {
|
||||
if (prevClassName === className && prevShowIfCollapsed === showIfCollapsed && Range.areIntersectingOrTouching(prevRange!, range)) {
|
||||
// merge into previous decoration
|
||||
prevRange = Range.plusRange(prevRange, range);
|
||||
prevRange = Range.plusRange(prevRange!, range);
|
||||
continue;
|
||||
}
|
||||
|
||||
// flush previous decoration
|
||||
if (prevClassName !== null) {
|
||||
this._renderNormalDecoration(ctx, prevRange, prevClassName, prevShowIfCollapsed, lineHeight, visibleStartLineNumber, output);
|
||||
this._renderNormalDecoration(ctx, prevRange!, prevClassName, prevShowIfCollapsed, lineHeight, visibleStartLineNumber, output);
|
||||
}
|
||||
|
||||
prevClassName = className;
|
||||
|
@ -185,7 +184,7 @@ export class DecorationsOverlay extends DynamicViewOverlay {
|
|||
}
|
||||
|
||||
if (prevClassName !== null) {
|
||||
this._renderNormalDecoration(ctx, prevRange, prevClassName, prevShowIfCollapsed, lineHeight, visibleStartLineNumber, output);
|
||||
this._renderNormalDecoration(ctx, prevRange!, prevClassName, prevShowIfCollapsed, lineHeight, visibleStartLineNumber, output);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ export class GlyphMarginOverlay extends DedupOverlay {
|
|||
private _glyphMargin: boolean;
|
||||
private _glyphMarginLeft: number;
|
||||
private _glyphMarginWidth: number;
|
||||
private _renderResult: string[];
|
||||
private _renderResult: string[] | null;
|
||||
|
||||
constructor(context: ViewContext) {
|
||||
super();
|
||||
|
@ -94,7 +94,6 @@ export class GlyphMarginOverlay extends DedupOverlay {
|
|||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
this._renderResult = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
|
|||
private _primaryLineNumber: number;
|
||||
private _lineHeight: number;
|
||||
private _spaceWidth: number;
|
||||
private _renderResult: string[];
|
||||
private _renderResult: string[] | null;
|
||||
private _enabled: boolean;
|
||||
private _activeIndentEnabled: boolean;
|
||||
|
||||
|
@ -37,7 +37,6 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
|
|||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
this._renderResult = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
|
|
@ -22,11 +22,11 @@ export class LineNumbersOverlay extends DynamicViewOverlay {
|
|||
|
||||
private _lineHeight: number;
|
||||
private _renderLineNumbers: RenderLineNumbersType;
|
||||
private _renderCustomLineNumbers: (lineNumber: number) => string;
|
||||
private _renderCustomLineNumbers: ((lineNumber: number) => string) | null;
|
||||
private _lineNumbersLeft: number;
|
||||
private _lineNumbersWidth: number;
|
||||
private _lastCursorModelPosition: Position;
|
||||
private _renderResult: string[];
|
||||
private _renderResult: string[] | null;
|
||||
|
||||
constructor(context: ViewContext) {
|
||||
super();
|
||||
|
@ -50,7 +50,6 @@ export class LineNumbersOverlay extends DynamicViewOverlay {
|
|||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
this._renderResult = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ export class RangeUtil {
|
|||
range.selectNodeContents(endNode);
|
||||
}
|
||||
|
||||
private static _readClientRects(startElement: Node, startOffset: number, endElement: Node, endOffset: number, endNode: HTMLElement): ClientRectList {
|
||||
private static _readClientRects(startElement: Node, startOffset: number, endElement: Node, endOffset: number, endNode: HTMLElement): ClientRectList | DOMRectList | null {
|
||||
let range = this._createRange();
|
||||
try {
|
||||
range.setStart(startElement, startOffset);
|
||||
|
@ -94,7 +94,7 @@ export class RangeUtil {
|
|||
return result;
|
||||
}
|
||||
|
||||
private static _createHorizontalRangesFromClientRects(clientRects: ClientRectList, clientRectDeltaLeft: number): HorizontalRange[] {
|
||||
private static _createHorizontalRangesFromClientRects(clientRects: ClientRectList | DOMRectList | null, clientRectDeltaLeft: number): HorizontalRange[] | null {
|
||||
if (!clientRects || clientRects.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ export class RangeUtil {
|
|||
return this._mergeAdjacentRanges(result);
|
||||
}
|
||||
|
||||
public static readHorizontalRanges(domNode: HTMLElement, startChildIndex: number, startOffset: number, endChildIndex: number, endOffset: number, clientRectDeltaLeft: number, endNode: HTMLElement): HorizontalRange[] {
|
||||
public static readHorizontalRanges(domNode: HTMLElement, startChildIndex: number, startOffset: number, endChildIndex: number, endOffset: number, clientRectDeltaLeft: number, endNode: HTMLElement): HorizontalRange[] | null {
|
||||
// Panic check
|
||||
let min = 0;
|
||||
let max = domNode.children.length - 1;
|
||||
|
@ -149,8 +149,8 @@ export class RangeUtil {
|
|||
return null;
|
||||
}
|
||||
|
||||
startOffset = Math.min(startElement.textContent.length, Math.max(0, startOffset));
|
||||
endOffset = Math.min(endElement.textContent.length, Math.max(0, endOffset));
|
||||
startOffset = Math.min(startElement.textContent!.length, Math.max(0, startOffset));
|
||||
endOffset = Math.min(endElement.textContent!.length, Math.max(0, endOffset));
|
||||
|
||||
let clientRects = this._readClientRects(startElement, startOffset, endElement, endOffset, endNode);
|
||||
return this._createHorizontalRangesFromClientRects(clientRects, clientRectDeltaLeft);
|
||||
|
|
|
@ -114,7 +114,7 @@ export class ViewLine implements IVisibleLine {
|
|||
|
||||
private _options: ViewLineOptions;
|
||||
private _isMaybeInvalid: boolean;
|
||||
private _renderedViewLine: IRenderedViewLine;
|
||||
private _renderedViewLine: IRenderedViewLine | null;
|
||||
|
||||
constructor(options: ViewLineOptions) {
|
||||
this._options = options;
|
||||
|
@ -124,7 +124,7 @@ export class ViewLine implements IVisibleLine {
|
|||
|
||||
// --- begin IVisibleLineData
|
||||
|
||||
public getDomNode(): HTMLElement {
|
||||
public getDomNode(): HTMLElement | null {
|
||||
if (this._renderedViewLine && this._renderedViewLine.domNode) {
|
||||
return this._renderedViewLine.domNode.domNode;
|
||||
}
|
||||
|
@ -282,7 +282,10 @@ export class ViewLine implements IVisibleLine {
|
|||
return this._renderedViewLine.getWidthIsFast();
|
||||
}
|
||||
|
||||
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
|
||||
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
|
||||
if (!this._renderedViewLine) {
|
||||
return null;
|
||||
}
|
||||
startColumn = startColumn | 0; // @perf
|
||||
endColumn = endColumn | 0; // @perf
|
||||
|
||||
|
@ -308,16 +311,19 @@ export class ViewLine implements IVisibleLine {
|
|||
}
|
||||
|
||||
public getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number {
|
||||
if (!this._renderedViewLine) {
|
||||
return 1;
|
||||
}
|
||||
return this._renderedViewLine.getColumnOfNodeOffset(lineNumber, spanNode, offset);
|
||||
}
|
||||
}
|
||||
|
||||
interface IRenderedViewLine {
|
||||
domNode: FastDomNode<HTMLElement>;
|
||||
domNode: FastDomNode<HTMLElement> | null;
|
||||
readonly input: RenderLineInput;
|
||||
getWidth(): number;
|
||||
getWidthIsFast(): boolean;
|
||||
getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[];
|
||||
getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null;
|
||||
getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number;
|
||||
}
|
||||
|
||||
|
@ -326,13 +332,13 @@ interface IRenderedViewLine {
|
|||
*/
|
||||
class FastRenderedViewLine implements IRenderedViewLine {
|
||||
|
||||
public domNode: FastDomNode<HTMLElement>;
|
||||
public domNode: FastDomNode<HTMLElement> | null;
|
||||
public readonly input: RenderLineInput;
|
||||
|
||||
private readonly _characterMapping: CharacterMapping;
|
||||
private readonly _charWidth: number;
|
||||
|
||||
constructor(domNode: FastDomNode<HTMLElement>, renderLineInput: RenderLineInput, characterMapping: CharacterMapping) {
|
||||
constructor(domNode: FastDomNode<HTMLElement> | null, renderLineInput: RenderLineInput, characterMapping: CharacterMapping) {
|
||||
this.domNode = domNode;
|
||||
this.input = renderLineInput;
|
||||
|
||||
|
@ -348,7 +354,7 @@ class FastRenderedViewLine implements IRenderedViewLine {
|
|||
return true;
|
||||
}
|
||||
|
||||
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
|
||||
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
|
||||
const startPosition = this._getCharPosition(startColumn);
|
||||
const endPosition = this._getCharPosition(endColumn);
|
||||
return [new HorizontalRange(startPosition, endPosition - startPosition)];
|
||||
|
@ -364,7 +370,7 @@ class FastRenderedViewLine implements IRenderedViewLine {
|
|||
}
|
||||
|
||||
public getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number {
|
||||
let spanNodeTextContentLength = spanNode.textContent.length;
|
||||
let spanNodeTextContentLength = spanNode.textContent!.length;
|
||||
|
||||
let spanIndex = -1;
|
||||
while (spanNode) {
|
||||
|
@ -393,7 +399,7 @@ class RenderedViewLine implements IRenderedViewLine {
|
|||
/**
|
||||
* This is a map that is used only when the line is guaranteed to have no RTL text.
|
||||
*/
|
||||
private _pixelOffsetCache: Int32Array;
|
||||
private _pixelOffsetCache: Int32Array | null;
|
||||
|
||||
constructor(domNode: FastDomNode<HTMLElement>, renderLineInput: RenderLineInput, characterMapping: CharacterMapping, containsRTL: boolean, containsForeignElements: ForeignElementType) {
|
||||
this.domNode = domNode;
|
||||
|
@ -438,7 +444,7 @@ class RenderedViewLine implements IRenderedViewLine {
|
|||
/**
|
||||
* Visible ranges for a model range
|
||||
*/
|
||||
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
|
||||
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
|
||||
if (this._pixelOffsetCache !== null) {
|
||||
// the text is LTR
|
||||
let startOffset = this._readPixelOffset(startColumn, context);
|
||||
|
@ -457,7 +463,7 @@ class RenderedViewLine implements IRenderedViewLine {
|
|||
return this._readVisibleRangesForRange(startColumn, endColumn, context);
|
||||
}
|
||||
|
||||
protected _readVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
|
||||
protected _readVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
|
||||
if (startColumn === endColumn) {
|
||||
let pixelOffset = this._readPixelOffset(startColumn, context);
|
||||
if (pixelOffset === -1) {
|
||||
|
@ -529,7 +535,7 @@ class RenderedViewLine implements IRenderedViewLine {
|
|||
return r[0].left;
|
||||
}
|
||||
|
||||
private _readRawVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
|
||||
private _readRawVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
|
||||
|
||||
if (startColumn === 1 && endColumn === this._characterMapping.length) {
|
||||
// This branch helps IE with bidi text & gives a performance boost to other browsers when reading visible ranges for an entire line
|
||||
|
@ -552,7 +558,7 @@ class RenderedViewLine implements IRenderedViewLine {
|
|||
* Returns the column for the text found at a specific offset inside a rendered dom node
|
||||
*/
|
||||
public getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number {
|
||||
let spanNodeTextContentLength = spanNode.textContent.length;
|
||||
let spanNodeTextContentLength = spanNode.textContent!.length;
|
||||
|
||||
let spanIndex = -1;
|
||||
while (spanNode) {
|
||||
|
@ -566,7 +572,7 @@ class RenderedViewLine implements IRenderedViewLine {
|
|||
}
|
||||
|
||||
class WebKitRenderedViewLine extends RenderedViewLine {
|
||||
protected _readVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
|
||||
protected _readVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
|
||||
let output = super._readVisibleRangesForRange(startColumn, endColumn, context);
|
||||
|
||||
if (!output || output.length === 0 || startColumn === endColumn || (startColumn === 1 && endColumn === this._characterMapping.length)) {
|
||||
|
@ -592,7 +598,7 @@ class WebKitRenderedViewLine extends RenderedViewLine {
|
|||
}
|
||||
}
|
||||
|
||||
const createRenderedLine: (domNode: FastDomNode<HTMLElement>, renderLineInput: RenderLineInput, characterMapping: CharacterMapping, containsRTL: boolean, containsForeignElements: ForeignElementType) => RenderedViewLine = (function () {
|
||||
const createRenderedLine: (domNode: FastDomNode<HTMLElement> | null, renderLineInput: RenderLineInput, characterMapping: CharacterMapping, containsRTL: boolean, containsForeignElements: ForeignElementType) => RenderedViewLine = (function () {
|
||||
if (browser.isWebKit) {
|
||||
return createWebKitRenderedLine;
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
|||
private _maxLineWidth: number;
|
||||
private _asyncUpdateLineWidths: RunOnceScheduler;
|
||||
|
||||
private _horizontalRevealRequest: HorizontalRevealRequest;
|
||||
private _horizontalRevealRequest: HorizontalRevealRequest | null;
|
||||
private _lastRenderedData: LastRenderedData;
|
||||
|
||||
constructor(context: ViewContext, linesContent: FastDomNode<HTMLElement>) {
|
||||
|
@ -281,7 +281,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
|||
|
||||
// ----------- HELPERS FOR OTHERS
|
||||
|
||||
public getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position {
|
||||
public getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position | null {
|
||||
let viewLineDomNode = this._getViewLineDomNode(spanNode);
|
||||
if (viewLineDomNode === null) {
|
||||
// Couldn't find view line node
|
||||
|
@ -319,7 +319,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
|||
return new Position(lineNumber, column);
|
||||
}
|
||||
|
||||
private _getViewLineDomNode(node: HTMLElement): HTMLElement {
|
||||
private _getViewLineDomNode(node: HTMLElement | null): HTMLElement | null {
|
||||
while (node && node.nodeType === 1) {
|
||||
if (node.className === ViewLine.CLASS_NAME) {
|
||||
return node;
|
||||
|
@ -355,15 +355,15 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
|||
return this._visibleLines.getVisibleLine(lineNumber).getWidth();
|
||||
}
|
||||
|
||||
public linesVisibleRangesForRange(range: Range, includeNewLines: boolean): LineVisibleRanges[] {
|
||||
public linesVisibleRangesForRange(_range: Range, includeNewLines: boolean): LineVisibleRanges[] | null {
|
||||
if (this.shouldRender()) {
|
||||
// Cannot read from the DOM because it is dirty
|
||||
// i.e. the model & the dom are out of sync, so I'd be reading something stale
|
||||
return null;
|
||||
}
|
||||
|
||||
let originalEndLineNumber = range.endLineNumber;
|
||||
range = Range.intersectRanges(range, this._lastRenderedData.getCurrentVisibleRange());
|
||||
let originalEndLineNumber = _range.endLineNumber;
|
||||
const range = Range.intersectRanges(_range, this._lastRenderedData.getCurrentVisibleRange());
|
||||
if (!range) {
|
||||
return null;
|
||||
}
|
||||
|
@ -371,7 +371,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
|||
let visibleRanges: LineVisibleRanges[] = [], visibleRangesLen = 0;
|
||||
let domReadingContext = new DomReadingContext(this.domNode.domNode, this._textRangeRestingSpot);
|
||||
|
||||
let nextLineModelLineNumber: number;
|
||||
let nextLineModelLineNumber: number = 0;
|
||||
if (includeNewLines) {
|
||||
nextLineModelLineNumber = this._context.model.coordinatesConverter.convertViewPositionToModelPosition(new Position(range.startLineNumber, 1)).lineNumber;
|
||||
}
|
||||
|
@ -411,7 +411,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
|||
return visibleRanges;
|
||||
}
|
||||
|
||||
private visibleRangesForRange2(range: Range): HorizontalRange[] {
|
||||
private visibleRangesForRange2(_range: Range): HorizontalRange[] | null {
|
||||
|
||||
if (this.shouldRender()) {
|
||||
// Cannot read from the DOM because it is dirty
|
||||
|
@ -419,7 +419,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
|||
return null;
|
||||
}
|
||||
|
||||
range = Range.intersectRanges(range, this._lastRenderedData.getCurrentVisibleRange());
|
||||
const range = Range.intersectRanges(_range, this._lastRenderedData.getCurrentVisibleRange());
|
||||
if (!range) {
|
||||
return null;
|
||||
}
|
||||
|
@ -453,7 +453,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
|||
return result;
|
||||
}
|
||||
|
||||
public visibleRangeForPosition(position: Position): HorizontalRange {
|
||||
public visibleRangeForPosition(position: Position): HorizontalRange | null {
|
||||
const visibleRanges = this.visibleRangesForRange2(new Range(position.lineNumber, position.column, position.lineNumber, position.column));
|
||||
if (!visibleRanges) {
|
||||
return null;
|
||||
|
|
|
@ -15,7 +15,7 @@ export class LinesDecorationsOverlay extends DedupOverlay {
|
|||
|
||||
private _decorationsLeft: number;
|
||||
private _decorationsWidth: number;
|
||||
private _renderResult: string[];
|
||||
private _renderResult: string[] | null;
|
||||
|
||||
constructor(context: ViewContext) {
|
||||
super();
|
||||
|
@ -28,7 +28,6 @@ export class LinesDecorationsOverlay extends DedupOverlay {
|
|||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
this._renderResult = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
|||
|
||||
export class MarginViewLineDecorationsOverlay extends DedupOverlay {
|
||||
private _context: ViewContext;
|
||||
private _renderResult: string[];
|
||||
private _renderResult: string[] | null;
|
||||
|
||||
constructor(context: ViewContext) {
|
||||
super();
|
||||
|
@ -22,7 +22,6 @@ export class MarginViewLineDecorationsOverlay extends DedupOverlay {
|
|||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
this._renderResult = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue