mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-09 08:15:05 +01:00
Merge branch 'master' into sandy081/userDataProvider
This commit is contained in:
@@ -102,23 +102,28 @@ steps:
|
||||
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
|
||||
|
||||
- script: |
|
||||
# Figure out the full absolute path of the product we just built
|
||||
# including the remote server and configure the integration tests
|
||||
# to run with these builds instead of running out of sources.
|
||||
set -e
|
||||
APP_ROOT=$(agent.builddirectory)/VSCode-darwin
|
||||
APP_NAME="`ls $APP_ROOT | head -n 1`"
|
||||
INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME/Contents/MacOS/Electron" \
|
||||
VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-darwin" \
|
||||
./scripts/test-integration.sh --build --tfs "Integration Tests"
|
||||
displayName: Run integration tests
|
||||
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
cd test/smoke
|
||||
yarn compile
|
||||
cd -
|
||||
yarn smoketest --web --headless
|
||||
continueOnError: true
|
||||
displayName: Run web smoke tests
|
||||
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
|
||||
# Web Smoke Tests disabled due to https://github.com/microsoft/vscode/issues/80308
|
||||
# - script: |
|
||||
# set -e
|
||||
# cd test/smoke
|
||||
# yarn compile
|
||||
# cd -
|
||||
# yarn smoketest --web --headless
|
||||
# continueOnError: true
|
||||
# displayName: Run web smoke tests
|
||||
# condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
|
||||
@@ -105,10 +105,14 @@ steps:
|
||||
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
|
||||
|
||||
- script: |
|
||||
# Figure out the full absolute path of the product we just built
|
||||
# including the remote server and configure the integration tests
|
||||
# to run with these builds instead of running out of sources.
|
||||
set -e
|
||||
APP_ROOT=$(agent.builddirectory)/VSCode-linux-x64
|
||||
APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName")
|
||||
INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \
|
||||
VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-x64" \
|
||||
DISPLAY=:10 ./scripts/test-integration.sh --build --tfs "Integration Tests"
|
||||
# yarn smoketest -- --build "$(agent.builddirectory)/VSCode-linux-x64"
|
||||
displayName: Run integration tests
|
||||
|
||||
@@ -104,6 +104,7 @@ steps:
|
||||
AZURE_WEBVIEW_STORAGE_ACCESS_KEY="$(vscode-webview-storage-key)" \
|
||||
./build/azure-pipelines/common/publish-webview.sh
|
||||
displayName: Publish Webview
|
||||
condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true'))
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
|
||||
@@ -15,6 +15,22 @@ steps:
|
||||
inputs:
|
||||
versionSpec: "1.x"
|
||||
|
||||
- bash: |
|
||||
TAG_VERSION=$(git describe --tags `git rev-list --tags --max-count=1`)
|
||||
CHANNEL="G1C14HJ2F"
|
||||
|
||||
if [ "$TAG_VERSION" == "1.999.0" ]; then
|
||||
MESSAGE="<!here>. Someone pushed 1.999.0 tag. Please delete it ASAP from remote and local."
|
||||
|
||||
curl -X POST -H "Authorization: Bearer $(SLACK_TOKEN)" \
|
||||
-H 'Content-type: application/json; charset=utf-8' \
|
||||
--data '{"channel":"'"$CHANNEL"'", "link_names": true, "text":"'"$MESSAGE"'"}' \
|
||||
https://slack.com/api/chat.postMessage
|
||||
|
||||
exit 1
|
||||
fi
|
||||
displayName: Check 1.999.0 tag
|
||||
|
||||
- bash: |
|
||||
# Install build dependencies
|
||||
(cd build && yarn)
|
||||
|
||||
@@ -113,12 +113,15 @@ steps:
|
||||
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
|
||||
|
||||
- powershell: |
|
||||
# Figure out the full absolute path of the product we just built
|
||||
# including the remote server and configure the integration tests
|
||||
# to run with these builds instead of running out of sources.
|
||||
. build/azure-pipelines/win32/exec.ps1
|
||||
$ErrorActionPreference = "Stop"
|
||||
$AppRoot = "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)"
|
||||
$AppProductJson = Get-Content -Raw -Path "$AppRoot\resources\app\product.json" | ConvertFrom-Json
|
||||
$AppNameShort = $AppProductJson.nameShort
|
||||
exec { $env:INTEGRATION_TEST_ELECTRON_PATH = "$AppRoot\$AppNameShort.exe"; .\scripts\test-integration.bat --build --tfs "Integration Tests" }
|
||||
exec { $env:INTEGRATION_TEST_ELECTRON_PATH = "$AppRoot\$AppNameShort.exe"; $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-win32-$(VSCODE_ARCH)"; .\scripts\test-integration.bat --build --tfs "Integration Tests" }
|
||||
displayName: Run integration tests
|
||||
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ const nlsDev = require('vscode-nls-dev');
|
||||
const root = path.dirname(__dirname);
|
||||
const commit = util.getVersion(root);
|
||||
const plumber = require('gulp-plumber');
|
||||
const _ = require('underscore');
|
||||
const ext = require('./lib/extensions');
|
||||
|
||||
const extensionsPath = path.join(path.dirname(__dirname), 'extensions');
|
||||
@@ -37,16 +36,16 @@ const tasks = compilations.map(function (tsconfigFile) {
|
||||
const absolutePath = path.join(extensionsPath, tsconfigFile);
|
||||
const relativeDirname = path.dirname(tsconfigFile);
|
||||
|
||||
const tsconfig = require(absolutePath);
|
||||
const tsOptions = _.assign({}, tsconfig.extends ? require(path.join(extensionsPath, relativeDirname, tsconfig.extends)).compilerOptions : {}, tsconfig.compilerOptions);
|
||||
tsOptions.verbose = false;
|
||||
tsOptions.sourceMap = true;
|
||||
const overrideOptions = {};
|
||||
overrideOptions.sourceMap = true;
|
||||
|
||||
const name = relativeDirname.replace(/\//g, '-');
|
||||
|
||||
const root = path.join('extensions', relativeDirname);
|
||||
const srcBase = path.join(root, 'src');
|
||||
const src = path.join(srcBase, '**');
|
||||
const srcOpts = { cwd: path.dirname(__dirname), base: srcBase };
|
||||
|
||||
const out = path.join(root, 'out');
|
||||
const baseUrl = getBaseUrl(out);
|
||||
|
||||
@@ -63,12 +62,12 @@ const tasks = compilations.map(function (tsconfigFile) {
|
||||
function createPipeline(build, emitError) {
|
||||
const reporter = createReporter();
|
||||
|
||||
tsOptions.inlineSources = !!build;
|
||||
tsOptions.base = path.dirname(absolutePath);
|
||||
overrideOptions.inlineSources = Boolean(build);
|
||||
overrideOptions.base = path.dirname(absolutePath);
|
||||
|
||||
const compilation = tsb.create(tsOptions, null, null, err => reporter(err.toString()));
|
||||
const compilation = tsb.create(absolutePath, overrideOptions, false, err => reporter(err.toString()));
|
||||
|
||||
return function () {
|
||||
const pipeline = function () {
|
||||
const input = es.through();
|
||||
const tsFilter = filter(['**/*.ts', '!**/lib/lib*.d.ts', '!**/node_modules/**'], { restore: true });
|
||||
const output = input
|
||||
@@ -98,15 +97,19 @@ const tasks = compilations.map(function (tsconfigFile) {
|
||||
|
||||
return es.duplex(input, output);
|
||||
};
|
||||
}
|
||||
|
||||
const srcOpts = { cwd: path.dirname(__dirname), base: srcBase };
|
||||
// add src-stream for project files
|
||||
pipeline.tsProjectSrc = () => {
|
||||
return compilation.src(srcOpts);
|
||||
};
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
const cleanTask = task.define(`clean-extension-${name}`, util.rimraf(out));
|
||||
|
||||
const compileTask = task.define(`compile-extension:${name}`, task.series(cleanTask, () => {
|
||||
const pipeline = createPipeline(false, true);
|
||||
const input = gulp.src(src, srcOpts);
|
||||
const input = pipeline.tsProjectSrc();
|
||||
|
||||
return input
|
||||
.pipe(pipeline())
|
||||
@@ -115,8 +118,8 @@ const tasks = compilations.map(function (tsconfigFile) {
|
||||
|
||||
const watchTask = task.define(`watch-extension:${name}`, task.series(cleanTask, () => {
|
||||
const pipeline = createPipeline(false);
|
||||
const input = gulp.src(src, srcOpts);
|
||||
const watchInput = watcher(src, srcOpts);
|
||||
const input = pipeline.tsProjectSrc();
|
||||
const watchInput = watcher(src, { ...srcOpts, ...{ readDelay: 200 } });
|
||||
|
||||
return watchInput
|
||||
.pipe(util.incremental(pipeline, input))
|
||||
@@ -125,7 +128,7 @@ const tasks = compilations.map(function (tsconfigFile) {
|
||||
|
||||
const compileBuildTask = task.define(`compile-build-extension-${name}`, task.series(cleanTask, () => {
|
||||
const pipeline = createPipeline(true, true);
|
||||
const input = gulp.src(src, srcOpts);
|
||||
const input = pipeline.tsProjectSrc();
|
||||
|
||||
return input
|
||||
.pipe(pipeline())
|
||||
@@ -160,4 +163,4 @@ const compileExtensionsBuildTask = task.define('compile-extensions-build', task.
|
||||
));
|
||||
|
||||
gulp.task(compileExtensionsBuildTask);
|
||||
exports.compileExtensionsBuildTask = compileExtensionsBuildTask;
|
||||
exports.compileExtensionsBuildTask = compileExtensionsBuildTask;
|
||||
|
||||
@@ -49,7 +49,6 @@ const nodeModules = ['electron', 'original-fs']
|
||||
const vscodeEntryPoints = _.flatten([
|
||||
buildfile.entrypoint('vs/workbench/workbench.desktop.main'),
|
||||
buildfile.base,
|
||||
buildfile.serviceWorker,
|
||||
buildfile.workbenchDesktop,
|
||||
buildfile.code
|
||||
]);
|
||||
@@ -94,6 +93,7 @@ const optimizeVSCodeTask = task.define('optimize-vscode', task.series(
|
||||
resources: vscodeResources,
|
||||
loaderConfig: common.loaderConfig(nodeModules),
|
||||
out: 'out-vscode',
|
||||
inlineAmdImages: true,
|
||||
bundleInfo: undefined
|
||||
})
|
||||
));
|
||||
@@ -480,7 +480,7 @@ gulp.task(task.define(
|
||||
optimizeVSCodeTask,
|
||||
function () {
|
||||
const pathToMetadata = './out-vscode/nls.metadata.json';
|
||||
const pathToExtensions = './extensions/*';
|
||||
const pathToExtensions = '.build/extensions/*';
|
||||
const pathToSetup = 'build/win32/**/{Default.isl,messages.en.isl}';
|
||||
|
||||
return es.merge(
|
||||
@@ -501,7 +501,7 @@ gulp.task(task.define(
|
||||
optimizeVSCodeTask,
|
||||
function () {
|
||||
const pathToMetadata = './out-vscode/nls.metadata.json';
|
||||
const pathToExtensions = './extensions/*';
|
||||
const pathToExtensions = '.build/extensions/*';
|
||||
const pathToSetup = 'build/win32/**/{Default.isl,messages.en.isl}';
|
||||
|
||||
return es.merge(
|
||||
|
||||
@@ -238,7 +238,8 @@ function prepareSnapPackage(arch) {
|
||||
|
||||
function buildSnapPackage(arch) {
|
||||
const snapBuildPath = getSnapBuildPath(arch);
|
||||
return shell.task(`cd ${snapBuildPath} && snapcraft build`);
|
||||
// Default target for snapcraft runs: pull, build, stage and prime, and finally assembles the snap.
|
||||
return shell.task(`cd ${snapBuildPath} && snapcraft`);
|
||||
}
|
||||
|
||||
const BUILD_TARGETS = [
|
||||
|
||||
@@ -34,7 +34,8 @@ const nodeModules = Object.keys(product.dependencies || {})
|
||||
const vscodeWebResources = [
|
||||
|
||||
// Workbench
|
||||
'out-build/vs/{base,platform,editor,workbench}/**/*.{svg,png,html}',
|
||||
'out-build/vs/{base,platform,editor,workbench}/**/*.{svg,png}',
|
||||
'out-build/vs/code/browser/workbench/workbench.html',
|
||||
'out-build/vs/base/browser/ui/octiconLabel/octicons/**',
|
||||
'out-build/vs/**/markdown.css',
|
||||
|
||||
@@ -56,7 +57,6 @@ const buildfile = require('../src/buildfile');
|
||||
const vscodeWebEntryPoints = _.flatten([
|
||||
buildfile.entrypoint('vs/workbench/workbench.web.api'),
|
||||
buildfile.base,
|
||||
buildfile.serviceWorker,
|
||||
buildfile.workerExtensionHost,
|
||||
buildfile.keyboardMaps,
|
||||
buildfile.workbenchWeb
|
||||
@@ -118,7 +118,10 @@ function packageTask(sourceFolderName, destinationFolderName) {
|
||||
|
||||
const favicon = gulp.src('resources/server/favicon.ico', { base: 'resources/server' });
|
||||
const manifest = gulp.src('resources/server/manifest.json', { base: 'resources/server' });
|
||||
const pwaicon = gulp.src('resources/server/code.png', { base: 'resources/server' });
|
||||
const pwaicons = es.merge(
|
||||
gulp.src('resources/server/code-192.png', { base: 'resources/server' }),
|
||||
gulp.src('resources/server/code-512.png', { base: 'resources/server' })
|
||||
);
|
||||
|
||||
let all = es.merge(
|
||||
packageJsonStream,
|
||||
@@ -128,7 +131,7 @@ function packageTask(sourceFolderName, destinationFolderName) {
|
||||
deps,
|
||||
favicon,
|
||||
manifest,
|
||||
pwaicon
|
||||
pwaicons
|
||||
);
|
||||
|
||||
let result = all
|
||||
|
||||
@@ -11,7 +11,6 @@ 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");
|
||||
@@ -22,14 +21,7 @@ const watch = require('./watch');
|
||||
const reporter = reporter_1.createReporter();
|
||||
function getTypeScriptCompilerOptions(src) {
|
||||
const rootDir = path.join(__dirname, `../../${src}`);
|
||||
const tsconfig = require(`../../${src}/tsconfig.json`);
|
||||
let options;
|
||||
if (tsconfig.extends) {
|
||||
options = Object.assign({}, require(path.join(rootDir, tsconfig.extends)).compilerOptions, tsconfig.compilerOptions);
|
||||
}
|
||||
else {
|
||||
options = tsconfig.compilerOptions;
|
||||
}
|
||||
let options = {};
|
||||
options.verbose = false;
|
||||
options.sourceMap = true;
|
||||
if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry
|
||||
@@ -38,14 +30,13 @@ function getTypeScriptCompilerOptions(src) {
|
||||
options.rootDir = rootDir;
|
||||
options.baseUrl = rootDir;
|
||||
options.sourceRoot = util.toFileUri(rootDir);
|
||||
options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 'CRLF' : 'LF';
|
||||
options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 0 : 1;
|
||||
return options;
|
||||
}
|
||||
function createCompile(src, build, emitError) {
|
||||
const opts = _.clone(getTypeScriptCompilerOptions(src));
|
||||
opts.inlineSources = !!build;
|
||||
opts.noFilesystemLookup = true;
|
||||
const ts = tsb.create(opts, true, undefined, err => reporter(err.toString()));
|
||||
const projectPath = path.join(__dirname, '../../', src, 'tsconfig.json');
|
||||
const overrideOptions = Object.assign(Object.assign({}, getTypeScriptCompilerOptions(src)), { inlineSources: Boolean(build) });
|
||||
const ts = tsb.create(projectPath, overrideOptions, false, err => reporter(err));
|
||||
return function (token) {
|
||||
const utf8Filter = util.filter(data => /(\/|\\)test(\/|\\).*utf8/.test(data.path));
|
||||
const tsFilter = util.filter(data => /\.ts$/.test(data.path));
|
||||
@@ -64,23 +55,17 @@ function createCompile(src, build, emitError) {
|
||||
.pipe(sourcemaps.write('.', {
|
||||
addComment: false,
|
||||
includeContent: !!build,
|
||||
sourceRoot: opts.sourceRoot
|
||||
sourceRoot: overrideOptions.sourceRoot
|
||||
}))
|
||||
.pipe(tsFilter.restore)
|
||||
.pipe(reporter.end(!!emitError));
|
||||
return es.duplex(input, output);
|
||||
};
|
||||
}
|
||||
const typesDts = [
|
||||
'node_modules/typescript/lib/*.d.ts',
|
||||
'node_modules/@types/**/*.d.ts',
|
||||
'!node_modules/@types/webpack/**/*',
|
||||
'!node_modules/@types/uglify-js/**/*',
|
||||
];
|
||||
function compileTask(src, out, build) {
|
||||
return function () {
|
||||
const compile = createCompile(src, build, true);
|
||||
const srcPipe = es.merge(gulp.src(`${src}/**`, { base: `${src}` }), gulp.src(typesDts));
|
||||
const srcPipe = gulp.src(`${src}/**`, { base: `${src}` });
|
||||
let generator = new MonacoGenerator(false);
|
||||
if (src === 'src') {
|
||||
generator.execute();
|
||||
@@ -95,8 +80,8 @@ exports.compileTask = compileTask;
|
||||
function watchTask(out, build) {
|
||||
return function () {
|
||||
const compile = createCompile('src', build);
|
||||
const src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src(typesDts));
|
||||
const watchSrc = watch('src/**', { base: 'src' });
|
||||
const src = gulp.src('src/**', { base: 'src' });
|
||||
const watchSrc = watch('src/**', { base: 'src', readDelay: 200 });
|
||||
let generator = new MonacoGenerator(true);
|
||||
generator.execute();
|
||||
return watchSrc
|
||||
|
||||
+11
-31
@@ -12,27 +12,21 @@ import * as bom from 'gulp-bom';
|
||||
import * as sourcemaps from 'gulp-sourcemaps';
|
||||
import * as tsb from 'gulp-tsb';
|
||||
import * as path from 'path';
|
||||
import * as _ from 'underscore';
|
||||
import * as monacodts from '../monaco/api';
|
||||
import * as nls from './nls';
|
||||
import { createReporter } from './reporter';
|
||||
import * as util from './util';
|
||||
import * as fancyLog from 'fancy-log';
|
||||
import * as ansiColors from 'ansi-colors';
|
||||
import ts = require('typescript');
|
||||
|
||||
const watch = require('./watch');
|
||||
|
||||
const reporter = createReporter();
|
||||
|
||||
function getTypeScriptCompilerOptions(src: string) {
|
||||
function getTypeScriptCompilerOptions(src: string): ts.CompilerOptions {
|
||||
const rootDir = path.join(__dirname, `../../${src}`);
|
||||
const tsconfig = require(`../../${src}/tsconfig.json`);
|
||||
let options: { [key: string]: any };
|
||||
if (tsconfig.extends) {
|
||||
options = Object.assign({}, require(path.join(rootDir, tsconfig.extends)).compilerOptions, tsconfig.compilerOptions);
|
||||
} else {
|
||||
options = tsconfig.compilerOptions;
|
||||
}
|
||||
let options: ts.CompilerOptions = {};
|
||||
options.verbose = false;
|
||||
options.sourceMap = true;
|
||||
if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry
|
||||
@@ -41,16 +35,15 @@ function getTypeScriptCompilerOptions(src: string) {
|
||||
options.rootDir = rootDir;
|
||||
options.baseUrl = rootDir;
|
||||
options.sourceRoot = util.toFileUri(rootDir);
|
||||
options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 'CRLF' : 'LF';
|
||||
options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 0 : 1;
|
||||
return options;
|
||||
}
|
||||
|
||||
function createCompile(src: string, build: boolean, emitError?: boolean): (token?: util.ICancellationToken) => NodeJS.ReadWriteStream {
|
||||
const opts = _.clone(getTypeScriptCompilerOptions(src));
|
||||
opts.inlineSources = !!build;
|
||||
opts.noFilesystemLookup = true;
|
||||
const projectPath = path.join(__dirname, '../../', src, 'tsconfig.json');
|
||||
const overrideOptions = { ...getTypeScriptCompilerOptions(src), inlineSources: Boolean(build) };
|
||||
|
||||
const ts = tsb.create(opts, true, undefined, err => reporter(err.toString()));
|
||||
const ts = tsb.create(projectPath, overrideOptions, false, err => reporter(err));
|
||||
|
||||
return function (token?: util.ICancellationToken) {
|
||||
|
||||
@@ -72,7 +65,7 @@ function createCompile(src: string, build: boolean, emitError?: boolean): (token
|
||||
.pipe(sourcemaps.write('.', {
|
||||
addComment: false,
|
||||
includeContent: !!build,
|
||||
sourceRoot: opts.sourceRoot
|
||||
sourceRoot: overrideOptions.sourceRoot
|
||||
}))
|
||||
.pipe(tsFilter.restore)
|
||||
.pipe(reporter.end(!!emitError));
|
||||
@@ -81,22 +74,12 @@ function createCompile(src: string, build: boolean, emitError?: boolean): (token
|
||||
};
|
||||
}
|
||||
|
||||
const typesDts = [
|
||||
'node_modules/typescript/lib/*.d.ts',
|
||||
'node_modules/@types/**/*.d.ts',
|
||||
'!node_modules/@types/webpack/**/*',
|
||||
'!node_modules/@types/uglify-js/**/*',
|
||||
];
|
||||
|
||||
export function compileTask(src: string, out: string, build: boolean): () => NodeJS.ReadWriteStream {
|
||||
|
||||
return function () {
|
||||
const compile = createCompile(src, build, true);
|
||||
|
||||
const srcPipe = es.merge(
|
||||
gulp.src(`${src}/**`, { base: `${src}` }),
|
||||
gulp.src(typesDts),
|
||||
);
|
||||
const srcPipe = gulp.src(`${src}/**`, { base: `${src}` });
|
||||
|
||||
let generator = new MonacoGenerator(false);
|
||||
if (src === 'src') {
|
||||
@@ -115,11 +98,8 @@ export function watchTask(out: string, build: boolean): () => NodeJS.ReadWriteSt
|
||||
return function () {
|
||||
const compile = createCompile('src', build);
|
||||
|
||||
const src = es.merge(
|
||||
gulp.src('src/**', { base: 'src' }),
|
||||
gulp.src(typesDts),
|
||||
);
|
||||
const watchSrc = watch('src/**', { base: 'src' });
|
||||
const src = gulp.src('src/**', { base: 'src' });
|
||||
const watchSrc = watch('src/**', { base: 'src', readDelay: 200 });
|
||||
|
||||
let generator = new MonacoGenerator(true);
|
||||
generator.execute();
|
||||
|
||||
+5
-5
@@ -580,7 +580,7 @@ function createXlfFilesForExtensions() {
|
||||
}
|
||||
return _xlf;
|
||||
}
|
||||
gulp.src([`./extensions/${extensionName}/package.nls.json`, `./extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }).pipe(event_stream_1.through(function (file) {
|
||||
gulp.src([`.build/extensions/${extensionName}/package.nls.json`, `.build/extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }).pipe(event_stream_1.through(function (file) {
|
||||
if (file.isBuffer()) {
|
||||
const buffer = file.contents;
|
||||
const basename = path.basename(file.path);
|
||||
@@ -603,7 +603,7 @@ function createXlfFilesForExtensions() {
|
||||
}
|
||||
else if (basename === 'nls.metadata.json') {
|
||||
const json = JSON.parse(buffer.toString('utf8'));
|
||||
const relPath = path.relative(`./extensions/${extensionName}`, path.dirname(file.path));
|
||||
const relPath = path.relative(`.build/extensions/${extensionName}`, path.dirname(file.path));
|
||||
for (let file in json) {
|
||||
const fileContent = json[file];
|
||||
getXlf().addFile(`extensions/${extensionName}/${relPath}/${file}`, fileContent.keys, fileContent.messages);
|
||||
@@ -906,8 +906,8 @@ function pullCoreAndExtensionsXlfFiles(apiHostname, username, password, language
|
||||
_coreAndExtensionResources.push(...json.workbench);
|
||||
// extensions
|
||||
let extensionsToLocalize = Object.create(null);
|
||||
glob.sync('./extensions/**/*.nls.json').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
|
||||
glob.sync('./extensions/*/node_modules/vscode-nls').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
|
||||
glob.sync('.build/extensions/**/*.nls.json').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
|
||||
glob.sync('.build/extensions/*/node_modules/vscode-nls').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
|
||||
Object.keys(extensionsToLocalize).forEach(extension => {
|
||||
_coreAndExtensionResources.push({ name: extension, project: extensionsProject });
|
||||
});
|
||||
@@ -1080,7 +1080,7 @@ function prepareI18nPackFiles(externalExtensions, resultingTranslationPaths, pse
|
||||
resultingTranslationPaths.push({ id: 'vscode', resourceName: 'main.i18n.json' });
|
||||
this.queue(translatedMainFile);
|
||||
for (let extension in extensionsPacks) {
|
||||
const translatedExtFile = createI18nFile(`./extensions/${extension}`, extensionsPacks[extension]);
|
||||
const translatedExtFile = createI18nFile(`.build/extensions/${extension}`, extensionsPacks[extension]);
|
||||
this.queue(translatedExtFile);
|
||||
const externalExtensionId = externalExtensions[extension];
|
||||
if (externalExtensionId) {
|
||||
|
||||
+5
-5
@@ -701,7 +701,7 @@ export function createXlfFilesForExtensions(): ThroughStream {
|
||||
}
|
||||
return _xlf;
|
||||
}
|
||||
gulp.src([`./extensions/${extensionName}/package.nls.json`, `./extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }).pipe(through(function (file: File) {
|
||||
gulp.src([`.build/extensions/${extensionName}/package.nls.json`, `.build/extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }).pipe(through(function (file: File) {
|
||||
if (file.isBuffer()) {
|
||||
const buffer: Buffer = file.contents as Buffer;
|
||||
const basename = path.basename(file.path);
|
||||
@@ -721,7 +721,7 @@ export function createXlfFilesForExtensions(): ThroughStream {
|
||||
getXlf().addFile(`extensions/${extensionName}/package`, keys, messages);
|
||||
} else if (basename === 'nls.metadata.json') {
|
||||
const json: BundledExtensionFormat = JSON.parse(buffer.toString('utf8'));
|
||||
const relPath = path.relative(`./extensions/${extensionName}`, path.dirname(file.path));
|
||||
const relPath = path.relative(`.build/extensions/${extensionName}`, path.dirname(file.path));
|
||||
for (let file in json) {
|
||||
const fileContent = json[file];
|
||||
getXlf().addFile(`extensions/${extensionName}/${relPath}/${file}`, fileContent.keys, fileContent.messages);
|
||||
@@ -1045,8 +1045,8 @@ export function pullCoreAndExtensionsXlfFiles(apiHostname: string, username: str
|
||||
|
||||
// extensions
|
||||
let extensionsToLocalize = Object.create(null);
|
||||
glob.sync('./extensions/**/*.nls.json').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
|
||||
glob.sync('./extensions/*/node_modules/vscode-nls').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
|
||||
glob.sync('.build/extensions/**/*.nls.json').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
|
||||
glob.sync('.build/extensions/*/node_modules/vscode-nls').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
|
||||
|
||||
Object.keys(extensionsToLocalize).forEach(extension => {
|
||||
_coreAndExtensionResources.push({ name: extension, project: extensionsProject });
|
||||
@@ -1245,7 +1245,7 @@ export function prepareI18nPackFiles(externalExtensions: Map<string>, resultingT
|
||||
|
||||
this.queue(translatedMainFile);
|
||||
for (let extension in extensionsPacks) {
|
||||
const translatedExtFile = createI18nFile(`./extensions/${extension}`, extensionsPacks[extension]);
|
||||
const translatedExtFile = createI18nFile(`.build/extensions/${extension}`, extensionsPacks[extension]);
|
||||
this.queue(translatedExtFile);
|
||||
|
||||
const externalExtensionId = externalExtensions[extension];
|
||||
|
||||
+42
-3
@@ -5,6 +5,7 @@
|
||||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const es = require("event-stream");
|
||||
const fs = require("fs");
|
||||
const gulp = require("gulp");
|
||||
const concat = require("gulp-concat");
|
||||
const minifyCSS = require("gulp-cssnano");
|
||||
@@ -132,6 +133,14 @@ function optimizeTask(opts) {
|
||||
if (err || !result) {
|
||||
return bundlesStream.emit('error', JSON.stringify(err));
|
||||
}
|
||||
if (opts.inlineAmdImages) {
|
||||
try {
|
||||
result = inlineAmdImages(src, result);
|
||||
}
|
||||
catch (err) {
|
||||
return bundlesStream.emit('error', JSON.stringify(err));
|
||||
}
|
||||
}
|
||||
toBundleStream(src, bundledFileHeader, result.files).pipe(bundlesStream);
|
||||
// Remove css inlined resources
|
||||
const filteredResources = resources.slice();
|
||||
@@ -167,6 +176,39 @@ function optimizeTask(opts) {
|
||||
};
|
||||
}
|
||||
exports.optimizeTask = optimizeTask;
|
||||
function inlineAmdImages(src, result) {
|
||||
for (const outputFile of result.files) {
|
||||
for (const sourceFile of outputFile.sources) {
|
||||
if (sourceFile.path && /\.js$/.test(sourceFile.path)) {
|
||||
sourceFile.contents = sourceFile.contents.replace(/\([^.]+\.registerAndGetAmdImageURL\(([^)]+)\)\)/g, (_, m0) => {
|
||||
let imagePath = m0;
|
||||
// remove `` or ''
|
||||
if ((imagePath.charAt(0) === '`' && imagePath.charAt(imagePath.length - 1) === '`')
|
||||
|| (imagePath.charAt(0) === '\'' && imagePath.charAt(imagePath.length - 1) === '\'')) {
|
||||
imagePath = imagePath.substr(1, imagePath.length - 2);
|
||||
}
|
||||
if (!/\.(png|svg)$/.test(imagePath)) {
|
||||
console.log(`original: ${_}`);
|
||||
return _;
|
||||
}
|
||||
const repoLocation = path.join(src, imagePath);
|
||||
const absoluteLocation = path.join(REPO_ROOT_PATH, repoLocation);
|
||||
if (!fs.existsSync(absoluteLocation)) {
|
||||
const message = `Invalid amd image url in file ${sourceFile.path}: ${imagePath}`;
|
||||
console.log(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
const fileContents = fs.readFileSync(absoluteLocation);
|
||||
const mime = /\.svg$/.test(imagePath) ? 'image/svg+xml' : 'image/png';
|
||||
// Mark the file as inlined so we don't ship it by itself
|
||||
result.cssInlinedResources.push(repoLocation);
|
||||
return `("data:${mime};base64,${fileContents.toString('base64')}")`;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Wrap around uglify and allow the preserveComments function
|
||||
* to have a file "context" to include our copyright only once per file.
|
||||
@@ -202,9 +244,6 @@ function uglifyWithCopyrights() {
|
||||
const output = input
|
||||
.pipe(flatmap((stream, f) => {
|
||||
return stream.pipe(minify({
|
||||
compress: {
|
||||
hoist_funs: true // required due to https://github.com/microsoft/vscode/issues/80202
|
||||
},
|
||||
output: {
|
||||
comments: preserveComments(f),
|
||||
max_line_len: 1024
|
||||
|
||||
+49
-3
@@ -6,6 +6,7 @@
|
||||
'use strict';
|
||||
|
||||
import * as es from 'event-stream';
|
||||
import * as fs from 'fs';
|
||||
import * as gulp from 'gulp';
|
||||
import * as concat from 'gulp-concat';
|
||||
import * as minifyCSS from 'gulp-cssnano';
|
||||
@@ -159,6 +160,10 @@ export interface IOptimizeTaskOpts {
|
||||
* (emit bundleInfo.json file)
|
||||
*/
|
||||
bundleInfo: boolean;
|
||||
/**
|
||||
* replace calls to `registerAndGetAmdImageURL` with data uris
|
||||
*/
|
||||
inlineAmdImages: boolean;
|
||||
/**
|
||||
* (out folder name)
|
||||
*/
|
||||
@@ -192,6 +197,14 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
|
||||
bundle.bundle(entryPoints, loaderConfig, function (err, result) {
|
||||
if (err || !result) { return bundlesStream.emit('error', JSON.stringify(err)); }
|
||||
|
||||
if (opts.inlineAmdImages) {
|
||||
try {
|
||||
result = inlineAmdImages(src, result);
|
||||
} catch (err) {
|
||||
return bundlesStream.emit('error', JSON.stringify(err));
|
||||
}
|
||||
}
|
||||
|
||||
toBundleStream(src, bundledFileHeader, result.files).pipe(bundlesStream);
|
||||
|
||||
// Remove css inlined resources
|
||||
@@ -236,6 +249,42 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
|
||||
};
|
||||
}
|
||||
|
||||
function inlineAmdImages(src: string, result: bundle.IBundleResult): bundle.IBundleResult {
|
||||
for (const outputFile of result.files) {
|
||||
for (const sourceFile of outputFile.sources) {
|
||||
if (sourceFile.path && /\.js$/.test(sourceFile.path)) {
|
||||
sourceFile.contents = sourceFile.contents.replace(/\([^.]+\.registerAndGetAmdImageURL\(([^)]+)\)\)/g, (_, m0) => {
|
||||
let imagePath = m0;
|
||||
// remove `` or ''
|
||||
if ((imagePath.charAt(0) === '`' && imagePath.charAt(imagePath.length - 1) === '`')
|
||||
|| (imagePath.charAt(0) === '\'' && imagePath.charAt(imagePath.length - 1) === '\'')) {
|
||||
imagePath = imagePath.substr(1, imagePath.length - 2);
|
||||
}
|
||||
if (!/\.(png|svg)$/.test(imagePath)) {
|
||||
console.log(`original: ${_}`);
|
||||
return _;
|
||||
}
|
||||
const repoLocation = path.join(src, imagePath);
|
||||
const absoluteLocation = path.join(REPO_ROOT_PATH, repoLocation);
|
||||
if (!fs.existsSync(absoluteLocation)) {
|
||||
const message = `Invalid amd image url in file ${sourceFile.path}: ${imagePath}`;
|
||||
console.log(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
const fileContents = fs.readFileSync(absoluteLocation);
|
||||
const mime = /\.svg$/.test(imagePath) ? 'image/svg+xml' : 'image/png';
|
||||
|
||||
// Mark the file as inlined so we don't ship it by itself
|
||||
result.cssInlinedResources.push(repoLocation);
|
||||
|
||||
return `("data:${mime};base64,${fileContents.toString('base64')}")`;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
declare class FileWithCopyright extends VinylFile {
|
||||
public __hasOurCopyright: boolean;
|
||||
}
|
||||
@@ -278,9 +327,6 @@ function uglifyWithCopyrights(): NodeJS.ReadWriteStream {
|
||||
const output = input
|
||||
.pipe(flatmap((stream, f) => {
|
||||
return stream.pipe(minify({
|
||||
compress: {
|
||||
hoist_funs: true // required due to https://github.com/microsoft/vscode/issues/80202
|
||||
},
|
||||
output: {
|
||||
comments: preserveComments(<FileWithCopyright>f),
|
||||
max_line_len: 1024
|
||||
|
||||
@@ -11,6 +11,9 @@ const Lint = require("tslint");
|
||||
*/
|
||||
class Rule extends Lint.Rules.AbstractRule {
|
||||
apply(sourceFile) {
|
||||
if (/\.d.ts$/.test(sourceFile.fileName)) {
|
||||
return [];
|
||||
}
|
||||
return this.applyWithWalker(new NoUnexternalizedStringsRuleWalker(sourceFile, this.getOptions()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,9 @@ import * as Lint from 'tslint';
|
||||
*/
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
if (/\.d.ts$/.test(sourceFile.fileName)) {
|
||||
return [];
|
||||
}
|
||||
return this.applyWithWalker(new NoUnexternalizedStringsRuleWalker(sourceFile, this.getOptions()));
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+4
-5
@@ -7,10 +7,9 @@ declare module "gulp-tsb" {
|
||||
}
|
||||
|
||||
export interface IncrementalCompiler {
|
||||
(token?:ICancellationToken): NodeJS.ReadWriteStream;
|
||||
// program?: ts.Program;
|
||||
(token?: ICancellationToken): NodeJS.ReadWriteStream;
|
||||
src(): NodeJS.ReadStream;
|
||||
}
|
||||
export function create(projectPath: string, existingOptions: any, verbose?: boolean, onError?: (message: any) => void): IncrementalCompiler;
|
||||
|
||||
export function create(configOrName: { [option: string]: string | number | boolean; } | string, verbose?: boolean, json?: boolean, onError?: (message: any) => void): IncrementalCompiler;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -148,8 +148,9 @@ function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName,
|
||||
}
|
||||
});
|
||||
}
|
||||
result = result.replace(/export default/g, 'export');
|
||||
result = result.replace(/export declare/g, 'export');
|
||||
result = result.replace(/export default /g, 'export ');
|
||||
result = result.replace(/export declare /g, 'export ');
|
||||
result = result.replace(/declare /g, '');
|
||||
if (declaration.kind === ts.SyntaxKind.EnumDeclaration) {
|
||||
result = result.replace(/const enum/, 'enum');
|
||||
enums.push(result);
|
||||
|
||||
+3
-2
@@ -178,8 +178,9 @@ function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declarati
|
||||
}
|
||||
});
|
||||
}
|
||||
result = result.replace(/export default/g, 'export');
|
||||
result = result.replace(/export declare/g, 'export');
|
||||
result = result.replace(/export default /g, 'export ');
|
||||
result = result.replace(/export declare /g, 'export ');
|
||||
result = result.replace(/declare /g, '');
|
||||
|
||||
if (declaration.kind === ts.SyntaxKind.EnumDeclaration) {
|
||||
result = result.replace(/const enum/, 'enum');
|
||||
|
||||
@@ -62,6 +62,7 @@ export interface ICommandHandler {
|
||||
#includeAll(vs/editor/common/editorCommon;editorOptions.=>): IScrollEvent
|
||||
#includeAll(vs/editor/common/model/textModelEvents):
|
||||
#includeAll(vs/editor/common/controller/cursorEvents):
|
||||
#include(vs/platform/accessibility/common/accessibility): AccessibilitySupport
|
||||
#includeAll(vs/editor/common/config/editorOptions):
|
||||
#includeAll(vs/editor/browser/editorBrowser;editorCommon.=>;editorOptions.=>):
|
||||
#include(vs/editor/common/config/fontInfo): FontInfo, BareFontInfo
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "monaco-editor-core",
|
||||
"private": true,
|
||||
"version": "0.16.0",
|
||||
"version": "0.18.0",
|
||||
"description": "A browser based code editor",
|
||||
"author": "Microsoft Corporation",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -80,19 +80,6 @@ if (fs.existsSync(processTreeDts)) {
|
||||
fs.unlinkSync(processTreeDts);
|
||||
}
|
||||
|
||||
// Rewrite the @types/node typings avoid a conflict with es2018 typings.
|
||||
// This is caused by our build not understanding `typesVersions` in the package.json
|
||||
//
|
||||
// TODO: Fix this
|
||||
{
|
||||
console.log('Rewriting node_modules/@types/node to workaround lack of typesVersions support');
|
||||
const indexPath = path.join('node_modules', '@types', 'node', 'index.d.ts');
|
||||
|
||||
const contents = fs.readFileSync(indexPath).toString()
|
||||
.replace(/interface IteratorResult<T> \{ \}/, '// VSCODE EDIT — remove IteratorResult\n// interface IteratorResult<T> { }');
|
||||
fs.writeFileSync(indexPath, contents);
|
||||
}
|
||||
|
||||
function getInstalledVersion(packageName, cwd) {
|
||||
const opts = {};
|
||||
if (cwd) {
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@
|
||||
"mime": "^1.3.4",
|
||||
"minimist": "^1.2.0",
|
||||
"request": "^2.85.0",
|
||||
"terser": "^4.2.1",
|
||||
"terser": "4.3.1",
|
||||
"tslint": "^5.9.1",
|
||||
"typescript": "3.6.2",
|
||||
"vsce": "1.48.0",
|
||||
|
||||
+10
-1
@@ -2169,7 +2169,7 @@ supports-color@^5.3.0:
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
terser@*, terser@^4.2.1:
|
||||
terser@*:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-4.2.1.tgz#1052cfe17576c66e7bc70fcc7119f22b155bdac1"
|
||||
integrity sha512-cGbc5utAcX4a9+2GGVX4DsenG6v0x3glnDi5hx8816X1McEAwPlPgRtXPJzSBsbpILxZ8MQMT0KvArLuE0HP5A==
|
||||
@@ -2178,6 +2178,15 @@ terser@*, terser@^4.2.1:
|
||||
source-map "~0.6.1"
|
||||
source-map-support "~0.5.12"
|
||||
|
||||
terser@4.3.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-4.3.1.tgz#09820bcb3398299c4b48d9a86aefc65127d0ed65"
|
||||
integrity sha512-pnzH6dnFEsR2aa2SJaKb1uSCl3QmIsJ8dEkj0Fky+2AwMMcC9doMqLOQIH6wVTEKaVfKVvLSk5qxPBEZT9mywg==
|
||||
dependencies:
|
||||
commander "^2.20.0"
|
||||
source-map "~0.6.1"
|
||||
source-map-support "~0.5.12"
|
||||
|
||||
through2@2.X, through2@^2.0.0, through2@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
|
||||
|
||||
@@ -745,6 +745,10 @@
|
||||
{
|
||||
"fileMatch": "*.css-data.json",
|
||||
"url": "https://raw.githubusercontent.com/Microsoft/vscode-css-languageservice/master/docs/customData.schema.json"
|
||||
},
|
||||
{
|
||||
"fileMatch": "package.json",
|
||||
"url": "./schemas/package.schema.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "CSS contributions to package.json",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"contributes": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"css.customData": {
|
||||
"type": "array",
|
||||
"markdownDescription": "A list of relative file paths pointing to JSON files following the [custom data format](https://github.com/Microsoft/vscode-css-languageservice/blob/master/docs/customData.md).\n\nVS Code loads custom data on startup to enhance its CSS support for the custom CSS properties, at directives, pseudo classes and pseudo elements you specify in the JSON files.\n\nThe file paths are relative to workspace and only workspace folder settings are considered.",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"description": "Relative path to a CSS custom data file"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,7 +128,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
const capabilities: ServerCapabilities = {
|
||||
// Tell the client that the server works in FULL text document sync mode
|
||||
textDocumentSync: documents.syncKind,
|
||||
completionProvider: snippetSupport ? { resolveProvider: false, triggerCharacters: ['/'] } : undefined,
|
||||
completionProvider: snippetSupport ? { resolveProvider: false, triggerCharacters: ['/', '-'] } : undefined,
|
||||
hoverProvider: true,
|
||||
documentSymbolProvider: true,
|
||||
referencesProvider: true,
|
||||
|
||||
@@ -231,6 +231,21 @@ export function expandEmmetAbbreviation(args: any): Thenable<boolean | undefined
|
||||
return fallbackTab();
|
||||
}
|
||||
|
||||
if (vscode.window.activeTextEditor.selections.length === 1 &&
|
||||
vscode.window.activeTextEditor.selection.isEmpty
|
||||
) {
|
||||
const anchor = vscode.window.activeTextEditor.selection.anchor;
|
||||
if (anchor.character === 0) {
|
||||
return fallbackTab();
|
||||
}
|
||||
|
||||
const prevPositionAnchor = anchor.translate(0, -1);
|
||||
const prevText = vscode.window.activeTextEditor.document.getText(new vscode.Range(prevPositionAnchor, anchor));
|
||||
if (prevText === ' ' || prevText === '\t') {
|
||||
return fallbackTab();
|
||||
}
|
||||
}
|
||||
|
||||
args = args || {};
|
||||
if (!args['language']) {
|
||||
args['language'] = vscode.window.activeTextEditor.document.languageId;
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { window, workspace, Uri, Disposable, Event, EventEmitter, DecorationData, DecorationProvider, ThemeColor } from 'vscode';
|
||||
import { window, workspace, Uri, Disposable, Event, EventEmitter, Decoration, DecorationProvider, ThemeColor } from 'vscode';
|
||||
import * as path from 'path';
|
||||
import { Repository, GitResourceGroup } from './repository';
|
||||
import { Model } from './model';
|
||||
import { debounce } from './decorators';
|
||||
import { filterEvent, dispose, anyEvent, fireEvent } from './util';
|
||||
import { GitErrorCodes, Status } from './api/git';
|
||||
import { GitErrorCodes } from './api/git';
|
||||
|
||||
type Callback = { resolve: (status: boolean) => void, reject: (err: any) => void };
|
||||
|
||||
@@ -29,7 +29,7 @@ class GitIgnoreDecorationProvider implements DecorationProvider {
|
||||
this.disposables.push(window.registerDecorationProvider(this));
|
||||
}
|
||||
|
||||
provideDecoration(uri: Uri): Promise<DecorationData | undefined> {
|
||||
provideDecoration(uri: Uri): Promise<Decoration | undefined> {
|
||||
const repository = this.model.getRepository(uri);
|
||||
|
||||
if (!repository) {
|
||||
@@ -48,7 +48,7 @@ class GitIgnoreDecorationProvider implements DecorationProvider {
|
||||
this.checkIgnoreSoon();
|
||||
}).then(ignored => {
|
||||
if (ignored) {
|
||||
return <DecorationData>{
|
||||
return <Decoration>{
|
||||
priority: 3,
|
||||
color: new ThemeColor('gitDecoration.ignoredResourceForeground')
|
||||
};
|
||||
@@ -89,7 +89,7 @@ class GitIgnoreDecorationProvider implements DecorationProvider {
|
||||
|
||||
class GitDecorationProvider implements DecorationProvider {
|
||||
|
||||
private static SubmoduleDecorationData: DecorationData = {
|
||||
private static SubmoduleDecorationData: Decoration = {
|
||||
title: 'Submodule',
|
||||
letter: 'S',
|
||||
color: new ThemeColor('gitDecoration.submoduleResourceForeground')
|
||||
@@ -99,7 +99,7 @@ class GitDecorationProvider implements DecorationProvider {
|
||||
readonly onDidChangeDecorations: Event<Uri[]> = this._onDidChangeDecorations.event;
|
||||
|
||||
private disposables: Disposable[] = [];
|
||||
private decorations = new Map<string, DecorationData>();
|
||||
private decorations = new Map<string, Decoration>();
|
||||
|
||||
constructor(private repository: Repository) {
|
||||
this.disposables.push(
|
||||
@@ -109,7 +109,7 @@ class GitDecorationProvider implements DecorationProvider {
|
||||
}
|
||||
|
||||
private onDidRunGitStatus(): void {
|
||||
let newDecorations = new Map<string, DecorationData>();
|
||||
let newDecorations = new Map<string, Decoration>();
|
||||
|
||||
this.collectSubmoduleDecorationData(newDecorations);
|
||||
this.collectDecorationData(this.repository.indexGroup, newDecorations);
|
||||
@@ -121,25 +121,22 @@ class GitDecorationProvider implements DecorationProvider {
|
||||
this._onDidChangeDecorations.fire([...uris.values()].map(value => Uri.parse(value, true)));
|
||||
}
|
||||
|
||||
private collectDecorationData(group: GitResourceGroup, bucket: Map<string, DecorationData>): void {
|
||||
private collectDecorationData(group: GitResourceGroup, bucket: Map<string, Decoration>): void {
|
||||
group.resourceStates.forEach(r => {
|
||||
if (r.resourceDecoration
|
||||
&& r.type !== Status.DELETED
|
||||
&& r.type !== Status.INDEX_DELETED
|
||||
) {
|
||||
if (r.resourceDecoration) {
|
||||
// not deleted and has a decoration
|
||||
bucket.set(r.original.toString(), r.resourceDecoration);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private collectSubmoduleDecorationData(bucket: Map<string, DecorationData>): void {
|
||||
private collectSubmoduleDecorationData(bucket: Map<string, Decoration>): void {
|
||||
for (const submodule of this.repository.submodules) {
|
||||
bucket.set(Uri.file(path.join(this.repository.root, submodule.path)).toString(), GitDecorationProvider.SubmoduleDecorationData);
|
||||
}
|
||||
}
|
||||
|
||||
provideDecoration(uri: Uri): DecorationData | undefined {
|
||||
provideDecoration(uri: Uri): Decoration | undefined {
|
||||
return this.decorations.get(uri.toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -1766,7 +1766,7 @@ export class Repository {
|
||||
}
|
||||
|
||||
const raw = await readfile(templatePath, 'utf8');
|
||||
return raw.replace(/\n?#.*/g, '');
|
||||
return raw.replace(/^\s*#.*$\n?/gm, '');
|
||||
|
||||
} catch (err) {
|
||||
return '';
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { commands, Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, SourceControlInputBoxValidation, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, DecorationData, Memento, SourceControlInputBoxValidationType, OutputChannel, LogLevel, env, ProgressOptions, CancellationToken } from 'vscode';
|
||||
import { commands, Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, SourceControlInputBoxValidation, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, Decoration, Memento, SourceControlInputBoxValidationType, OutputChannel, LogLevel, env, ProgressOptions, CancellationToken } from 'vscode';
|
||||
import { Repository as BaseRepository, Commit, Stash, GitError, Submodule, CommitOptions, ForcePushMode } from './git';
|
||||
import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent, combinedDisposable } from './util';
|
||||
import { memoize, throttle, debounce } from './decorators';
|
||||
@@ -157,10 +157,7 @@ export class Resource implements SourceControlResourceState {
|
||||
const tooltip = this.tooltip;
|
||||
const strikeThrough = this.strikeThrough;
|
||||
const faded = this.faded;
|
||||
const letter = this.letter;
|
||||
const color = this.color;
|
||||
|
||||
return { strikeThrough, faded, tooltip, light, dark, letter, color, source: 'git.resource' /*todo@joh*/ };
|
||||
return { strikeThrough, faded, tooltip, light, dark };
|
||||
}
|
||||
|
||||
get letter(): string {
|
||||
@@ -247,12 +244,12 @@ export class Resource implements SourceControlResourceState {
|
||||
}
|
||||
}
|
||||
|
||||
get resourceDecoration(): DecorationData {
|
||||
get resourceDecoration(): Decoration {
|
||||
const title = this.tooltip;
|
||||
const letter = this.letter;
|
||||
const color = this.color;
|
||||
const priority = this.priority;
|
||||
return { bubble: true, source: 'git.resource', title, letter, color, priority };
|
||||
return { bubble: true, title, letter, color, priority };
|
||||
}
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -71,6 +71,7 @@ class SyncStatusBar {
|
||||
|
||||
const onEnablementChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.enableStatusBarSync'));
|
||||
onEnablementChange(this.updateEnablement, this, this.disposables);
|
||||
this.updateEnablement();
|
||||
|
||||
this._onDidChange.fire();
|
||||
}
|
||||
|
||||
@@ -62,8 +62,10 @@ function getOutputChannel(): vscode.OutputChannel {
|
||||
|
||||
function showError() {
|
||||
vscode.window.showWarningMessage(localize('gulpTaskDetectError', 'Problem finding gulp tasks. See the output for more information.'),
|
||||
localize('gulpShowOutput', 'Go to output')).then(() => {
|
||||
_channel.show(true);
|
||||
localize('gulpShowOutput', 'Go to output')).then((choice) => {
|
||||
if (choice !== undefined) {
|
||||
_channel.show(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -156,8 +158,13 @@ class FolderDetector {
|
||||
try {
|
||||
let { stdout, stderr } = await exec(commandLine, { cwd: rootPath });
|
||||
if (stderr && stderr.length > 0) {
|
||||
getOutputChannel().appendLine(stderr);
|
||||
showError();
|
||||
// Filter out "No license field"
|
||||
const errors = stderr.split('\n');
|
||||
errors.pop(); // The last line is empty.
|
||||
if (!errors.every(value => value.indexOf('No license field') >= 0)) {
|
||||
getOutputChannel().appendLine(stderr);
|
||||
showError();
|
||||
}
|
||||
}
|
||||
let result: vscode.Task[] = [];
|
||||
if (stdout) {
|
||||
|
||||
@@ -188,6 +188,10 @@
|
||||
{
|
||||
"fileMatch": "*.html-data.json",
|
||||
"url": "https://raw.githubusercontent.com/Microsoft/vscode-html-languageservice/master/docs/customData.schema.json"
|
||||
},
|
||||
{
|
||||
"fileMatch": "package.json",
|
||||
"url": "./schemas/package.schema.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "HTML contributions to package.json",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"contributes": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"html.customData": {
|
||||
"type": "array",
|
||||
"markdownDescription": "A list of relative file paths pointing to JSON files following the [custom data format](https://github.com/Microsoft/vscode-html-languageservice/blob/master/docs/customData.md).\n\nVS Code loads custom data on startup to enhance its HTML support for the custom HTML tags, attributes and attribute values you specify in the JSON files.\n\nThe file paths are relative to workspace and only workspace folder settings are considered.",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"description": "Relative path to a HTML custom data file"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,8 +46,8 @@ suite('HTML Embedded Formatting', () => {
|
||||
}
|
||||
|
||||
function assertFormatWithFixture(fixtureName: string, expectedPath: string, options?: any, formatOptions?: FormattingOptions): void {
|
||||
let input = fs.readFileSync(path.join(__dirname, 'fixtures', 'inputs', fixtureName)).toString().replace(/\r\n/mg, '\n');
|
||||
let expected = fs.readFileSync(path.join(__dirname, 'fixtures', 'expected', expectedPath)).toString().replace(/\r\n/mg, '\n');
|
||||
let input = fs.readFileSync(path.join(__dirname, '..', '..', 'src', 'test', 'fixtures', 'inputs', fixtureName)).toString().replace(/\r\n/mg, '\n');
|
||||
let expected = fs.readFileSync(path.join(__dirname, '..', '..', 'src', 'test', 'fixtures', 'expected', expectedPath)).toString().replace(/\r\n/mg, '\n');
|
||||
assertFormat(input, expected, options, formatOptions, expectedPath);
|
||||
}
|
||||
|
||||
@@ -208,4 +208,4 @@ preserve_newlines: true
|
||||
unformatted: Array(1)["wbr"]
|
||||
wrap_attributes: "auto"
|
||||
wrap_attributes_indent_size: undefined
|
||||
wrap_line_length: 120*/
|
||||
wrap_line_length: 120*/
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,13 +1,7 @@
|
||||
{
|
||||
"extends": "../../shared.tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/",
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"jsx": "react",
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"strictBindCallApply": true,
|
||||
"noImplicitAny": true,
|
||||
"noUnusedLocals": true
|
||||
"jsx": "react"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
-20
@@ -1,7 +1,7 @@
|
||||
[
|
||||
{
|
||||
"c": "{",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments punctuation.definition.dictionary.begin.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json punctuation.definition.dictionary.begin.json",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -12,7 +12,7 @@
|
||||
},
|
||||
{
|
||||
"c": "\t",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -23,7 +23,7 @@
|
||||
},
|
||||
{
|
||||
"c": "\"",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments string.json.comments support.type.property-name.json.comments punctuation.support.type.property-name.begin.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json string.json support.type.property-name.json punctuation.support.type.property-name.begin.json",
|
||||
"r": {
|
||||
"dark_plus": "support.type.property-name: #9CDCFE",
|
||||
"light_plus": "support.type.property-name.json: #0451A5",
|
||||
@@ -34,7 +34,7 @@
|
||||
},
|
||||
{
|
||||
"c": "compilerOptions",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments string.json.comments support.type.property-name.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json string.json support.type.property-name.json",
|
||||
"r": {
|
||||
"dark_plus": "support.type.property-name: #9CDCFE",
|
||||
"light_plus": "support.type.property-name.json: #0451A5",
|
||||
@@ -45,7 +45,7 @@
|
||||
},
|
||||
{
|
||||
"c": "\"",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments string.json.comments support.type.property-name.json.comments punctuation.support.type.property-name.end.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json string.json support.type.property-name.json punctuation.support.type.property-name.end.json",
|
||||
"r": {
|
||||
"dark_plus": "support.type.property-name: #9CDCFE",
|
||||
"light_plus": "support.type.property-name.json: #0451A5",
|
||||
@@ -56,7 +56,7 @@
|
||||
},
|
||||
{
|
||||
"c": ":",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments punctuation.separator.dictionary.key-value.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json punctuation.separator.dictionary.key-value.json",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -67,7 +67,7 @@
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -78,7 +78,7 @@
|
||||
},
|
||||
{
|
||||
"c": "{",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments punctuation.definition.dictionary.begin.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json punctuation.definition.dictionary.begin.json",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -89,7 +89,7 @@
|
||||
},
|
||||
{
|
||||
"c": "\t\t",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -100,7 +100,7 @@
|
||||
},
|
||||
{
|
||||
"c": "\"",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments string.json.comments support.type.property-name.json.comments punctuation.support.type.property-name.begin.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json string.json support.type.property-name.json punctuation.support.type.property-name.begin.json",
|
||||
"r": {
|
||||
"dark_plus": "support.type.property-name: #9CDCFE",
|
||||
"light_plus": "support.type.property-name.json: #0451A5",
|
||||
@@ -111,7 +111,7 @@
|
||||
},
|
||||
{
|
||||
"c": "target",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments string.json.comments support.type.property-name.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json string.json support.type.property-name.json",
|
||||
"r": {
|
||||
"dark_plus": "support.type.property-name: #9CDCFE",
|
||||
"light_plus": "support.type.property-name.json: #0451A5",
|
||||
@@ -122,7 +122,7 @@
|
||||
},
|
||||
{
|
||||
"c": "\"",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments string.json.comments support.type.property-name.json.comments punctuation.support.type.property-name.end.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json string.json support.type.property-name.json punctuation.support.type.property-name.end.json",
|
||||
"r": {
|
||||
"dark_plus": "support.type.property-name: #9CDCFE",
|
||||
"light_plus": "support.type.property-name.json: #0451A5",
|
||||
@@ -133,7 +133,7 @@
|
||||
},
|
||||
{
|
||||
"c": ":",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments punctuation.separator.dictionary.key-value.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json punctuation.separator.dictionary.key-value.json",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -144,7 +144,7 @@
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -155,7 +155,7 @@
|
||||
},
|
||||
{
|
||||
"c": "\"",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments string.quoted.double.json.comments punctuation.definition.string.begin.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json punctuation.definition.string.begin.json",
|
||||
"r": {
|
||||
"dark_plus": "string: #CE9178",
|
||||
"light_plus": "string: #A31515",
|
||||
@@ -166,7 +166,7 @@
|
||||
},
|
||||
{
|
||||
"c": "es6",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments string.quoted.double.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json",
|
||||
"r": {
|
||||
"dark_plus": "string: #CE9178",
|
||||
"light_plus": "string: #A31515",
|
||||
@@ -177,7 +177,7 @@
|
||||
},
|
||||
{
|
||||
"c": "\"",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments string.quoted.double.json.comments punctuation.definition.string.end.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json punctuation.definition.string.end.json",
|
||||
"r": {
|
||||
"dark_plus": "string: #CE9178",
|
||||
"light_plus": "string: #A31515",
|
||||
@@ -188,7 +188,7 @@
|
||||
},
|
||||
{
|
||||
"c": "\t",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -199,7 +199,7 @@
|
||||
},
|
||||
{
|
||||
"c": "}",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments punctuation.definition.dictionary.end.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json punctuation.definition.dictionary.end.json",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -210,7 +210,7 @@
|
||||
},
|
||||
{
|
||||
"c": "}",
|
||||
"t": "source.json.comments meta.structure.dictionary.json.comments punctuation.definition.dictionary.end.json.comments",
|
||||
"t": "source.json meta.structure.dictionary.json punctuation.definition.dictionary.end.json",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
@@ -78,21 +78,26 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
}
|
||||
|
||||
const { updateUrl, commit, quality, serverDataFolderName, dataFolderName } = getProductConfiguration();
|
||||
const serverCommand = process.platform === 'win32' ? 'server.bat' : 'server.sh';
|
||||
const commandArgs = ['--port=0', '--disable-telemetry'];
|
||||
const env = getNewEnv();
|
||||
const remoteDataDir = process.env['TESTRESOLVER_DATA_FOLDER'] || path.join(os.homedir(), serverDataFolderName || `${dataFolderName}-testresolver`);
|
||||
env['VSCODE_AGENT_FOLDER'] = remoteDataDir;
|
||||
outputChannel.appendLine(`Using data folder at ${remoteDataDir}`);
|
||||
|
||||
if (!commit || env['TEST_RESOLVER_USE_SERVER_FROM_SOURCES']) { // dev mode
|
||||
if (!commit) { // dev mode
|
||||
const serverCommand = process.platform === 'win32' ? 'server.bat' : 'server.sh';
|
||||
const vscodePath = path.resolve(path.join(context.extensionPath, '..', '..'));
|
||||
const serverCommandPath = path.join(vscodePath, 'resources', 'server', 'bin-dev', serverCommand);
|
||||
extHostProcess = cp.spawn(serverCommandPath, commandArgs, { env, cwd: vscodePath });
|
||||
} else {
|
||||
const serverBin = path.join(remoteDataDir, 'bin');
|
||||
progress.report({ message: 'Installing VSCode Server' });
|
||||
const serverLocation = await downloadAndUnzipVSCodeServer(updateUrl, commit, quality, serverBin);
|
||||
const serverCommand = process.platform === 'win32' ? 'server.cmd' : 'server.sh';
|
||||
let serverLocation = env['VSCODE_REMOTE_SERVER_PATH']; // support environment variable to specify location of server on disk
|
||||
if (!serverLocation) {
|
||||
const serverBin = path.join(remoteDataDir, 'bin');
|
||||
progress.report({ message: 'Installing VSCode Server' });
|
||||
serverLocation = await downloadAndUnzipVSCodeServer(updateUrl, commit, quality, serverBin);
|
||||
}
|
||||
|
||||
outputChannel.appendLine(`Using server build at ${serverLocation}`);
|
||||
|
||||
extHostProcess = cp.spawn(path.join(serverLocation, serverCommand), commandArgs, { env, cwd: serverLocation });
|
||||
|
||||
+3
-4
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "code-oss-dev",
|
||||
"version": "1.39.0",
|
||||
"distro": "323c0a11187dcde94de3a5d913cd44437e85369a",
|
||||
"distro": "8516b3c6e37976c7f4a183ec1196a939f0ff11bf",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
},
|
||||
@@ -52,7 +52,7 @@
|
||||
"vscode-ripgrep": "^1.5.6",
|
||||
"vscode-sqlite3": "4.0.8",
|
||||
"vscode-textmate": "^4.2.2",
|
||||
"xterm": "3.15.0-beta101",
|
||||
"xterm": "3.15.0-beta108",
|
||||
"xterm-addon-search": "0.2.0-beta5",
|
||||
"xterm-addon-web-links": "0.1.0-beta10",
|
||||
"yauzl": "^2.9.2",
|
||||
@@ -97,7 +97,7 @@
|
||||
"gulp-rename": "^1.2.0",
|
||||
"gulp-replace": "^0.5.4",
|
||||
"gulp-shell": "^0.6.5",
|
||||
"gulp-tsb": "2.0.7",
|
||||
"gulp-tsb": "4.0.1",
|
||||
"gulp-tslint": "^8.1.3",
|
||||
"gulp-untar": "^0.0.7",
|
||||
"gulp-vinyl-zip": "^2.1.2",
|
||||
@@ -120,7 +120,6 @@
|
||||
"optimist": "0.3.5",
|
||||
"p-all": "^1.0.0",
|
||||
"pump": "^1.0.1",
|
||||
"puppeteer": "^1.19.0",
|
||||
"queue": "3.0.6",
|
||||
"rcedit": "^1.1.0",
|
||||
"rimraf": "^2.2.8",
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
"vscode-proxy-agent": "0.4.0",
|
||||
"vscode-ripgrep": "^1.5.6",
|
||||
"vscode-textmate": "^4.2.2",
|
||||
"xterm": "3.15.0-beta101",
|
||||
"xterm": "3.15.0-beta108",
|
||||
"xterm-addon-search": "0.2.0-beta5",
|
||||
"xterm-addon-web-links": "0.1.0-beta10",
|
||||
"yauzl": "^2.9.2",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"onigasm-umd": "^2.2.2",
|
||||
"semver-umd": "^5.5.3",
|
||||
"vscode-textmate": "^4.2.2",
|
||||
"xterm": "3.15.0-beta101",
|
||||
"xterm": "3.15.0-beta108",
|
||||
"xterm-addon-search": "0.2.0-beta5",
|
||||
"xterm-addon-web-links": "0.1.0-beta10"
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ xterm-addon-web-links@0.1.0-beta10:
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23"
|
||||
integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg==
|
||||
|
||||
xterm@3.15.0-beta101:
|
||||
version "3.15.0-beta101"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta101.tgz#38ffa0df5a3e9bdcb1818e74fe59b2f98b0fff69"
|
||||
integrity sha512-HRa7+FDqQ8iWBTvb1Ni+uMGILnu6k9mF7JHMHRHfWxFoQlSoGYCyfdyXlJjk68YN8GsEQREmrII6cPLiQizdEQ==
|
||||
xterm@3.15.0-beta108:
|
||||
version "3.15.0-beta108"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta108.tgz#d113f6d1e4d4b7645ab3ff002c81a4dba8a78a28"
|
||||
integrity sha512-btZXgI9BeawFzitw3EZvFPsH3kfBgJS55LOdz9DjEany3y9FfvmnVhq7wn4x1PmTU/djHobGGhMNemxptk+ryg==
|
||||
|
||||
+4
-4
@@ -1173,10 +1173,10 @@ xterm-addon-web-links@0.1.0-beta10:
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23"
|
||||
integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg==
|
||||
|
||||
xterm@3.15.0-beta101:
|
||||
version "3.15.0-beta101"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta101.tgz#38ffa0df5a3e9bdcb1818e74fe59b2f98b0fff69"
|
||||
integrity sha512-HRa7+FDqQ8iWBTvb1Ni+uMGILnu6k9mF7JHMHRHfWxFoQlSoGYCyfdyXlJjk68YN8GsEQREmrII6cPLiQizdEQ==
|
||||
xterm@3.15.0-beta108:
|
||||
version "3.15.0-beta108"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta108.tgz#d113f6d1e4d4b7645ab3ff002c81a4dba8a78a28"
|
||||
integrity sha512-btZXgI9BeawFzitw3EZvFPsH3kfBgJS55LOdz9DjEany3y9FfvmnVhq7wn4x1PmTU/djHobGGhMNemxptk+ryg==
|
||||
|
||||
yauzl@^2.9.2:
|
||||
version "2.10.0"
|
||||
|
||||
@@ -26,7 +26,7 @@ if grep -qi Microsoft /proc/version; then
|
||||
# use the Remote WSL extension if installed
|
||||
WSL_EXT_ID="ms-vscode-remote.remote-wsl"
|
||||
|
||||
if [ $WSL_BUILD -ge 41955 ]; then
|
||||
if [ $WSL_BUILD -ge 41955 -a $WSL_BUILD -lt 41959 ]; then
|
||||
# WSL2 in workaround for https://github.com/microsoft/WSL/issues/4337
|
||||
CWD="$(pwd)"
|
||||
cd "$VSCODE_PATH"
|
||||
|
||||
@@ -5,11 +5,14 @@ pushd %~dp0\..
|
||||
|
||||
set VSCODEUSERDATADIR=%TMP%\vscodeuserfolder-%RANDOM%-%TIME:~6,5%
|
||||
|
||||
:: Figure out which Electron to use for running tests
|
||||
if "%INTEGRATION_TEST_ELECTRON_PATH%"=="" (
|
||||
:: code.bat makes sure Test Extensions are compiled
|
||||
:: Run out of sources: no need to compile as code.sh takes care of it
|
||||
set INTEGRATION_TEST_ELECTRON_PATH=.\scripts\code.bat
|
||||
|
||||
echo "Running integration tests out of sources."
|
||||
) else (
|
||||
:: Compile Test Extensions
|
||||
:: Run from a built: need to compile all test extensions
|
||||
call yarn gulp compile-extension:vscode-api-tests
|
||||
call yarn gulp compile-extension:vscode-colorize-tests
|
||||
call yarn gulp compile-extension:markdown-language-features
|
||||
@@ -18,7 +21,7 @@ if "%INTEGRATION_TEST_ELECTRON_PATH%"=="" (
|
||||
call yarn gulp compile-extension:html-language-features-server
|
||||
call yarn gulp compile-extension:json-language-features-server
|
||||
|
||||
echo "Using %INTEGRATION_TEST_ELECTRON_PATH% as Electron path"
|
||||
echo "Running integration tests with '%INTEGRATION_TEST_ELECTRON_PATH%' as build."
|
||||
)
|
||||
|
||||
:: Integration & performance tests in AMD
|
||||
|
||||
@@ -15,10 +15,12 @@ cd $ROOT
|
||||
# Figure out which Electron to use for running tests
|
||||
if [ -z "$INTEGRATION_TEST_ELECTRON_PATH" ]
|
||||
then
|
||||
# code.sh makes sure Test Extensions are compiled
|
||||
# Run out of sources: no need to compile as code.sh takes care of it
|
||||
INTEGRATION_TEST_ELECTRON_PATH="./scripts/code.sh"
|
||||
|
||||
echo "Running integration tests out of sources."
|
||||
else
|
||||
# Compile Test Extensions
|
||||
# Run from a built: need to compile all test extensions
|
||||
yarn gulp compile-extension:vscode-api-tests
|
||||
yarn gulp compile-extension:vscode-colorize-tests
|
||||
yarn gulp compile-extension:markdown-language-features
|
||||
@@ -27,7 +29,7 @@ else
|
||||
yarn gulp compile-extension:html-language-features-server
|
||||
yarn gulp compile-extension:json-language-features-server
|
||||
|
||||
echo "Using $INTEGRATION_TEST_ELECTRON_PATH as Electron path"
|
||||
echo "Running integration tests with '$INTEGRATION_TEST_ELECTRON_PATH' as build."
|
||||
fi
|
||||
|
||||
# Integration tests in AMD
|
||||
|
||||
Vendored
+1
-1
@@ -34,7 +34,7 @@ exports.load = function (modulePaths, resultCallback, options) {
|
||||
* // configuration: IWindowConfiguration
|
||||
* @type {{
|
||||
* zoomLevel?: number,
|
||||
* extensionDevelopmentPath?: string | string[],
|
||||
* extensionDevelopmentPath?: string[],
|
||||
* extensionTestsPath?: string,
|
||||
* userEnv?: { [key: string]: string | undefined },
|
||||
* appRoot?: string,
|
||||
|
||||
@@ -15,14 +15,6 @@ exports.base = [{
|
||||
dest: 'vs/base/worker/workerMain.js'
|
||||
}];
|
||||
|
||||
exports.serviceWorker = [{
|
||||
name: 'vs/workbench/contrib/resources/browser/resourceServiceWorker',
|
||||
// include: ['vs/editor/common/services/editorSimpleWorker'],
|
||||
prepend: ['vs/loader.js'],
|
||||
append: ['vs/workbench/contrib/resources/browser/resourceServiceWorkerMain'],
|
||||
dest: 'vs/workbench/contrib/resources/browser/resourceServiceWorkerMain.js'
|
||||
}];
|
||||
|
||||
exports.workerExtensionHost = [entrypoint('vs/workbench/services/extensions/worker/extensionHostWorker')];
|
||||
|
||||
exports.workbenchDesktop = require('./vs/workbench/buildfile.desktop').collectModules();
|
||||
|
||||
+4
-1
@@ -24,6 +24,9 @@
|
||||
"./vs"
|
||||
],
|
||||
"exclude": [
|
||||
"./typings/require-monaco.d.ts"
|
||||
"./typings/require-monaco.d.ts",
|
||||
"./typings/xterm.d.ts",
|
||||
"./typings/xterm-addon-search.d.ts",
|
||||
"./typings/xterm-addon-web-links.d.ts"
|
||||
]
|
||||
}
|
||||
|
||||
Vendored
-36
@@ -1043,39 +1043,3 @@ declare module 'xterm' {
|
||||
addOscHandler(ident: number, callback: (data: string) => boolean): IDisposable;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Modifications to official .d.ts below
|
||||
declare module 'xterm' {
|
||||
interface TerminalCore {
|
||||
_onScroll: IEventEmitter<number>;
|
||||
_onKey: IEventEmitter<{ key: string }>;
|
||||
|
||||
_charSizeService: {
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
|
||||
_coreService: {
|
||||
triggerDataEvent(data: string, wasUserInput?: boolean): void;
|
||||
}
|
||||
|
||||
_renderService: {
|
||||
_renderer: {
|
||||
_renderLayers: any[];
|
||||
};
|
||||
_onIntersectionChange: any;
|
||||
};
|
||||
}
|
||||
|
||||
interface IEventEmitter<T> {
|
||||
fire(e: T): void;
|
||||
}
|
||||
|
||||
interface Terminal {
|
||||
_core: TerminalCore;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import { parse } from 'vs/base/common/marshalling';
|
||||
import { cloneAndChange } from 'vs/base/common/objects';
|
||||
import { escape } from 'vs/base/common/strings';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
|
||||
export interface MarkdownRenderOptions extends FormattedTextRenderOptions {
|
||||
codeBlockRenderer?: (modeId: string, value: string) => Promise<string>;
|
||||
@@ -172,9 +173,9 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
|
||||
renderer
|
||||
};
|
||||
|
||||
const allowedSchemes = ['http', 'https', 'mailto', 'data'];
|
||||
const allowedSchemes = [Schemas.http, Schemas.https, Schemas.mailto, Schemas.data, Schemas.file, Schemas.vscodeRemote];
|
||||
if (markdown.isTrusted) {
|
||||
allowedSchemes.push('command');
|
||||
allowedSchemes.push(Schemas.command);
|
||||
}
|
||||
|
||||
const renderedMarkdown = marked.parse(markdown.value, markedOptions);
|
||||
|
||||
@@ -92,8 +92,6 @@ export class Dialog extends Disposable {
|
||||
checkboxMessageElement.innerText = this.options.checkboxLabel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const toolbarRowElement = this.element.appendChild($('.dialog-toolbar-row'));
|
||||
this.toolbarContainer = toolbarRowElement.appendChild($('.dialog-toolbar'));
|
||||
}
|
||||
|
||||
@@ -64,6 +64,10 @@
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.monaco-inputbox > .wrapper > textarea.input.empty {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.monaco-inputbox > .wrapper > textarea.input::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ export class InputBox extends Widget {
|
||||
let tagName = this.options.flexibleHeight ? 'textarea' : 'input';
|
||||
|
||||
let wrapper = dom.append(this.element, $('.wrapper'));
|
||||
this.input = dom.append(wrapper, $(tagName + '.input'));
|
||||
this.input = dom.append(wrapper, $(tagName + '.input.empty'));
|
||||
this.input.setAttribute('autocorrect', 'off');
|
||||
this.input.setAttribute('autocapitalize', 'off');
|
||||
this.input.setAttribute('spellcheck', 'false');
|
||||
@@ -240,6 +240,7 @@ export class InputBox extends Widget {
|
||||
}
|
||||
|
||||
public setPlaceHolder(placeHolder: string): void {
|
||||
this.placeholder = placeHolder;
|
||||
this.input.setAttribute('placeholder', placeHolder);
|
||||
this.input.title = placeHolder;
|
||||
}
|
||||
@@ -506,6 +507,7 @@ export class InputBox extends Widget {
|
||||
|
||||
this.validate();
|
||||
this.updateMirror();
|
||||
dom.toggleClass(this.input, 'empty', !this.value);
|
||||
|
||||
if (this.state === 'open' && this.contextViewProvider) {
|
||||
this.contextViewProvider.layout();
|
||||
@@ -517,7 +519,7 @@ export class InputBox extends Widget {
|
||||
return;
|
||||
}
|
||||
|
||||
const value = this.value || this.placeholder;
|
||||
const value = this.value;
|
||||
const lastCharCode = value.charCodeAt(value.length - 1);
|
||||
const suffix = lastCharCode === 10 ? ' ' : '';
|
||||
const mirrorTextContent = value + suffix;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { getOrDefault } from 'vs/base/common/objects';
|
||||
import { IDisposable, dispose, Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IDisposable, dispose, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { Gesture, EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
@@ -188,7 +188,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
private currentDragFeedbackDisposable: IDisposable = Disposable.None;
|
||||
private onDragLeaveTimeout: IDisposable = Disposable.None;
|
||||
|
||||
private disposables: IDisposable[];
|
||||
private readonly disposables: DisposableStore = new DisposableStore();
|
||||
|
||||
private _onDidChangeContentHeight = new Emitter<number>();
|
||||
readonly onDidChangeContentHeight: Event<number> = Event.latch(this._onDidChangeContentHeight.event);
|
||||
@@ -214,7 +214,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
this.renderers.set(renderer.templateId, renderer);
|
||||
}
|
||||
|
||||
this.cache = new RowCache(this.renderers);
|
||||
this.cache = this.disposables.add(new RowCache(this.renderers));
|
||||
|
||||
this.lastRenderTop = 0;
|
||||
this.lastRenderHeight = 0;
|
||||
@@ -238,18 +238,16 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
this.rowsContainer.className = 'monaco-list-rows';
|
||||
Gesture.addTarget(this.rowsContainer);
|
||||
|
||||
this.scrollableElement = new ScrollableElement(this.rowsContainer, {
|
||||
this.scrollableElement = this.disposables.add(new ScrollableElement(this.rowsContainer, {
|
||||
alwaysConsumeMouseWheel: true,
|
||||
horizontal: this.horizontalScrolling ? ScrollbarVisibility.Auto : ScrollbarVisibility.Hidden,
|
||||
vertical: getOrDefault(options, o => o.verticalScrollMode, DefaultOptions.verticalScrollMode),
|
||||
useShadows: getOrDefault(options, o => o.useShadows, DefaultOptions.useShadows)
|
||||
});
|
||||
}));
|
||||
|
||||
this.domNode.appendChild(this.scrollableElement.getDomNode());
|
||||
container.appendChild(this.domNode);
|
||||
|
||||
this.disposables = [this.scrollableElement, this.cache];
|
||||
|
||||
this.scrollableElement.onScroll(this.onScroll, this, this.disposables);
|
||||
domEvent(this.rowsContainer, TouchEventType.Change)(this.onTouchChange, this, this.disposables);
|
||||
|
||||
@@ -1178,6 +1176,6 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
this.domNode.parentNode.removeChild(this.domNode);
|
||||
}
|
||||
|
||||
this.disposables = dispose(this.disposables);
|
||||
dispose(this.disposables);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@font-face {
|
||||
font-family: "octicons2";
|
||||
src: url("./octicons2.ttf?81972c7f658ef56eeefe672e514d35a3") format("truetype"),
|
||||
url("./octicons2.svg?81972c7f658ef56eeefe672e514d35a3#octicons2") format("svg");
|
||||
src: url("./octicons2.ttf?04609cb7b40cfe676d00e166656be7e8") format("truetype"),
|
||||
url("./octicons2.svg?04609cb7b40cfe676d00e166656be7e8#octicons2") format("svg");
|
||||
}
|
||||
|
||||
.octicon, .mega-octicon {
|
||||
@@ -247,5 +247,6 @@ body[data-octicons-update="enabled"] .octicon-warning:before { content: "\f02d"
|
||||
body[data-octicons-update="enabled"] .octicon-controls:before { content: "\26ad" }
|
||||
body[data-octicons-update="enabled"] .octicon-event:before { content: "\26ae" }
|
||||
body[data-octicons-update="enabled"] .octicon-record-keys:before { content: "\26af" }
|
||||
body[data-octicons-update="enabled"] .octicon-archive:before { content: "\f101" }
|
||||
body[data-octicons-update="enabled"] .octicon-arrow-both:before { content: "\f102" }
|
||||
body[data-octicons-update="enabled"] .octicon-Vector:before { content: "\f101" }
|
||||
body[data-octicons-update="enabled"] .octicon-archive:before { content: "\f102" }
|
||||
body[data-octicons-update="enabled"] .octicon-arrow-both:before { content: "\f103" }
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 227 KiB After Width: | Height: | Size: 226 KiB |
Binary file not shown.
@@ -143,7 +143,7 @@ export class Sash extends Disposable {
|
||||
this._register(domEvent(this.el, EventType.Start)(this.onTouchStart, this));
|
||||
|
||||
if (isIPad) {
|
||||
// see also http://ux.stackexchange.com/questions/39023/what-is-the-optimum-button-size-of-touch-screen-applications
|
||||
// see also https://ux.stackexchange.com/questions/39023/what-is-the-optimum-button-size-of-touch-screen-applications
|
||||
addClass(this.el, 'touch');
|
||||
}
|
||||
|
||||
|
||||
@@ -21,24 +21,15 @@
|
||||
}
|
||||
|
||||
.monaco-split-view2 > .split-view-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.monaco-split-view2.vertical > .split-view-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.monaco-split-view2.horizontal > .split-view-container {
|
||||
flex-direction: row;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.monaco-split-view2 > .split-view-container > .split-view-view {
|
||||
white-space: initial;
|
||||
flex: none;
|
||||
position: relative;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.monaco-split-view2 > .split-view-container > .split-view-view:not(.visible) {
|
||||
@@ -51,7 +42,6 @@
|
||||
|
||||
.monaco-split-view2.horizontal > .split-view-container > .split-view-view {
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.monaco-split-view2.separator-border > .split-view-container > .split-view-view:not(:first-child)::before {
|
||||
@@ -72,4 +62,4 @@
|
||||
.monaco-split-view2.separator-border.vertical > .split-view-container > .split-view-view:not(:first-child)::before {
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,10 +125,13 @@ abstract class ViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
layout(orthogonalSize: number | undefined): void {
|
||||
layout(position: number, orthogonalSize: number | undefined): void {
|
||||
this.layoutContainer(position);
|
||||
this.view.layout(this.size, orthogonalSize);
|
||||
}
|
||||
|
||||
abstract layoutContainer(position: number): void;
|
||||
|
||||
dispose(): IView {
|
||||
this.disposable.dispose();
|
||||
return this.view;
|
||||
@@ -137,16 +140,16 @@ abstract class ViewItem {
|
||||
|
||||
class VerticalViewItem extends ViewItem {
|
||||
|
||||
layout(orthogonalSize: number | undefined): void {
|
||||
super.layout(orthogonalSize);
|
||||
layoutContainer(position: number): void {
|
||||
this.container.style.top = `${position}px`;
|
||||
this.container.style.height = `${this.size}px`;
|
||||
}
|
||||
}
|
||||
|
||||
class HorizontalViewItem extends ViewItem {
|
||||
|
||||
layout(orthogonalSize: number | undefined): void {
|
||||
super.layout(orthogonalSize);
|
||||
layoutContainer(position: number): void {
|
||||
this.container.style.left = `${position}px`;
|
||||
this.container.style.width = `${this.size}px`;
|
||||
}
|
||||
}
|
||||
@@ -846,7 +849,12 @@ export class SplitView extends Disposable {
|
||||
this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
|
||||
|
||||
// Layout views
|
||||
this.viewItems.forEach(item => item.layout(this.orthogonalSize));
|
||||
let position = 0;
|
||||
|
||||
for (const viewItem of this.viewItems) {
|
||||
viewItem.layout(position, this.orthogonalSize);
|
||||
position += viewItem.size;
|
||||
}
|
||||
|
||||
// Layout sashes
|
||||
this.sashItems.forEach(item => item.sash.layout());
|
||||
@@ -903,7 +911,7 @@ export class SplitView extends Disposable {
|
||||
position += this.viewItems[i].size;
|
||||
|
||||
if (this.sashItems[i].sash === sash) {
|
||||
return position;
|
||||
return Math.min(position, this.contentSize - 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1053,13 +1053,15 @@ class TreeNodeListMouseController<T, TFilterData, TRef> extends MouseController<
|
||||
return super.onPointer(e);
|
||||
}
|
||||
|
||||
const model = ((this.tree as any).model as ITreeModel<T, TFilterData, TRef>); // internal
|
||||
const location = model.getNodeLocation(node);
|
||||
const recursive = e.browserEvent.altKey;
|
||||
model.setCollapsed(location, undefined, recursive);
|
||||
if (node.collapsible) {
|
||||
const model = ((this.tree as any).model as ITreeModel<T, TFilterData, TRef>); // internal
|
||||
const location = model.getNodeLocation(node);
|
||||
const recursive = e.browserEvent.altKey;
|
||||
model.setCollapsed(location, undefined, recursive);
|
||||
|
||||
if (expandOnlyOnTwistieClick && onTwistie) {
|
||||
return;
|
||||
if (expandOnlyOnTwistieClick && onTwistie) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
super.onPointer(e);
|
||||
@@ -1418,6 +1420,10 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
|
||||
return this.model.isCollapsible(location);
|
||||
}
|
||||
|
||||
setCollapsible(location: TRef, collapsible?: boolean): boolean {
|
||||
return this.model.setCollapsible(location, collapsible);
|
||||
}
|
||||
|
||||
isCollapsed(location: TRef): boolean {
|
||||
return this.model.isCollapsed(location);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ interface IAsyncDataTreeNode<TInput, T> {
|
||||
readonly parent: IAsyncDataTreeNode<TInput, T> | null;
|
||||
readonly children: IAsyncDataTreeNode<TInput, T>[];
|
||||
readonly id?: string | null;
|
||||
loading: boolean;
|
||||
refreshPromise: Promise<void> | undefined;
|
||||
hasChildren: boolean;
|
||||
stale: boolean;
|
||||
slow: boolean;
|
||||
@@ -41,7 +41,7 @@ function createAsyncDataTreeNode<TInput, T>(props: IAsyncDataTreeNodeRequiredPro
|
||||
return {
|
||||
...props,
|
||||
children: [],
|
||||
loading: false,
|
||||
refreshPromise: undefined,
|
||||
stale: true,
|
||||
slow: false,
|
||||
collapsedByDefault: undefined
|
||||
@@ -451,7 +451,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
||||
|
||||
const viewStateContext = viewState && { viewState, focus: [], selection: [] } as IAsyncDataTreeViewStateContext<TInput, T>;
|
||||
|
||||
await this.updateChildren(input, true, viewStateContext);
|
||||
await this._updateChildren(input, true, viewStateContext);
|
||||
|
||||
if (viewStateContext) {
|
||||
this.tree.setFocus(viewStateContext.focus);
|
||||
@@ -463,13 +463,17 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
async updateChildren(element: TInput | T = this.root.element, recursive = true, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): Promise<void> {
|
||||
async updateChildren(element: TInput | T = this.root.element, recursive = true): Promise<void> {
|
||||
await this._updateChildren(element, recursive);
|
||||
}
|
||||
|
||||
private async _updateChildren(element: TInput | T = this.root.element, recursive = true, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): Promise<void> {
|
||||
if (typeof this.root.element === 'undefined') {
|
||||
throw new TreeError(this.user, 'Tree input not set');
|
||||
}
|
||||
|
||||
if (this.root.loading) {
|
||||
await this.subTreeRefreshPromises.get(this.root)!;
|
||||
if (this.root.refreshPromise) {
|
||||
await this.root.refreshPromise;
|
||||
await Event.toPromise(this._onDidRender.event);
|
||||
}
|
||||
|
||||
@@ -519,21 +523,26 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
||||
throw new TreeError(this.user, 'Tree input not set');
|
||||
}
|
||||
|
||||
if (this.root.loading) {
|
||||
await this.subTreeRefreshPromises.get(this.root)!;
|
||||
if (this.root.refreshPromise) {
|
||||
await this.root.refreshPromise;
|
||||
await Event.toPromise(this._onDidRender.event);
|
||||
}
|
||||
|
||||
const node = this.getDataNode(element);
|
||||
|
||||
if (node !== this.root && !node.loading && !this.tree.isCollapsed(node)) {
|
||||
if (node.refreshPromise) {
|
||||
await this.root.refreshPromise;
|
||||
await Event.toPromise(this._onDidRender.event);
|
||||
}
|
||||
|
||||
if (node !== this.root && !node.refreshPromise && !this.tree.isCollapsed(node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const result = this.tree.expand(node === this.root ? null : node, recursive);
|
||||
|
||||
if (node.loading) {
|
||||
await this.subTreeRefreshPromises.get(node)!;
|
||||
if (node.refreshPromise) {
|
||||
await this.root.refreshPromise;
|
||||
await Event.toPromise(this._onDidRender.event);
|
||||
}
|
||||
|
||||
@@ -677,18 +686,18 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
||||
return result;
|
||||
}
|
||||
|
||||
result = this.doRefreshSubTree(node, recursive, viewStateContext);
|
||||
this.subTreeRefreshPromises.set(node, result);
|
||||
|
||||
try {
|
||||
await result;
|
||||
} finally {
|
||||
this.subTreeRefreshPromises.delete(node);
|
||||
}
|
||||
return this.doRefreshSubTree(node, recursive, viewStateContext);
|
||||
}
|
||||
|
||||
private async doRefreshSubTree(node: IAsyncDataTreeNode<TInput, T>, recursive: boolean, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): Promise<void> {
|
||||
node.loading = true;
|
||||
let done: () => void;
|
||||
node.refreshPromise = new Promise(c => done = c);
|
||||
this.subTreeRefreshPromises.set(node, node.refreshPromise);
|
||||
|
||||
node.refreshPromise.finally(() => {
|
||||
node.refreshPromise = undefined;
|
||||
this.subTreeRefreshPromises.delete(node);
|
||||
});
|
||||
|
||||
try {
|
||||
const childrenToRefresh = await this.doRefreshNode(node, recursive, viewStateContext);
|
||||
@@ -696,7 +705,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
||||
|
||||
await Promise.all(childrenToRefresh.map(child => this.doRefreshSubTree(child, recursive, viewStateContext)));
|
||||
} finally {
|
||||
node.loading = false;
|
||||
done!();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -869,6 +878,11 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
||||
private render(node: IAsyncDataTreeNode<TInput, T>, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): void {
|
||||
const children = node.children.map(c => asTreeElement(c, viewStateContext));
|
||||
this.tree.setChildren(node === this.root ? null : node, children);
|
||||
|
||||
if (node !== this.root) {
|
||||
this.tree.setCollapsible(node, node.hasChildren);
|
||||
}
|
||||
|
||||
this._onDidRender.fire();
|
||||
}
|
||||
|
||||
|
||||
@@ -231,6 +231,11 @@ export class CompressedTreeModel<T extends NonNullable<any>, TFilterData extends
|
||||
return this.model.isCollapsible(compressedNode);
|
||||
}
|
||||
|
||||
setCollapsible(location: T | null, collapsible?: boolean): boolean {
|
||||
const compressedNode = this.getCompressedNode(location);
|
||||
return this.model.setCollapsible(compressedNode, collapsible);
|
||||
}
|
||||
|
||||
isCollapsed(location: T | null): boolean {
|
||||
const compressedNode = this.getCompressedNode(location);
|
||||
return this.model.isCollapsed(compressedNode);
|
||||
@@ -397,6 +402,10 @@ export class CompressedObjectTreeModel<T extends NonNullable<any>, TFilterData e
|
||||
return this.model.isCollapsible(location);
|
||||
}
|
||||
|
||||
setCollapsible(location: T | null, collapsed?: boolean): boolean {
|
||||
return this.model.setCollapsible(location, collapsed);
|
||||
}
|
||||
|
||||
isCollapsed(location: T | null): boolean {
|
||||
return this.model.isCollapsed(location);
|
||||
}
|
||||
|
||||
@@ -46,6 +46,21 @@ export interface IIndexTreeModelOptions<T, TFilterData> {
|
||||
readonly autoExpandSingleChildren?: boolean;
|
||||
}
|
||||
|
||||
interface CollapsibleStateUpdate {
|
||||
readonly collapsible: boolean;
|
||||
}
|
||||
|
||||
interface CollapsedStateUpdate {
|
||||
readonly collapsed: boolean;
|
||||
readonly recursive: boolean;
|
||||
}
|
||||
|
||||
type CollapseStateUpdate = CollapsibleStateUpdate | CollapsedStateUpdate;
|
||||
|
||||
function isCollapsibleStateUpdate(update: CollapseStateUpdate): update is CollapsibleStateUpdate {
|
||||
return typeof (update as any).collapsible === 'boolean';
|
||||
}
|
||||
|
||||
export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = void> implements ITreeModel<T, TFilterData, number[]> {
|
||||
|
||||
readonly rootRef = [];
|
||||
@@ -205,6 +220,17 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
|
||||
return this.getTreeNode(location).collapsible;
|
||||
}
|
||||
|
||||
setCollapsible(location: number[], collapsible?: boolean): boolean {
|
||||
const node = this.getTreeNode(location);
|
||||
|
||||
if (typeof collapsible === 'undefined') {
|
||||
collapsible = !node.collapsible;
|
||||
}
|
||||
|
||||
const update: CollapsibleStateUpdate = { collapsible };
|
||||
return this.eventBufferer.bufferEvents(() => this._setCollapseState(location, update));
|
||||
}
|
||||
|
||||
isCollapsed(location: number[]): boolean {
|
||||
return this.getTreeNode(location).collapsed;
|
||||
}
|
||||
@@ -216,15 +242,16 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
|
||||
collapsed = !node.collapsed;
|
||||
}
|
||||
|
||||
return this.eventBufferer.bufferEvents(() => this._setCollapsed(location, collapsed!, recursive));
|
||||
const update: CollapsedStateUpdate = { collapsed, recursive: recursive || false };
|
||||
return this.eventBufferer.bufferEvents(() => this._setCollapseState(location, update));
|
||||
}
|
||||
|
||||
private _setCollapsed(location: number[], collapsed: boolean, recursive?: boolean): boolean {
|
||||
private _setCollapseState(location: number[], update: CollapseStateUpdate): boolean {
|
||||
const { node, listIndex, revealed } = this.getTreeNodeWithListIndex(location);
|
||||
|
||||
const result = this._setListNodeCollapsed(node, listIndex, revealed, collapsed!, recursive || false);
|
||||
const result = this._setListNodeCollapseState(node, listIndex, revealed, update);
|
||||
|
||||
if (node !== this.root && this.autoExpandSingleChildren && !collapsed! && !recursive) {
|
||||
if (node !== this.root && this.autoExpandSingleChildren && result && !isCollapsibleStateUpdate(update) && node.collapsible && !node.collapsed && !update.recursive) {
|
||||
let onlyVisibleChildIndex = -1;
|
||||
|
||||
for (let i = 0; i < node.children.length; i++) {
|
||||
@@ -241,17 +268,17 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
|
||||
}
|
||||
|
||||
if (onlyVisibleChildIndex > -1) {
|
||||
this._setCollapsed([...location, onlyVisibleChildIndex], false, false);
|
||||
this._setCollapseState([...location, onlyVisibleChildIndex], update);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private _setListNodeCollapsed(node: IMutableTreeNode<T, TFilterData>, listIndex: number, revealed: boolean, collapsed: boolean, recursive: boolean): boolean {
|
||||
const result = this._setNodeCollapsed(node, collapsed, recursive, false);
|
||||
private _setListNodeCollapseState(node: IMutableTreeNode<T, TFilterData>, listIndex: number, revealed: boolean, update: CollapseStateUpdate): boolean {
|
||||
const result = this._setNodeCollapseState(node, update, false);
|
||||
|
||||
if (!revealed || !node.visible) {
|
||||
if (!revealed || !node.visible || !result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -263,20 +290,28 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
|
||||
return result;
|
||||
}
|
||||
|
||||
private _setNodeCollapsed(node: IMutableTreeNode<T, TFilterData>, collapsed: boolean, recursive: boolean, deep: boolean): boolean {
|
||||
let result = node.collapsible && node.collapsed !== collapsed;
|
||||
private _setNodeCollapseState(node: IMutableTreeNode<T, TFilterData>, update: CollapseStateUpdate, deep: boolean): boolean {
|
||||
let result: boolean;
|
||||
|
||||
if (node.collapsible) {
|
||||
node.collapsed = collapsed;
|
||||
if (node === this.root) {
|
||||
result = false;
|
||||
} else {
|
||||
if (isCollapsibleStateUpdate(update)) {
|
||||
result = node.collapsible !== update.collapsible;
|
||||
node.collapsible = update.collapsible;
|
||||
} else {
|
||||
result = node.collapsed !== update.collapsed;
|
||||
node.collapsed = update.collapsed;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
this._onDidChangeCollapseState.fire({ node, deep });
|
||||
}
|
||||
}
|
||||
|
||||
if (recursive) {
|
||||
if (!isCollapsibleStateUpdate(update) && update.recursive) {
|
||||
for (const child of node.children) {
|
||||
result = this._setNodeCollapsed(child, collapsed, true, true) || result;
|
||||
result = this._setNodeCollapseState(child, update, true) || result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +327,7 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
|
||||
location = location.slice(0, location.length - 1);
|
||||
|
||||
if (node.collapsed) {
|
||||
this._setCollapsed(location, false);
|
||||
this._setCollapseState(location, { collapsed: false, recursive: false });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -216,6 +216,11 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
|
||||
return this.model.isCollapsible(location);
|
||||
}
|
||||
|
||||
setCollapsible(element: T | null, collapsible?: boolean): boolean {
|
||||
const location = this.getElementLocation(element);
|
||||
return this.model.setCollapsible(location, collapsible);
|
||||
}
|
||||
|
||||
isCollapsed(element: T | null): boolean {
|
||||
const location = this.getElementLocation(element);
|
||||
return this.model.isCollapsed(location);
|
||||
|
||||
@@ -120,6 +120,7 @@ export interface ITreeModel<T, TFilterData, TRef> {
|
||||
getLastElementAncestor(location?: TRef): T | undefined;
|
||||
|
||||
isCollapsible(location: TRef): boolean;
|
||||
setCollapsible(location: TRef, collapsible?: boolean): boolean;
|
||||
isCollapsed(location: TRef): boolean;
|
||||
setCollapsed(location: TRef, collapsed?: boolean, recursive?: boolean): boolean;
|
||||
expandTo(location: TRef): void;
|
||||
|
||||
@@ -8,3 +8,11 @@ import { URI } from 'vs/base/common/uri';
|
||||
export function getPathFromAmdModule(requirefn: typeof require, relativePath: string): string {
|
||||
return URI.parse(requirefn.toUrl(relativePath)).fsPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reference a resource that might be inlined.
|
||||
* Do not rename this method unless you adopt the build scripts.
|
||||
*/
|
||||
export function registerAndGetAmdImageURL(absolutePath: string): string {
|
||||
return require.toUrl(absolutePath);
|
||||
}
|
||||
|
||||
@@ -7,17 +7,14 @@
|
||||
* An interface for a JavaScript object that
|
||||
* acts a dictionary. The keys are strings.
|
||||
*/
|
||||
export interface IStringDictionary<V> {
|
||||
[name: string]: V;
|
||||
}
|
||||
export type IStringDictionary<V> = Record<string, V>;
|
||||
|
||||
|
||||
/**
|
||||
* An interface for a JavaScript object that
|
||||
* acts a dictionary. The keys are numbers.
|
||||
*/
|
||||
export interface INumberDictionary<V> {
|
||||
[idx: number]: V;
|
||||
}
|
||||
export type INumberDictionary<V> = Record<number, V>;
|
||||
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
@@ -136,4 +133,4 @@ export class SetMap<K, V> {
|
||||
|
||||
values.forEach(fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,9 +114,9 @@ export function log(entry: IRemoteConsoleLog, label: string): void {
|
||||
// First arg is a string
|
||||
if (typeof args[0] === 'string') {
|
||||
if (topFrame && isOneStringArg) {
|
||||
consoleArgs = [`%c[${label}] %c${args[0]} %c${topFrame}`, color('blue'), color('black'), color('grey')];
|
||||
consoleArgs = [`%c[${label}] %c${args[0]} %c${topFrame}`, color('blue'), color(''), color('grey')];
|
||||
} else {
|
||||
consoleArgs = [`%c[${label}] %c${args[0]}`, color('blue'), color('black'), ...args.slice(1)];
|
||||
consoleArgs = [`%c[${label}] %c${args[0]}`, color('blue'), color(''), ...args.slice(1)];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,4 +139,4 @@ export function log(entry: IRemoteConsoleLog, label: string): void {
|
||||
|
||||
function color(color: string): string {
|
||||
return `color: ${color}`;
|
||||
}
|
||||
}
|
||||
|
||||
+13
-13
@@ -207,17 +207,17 @@ export function createScanner(text: string, ignoreTrivia: boolean = false): JSON
|
||||
|
||||
function scanHexDigits(count: number): number {
|
||||
let digits = 0;
|
||||
let value = 0;
|
||||
let hexValue = 0;
|
||||
while (digits < count) {
|
||||
const ch = text.charCodeAt(pos);
|
||||
if (ch >= CharacterCodes._0 && ch <= CharacterCodes._9) {
|
||||
value = value * 16 + ch - CharacterCodes._0;
|
||||
hexValue = hexValue * 16 + ch - CharacterCodes._0;
|
||||
}
|
||||
else if (ch >= CharacterCodes.A && ch <= CharacterCodes.F) {
|
||||
value = value * 16 + ch - CharacterCodes.A + 10;
|
||||
hexValue = hexValue * 16 + ch - CharacterCodes.A + 10;
|
||||
}
|
||||
else if (ch >= CharacterCodes.a && ch <= CharacterCodes.f) {
|
||||
value = value * 16 + ch - CharacterCodes.a + 10;
|
||||
hexValue = hexValue * 16 + ch - CharacterCodes.a + 10;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
@@ -226,9 +226,9 @@ export function createScanner(text: string, ignoreTrivia: boolean = false): JSON
|
||||
digits++;
|
||||
}
|
||||
if (digits < count) {
|
||||
value = -1;
|
||||
hexValue = -1;
|
||||
}
|
||||
return value;
|
||||
return hexValue;
|
||||
}
|
||||
|
||||
function setPosition(newPosition: number) {
|
||||
@@ -291,7 +291,7 @@ export function createScanner(text: string, ignoreTrivia: boolean = false): JSON
|
||||
scanError = ScanError.UnexpectedEndOfString;
|
||||
break;
|
||||
}
|
||||
let ch = text.charCodeAt(pos);
|
||||
const ch = text.charCodeAt(pos);
|
||||
if (ch === CharacterCodes.doubleQuote) {
|
||||
result += text.substring(start, pos);
|
||||
pos++;
|
||||
@@ -304,8 +304,8 @@ export function createScanner(text: string, ignoreTrivia: boolean = false): JSON
|
||||
scanError = ScanError.UnexpectedEndOfString;
|
||||
break;
|
||||
}
|
||||
ch = text.charCodeAt(pos++);
|
||||
switch (ch) {
|
||||
const ch2 = text.charCodeAt(pos++);
|
||||
switch (ch2) {
|
||||
case CharacterCodes.doubleQuote:
|
||||
result += '\"';
|
||||
break;
|
||||
@@ -331,9 +331,9 @@ export function createScanner(text: string, ignoreTrivia: boolean = false): JSON
|
||||
result += '\t';
|
||||
break;
|
||||
case CharacterCodes.u:
|
||||
const ch = scanHexDigits(4);
|
||||
if (ch >= 0) {
|
||||
result += String.fromCharCode(ch);
|
||||
const ch3 = scanHexDigits(4);
|
||||
if (ch3 >= 0) {
|
||||
result += String.fromCharCode(ch3);
|
||||
} else {
|
||||
scanError = ScanError.InvalidUnicode;
|
||||
}
|
||||
@@ -1340,4 +1340,4 @@ function getLiteralNodeType(value: any): NodeType {
|
||||
case 'string': return 'string';
|
||||
default: return 'null';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,11 +144,11 @@ function withFormatting(text: string, edit: Edit, formattingOptions: FormattingO
|
||||
|
||||
// apply the formatting edits and track the begin and end offsets of the changes
|
||||
for (let i = edits.length - 1; i >= 0; i--) {
|
||||
const edit = edits[i];
|
||||
newText = applyEdit(newText, edit);
|
||||
begin = Math.min(begin, edit.offset);
|
||||
end = Math.max(end, edit.offset + edit.length);
|
||||
end += edit.content.length - edit.length;
|
||||
const curr = edits[i];
|
||||
newText = applyEdit(newText, curr);
|
||||
begin = Math.min(begin, curr.offset);
|
||||
end = Math.max(end, curr.offset + curr.length);
|
||||
end += curr.content.length - curr.length;
|
||||
}
|
||||
// create a single edit with all changes
|
||||
const editLength = text.length - (newText.length - end) - begin;
|
||||
@@ -182,4 +182,4 @@ export function applyEdits(text: string, edits: Edit[]): string {
|
||||
|
||||
export function isWS(text: string, offset: number) {
|
||||
return '\r\n \t'.indexOf(text.charAt(offset)) !== -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ export function values<V>(forEachable: { forEach(callback: (value: V, ...more: a
|
||||
|
||||
export function keys<K, V>(map: Map<K, V>): K[] {
|
||||
const result: K[] = [];
|
||||
map.forEach((value, key) => result.push(key));
|
||||
map.forEach((_value, key) => result.push(key));
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -482,8 +482,6 @@ export class ResourceMap<T> {
|
||||
}
|
||||
}
|
||||
|
||||
// We should fold BoundedMap and LinkedMap. See https://github.com/Microsoft/vscode/issues/28496
|
||||
|
||||
interface Item<K, V> {
|
||||
previous: Item<K, V> | undefined;
|
||||
next: Item<K, V> | undefined;
|
||||
|
||||
@@ -5,11 +5,6 @@
|
||||
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
|
||||
/**
|
||||
* The empty string.
|
||||
*/
|
||||
export const empty = '';
|
||||
|
||||
export function isFalsyOrWhitespace(str: string | undefined): boolean {
|
||||
if (!str || typeof str !== 'string') {
|
||||
return true;
|
||||
@@ -70,7 +65,7 @@ export function escape(html: string): string {
|
||||
* Escapes regular expression characters in a given string
|
||||
*/
|
||||
export function escapeRegExpCharacters(value: string): string {
|
||||
return value.replace(/[\-\\\{\}\*\+\?\|\^\$\.\[\]\(\)\#]/g, '\\$&');
|
||||
return value.replace(/[\\\{\}\*\+\?\|\^\$\.\[\]\(\)]/g, '\\$&');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -608,7 +603,7 @@ export function lcut(text: string, n: number) {
|
||||
re.lastIndex += 1;
|
||||
}
|
||||
|
||||
return text.substring(i).replace(/^\s/, empty);
|
||||
return text.substring(i).replace(/^\s/, '');
|
||||
}
|
||||
|
||||
// Escape codes
|
||||
@@ -636,7 +631,7 @@ export const removeAccents: (str: string) => string = (function () {
|
||||
// see: https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript/37511463#37511463
|
||||
const regex = /[\u0300-\u036f]/g;
|
||||
return function (str: string) {
|
||||
return (str as any).normalize('NFD').replace(regex, empty);
|
||||
return (str as any).normalize('NFD').replace(regex, '');
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -8,6 +8,7 @@ import { ITreeNode, ITreeRenderer, IAsyncDataSource } from 'vs/base/browser/ui/t
|
||||
import { AsyncDataTree } from 'vs/base/browser/ui/tree/asyncDataTree';
|
||||
import { IListVirtualDelegate, IIdentityProvider } from 'vs/base/browser/ui/list/list';
|
||||
import { hasClass } from 'vs/base/browser/dom';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
|
||||
interface Element {
|
||||
id: string;
|
||||
@@ -26,104 +27,89 @@ function find(elements: Element[] | undefined, id: string): Element {
|
||||
throw new Error('element not found');
|
||||
}
|
||||
|
||||
class Renderer implements ITreeRenderer<Element, void, HTMLElement> {
|
||||
readonly templateId = 'default';
|
||||
renderTemplate(container: HTMLElement): HTMLElement {
|
||||
return container;
|
||||
}
|
||||
renderElement(element: ITreeNode<Element, void>, index: number, templateData: HTMLElement): void {
|
||||
templateData.textContent = element.element.id;
|
||||
}
|
||||
disposeTemplate(templateData: HTMLElement): void {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
class IdentityProvider implements IIdentityProvider<Element> {
|
||||
getId(element: Element) {
|
||||
return element.id;
|
||||
}
|
||||
}
|
||||
|
||||
class VirtualDelegate implements IListVirtualDelegate<Element> {
|
||||
getHeight() { return 20; }
|
||||
getTemplateId(element: Element): string { return 'default'; }
|
||||
}
|
||||
|
||||
class DataSource implements IAsyncDataSource<Element, Element> {
|
||||
hasChildren(element: Element): boolean {
|
||||
return !!element.children && element.children.length > 0;
|
||||
}
|
||||
getChildren(element: Element): Promise<Element[]> {
|
||||
return Promise.resolve(element.children || []);
|
||||
}
|
||||
}
|
||||
|
||||
class Model {
|
||||
|
||||
constructor(readonly root: Element) { }
|
||||
|
||||
get(id: string): Element {
|
||||
return find(this.root.children, id);
|
||||
}
|
||||
}
|
||||
|
||||
suite('AsyncDataTree', function () {
|
||||
|
||||
test('Collapse state should be preserved across refresh calls', async () => {
|
||||
const container = document.createElement('div');
|
||||
container.style.width = '200px';
|
||||
container.style.height = '200px';
|
||||
|
||||
const delegate = new class implements IListVirtualDelegate<Element> {
|
||||
getHeight() { return 20; }
|
||||
getTemplateId(element: Element): string { return 'default'; }
|
||||
};
|
||||
|
||||
const renderer = new class implements ITreeRenderer<Element, void, HTMLElement> {
|
||||
readonly templateId = 'default';
|
||||
renderTemplate(container: HTMLElement): HTMLElement {
|
||||
return container;
|
||||
}
|
||||
renderElement(element: ITreeNode<Element, void>, index: number, templateData: HTMLElement): void {
|
||||
templateData.textContent = element.element.id;
|
||||
}
|
||||
disposeTemplate(templateData: HTMLElement): void {
|
||||
// noop
|
||||
}
|
||||
};
|
||||
|
||||
const dataSource = new class implements IAsyncDataSource<Element, Element> {
|
||||
hasChildren(element: Element): boolean {
|
||||
return !!element.children && element.children.length > 0;
|
||||
}
|
||||
getChildren(element: Element): Promise<Element[]> {
|
||||
return Promise.resolve(element.children || []);
|
||||
}
|
||||
};
|
||||
|
||||
const identityProvider = new class implements IIdentityProvider<Element> {
|
||||
getId(element: Element) {
|
||||
return element.id;
|
||||
}
|
||||
};
|
||||
|
||||
const root: Element = {
|
||||
const model = new Model({
|
||||
id: 'root',
|
||||
children: [{
|
||||
id: 'a'
|
||||
}]
|
||||
};
|
||||
});
|
||||
|
||||
const _: (id: string) => Element = find.bind(null, root.children);
|
||||
|
||||
const tree = new AsyncDataTree<Element, Element>('test', container, delegate, [renderer], dataSource, { identityProvider });
|
||||
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], new DataSource(), { identityProvider: new IdentityProvider() });
|
||||
tree.layout(200);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 0);
|
||||
|
||||
await tree.setInput(root);
|
||||
await tree.setInput(model.root);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
|
||||
_('a').children = [
|
||||
model.get('a').children = [
|
||||
{ id: 'aa' },
|
||||
{ id: 'ab' },
|
||||
{ id: 'ac' }
|
||||
];
|
||||
|
||||
await tree.updateChildren(root);
|
||||
await tree.updateChildren(model.root);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
|
||||
await tree.expand(_('a'));
|
||||
await tree.expand(model.get('a'));
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 4);
|
||||
|
||||
_('a').children = [];
|
||||
await tree.updateChildren(root);
|
||||
model.get('a').children = [];
|
||||
await tree.updateChildren(model.root);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
});
|
||||
|
||||
test('issue #68648', async () => {
|
||||
const container = document.createElement('div');
|
||||
container.style.width = '200px';
|
||||
container.style.height = '200px';
|
||||
|
||||
const delegate = new class implements IListVirtualDelegate<Element> {
|
||||
getHeight() { return 20; }
|
||||
getTemplateId(element: Element): string { return 'default'; }
|
||||
};
|
||||
|
||||
const renderer = new class implements ITreeRenderer<Element, void, HTMLElement> {
|
||||
readonly templateId = 'default';
|
||||
renderTemplate(container: HTMLElement): HTMLElement {
|
||||
return container;
|
||||
}
|
||||
renderElement(element: ITreeNode<Element, void>, index: number, templateData: HTMLElement): void {
|
||||
templateData.textContent = element.element.id;
|
||||
}
|
||||
disposeTemplate(templateData: HTMLElement): void {
|
||||
// noop
|
||||
}
|
||||
};
|
||||
|
||||
const getChildrenCalls: string[] = [];
|
||||
const dataSource = new class implements IAsyncDataSource<Element, Element> {
|
||||
@@ -136,25 +122,17 @@ suite('AsyncDataTree', function () {
|
||||
}
|
||||
};
|
||||
|
||||
const identityProvider = new class implements IIdentityProvider<Element> {
|
||||
getId(element: Element) {
|
||||
return element.id;
|
||||
}
|
||||
};
|
||||
|
||||
const root: Element = {
|
||||
const model = new Model({
|
||||
id: 'root',
|
||||
children: [{
|
||||
id: 'a'
|
||||
}]
|
||||
};
|
||||
});
|
||||
|
||||
const _: (id: string) => Element = find.bind(null, root.children);
|
||||
|
||||
const tree = new AsyncDataTree<Element, Element>('test', container, delegate, [renderer], dataSource, { identityProvider });
|
||||
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], dataSource, { identityProvider: new IdentityProvider() });
|
||||
tree.layout(200);
|
||||
|
||||
await tree.setInput(root);
|
||||
await tree.setInput(model.root);
|
||||
assert.deepStrictEqual(getChildrenCalls, ['root']);
|
||||
|
||||
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
@@ -162,8 +140,8 @@ suite('AsyncDataTree', function () {
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(tree.getNode().children[0].collapsed);
|
||||
|
||||
_('a').children = [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }];
|
||||
await tree.updateChildren(root);
|
||||
model.get('a').children = [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }];
|
||||
await tree.updateChildren(model.root);
|
||||
|
||||
assert.deepStrictEqual(getChildrenCalls, ['root', 'root']);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
@@ -171,8 +149,8 @@ suite('AsyncDataTree', function () {
|
||||
assert(hasClass(twistie, 'collapsed'));
|
||||
assert(tree.getNode().children[0].collapsed);
|
||||
|
||||
_('a').children = [];
|
||||
await tree.updateChildren(root);
|
||||
model.get('a').children = [];
|
||||
await tree.updateChildren(model.root);
|
||||
|
||||
assert.deepStrictEqual(getChildrenCalls, ['root', 'root', 'root']);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
@@ -180,8 +158,8 @@ suite('AsyncDataTree', function () {
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(tree.getNode().children[0].collapsed);
|
||||
|
||||
_('a').children = [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }];
|
||||
await tree.updateChildren(root);
|
||||
model.get('a').children = [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }];
|
||||
await tree.updateChildren(model.root);
|
||||
|
||||
assert.deepStrictEqual(getChildrenCalls, ['root', 'root', 'root', 'root']);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
@@ -192,26 +170,6 @@ suite('AsyncDataTree', function () {
|
||||
|
||||
test('issue #67722 - once resolved, refreshed collapsed nodes should only get children when expanded', async () => {
|
||||
const container = document.createElement('div');
|
||||
container.style.width = '200px';
|
||||
container.style.height = '200px';
|
||||
|
||||
const delegate = new class implements IListVirtualDelegate<Element> {
|
||||
getHeight() { return 20; }
|
||||
getTemplateId(element: Element): string { return 'default'; }
|
||||
};
|
||||
|
||||
const renderer = new class implements ITreeRenderer<Element, void, HTMLElement> {
|
||||
readonly templateId = 'default';
|
||||
renderTemplate(container: HTMLElement): HTMLElement {
|
||||
return container;
|
||||
}
|
||||
renderElement(element: ITreeNode<Element, void>, index: number, templateData: HTMLElement): void {
|
||||
templateData.textContent = element.element.id;
|
||||
}
|
||||
disposeTemplate(templateData: HTMLElement): void {
|
||||
// noop
|
||||
}
|
||||
};
|
||||
|
||||
const getChildrenCalls: string[] = [];
|
||||
const dataSource = new class implements IAsyncDataSource<Element, Element> {
|
||||
@@ -224,131 +182,66 @@ suite('AsyncDataTree', function () {
|
||||
}
|
||||
};
|
||||
|
||||
const identityProvider = new class implements IIdentityProvider<Element> {
|
||||
getId(element: Element) {
|
||||
return element.id;
|
||||
}
|
||||
};
|
||||
|
||||
const root: Element = {
|
||||
const model = new Model({
|
||||
id: 'root',
|
||||
children: [{
|
||||
id: 'a', children: [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }]
|
||||
}]
|
||||
};
|
||||
});
|
||||
|
||||
const _: (id: string) => Element = find.bind(null, root.children);
|
||||
|
||||
const tree = new AsyncDataTree<Element, Element>('test', container, delegate, [renderer], dataSource, { identityProvider });
|
||||
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], dataSource, { identityProvider: new IdentityProvider() });
|
||||
tree.layout(200);
|
||||
|
||||
await tree.setInput(root);
|
||||
assert(tree.getNode(_('a')).collapsed);
|
||||
await tree.setInput(model.root);
|
||||
assert(tree.getNode(model.get('a')).collapsed);
|
||||
assert.deepStrictEqual(getChildrenCalls, ['root']);
|
||||
|
||||
await tree.expand(_('a'));
|
||||
assert(!tree.getNode(_('a')).collapsed);
|
||||
await tree.expand(model.get('a'));
|
||||
assert(!tree.getNode(model.get('a')).collapsed);
|
||||
assert.deepStrictEqual(getChildrenCalls, ['root', 'a']);
|
||||
|
||||
tree.collapse(_('a'));
|
||||
assert(tree.getNode(_('a')).collapsed);
|
||||
tree.collapse(model.get('a'));
|
||||
assert(tree.getNode(model.get('a')).collapsed);
|
||||
assert.deepStrictEqual(getChildrenCalls, ['root', 'a']);
|
||||
|
||||
await tree.updateChildren();
|
||||
assert(tree.getNode(_('a')).collapsed);
|
||||
assert(tree.getNode(model.get('a')).collapsed);
|
||||
assert.deepStrictEqual(getChildrenCalls, ['root', 'a', 'root'], 'a should not be refreshed, since it\' collapsed');
|
||||
});
|
||||
|
||||
test('resolved collapsed nodes which lose children should lose twistie as well', async () => {
|
||||
const container = document.createElement('div');
|
||||
container.style.width = '200px';
|
||||
container.style.height = '200px';
|
||||
|
||||
const delegate = new class implements IListVirtualDelegate<Element> {
|
||||
getHeight() { return 20; }
|
||||
getTemplateId(element: Element): string { return 'default'; }
|
||||
};
|
||||
|
||||
const renderer = new class implements ITreeRenderer<Element, void, HTMLElement> {
|
||||
readonly templateId = 'default';
|
||||
renderTemplate(container: HTMLElement): HTMLElement {
|
||||
return container;
|
||||
}
|
||||
renderElement(element: ITreeNode<Element, void>, index: number, templateData: HTMLElement): void {
|
||||
templateData.textContent = element.element.id;
|
||||
}
|
||||
disposeTemplate(templateData: HTMLElement): void {
|
||||
// noop
|
||||
}
|
||||
};
|
||||
|
||||
const dataSource = new class implements IAsyncDataSource<Element, Element> {
|
||||
hasChildren(element: Element): boolean {
|
||||
return !!element.children && element.children.length > 0;
|
||||
}
|
||||
getChildren(element: Element): Promise<Element[]> {
|
||||
return Promise.resolve(element.children || []);
|
||||
}
|
||||
};
|
||||
|
||||
const identityProvider = new class implements IIdentityProvider<Element> {
|
||||
getId(element: Element) {
|
||||
return element.id;
|
||||
}
|
||||
};
|
||||
|
||||
const root: Element = {
|
||||
const model = new Model({
|
||||
id: 'root',
|
||||
children: [{
|
||||
id: 'a', children: [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }]
|
||||
}]
|
||||
};
|
||||
});
|
||||
|
||||
const _: (id: string) => Element = find.bind(null, root.children);
|
||||
|
||||
const tree = new AsyncDataTree<Element, Element>('test', container, delegate, [renderer], dataSource, { identityProvider });
|
||||
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], new DataSource(), { identityProvider: new IdentityProvider() });
|
||||
tree.layout(200);
|
||||
|
||||
await tree.setInput(root);
|
||||
await tree.expand(_('a'));
|
||||
await tree.setInput(model.root);
|
||||
await tree.expand(model.get('a'));
|
||||
|
||||
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(!tree.getNode(_('a')).collapsed);
|
||||
assert(!tree.getNode(model.get('a')).collapsed);
|
||||
|
||||
tree.collapse(_('a'));
|
||||
_('a').children = [];
|
||||
await tree.updateChildren(root);
|
||||
tree.collapse(model.get('a'));
|
||||
model.get('a').children = [];
|
||||
await tree.updateChildren(model.root);
|
||||
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(tree.getNode(_('a')).collapsed);
|
||||
assert(tree.getNode(model.get('a')).collapsed);
|
||||
});
|
||||
|
||||
test('support default collapse state per element', async () => {
|
||||
const container = document.createElement('div');
|
||||
container.style.width = '200px';
|
||||
container.style.height = '200px';
|
||||
|
||||
const delegate = new class implements IListVirtualDelegate<Element> {
|
||||
getHeight() { return 20; }
|
||||
getTemplateId(element: Element): string { return 'default'; }
|
||||
};
|
||||
|
||||
const renderer = new class implements ITreeRenderer<Element, void, HTMLElement> {
|
||||
readonly templateId = 'default';
|
||||
renderTemplate(container: HTMLElement): HTMLElement {
|
||||
return container;
|
||||
}
|
||||
renderElement(element: ITreeNode<Element, void>, index: number, templateData: HTMLElement): void {
|
||||
templateData.textContent = element.element.id;
|
||||
}
|
||||
disposeTemplate(templateData: HTMLElement): void {
|
||||
// noop
|
||||
}
|
||||
};
|
||||
|
||||
const getChildrenCalls: string[] = [];
|
||||
const dataSource = new class implements IAsyncDataSource<Element, Element> {
|
||||
@@ -361,22 +254,139 @@ suite('AsyncDataTree', function () {
|
||||
}
|
||||
};
|
||||
|
||||
const root: Element = {
|
||||
const model = new Model({
|
||||
id: 'root',
|
||||
children: [{
|
||||
id: 'a', children: [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }]
|
||||
}]
|
||||
};
|
||||
});
|
||||
|
||||
const _: (id: string) => Element = find.bind(null, root.children);
|
||||
|
||||
const tree = new AsyncDataTree<Element, Element>('test', container, delegate, [renderer], dataSource, {
|
||||
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], dataSource, {
|
||||
collapseByDefault: el => el.id !== 'a'
|
||||
});
|
||||
tree.layout(200);
|
||||
|
||||
await tree.setInput(root);
|
||||
assert(!tree.getNode(_('a')).collapsed);
|
||||
await tree.setInput(model.root);
|
||||
assert(!tree.getNode(model.get('a')).collapsed);
|
||||
assert.deepStrictEqual(getChildrenCalls, ['root', 'a']);
|
||||
});
|
||||
|
||||
test('issue #80098 - concurrent refresh and expand', async () => {
|
||||
const container = document.createElement('div');
|
||||
|
||||
const calls: Function[] = [];
|
||||
const dataSource = new class implements IAsyncDataSource<Element, Element> {
|
||||
hasChildren(element: Element): boolean {
|
||||
return !!element.children && element.children.length > 0;
|
||||
}
|
||||
getChildren(element: Element): Promise<Element[]> {
|
||||
return new Promise(c => calls.push(() => c(element.children)));
|
||||
}
|
||||
};
|
||||
|
||||
const model = new Model({
|
||||
id: 'root',
|
||||
children: [{
|
||||
id: 'a', children: [{
|
||||
id: 'aa'
|
||||
}]
|
||||
}]
|
||||
});
|
||||
|
||||
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], dataSource, { identityProvider: new IdentityProvider() });
|
||||
tree.layout(200);
|
||||
|
||||
const pSetInput = tree.setInput(model.root);
|
||||
calls.pop()!(); // resolve getChildren(root)
|
||||
await pSetInput;
|
||||
|
||||
const pUpdateChildrenA = tree.updateChildren(model.get('a'));
|
||||
const pExpandA = tree.expand(model.get('a'));
|
||||
assert.equal(calls.length, 1, 'expand(a) still hasn\'t called getChildren(a)');
|
||||
|
||||
calls.pop()!();
|
||||
assert.equal(calls.length, 0, 'no pending getChildren calls');
|
||||
|
||||
await pUpdateChildrenA;
|
||||
assert.equal(calls.length, 0, 'expand(a) should not have forced a second refresh');
|
||||
|
||||
const result = await pExpandA;
|
||||
assert.equal(result, true, 'expand(a) should be done');
|
||||
});
|
||||
|
||||
test('issue #80098 - first expand should call getChildren', async () => {
|
||||
const container = document.createElement('div');
|
||||
|
||||
const calls: Function[] = [];
|
||||
const dataSource = new class implements IAsyncDataSource<Element, Element> {
|
||||
hasChildren(element: Element): boolean {
|
||||
return !!element.children && element.children.length > 0;
|
||||
}
|
||||
getChildren(element: Element): Promise<Element[]> {
|
||||
return new Promise(c => calls.push(() => c(element.children)));
|
||||
}
|
||||
};
|
||||
|
||||
const model = new Model({
|
||||
id: 'root',
|
||||
children: [{
|
||||
id: 'a', children: [{
|
||||
id: 'aa'
|
||||
}]
|
||||
}]
|
||||
});
|
||||
|
||||
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], dataSource, { identityProvider: new IdentityProvider() });
|
||||
tree.layout(200);
|
||||
|
||||
const pSetInput = tree.setInput(model.root);
|
||||
calls.pop()!(); // resolve getChildren(root)
|
||||
await pSetInput;
|
||||
|
||||
const pExpandA = tree.expand(model.get('a'));
|
||||
assert.equal(calls.length, 1, 'expand(a) should\'ve called getChildren(a)');
|
||||
|
||||
let race = await Promise.race([pExpandA.then(() => 'expand'), timeout(1).then(() => 'timeout')]);
|
||||
assert.equal(race, 'timeout', 'expand(a) should not be yet done');
|
||||
|
||||
calls.pop()!();
|
||||
assert.equal(calls.length, 0, 'no pending getChildren calls');
|
||||
|
||||
race = await Promise.race([pExpandA.then(() => 'expand'), timeout(1).then(() => 'timeout')]);
|
||||
assert.equal(race, 'expand', 'expand(a) should now be done');
|
||||
});
|
||||
|
||||
test('issue #78388 - tree should react to hasChildren toggles', async () => {
|
||||
const container = document.createElement('div');
|
||||
const model = new Model({
|
||||
id: 'root',
|
||||
children: [{
|
||||
id: 'a'
|
||||
}]
|
||||
});
|
||||
|
||||
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], new DataSource(), { identityProvider: new IdentityProvider() });
|
||||
tree.layout(200);
|
||||
|
||||
await tree.setInput(model.root);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
|
||||
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
|
||||
model.get('a').children = [{ id: 'aa' }];
|
||||
await tree.updateChildren(model.get('a'), false);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(hasClass(twistie, 'collapsible'));
|
||||
assert(hasClass(twistie, 'collapsed'));
|
||||
|
||||
model.get('a').children = [];
|
||||
await tree.updateChildren(model.get('a'), false);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -333,6 +333,67 @@ suite('IndexTreeModel', function () {
|
||||
assert.deepEqual(toArray(list), [1, 11, 2]);
|
||||
});
|
||||
|
||||
test('setCollapsible', () => {
|
||||
const list: ITreeNode<number>[] = [];
|
||||
const model = new IndexTreeModel<number>('test', toSpliceable(list), -1);
|
||||
|
||||
model.splice([0], 0, Iterator.fromArray([
|
||||
{
|
||||
element: 0, children: Iterator.fromArray([
|
||||
{ element: 10 }
|
||||
])
|
||||
}
|
||||
]));
|
||||
|
||||
assert.deepEqual(list.length, 2);
|
||||
|
||||
model.setCollapsible([0], false);
|
||||
assert.deepEqual(list.length, 2);
|
||||
assert.deepEqual(list[0].element, 0);
|
||||
assert.deepEqual(list[0].collapsible, false);
|
||||
assert.deepEqual(list[0].collapsed, false);
|
||||
assert.deepEqual(list[1].element, 10);
|
||||
assert.deepEqual(list[1].collapsible, false);
|
||||
assert.deepEqual(list[1].collapsed, false);
|
||||
|
||||
model.setCollapsed([0], true);
|
||||
assert.deepEqual(list.length, 1);
|
||||
assert.deepEqual(list[0].element, 0);
|
||||
assert.deepEqual(list[0].collapsible, false);
|
||||
assert.deepEqual(list[0].collapsed, true);
|
||||
|
||||
model.setCollapsed([0], false);
|
||||
assert.deepEqual(list[0].element, 0);
|
||||
assert.deepEqual(list[0].collapsible, false);
|
||||
assert.deepEqual(list[0].collapsed, false);
|
||||
assert.deepEqual(list[1].element, 10);
|
||||
assert.deepEqual(list[1].collapsible, false);
|
||||
assert.deepEqual(list[1].collapsed, false);
|
||||
|
||||
model.setCollapsible([0], true);
|
||||
assert.deepEqual(list.length, 2);
|
||||
assert.deepEqual(list[0].element, 0);
|
||||
assert.deepEqual(list[0].collapsible, true);
|
||||
assert.deepEqual(list[0].collapsed, false);
|
||||
assert.deepEqual(list[1].element, 10);
|
||||
assert.deepEqual(list[1].collapsible, false);
|
||||
assert.deepEqual(list[1].collapsed, false);
|
||||
|
||||
model.setCollapsed([0], true);
|
||||
assert.deepEqual(list.length, 1);
|
||||
assert.deepEqual(list[0].element, 0);
|
||||
assert.deepEqual(list[0].collapsible, true);
|
||||
assert.deepEqual(list[0].collapsed, true);
|
||||
|
||||
model.setCollapsed([0], false);
|
||||
assert.deepEqual(list[0].element, 0);
|
||||
assert.deepEqual(list[0].collapsible, true);
|
||||
assert.deepEqual(list[0].collapsed, false);
|
||||
assert.deepEqual(list[1].element, 10);
|
||||
assert.deepEqual(list[1].collapsible, false);
|
||||
assert.deepEqual(list[1].collapsed, false);
|
||||
});
|
||||
|
||||
test('simple filter', function () {
|
||||
const list: ITreeNode<number>[] = [];
|
||||
const filter = new class implements ITreeFilter<number> {
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IWorkbenchConstructionOptions, create } from 'vs/workbench/workbench.web.api';
|
||||
import { IURLCallbackProvider } from 'vs/workbench/services/url/browser/urlService';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { streamToBuffer } from 'vs/base/common/buffer';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { request } from 'vs/base/parts/request/browser/request';
|
||||
import { ICredentialsProvider } from 'vs/workbench/services/credentials/browser/credentialsService';
|
||||
|
||||
export function main(): void {
|
||||
const options: IWorkbenchConstructionOptions = JSON.parse(document.getElementById('vscode-workbench-web-configuration')!.getAttribute('data-settings')!);
|
||||
options.urlCallbackProvider = new PollingURLCallbackProvider();
|
||||
options.credentialsProvider = new LocalStorageCredentialsProvider();
|
||||
|
||||
create(document.body, options);
|
||||
}
|
||||
|
||||
interface ICredential {
|
||||
service: string;
|
||||
account: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
class LocalStorageCredentialsProvider implements ICredentialsProvider {
|
||||
|
||||
static readonly CREDENTIALS_OPENED_KEY = 'credentials.provider';
|
||||
|
||||
private _credentials: ICredential[];
|
||||
private get credentials(): ICredential[] {
|
||||
if (!this._credentials) {
|
||||
try {
|
||||
const serializedCredentials = window.localStorage.getItem(LocalStorageCredentialsProvider.CREDENTIALS_OPENED_KEY);
|
||||
if (serializedCredentials) {
|
||||
this._credentials = JSON.parse(serializedCredentials);
|
||||
}
|
||||
} catch (error) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (!Array.isArray(this._credentials)) {
|
||||
this._credentials = [];
|
||||
}
|
||||
}
|
||||
|
||||
return this._credentials;
|
||||
}
|
||||
|
||||
private save(): void {
|
||||
window.localStorage.setItem(LocalStorageCredentialsProvider.CREDENTIALS_OPENED_KEY, JSON.stringify(this.credentials));
|
||||
}
|
||||
|
||||
async getPassword(service: string, account: string): Promise<string | null> {
|
||||
return this.doGetPassword(service, account);
|
||||
}
|
||||
|
||||
private async doGetPassword(service: string, account?: string): Promise<string | null> {
|
||||
for (const credential of this.credentials) {
|
||||
if (credential.service === service) {
|
||||
if (typeof account !== 'string' || account === credential.account) {
|
||||
return credential.password;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async setPassword(service: string, account: string, password: string): Promise<void> {
|
||||
this.deletePassword(service, account);
|
||||
|
||||
this.credentials.push({ service, account, password });
|
||||
|
||||
this.save();
|
||||
}
|
||||
|
||||
async deletePassword(service: string, account: string): Promise<boolean> {
|
||||
let found = false;
|
||||
|
||||
this._credentials = this.credentials.filter(credential => {
|
||||
if (credential.service === service && credential.account === account) {
|
||||
found = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (found) {
|
||||
this.save();
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
async findPassword(service: string): Promise<string | null> {
|
||||
return this.doGetPassword(service);
|
||||
}
|
||||
|
||||
async findCredentials(service: string): Promise<Array<{ account: string, password: string }>> {
|
||||
return this.credentials
|
||||
.filter(credential => credential.service === service)
|
||||
.map(({ account, password }) => ({ account, password }));
|
||||
}
|
||||
}
|
||||
|
||||
class PollingURLCallbackProvider extends Disposable implements IURLCallbackProvider {
|
||||
|
||||
static FETCH_INTERVAL = 500; // fetch every 500ms
|
||||
static FETCH_TIMEOUT = 5 * 60 * 1000; // ...but stop after 5min
|
||||
|
||||
static QUERY_KEYS = {
|
||||
REQUEST_ID: 'vscode-requestId',
|
||||
SCHEME: 'vscode-scheme',
|
||||
AUTHORITY: 'vscode-authority',
|
||||
PATH: 'vscode-path',
|
||||
QUERY: 'vscode-query',
|
||||
FRAGMENT: 'vscode-fragment'
|
||||
};
|
||||
|
||||
private readonly _onCallback: Emitter<URI> = this._register(new Emitter<URI>());
|
||||
readonly onCallback: Event<URI> = this._onCallback.event;
|
||||
|
||||
create(options?: Partial<UriComponents>): URI {
|
||||
const queryValues: Map<string, string> = new Map();
|
||||
|
||||
const requestId = generateUuid();
|
||||
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.REQUEST_ID, requestId);
|
||||
|
||||
const { scheme, authority, path, query, fragment } = options ? options : { scheme: undefined, authority: undefined, path: undefined, query: undefined, fragment: undefined };
|
||||
|
||||
if (scheme) {
|
||||
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.SCHEME, scheme);
|
||||
}
|
||||
|
||||
if (authority) {
|
||||
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.AUTHORITY, authority);
|
||||
}
|
||||
|
||||
if (path) {
|
||||
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.PATH, path);
|
||||
}
|
||||
|
||||
if (query) {
|
||||
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.QUERY, query);
|
||||
}
|
||||
|
||||
if (fragment) {
|
||||
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.FRAGMENT, fragment);
|
||||
}
|
||||
|
||||
// Start to poll on the callback being fired
|
||||
this.periodicFetchCallback(requestId, Date.now());
|
||||
|
||||
return this.doCreateUri('/callback', queryValues);
|
||||
}
|
||||
|
||||
private async periodicFetchCallback(requestId: string, startTime: number): Promise<void> {
|
||||
|
||||
// Ask server for callback results
|
||||
const queryValues: Map<string, string> = new Map();
|
||||
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.REQUEST_ID, requestId);
|
||||
|
||||
const result = await request({
|
||||
url: this.doCreateUri('/fetch-callback', queryValues).toString(true)
|
||||
}, CancellationToken.None);
|
||||
|
||||
// Check for callback results
|
||||
const content = await streamToBuffer(result.stream);
|
||||
if (content.byteLength > 0) {
|
||||
try {
|
||||
this._onCallback.fire(URI.revive(JSON.parse(content.toString())));
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
return; // done
|
||||
}
|
||||
|
||||
// Continue fetching unless we hit the timeout
|
||||
if (Date.now() - startTime < PollingURLCallbackProvider.FETCH_TIMEOUT) {
|
||||
setTimeout(() => this.periodicFetchCallback(requestId, startTime), PollingURLCallbackProvider.FETCH_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
private doCreateUri(path: string, queryValues: Map<string, string>): URI {
|
||||
let query: string | undefined = undefined;
|
||||
|
||||
if (queryValues) {
|
||||
let index = 0;
|
||||
queryValues.forEach((value, key) => {
|
||||
if (!query) {
|
||||
query = '';
|
||||
}
|
||||
|
||||
const prefix = (index++ === 0) ? '' : '&';
|
||||
query += `${prefix}${key}=${encodeURIComponent(value)}`;
|
||||
});
|
||||
}
|
||||
|
||||
return URI.parse(window.location.href).with({ path, query });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<!-- Disable pinch zooming -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
|
||||
|
||||
<!-- Content Security Policy -->
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="
|
||||
default-src 'self';
|
||||
img-src 'self' https: data: blob:;
|
||||
media-src 'none';
|
||||
script-src 'self' https://az416426.vo.msecnd.net 'unsafe-eval' https: 'sha256-4DqvCTjCHj2KW4QxC/Yt6uBwMRyYiEg7kOoykSEkonQ=' 'sha256-g94DXzh59qc37AZjL7sV1lYN7OX4K1fgKl4ts5tAQDw=';
|
||||
child-src 'self';
|
||||
frame-src 'self' {{WEBVIEW_ENDPOINT}} https://*.vscode-webview-test.com;
|
||||
worker-src 'self';
|
||||
style-src 'self' 'unsafe-inline';
|
||||
connect-src 'self' ws: wss: https:;
|
||||
font-src 'self' blob:;
|
||||
manifest-src 'self';
|
||||
">
|
||||
|
||||
<!-- Workbench Configuration -->
|
||||
<meta id="vscode-workbench-web-configuration" data-settings="{{WORKBENCH_WEB_CONGIGURATION}}">
|
||||
|
||||
<!-- Workarounds/Hacks (remote user data uri) -->
|
||||
<meta id="vscode-remote-user-data-uri" data-settings="{{REMOTE_USER_DATA_URI}}">
|
||||
|
||||
<!-- Workbench Icon/Manifest/CSS -->
|
||||
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link data-name="vs/workbench/workbench.web.api" rel="stylesheet" href="./static/out/vs/workbench/workbench.web.api.css">
|
||||
</head>
|
||||
|
||||
<body aria-label="">
|
||||
</body>
|
||||
|
||||
<!-- Startup (do not modify order of script tags!) -->
|
||||
<script>
|
||||
// NOTE: Changes to inline scripts require update of content security policy
|
||||
self.require = {
|
||||
baseUrl: `${window.location.origin}/static/out`,
|
||||
paths: {
|
||||
'vscode-textmate': `${window.location.origin}/static/node_modules/vscode-textmate/release/main`,
|
||||
'onigasm-umd': `${window.location.origin}/static/node_modules/onigasm-umd/release/main`,
|
||||
'xterm': `${window.location.origin}/static/node_modules/xterm/lib/xterm.js`,
|
||||
'xterm-addon-search': `${window.location.origin}/static/node_modules/xterm-addon-search/lib/xterm-addon-search.js`,
|
||||
'xterm-addon-web-links': `${window.location.origin}/static/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`,
|
||||
'semver-umd': `${window.location.origin}/static/node_modules/semver-umd/lib/semver-umd.js`,
|
||||
'@microsoft/applicationinsights-web': `${window.location.origin}/static/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js`,
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script src="./static/out/vs/loader.js"></script>
|
||||
<script>
|
||||
// NOTE: Changes to inline scripts require update of content security policy
|
||||
require(['vs/code/browser/workbench/web.main'], function (web) {
|
||||
web.main();
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -10,18 +10,19 @@
|
||||
<!-- Content Security Policy -->
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="default-src 'none';
|
||||
content="
|
||||
default-src 'self';
|
||||
img-src 'self' https: data: blob:;
|
||||
media-src 'none';
|
||||
script-src 'self' https://az416426.vo.msecnd.net 'unsafe-eval' https:;
|
||||
script-src 'self' https://az416426.vo.msecnd.net 'unsafe-eval' https: 'sha256-4DqvCTjCHj2KW4QxC/Yt6uBwMRyYiEg7kOoykSEkonQ=' 'sha256-kXwJWoOluR7vyWhuqykdzYEHvOuOu2ZZhnBm0EBbYvU=';
|
||||
child-src 'self';
|
||||
frame-src 'self' {{WEBVIEW_ENDPOINT}} https://*.vscode-webview-test.com;
|
||||
worker-src 'self';
|
||||
style-src 'self' 'unsafe-inline';
|
||||
connect-src 'self' ws: wss: https:;
|
||||
font-src 'self' blob:;
|
||||
manifest-src 'self';"
|
||||
>
|
||||
manifest-src 'self';
|
||||
">
|
||||
|
||||
<!-- Workbench Configuration -->
|
||||
<meta id="vscode-workbench-web-configuration" data-settings="{{WORKBENCH_WEB_CONGIGURATION}}">
|
||||
@@ -33,13 +34,40 @@
|
||||
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link data-name="vs/workbench/workbench.web.api" rel="stylesheet" href="./static/out/vs/workbench/workbench.web.api.css">
|
||||
|
||||
<!-- Prefetch to avoid waterfall -->
|
||||
<link rel="prefetch" href="./static/node_modules/semver-umd/lib/semver-umd.js">
|
||||
<link rel="prefetch" href="./static/node_modules/onigasm-umd/release/main.js"> <!-- TODO@ben TODO@alex: should be lazy -->
|
||||
<link rel="prefetch" href="./static/out/vs/code/browser/workbench/web.main.js"> <!--TODO@ben: Why is it not built -->
|
||||
<link rel="prefetch" href="./static/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js">
|
||||
</head>
|
||||
|
||||
<body aria-label="">
|
||||
</body>
|
||||
|
||||
<!-- Startup (do not modify order of script tags!) -->
|
||||
<script>
|
||||
// NOTE: Changes to inline scripts require update of content security policy
|
||||
self.require = {
|
||||
baseUrl: `${window.location.origin}/static/out`,
|
||||
paths: {
|
||||
'vscode-textmate': `${window.location.origin}/static/node_modules/vscode-textmate/release/main`,
|
||||
'onigasm-umd': `${window.location.origin}/static/node_modules/onigasm-umd/release/main`,
|
||||
'xterm': `${window.location.origin}/static/node_modules/xterm/lib/xterm.js`,
|
||||
'xterm-addon-search': `${window.location.origin}/static/node_modules/xterm-addon-search/lib/xterm-addon-search.js`,
|
||||
'xterm-addon-web-links': `${window.location.origin}/static/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`,
|
||||
'semver-umd': `${window.location.origin}/static/node_modules/semver-umd/lib/semver-umd.js`,
|
||||
'@microsoft/applicationinsights-web': `${window.location.origin}/static/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js`,
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script src="./static/out/vs/loader.js"></script>
|
||||
<script src="./static/out/vs/workbench/workbench.web.api.nls.js"></script>
|
||||
<script src="./static/out/vs/code/browser/workbench/workbench.js"></script>
|
||||
<script src="./static/out/vs/workbench/workbench.web.api.js"></script>
|
||||
<!-- <script src="./static/out/vs/code/browser/workbench/web.main.js"></script> TODO@ben: Why is it not built-->
|
||||
<script>
|
||||
require(['vs/code/browser/workbench/web.main'], function (web) {
|
||||
web.main();
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
//@ts-check
|
||||
'use strict';
|
||||
|
||||
(function () {
|
||||
|
||||
/** @type any */
|
||||
const amdLoader = require;
|
||||
|
||||
amdLoader.config({
|
||||
baseUrl: `${window.location.origin}/static/out`,
|
||||
paths: {
|
||||
'vscode-textmate': `${window.location.origin}/static/node_modules/vscode-textmate/release/main`,
|
||||
'onigasm-umd': `${window.location.origin}/static/node_modules/onigasm-umd/release/main`,
|
||||
'xterm': `${window.location.origin}/static/node_modules/xterm/lib/xterm.js`,
|
||||
'xterm-addon-search': `${window.location.origin}/static/node_modules/xterm-addon-search/lib/xterm-addon-search.js`,
|
||||
'xterm-addon-web-links': `${window.location.origin}/static/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`,
|
||||
'semver-umd': `${window.location.origin}/static/node_modules/semver-umd/lib/semver-umd.js`,
|
||||
'@microsoft/applicationinsights-web': `${window.location.origin}/static/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js`,
|
||||
}
|
||||
});
|
||||
|
||||
amdLoader(['vs/workbench/workbench.web.api'], function (api) {
|
||||
const options = JSON.parse(document.getElementById('vscode-workbench-web-configuration').getAttribute('data-settings'));
|
||||
api.create(document.body, options);
|
||||
});
|
||||
})();
|
||||
@@ -49,7 +49,7 @@ bootstrapWindow.load([
|
||||
* @param {{
|
||||
* partsSplashPath?: string,
|
||||
* highContrast?: boolean,
|
||||
* extensionDevelopmentPath?: string | string[],
|
||||
* extensionDevelopmentPath?: string[],
|
||||
* folderUri?: object,
|
||||
* workspace?: object
|
||||
* }} configuration
|
||||
|
||||
@@ -26,7 +26,7 @@ import { IStateService } from 'vs/platform/state/common/state';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IURLService } from 'vs/platform/url/common/url';
|
||||
import { URLHandlerChannelClient, URLServiceChannel } from 'vs/platform/url/node/urlIpc';
|
||||
import { URLHandlerChannelClient, URLServiceChannel, URLHandlerRouter } from 'vs/platform/url/common/urlIpc';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { NullTelemetryService, combinedAppender, LogAppender } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { TelemetryAppenderClient } from 'vs/platform/telemetry/node/telemetryIpc';
|
||||
@@ -56,7 +56,6 @@ import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver';
|
||||
import { IMenubarService } from 'vs/platform/menubar/node/menubar';
|
||||
import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService';
|
||||
import { MenubarChannel } from 'vs/platform/menubar/node/menubarIpc';
|
||||
import { hasArgs } from 'vs/platform/environment/node/argv';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { registerContextMenuListener } from 'vs/base/parts/contextmenu/electron-main/contextmenu';
|
||||
import { homedir } from 'os';
|
||||
@@ -580,7 +579,8 @@ export class CodeApplication extends Disposable {
|
||||
// Create a URL handler which forwards to the last active window
|
||||
const activeWindowManager = new ActiveWindowManager(windowsService);
|
||||
const activeWindowRouter = new StaticRouter(ctx => activeWindowManager.getActiveClientId().then(id => ctx === id));
|
||||
const urlHandlerChannel = electronIpcServer.getChannel('urlHandler', activeWindowRouter);
|
||||
const urlHandlerRouter = new URLHandlerRouter(activeWindowRouter);
|
||||
const urlHandlerChannel = electronIpcServer.getChannel('urlHandler', urlHandlerRouter);
|
||||
const multiplexURLHandler = new URLHandlerChannelClient(urlHandlerChannel);
|
||||
|
||||
// On Mac, Code can be running without any open windows, so we must create a window to handle urls,
|
||||
@@ -616,9 +616,9 @@ export class CodeApplication extends Disposable {
|
||||
// Open our first window
|
||||
const macOpenFiles: string[] = (<any>global).macOpenFiles;
|
||||
const context = !!process.env['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.DESKTOP;
|
||||
const hasCliArgs = hasArgs(args._);
|
||||
const hasFolderURIs = hasArgs(args['folder-uri']);
|
||||
const hasFileURIs = hasArgs(args['file-uri']);
|
||||
const hasCliArgs = args._.length;
|
||||
const hasFolderURIs = !!args['folder-uri'];
|
||||
const hasFileURIs = !!args['file-uri'];
|
||||
const noRecentEntry = args['skip-add-to-recently-opened'] === true;
|
||||
const waitMarkerFileURI = args.wait && args.waitMarkerFilePath ? URI.file(args.waitMarkerFilePath) : undefined;
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, R
|
||||
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { parseArgs } from 'vs/platform/environment/node/argv';
|
||||
import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
|
||||
import product from 'vs/platform/product/node/product';
|
||||
import { IWindowSettings, MenuBarVisibility, IWindowConfiguration, ReadyState, getTitleBarStyle } from 'vs/platform/windows/common/windows';
|
||||
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
@@ -32,7 +32,7 @@ const RUN_TEXTMATE_IN_WORKER = false;
|
||||
|
||||
export interface IWindowCreationOptions {
|
||||
state: IWindowState;
|
||||
extensionDevelopmentPath?: string | string[];
|
||||
extensionDevelopmentPath?: string[];
|
||||
isExtensionTestHost?: boolean;
|
||||
}
|
||||
|
||||
@@ -574,7 +574,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
windowConfiguration.partsSplashPath = path.join(this.environmentService.userDataPath, 'rapid_render.json');
|
||||
|
||||
// Config (combination of process.argv and window configuration)
|
||||
const environment = parseArgs(process.argv);
|
||||
const environment = parseArgs(process.argv, OPTIONS);
|
||||
const config = objects.assign(environment, windowConfiguration);
|
||||
for (const key in config) {
|
||||
const configValue = (config as any)[key];
|
||||
|
||||
@@ -12,7 +12,6 @@ import { IBackupMainService, IEmptyWindowBackupInfo } from 'vs/platform/backup/c
|
||||
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import { IStateService } from 'vs/platform/state/common/state';
|
||||
import { CodeWindow, defaultWindowState } from 'vs/code/electron-main/window';
|
||||
import { hasArgs, asArray } from 'vs/platform/environment/node/argv';
|
||||
import { ipcMain as ipc, screen, BrowserWindow, dialog, systemPreferences, FileFilter } from 'electron';
|
||||
import { parseLineAndColumnAware } from 'vs/code/node/paths';
|
||||
import { ILifecycleService, UnloadReason, LifecycleService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
|
||||
@@ -450,7 +449,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
// Make sure to pass focus to the most relevant of the windows if we open multiple
|
||||
if (usedWindows.length > 1) {
|
||||
|
||||
const focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && !hasArgs(openConfig.cli._) && !hasArgs(openConfig.cli['file-uri']) && !hasArgs(openConfig.cli['folder-uri']) && !(openConfig.urisToOpen && openConfig.urisToOpen.length);
|
||||
const focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && openConfig.cli._.length && !openConfig.cli['file-uri'] && !openConfig.cli['folder-uri'] && !(openConfig.urisToOpen && openConfig.urisToOpen.length);
|
||||
let focusLastOpened = true;
|
||||
let focusLastWindow = true;
|
||||
|
||||
@@ -811,7 +810,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
|
||||
// Extract paths: from CLI
|
||||
else if (hasArgs(openConfig.cli._) || hasArgs(openConfig.cli['folder-uri']) || hasArgs(openConfig.cli['file-uri'])) {
|
||||
else if (openConfig.cli._.length || openConfig.cli['folder-uri'] || openConfig.cli['file-uri']) {
|
||||
windowsToOpen = this.doExtractPathsFromCLI(openConfig.cli);
|
||||
isCommandLineOrAPICall = true;
|
||||
}
|
||||
@@ -885,31 +884,36 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
const parseOptions: IPathParseOptions = { ignoreFileNotFound: true, gotoLineMode: cli.goto, remoteAuthority: cli.remote || undefined };
|
||||
|
||||
// folder uris
|
||||
const folderUris = asArray(cli['folder-uri']);
|
||||
for (let f of folderUris) {
|
||||
const folderUri = this.argToUri(f);
|
||||
if (folderUri) {
|
||||
const path = this.parseUri({ folderUri }, parseOptions);
|
||||
if (path) {
|
||||
pathsToOpen.push(path);
|
||||
const folderUris = cli['folder-uri'];
|
||||
if (folderUris) {
|
||||
for (let f of folderUris) {
|
||||
const folderUri = this.argToUri(f);
|
||||
if (folderUri) {
|
||||
const path = this.parseUri({ folderUri }, parseOptions);
|
||||
if (path) {
|
||||
pathsToOpen.push(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// file uris
|
||||
const fileUris = asArray(cli['file-uri']);
|
||||
for (let f of fileUris) {
|
||||
const fileUri = this.argToUri(f);
|
||||
if (fileUri) {
|
||||
const path = this.parseUri(hasWorkspaceFileExtension(f) ? { workspaceUri: fileUri } : { fileUri }, parseOptions);
|
||||
if (path) {
|
||||
pathsToOpen.push(path);
|
||||
const fileUris = cli['file-uri'];
|
||||
if (fileUris) {
|
||||
for (let f of fileUris) {
|
||||
const fileUri = this.argToUri(f);
|
||||
if (fileUri) {
|
||||
const path = this.parseUri(hasWorkspaceFileExtension(f) ? { workspaceUri: fileUri } : { fileUri }, parseOptions);
|
||||
if (path) {
|
||||
pathsToOpen.push(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// folder or file paths
|
||||
const cliArgs = asArray(cli._);
|
||||
const cliArgs = cli._;
|
||||
for (let cliArg of cliArgs) {
|
||||
const path = this.parsePath(cliArg, parseOptions);
|
||||
if (path) {
|
||||
@@ -1166,7 +1170,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
return { openFolderInNewWindow: !!openFolderInNewWindow, openFilesInNewWindow };
|
||||
}
|
||||
|
||||
openExtensionDevelopmentHostWindow(extensionDevelopmentPath: string | string[], openConfig: IOpenConfiguration): void {
|
||||
openExtensionDevelopmentHostWindow(extensionDevelopmentPath: string[], openConfig: IOpenConfiguration): void {
|
||||
|
||||
// Reload an existing extension development host window on the same path
|
||||
// We currently do not allow more than one extension development window
|
||||
@@ -1178,8 +1182,8 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
|
||||
return;
|
||||
}
|
||||
let folderUris = asArray(openConfig.cli['folder-uri']);
|
||||
let fileUris = asArray(openConfig.cli['file-uri']);
|
||||
let folderUris = openConfig.cli['folder-uri'] || [];
|
||||
let fileUris = openConfig.cli['file-uri'] || [];
|
||||
let cliArgs = openConfig.cli._;
|
||||
|
||||
// Fill in previously opened workspace unless an explicit path is provided and we are not unit testing
|
||||
@@ -1203,10 +1207,6 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
}
|
||||
|
||||
if (!Array.isArray(extensionDevelopmentPath)) {
|
||||
extensionDevelopmentPath = [extensionDevelopmentPath];
|
||||
}
|
||||
|
||||
let authority = '';
|
||||
for (let p of extensionDevelopmentPath) {
|
||||
if (p.match(/^[a-zA-Z][a-zA-Z0-9\+\-\.]+:/)) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { spawn, ChildProcess, SpawnOptions } from 'child_process';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { buildHelpMessage, buildVersionMessage, addArg, createWaitMarkerFile } from 'vs/platform/environment/node/argv';
|
||||
import { buildHelpMessage, buildVersionMessage, addArg, createWaitMarkerFile, OPTIONS } from 'vs/platform/environment/node/argv';
|
||||
import { parseCLIProcessArgv } from 'vs/platform/environment/node/argvHelper';
|
||||
import { ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import product from 'vs/platform/product/node/product';
|
||||
@@ -47,7 +47,7 @@ export async function main(argv: string[]): Promise<any> {
|
||||
// Help
|
||||
if (args.help) {
|
||||
const executable = `${product.applicationName}${os.platform() === 'win32' ? '.exe' : ''}`;
|
||||
console.log(buildHelpMessage(product.nameLong, executable, pkg.version));
|
||||
console.log(buildHelpMessage(product.nameLong, executable, pkg.version, OPTIONS));
|
||||
}
|
||||
|
||||
// Version Info
|
||||
|
||||
@@ -83,23 +83,14 @@ export class Main {
|
||||
async run(argv: ParsedArgs): Promise<void> {
|
||||
if (argv['install-source']) {
|
||||
await this.setInstallSource(argv['install-source']);
|
||||
|
||||
} else if (argv['list-extensions']) {
|
||||
await this.listExtensions(!!argv['show-versions'], argv['category']);
|
||||
|
||||
} else if (argv['install-extension']) {
|
||||
const arg = argv['install-extension'];
|
||||
const args: string[] = typeof arg === 'string' ? [arg] : arg;
|
||||
await this.installExtensions(args, !!argv['force']);
|
||||
|
||||
await this.installExtensions(argv['install-extension'], !!argv['force']);
|
||||
} else if (argv['uninstall-extension']) {
|
||||
const arg = argv['uninstall-extension'];
|
||||
const ids: string[] = typeof arg === 'string' ? [arg] : arg;
|
||||
await this.uninstallExtension(ids);
|
||||
await this.uninstallExtension(argv['uninstall-extension']);
|
||||
} else if (argv['locate-extension']) {
|
||||
const arg = argv['locate-extension'];
|
||||
const ids: string[] = typeof arg === 'string' ? [arg] : arg;
|
||||
await this.locateExtension(ids);
|
||||
await this.locateExtension(argv['locate-extension']);
|
||||
} else if (argv['telemetry']) {
|
||||
console.log(buildTelemetryMessage(this.environmentService.appRoot, this.environmentService.extensionsPath ? this.environmentService.extensionsPath : undefined));
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export interface ISimpleWindow {
|
||||
openedWorkspace?: IWorkspaceIdentifier;
|
||||
openedFolderUri?: URI;
|
||||
|
||||
extensionDevelopmentPath?: string | string[];
|
||||
extensionDevelopmentPath?: string[];
|
||||
lastFocusTime: number;
|
||||
}
|
||||
|
||||
@@ -95,30 +95,17 @@ export function findWindowOnWorkspace<W extends ISimpleWindow>(windows: W[], wor
|
||||
return null;
|
||||
}
|
||||
|
||||
export function findWindowOnExtensionDevelopmentPath<W extends ISimpleWindow>(windows: W[], extensionDevelopmentPath: string | string[]): W | null {
|
||||
export function findWindowOnExtensionDevelopmentPath<W extends ISimpleWindow>(windows: W[], extensionDevelopmentPaths: string[]): W | null {
|
||||
|
||||
const matches = (uriString: string): boolean => {
|
||||
if (Array.isArray(extensionDevelopmentPath)) {
|
||||
return extensionDevelopmentPath.some(p => extpath.isEqual(p, uriString, !platform.isLinux /* ignorecase */));
|
||||
} else if (extensionDevelopmentPath) {
|
||||
return extpath.isEqual(extensionDevelopmentPath, uriString, !platform.isLinux /* ignorecase */);
|
||||
}
|
||||
return false;
|
||||
return extensionDevelopmentPaths.some(p => extpath.isEqual(p, uriString, !platform.isLinux /* ignorecase */));
|
||||
};
|
||||
|
||||
for (const window of windows) {
|
||||
// match on extension development path. The path can be one or more paths or uri strings, using paths.isEqual is not 100% correct but good enough
|
||||
|
||||
if (window.extensionDevelopmentPath) {
|
||||
if (Array.isArray(window.extensionDevelopmentPath)) {
|
||||
if (window.extensionDevelopmentPath.some(p => matches(p))) {
|
||||
return window;
|
||||
}
|
||||
} else if (window.extensionDevelopmentPath) {
|
||||
if (matches(window.extensionDevelopmentPath)) {
|
||||
return window;
|
||||
}
|
||||
}
|
||||
const currPaths = window.extensionDevelopmentPath;
|
||||
if (currPaths && currPaths.some(p => matches(p))) {
|
||||
return window;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,29 +4,28 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as assert from 'assert';
|
||||
import { formatOptions, Option, addArg } from 'vs/platform/environment/node/argv';
|
||||
import { ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
|
||||
suite('formatOptions', () => {
|
||||
|
||||
function o(id: keyof ParsedArgs, description: string): Option {
|
||||
function o(description: string): Option<any> {
|
||||
return {
|
||||
id, description, type: 'string'
|
||||
description, type: 'string'
|
||||
};
|
||||
}
|
||||
|
||||
test('Text should display small columns correctly', () => {
|
||||
assert.deepEqual(
|
||||
formatOptions([
|
||||
o('add', 'bar')
|
||||
], 80),
|
||||
formatOptions({
|
||||
'add': o('bar')
|
||||
}, 80),
|
||||
[' --add bar']
|
||||
);
|
||||
assert.deepEqual(
|
||||
formatOptions([
|
||||
o('add', 'bar'),
|
||||
o('wait', 'ba'),
|
||||
o('trace', 'b')
|
||||
], 80),
|
||||
formatOptions({
|
||||
'add': o('bar'),
|
||||
'wait': o('ba'),
|
||||
'trace': o('b')
|
||||
}, 80),
|
||||
[
|
||||
' --add bar',
|
||||
' --wait ba',
|
||||
@@ -36,9 +35,9 @@ suite('formatOptions', () => {
|
||||
|
||||
test('Text should wrap', () => {
|
||||
assert.deepEqual(
|
||||
formatOptions([
|
||||
o('add', (<any>'bar ').repeat(9))
|
||||
], 40),
|
||||
formatOptions({
|
||||
'add': o((<any>'bar ').repeat(9))
|
||||
}, 40),
|
||||
[
|
||||
' --add bar bar bar bar bar bar bar bar',
|
||||
' bar'
|
||||
@@ -47,9 +46,9 @@ suite('formatOptions', () => {
|
||||
|
||||
test('Text should revert to the condensed view when the terminal is too narrow', () => {
|
||||
assert.deepEqual(
|
||||
formatOptions([
|
||||
o('add', (<any>'bar ').repeat(9))
|
||||
], 30),
|
||||
formatOptions({
|
||||
'add': o((<any>'bar ').repeat(9))
|
||||
}, 30),
|
||||
[
|
||||
' --add',
|
||||
' bar bar bar bar bar bar bar bar bar '
|
||||
|
||||
@@ -11,7 +11,7 @@ import * as platform from 'vs/base/common/platform';
|
||||
import { CharWidthRequest, CharWidthRequestType, readCharWidths } from 'vs/editor/browser/config/charWidthReader';
|
||||
import { ElementSizeObserver } from 'vs/editor/browser/config/elementSizeObserver';
|
||||
import { CommonEditorConfiguration, IEnvConfiguration } from 'vs/editor/common/config/commonEditorConfig';
|
||||
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { IEditorOptions, EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
import { BareFontInfo, FontInfo } from 'vs/editor/common/config/fontInfo';
|
||||
import { IDimension } from 'vs/editor/common/editorCommon';
|
||||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||
@@ -320,7 +320,7 @@ export class Configuration extends CommonEditorConfiguration {
|
||||
|
||||
this._register(CSSBasedConfiguration.INSTANCE.onDidChange(() => this._onCSSBasedConfigurationChanged()));
|
||||
|
||||
if (this._validatedOptions.automaticLayout) {
|
||||
if (this._validatedOptions.get(EditorOption.automaticLayout)) {
|
||||
this._elementSizeObserver.startObserving();
|
||||
}
|
||||
|
||||
|
||||
@@ -294,7 +294,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorMoveCommands.moveTo(cursors.context, cursors.getPrimaryCursor(), this._inSelectionMode, args.position, args.viewPosition)
|
||||
]
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +322,7 @@ export namespace CoreNavigationCommands {
|
||||
toViewLineNumber: result.toLineNumber,
|
||||
toViewVisualColumn: result.toVisualColumn
|
||||
});
|
||||
cursors.reveal(true, (result.reversed ? RevealTarget.TopMost : RevealTarget.BottomMost), ScrollType.Smooth);
|
||||
cursors.reveal(args.source, true, (result.reversed ? RevealTarget.TopMost : RevealTarget.BottomMost), ScrollType.Smooth);
|
||||
}
|
||||
|
||||
protected abstract _getColumnSelectResult(context: CursorContext, primary: CursorState, prevColumnSelectData: IColumnSelectData, args: any): IColumnSelectResult;
|
||||
@@ -343,12 +343,8 @@ export namespace CoreNavigationCommands {
|
||||
const validatedPosition = context.model.validatePosition(args.position);
|
||||
const validatedViewPosition = context.validateViewPosition(new Position(args.viewPosition.lineNumber, args.viewPosition.column), validatedPosition);
|
||||
|
||||
let fromViewLineNumber = prevColumnSelectData.fromViewLineNumber;
|
||||
let fromViewVisualColumn = prevColumnSelectData.fromViewVisualColumn;
|
||||
if (!prevColumnSelectData.isReal && args.setAnchorIfNotSet) {
|
||||
fromViewLineNumber = validatedViewPosition.lineNumber;
|
||||
fromViewVisualColumn = args.mouseColumn - 1;
|
||||
}
|
||||
let fromViewLineNumber = args.doColumnSelect ? prevColumnSelectData.fromViewLineNumber : validatedViewPosition.lineNumber;
|
||||
let fromViewVisualColumn = args.doColumnSelect ? prevColumnSelectData.fromViewVisualColumn : args.mouseColumn - 1;
|
||||
return ColumnSelection.columnSelect(context.config, context.viewModel, fromViewLineNumber, fromViewVisualColumn, validatedViewPosition.lineNumber, args.mouseColumn - 1);
|
||||
}
|
||||
});
|
||||
@@ -492,7 +488,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorChangeReason.Explicit,
|
||||
CursorMoveCommands.move(cursors.context, cursors.getAll(), args)
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
cursors.reveal(source, true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -831,7 +827,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorChangeReason.Explicit,
|
||||
CursorMoveCommands.moveToBeginningOfLine(cursors.context, cursors.getAll(), this._inSelectionMode)
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -880,7 +876,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorChangeReason.Explicit,
|
||||
this._exec(cursors.context, cursors.getAll())
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
|
||||
private _exec(context: CursorContext, cursors: CursorState[]): PartialCursorState[] {
|
||||
@@ -910,7 +906,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorChangeReason.Explicit,
|
||||
CursorMoveCommands.moveToEndOfLine(cursors.context, cursors.getAll(), this._inSelectionMode)
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -959,7 +955,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorChangeReason.Explicit,
|
||||
this._exec(cursors.context, cursors.getAll())
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
|
||||
private _exec(context: CursorContext, cursors: CursorState[]): PartialCursorState[] {
|
||||
@@ -990,7 +986,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorChangeReason.Explicit,
|
||||
CursorMoveCommands.moveToBeginningOfBuffer(cursors.context, cursors.getAll(), this._inSelectionMode)
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1034,7 +1030,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorChangeReason.Explicit,
|
||||
CursorMoveCommands.moveToEndOfBuffer(cursors.context, cursors.getAll(), this._inSelectionMode)
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1253,7 +1249,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorMoveCommands.word(cursors.context, cursors.getPrimaryCursor(), this._inSelectionMode, args.position)
|
||||
]
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1313,7 +1309,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorMoveCommands.line(cursors.context, cursors.getPrimaryCursor(), this._inSelectionMode, args.position, args.viewPosition)
|
||||
]
|
||||
);
|
||||
cursors.reveal(false, RevealTarget.Primary, ScrollType.Smooth);
|
||||
cursors.reveal(args.source, false, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1385,7 +1381,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorChangeReason.Explicit,
|
||||
CursorMoveCommands.expandLineSelection(cursors.context, cursors.getAll())
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1413,7 +1409,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorMoveCommands.cancelSelection(cursors.context, cursors.getPrimaryCursor())
|
||||
]
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1440,7 +1436,7 @@ export namespace CoreNavigationCommands {
|
||||
cursors.getPrimaryCursor()
|
||||
]
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1488,7 +1484,7 @@ export namespace CoreNavigationCommands {
|
||||
|
||||
const viewRange = cursors.context.convertModelRangeToViewRange(range);
|
||||
|
||||
cursors.revealRange(false, viewRange, revealAt, ScrollType.Smooth);
|
||||
cursors.revealRange(args.source, false, viewRange, revealAt, ScrollType.Smooth);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ import { HorizontalRange } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
|
||||
import { EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
|
||||
|
||||
/**
|
||||
* Merges mouse events when mouse move events are throttled
|
||||
@@ -111,7 +113,7 @@ export class MouseHandler extends ViewEventHandler {
|
||||
const onMouseWheel = (browserEvent: IMouseWheelEvent) => {
|
||||
this.viewController.emitMouseWheel(browserEvent);
|
||||
|
||||
if (!this._context.configuration.editor.viewInfo.mouseWheelZoom) {
|
||||
if (!this._context.configuration.options.get(EditorOption.mouseWheelZoom)) {
|
||||
return;
|
||||
}
|
||||
const e = new StandardWheelEvent(browserEvent);
|
||||
@@ -216,7 +218,7 @@ export class MouseHandler extends ViewEventHandler {
|
||||
const targetIsContent = (t.type === editorBrowser.MouseTargetType.CONTENT_TEXT || t.type === editorBrowser.MouseTargetType.CONTENT_EMPTY);
|
||||
const targetIsGutter = (t.type === editorBrowser.MouseTargetType.GUTTER_GLYPH_MARGIN || t.type === editorBrowser.MouseTargetType.GUTTER_LINE_NUMBERS || t.type === editorBrowser.MouseTargetType.GUTTER_LINE_DECORATIONS);
|
||||
const targetIsLineNumbers = (t.type === editorBrowser.MouseTargetType.GUTTER_LINE_NUMBERS);
|
||||
const selectOnLineNumbers = this._context.configuration.editor.viewInfo.selectOnLineNumbers;
|
||||
const selectOnLineNumbers = this._context.configuration.options.get(EditorOption.selectOnLineNumbers);
|
||||
const targetIsViewZone = (t.type === editorBrowser.MouseTargetType.CONTENT_VIEW_ZONE || t.type === editorBrowser.MouseTargetType.GUTTER_VIEW_ZONE);
|
||||
const targetIsWidget = (t.type === editorBrowser.MouseTargetType.CONTENT_WIDGET);
|
||||
|
||||
@@ -351,8 +353,10 @@ class MouseDownOperation extends Disposable {
|
||||
// Overwrite the detail of the MouseEvent, as it will be sent out in an event and contributions might rely on it.
|
||||
e.detail = this._mouseState.count;
|
||||
|
||||
if (!this._context.configuration.editor.readOnly
|
||||
&& this._context.configuration.editor.dragAndDrop
|
||||
const options = this._context.configuration.options;
|
||||
|
||||
if (!options.get(EditorOption.readOnly)
|
||||
&& options.get(EditorOption.dragAndDrop)
|
||||
&& !this._mouseState.altKey // we don't support multiple mouse
|
||||
&& e.detail < 2 // only single click on a selection can work
|
||||
&& !this._isActive // the mouse is not down yet
|
||||
|
||||
@@ -10,7 +10,7 @@ import { ClientCoordinates, EditorMouseEvent, EditorPagePosition, PageCoordinate
|
||||
import { PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
|
||||
import { ViewLine } from 'vs/editor/browser/viewParts/lines/viewLine';
|
||||
import { IViewCursorRenderData } from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
|
||||
import { EditorLayoutInfo } from 'vs/editor/common/config/editorOptions';
|
||||
import { EditorLayoutInfo, EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range as EditorRange } from 'vs/editor/common/core/range';
|
||||
import { HorizontalRange } from 'vs/editor/common/view/renderingContext';
|
||||
@@ -239,10 +239,11 @@ export class HitTestContext {
|
||||
|
||||
constructor(context: ViewContext, viewHelper: IPointerHandlerHelper, lastViewCursorsRenderData: IViewCursorRenderData[]) {
|
||||
this.model = context.model;
|
||||
this.layoutInfo = context.configuration.editor.layoutInfo;
|
||||
const options = context.configuration.options;
|
||||
this.layoutInfo = options.get(EditorOption.layoutInfo);
|
||||
this.viewDomNode = viewHelper.viewDomNode;
|
||||
this.lineHeight = context.configuration.editor.lineHeight;
|
||||
this.typicalHalfwidthCharacterWidth = context.configuration.editor.fontInfo.typicalHalfwidthCharacterWidth;
|
||||
this.lineHeight = options.get(EditorOption.lineHeight);
|
||||
this.typicalHalfwidthCharacterWidth = options.get(EditorOption.fontInfo).typicalHalfwidthCharacterWidth;
|
||||
this.lastViewCursorsRenderData = lastViewCursorsRenderData;
|
||||
this._context = context;
|
||||
this._viewHelper = viewHelper;
|
||||
@@ -713,9 +714,10 @@ export class MouseTargetFactory {
|
||||
}
|
||||
|
||||
public getMouseColumn(editorPos: EditorPagePosition, pos: PageCoordinates): number {
|
||||
const layoutInfo = this._context.configuration.editor.layoutInfo;
|
||||
const options = this._context.configuration.options;
|
||||
const layoutInfo = options.get(EditorOption.layoutInfo);
|
||||
const mouseContentHorizontalOffset = this._context.viewLayout.getCurrentScrollLeft() + pos.x - editorPos.x - layoutInfo.contentLeft;
|
||||
return MouseTargetFactory._getMouseColumn(mouseContentHorizontalOffset, this._context.configuration.editor.fontInfo.typicalHalfwidthCharacterWidth);
|
||||
return MouseTargetFactory._getMouseColumn(mouseContentHorizontalOffset, options.get(EditorOption.fontInfo).typicalHalfwidthCharacterWidth);
|
||||
}
|
||||
|
||||
public static _getMouseColumn(mouseContentHorizontalOffset: number, typicalHalfwidthCharacterWidth: number): number {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./textAreaHandler';
|
||||
import * as nls from 'vs/nls';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
@@ -16,7 +17,7 @@ import { ViewController } from 'vs/editor/browser/view/viewController';
|
||||
import { PartFingerprint, PartFingerprints, ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { LineNumbersOverlay } from 'vs/editor/browser/viewParts/lineNumbers/lineNumbers';
|
||||
import { Margin } from 'vs/editor/browser/viewParts/margin/margin';
|
||||
import { RenderLineNumbersType } from 'vs/editor/common/config/editorOptions';
|
||||
import { RenderLineNumbersType, EditorOption, IComputedEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
|
||||
import { WordCharacterClass, getMapForWordSeparators } from 'vs/editor/common/controller/wordCharacterClassifier';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
@@ -91,12 +92,13 @@ export class TextAreaHandler extends ViewPart {
|
||||
|
||||
private readonly _viewController: ViewController;
|
||||
private readonly _viewHelper: ITextAreaHandlerHelper;
|
||||
private _scrollLeft: number;
|
||||
private _scrollTop: number;
|
||||
|
||||
private _accessibilitySupport: AccessibilitySupport;
|
||||
private _contentLeft: number;
|
||||
private _contentWidth: number;
|
||||
private _contentHeight: number;
|
||||
private _scrollLeft: number;
|
||||
private _scrollTop: number;
|
||||
private _fontInfo: BareFontInfo;
|
||||
private _lineHeight: number;
|
||||
private _emptySelectionClipboard: boolean;
|
||||
@@ -117,19 +119,20 @@ export class TextAreaHandler extends ViewPart {
|
||||
|
||||
this._viewController = viewController;
|
||||
this._viewHelper = viewHelper;
|
||||
|
||||
const conf = this._context.configuration.editor;
|
||||
|
||||
this._accessibilitySupport = conf.accessibilitySupport;
|
||||
this._contentLeft = conf.layoutInfo.contentLeft;
|
||||
this._contentWidth = conf.layoutInfo.contentWidth;
|
||||
this._contentHeight = conf.layoutInfo.contentHeight;
|
||||
this._scrollLeft = 0;
|
||||
this._scrollTop = 0;
|
||||
this._fontInfo = conf.fontInfo;
|
||||
this._lineHeight = conf.lineHeight;
|
||||
this._emptySelectionClipboard = conf.emptySelectionClipboard;
|
||||
this._copyWithSyntaxHighlighting = conf.copyWithSyntaxHighlighting;
|
||||
|
||||
const options = this._context.configuration.options;
|
||||
const layoutInfo = options.get(EditorOption.layoutInfo);
|
||||
|
||||
this._accessibilitySupport = options.get(EditorOption.accessibilitySupport);
|
||||
this._contentLeft = layoutInfo.contentLeft;
|
||||
this._contentWidth = layoutInfo.contentWidth;
|
||||
this._contentHeight = layoutInfo.contentHeight;
|
||||
this._fontInfo = options.get(EditorOption.fontInfo);
|
||||
this._lineHeight = options.get(EditorOption.lineHeight);
|
||||
this._emptySelectionClipboard = options.get(EditorOption.emptySelectionClipboard);
|
||||
this._copyWithSyntaxHighlighting = options.get(EditorOption.copyWithSyntaxHighlighting);
|
||||
|
||||
this._visibleTextArea = null;
|
||||
this._selections = [new Selection(1, 1, 1, 1)];
|
||||
@@ -143,7 +146,7 @@ export class TextAreaHandler extends ViewPart {
|
||||
this.textArea.setAttribute('autocapitalize', 'off');
|
||||
this.textArea.setAttribute('autocomplete', 'off');
|
||||
this.textArea.setAttribute('spellcheck', 'false');
|
||||
this.textArea.setAttribute('aria-label', conf.viewInfo.ariaLabel);
|
||||
this.textArea.setAttribute('aria-label', this._getAriaLabel(options));
|
||||
this.textArea.setAttribute('role', 'textbox');
|
||||
this.textArea.setAttribute('aria-multiline', 'true');
|
||||
this.textArea.setAttribute('aria-haspopup', 'false');
|
||||
@@ -280,6 +283,7 @@ export class TextAreaHandler extends ViewPart {
|
||||
const column = this._selections[0].startColumn;
|
||||
|
||||
this._context.privateViewEventBus.emit(new viewEvents.ViewRevealRangeRequestEvent(
|
||||
'keyboard',
|
||||
new Range(lineNumber, column, lineNumber, column),
|
||||
viewEvents.VerticalRevealType.Simple,
|
||||
true,
|
||||
@@ -340,7 +344,7 @@ export class TextAreaHandler extends ViewPart {
|
||||
|
||||
private _getWordBeforePosition(position: Position): string {
|
||||
const lineContent = this._context.model.getLineContent(position.lineNumber);
|
||||
const wordSeparators = getMapForWordSeparators(this._context.configuration.editor.wordSeparators);
|
||||
const wordSeparators = getMapForWordSeparators(this._context.configuration.options.get(EditorOption.wordSeparators));
|
||||
|
||||
let column = position.column;
|
||||
let distance = 0;
|
||||
@@ -367,35 +371,33 @@ export class TextAreaHandler extends ViewPart {
|
||||
return '';
|
||||
}
|
||||
|
||||
private _getAriaLabel(options: IComputedEditorOptions): string {
|
||||
const accessibilitySupport = options.get(EditorOption.accessibilitySupport);
|
||||
if (accessibilitySupport === AccessibilitySupport.Disabled) {
|
||||
return nls.localize('accessibilityOffAriaLabel', "The editor is not accessible at this time. Press Alt+F1 for options.");
|
||||
}
|
||||
return options.get(EditorOption.ariaLabel);
|
||||
}
|
||||
|
||||
// --- begin event handlers
|
||||
|
||||
public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean {
|
||||
const conf = this._context.configuration.editor;
|
||||
const options = this._context.configuration.options;
|
||||
const layoutInfo = options.get(EditorOption.layoutInfo);
|
||||
|
||||
if (e.fontInfo) {
|
||||
this._fontInfo = conf.fontInfo;
|
||||
}
|
||||
if (e.viewInfo) {
|
||||
this.textArea.setAttribute('aria-label', conf.viewInfo.ariaLabel);
|
||||
}
|
||||
if (e.layoutInfo) {
|
||||
this._contentLeft = conf.layoutInfo.contentLeft;
|
||||
this._contentWidth = conf.layoutInfo.contentWidth;
|
||||
this._contentHeight = conf.layoutInfo.contentHeight;
|
||||
}
|
||||
if (e.lineHeight) {
|
||||
this._lineHeight = conf.lineHeight;
|
||||
}
|
||||
if (e.accessibilitySupport) {
|
||||
this._accessibilitySupport = conf.accessibilitySupport;
|
||||
this._accessibilitySupport = options.get(EditorOption.accessibilitySupport);
|
||||
this._contentLeft = layoutInfo.contentLeft;
|
||||
this._contentWidth = layoutInfo.contentWidth;
|
||||
this._contentHeight = layoutInfo.contentHeight;
|
||||
this._fontInfo = options.get(EditorOption.fontInfo);
|
||||
this._lineHeight = options.get(EditorOption.lineHeight);
|
||||
this._emptySelectionClipboard = options.get(EditorOption.emptySelectionClipboard);
|
||||
this._copyWithSyntaxHighlighting = options.get(EditorOption.copyWithSyntaxHighlighting);
|
||||
this.textArea.setAttribute('aria-label', this._getAriaLabel(options));
|
||||
|
||||
if (e.hasChanged(EditorOption.accessibilitySupport)) {
|
||||
this._textAreaInput.writeScreenReaderContent('strategy changed');
|
||||
}
|
||||
if (e.emptySelectionClipboard) {
|
||||
this._emptySelectionClipboard = conf.emptySelectionClipboard;
|
||||
}
|
||||
if (e.copyWithSyntaxHighlighting) {
|
||||
this._copyWithSyntaxHighlighting = conf.copyWithSyntaxHighlighting;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -544,10 +546,12 @@ export class TextAreaHandler extends ViewPart {
|
||||
tac.setWidth(1);
|
||||
tac.setHeight(1);
|
||||
|
||||
if (this._context.configuration.editor.viewInfo.glyphMargin) {
|
||||
const options = this._context.configuration.options;
|
||||
|
||||
if (options.get(EditorOption.glyphMargin)) {
|
||||
tac.setClassName('monaco-editor-background textAreaCover ' + Margin.OUTER_CLASS_NAME);
|
||||
} else {
|
||||
if (this._context.configuration.editor.viewInfo.renderLineNumbers !== RenderLineNumbersType.Off) {
|
||||
if (options.get(EditorOption.lineNumbers).renderType !== RenderLineNumbersType.Off) {
|
||||
tac.setClassName('monaco-editor-background textAreaCover ' + LineNumbersOverlay.CLASS_NAME);
|
||||
} else {
|
||||
tac.setClassName('monaco-editor-background textAreaCover');
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { IMouseEvent, IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import * as editorOptions from 'vs/editor/common/config/editorOptions';
|
||||
import { OverviewRulerPosition, ConfigurationChangedEvent, EditorLayoutInfo, IComputedEditorOptions, EditorOption, FindComputedEditorOptionValueById, IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { ICursors } from 'vs/editor/common/controller/cursorCommon';
|
||||
import { ICursorPositionChangedEvent, ICursorSelectionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
|
||||
import { IPosition, Position } from 'vs/editor/common/core/position';
|
||||
@@ -315,7 +315,7 @@ export interface IOverviewRuler {
|
||||
getDomNode(): HTMLElement;
|
||||
dispose(): void;
|
||||
setZones(zones: OverviewRulerZone[]): void;
|
||||
setLayout(position: editorOptions.OverviewRulerPosition): void;
|
||||
setLayout(position: OverviewRulerPosition): void;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -351,7 +351,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
* An event emitted when the configuration of the editor has changed. (e.g. `editor.updateOptions()`)
|
||||
* @event
|
||||
*/
|
||||
onDidChangeConfiguration(listener: (e: editorOptions.IConfigurationChangedEvent) => void): IDisposable;
|
||||
onDidChangeConfiguration(listener: (e: ConfigurationChangedEvent) => void): IDisposable;
|
||||
/**
|
||||
* An event emitted when the cursor position has changed.
|
||||
* @event
|
||||
@@ -481,7 +481,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
* An event emitted when the layout of the editor has changed.
|
||||
* @event
|
||||
*/
|
||||
onDidLayoutChange(listener: (e: editorOptions.EditorLayoutInfo) => void): IDisposable;
|
||||
onDidLayoutChange(listener: (e: EditorLayoutInfo) => void): IDisposable;
|
||||
/**
|
||||
* An event emitted when the scroll in the editor has changed.
|
||||
* @event
|
||||
@@ -532,15 +532,19 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
setModel(model: ITextModel | null): void;
|
||||
|
||||
/**
|
||||
* Returns the current editor's configuration
|
||||
*/
|
||||
getConfiguration(): editorOptions.InternalEditorOptions;
|
||||
|
||||
/**
|
||||
* Returns the 'raw' editor's configuration (without any validation or defaults).
|
||||
* @internal
|
||||
*/
|
||||
getRawConfiguration(): editorOptions.IEditorOptions;
|
||||
getOptions(): IComputedEditorOptions;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getOption<T extends EditorOption>(id: T): FindComputedEditorOptionValueById<T>;
|
||||
|
||||
/**
|
||||
* Returns the editor's configuration (without any validation or defaults).
|
||||
*/
|
||||
getRawOptions(): IEditorOptions;
|
||||
|
||||
/**
|
||||
* Get value of the current model attached to this editor.
|
||||
@@ -655,7 +659,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
/**
|
||||
* Get the layout info for the editor.
|
||||
*/
|
||||
getLayoutInfo(): editorOptions.EditorLayoutInfo;
|
||||
getLayoutInfo(): EditorLayoutInfo;
|
||||
|
||||
/**
|
||||
* Returns the ranges that are currently visible.
|
||||
|
||||
@@ -12,6 +12,7 @@ import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { IConfiguration } from 'vs/editor/common/editorCommon';
|
||||
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
|
||||
export interface IMouseDispatchData {
|
||||
position: Position;
|
||||
@@ -107,7 +108,7 @@ export class ViewController {
|
||||
}
|
||||
|
||||
private _hasMulticursorModifier(data: IMouseDispatchData): boolean {
|
||||
switch (this.configuration.editor.multiCursorModifier) {
|
||||
switch (this.configuration.options.get(EditorOption.multiCursorModifier)) {
|
||||
case 'altKey':
|
||||
return data.altKey;
|
||||
case 'ctrlKey':
|
||||
@@ -119,7 +120,7 @@ export class ViewController {
|
||||
}
|
||||
|
||||
private _hasNonMulticursorModifier(data: IMouseDispatchData): boolean {
|
||||
switch (this.configuration.editor.multiCursorModifier) {
|
||||
switch (this.configuration.options.get(EditorOption.multiCursorModifier)) {
|
||||
case 'altKey':
|
||||
return data.ctrlKey || data.metaKey;
|
||||
case 'ctrlKey':
|
||||
@@ -132,11 +133,7 @@ export class ViewController {
|
||||
|
||||
public dispatchMouse(data: IMouseDispatchData): void {
|
||||
if (data.middleButton) {
|
||||
if (data.inSelectionMode) {
|
||||
this._columnSelect(data.position, data.mouseColumn, true);
|
||||
} else {
|
||||
this.moveTo(data.position);
|
||||
}
|
||||
this._columnSelect(data.position, data.mouseColumn, data.inSelectionMode);
|
||||
} else if (data.startedOnLineNumbers) {
|
||||
// If the dragging started on the gutter, then have operations work on the entire line
|
||||
if (this._hasMulticursorModifier(data)) {
|
||||
@@ -182,7 +179,7 @@ export class ViewController {
|
||||
if (this._hasMulticursorModifier(data)) {
|
||||
if (!this._hasNonMulticursorModifier(data)) {
|
||||
if (data.shiftKey) {
|
||||
this._columnSelect(data.position, data.mouseColumn, false);
|
||||
this._columnSelect(data.position, data.mouseColumn, true);
|
||||
} else {
|
||||
// Do multi-cursor operations only when purely alt is pressed
|
||||
if (data.inSelectionMode) {
|
||||
@@ -222,13 +219,13 @@ export class ViewController {
|
||||
this._execMouseCommand(CoreNavigationCommands.MoveToSelect, this._usualArgs(viewPosition));
|
||||
}
|
||||
|
||||
private _columnSelect(viewPosition: Position, mouseColumn: number, setAnchorIfNotSet: boolean): void {
|
||||
private _columnSelect(viewPosition: Position, mouseColumn: number, doColumnSelect: boolean): void {
|
||||
viewPosition = this._validateViewColumn(viewPosition);
|
||||
this._execMouseCommand(CoreNavigationCommands.ColumnSelect, {
|
||||
position: this._convertViewToModelPosition(viewPosition),
|
||||
viewPosition: viewPosition,
|
||||
mouseColumn: mouseColumn,
|
||||
setAnchorIfNotSet: setAnchorIfNotSet
|
||||
doColumnSelect: doColumnSelect
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user