Merge master

This commit is contained in:
isidor
2016-01-21 18:14:07 +01:00
111 changed files with 1612 additions and 1151 deletions
+29 -13
View File
@@ -20,7 +20,7 @@ var remote = require('gulp-remote-src');
var File = require('vinyl');
var rimraf = require('rimraf');
var _ = require('underscore');
var packagejson = require('../package.json');
var packageJson = require('../package.json');
var util = require('./lib/util');
var buildfile = require('../src/buildfile');
var common = require('./gulpfile.common');
@@ -98,16 +98,22 @@ var product = JSON.parse(fs.readFileSync(path.join(root, 'product.json'), 'utf8'
var darwinCreditsTemplate = product.darwinCredits && _.template(fs.readFileSync(path.join(root, product.darwinCredits), 'utf8'));
var config = {
version: packagejson.electronVersion,
version: packageJson.electronVersion,
productAppName: product.nameLong,
companyName: product.companyName,
copyright: product.copyright,
darwinIcon: product.icons.application.icns,
companyName: 'Microsoft Corporation',
copyright: 'Copyright (C) 2015 Microsoft. All rights reserved',
darwinIcon: 'resources/darwin/code.icns',
darwinBundleIdentifier: product.darwinBundleIdentifier,
darwinApplicationCategoryType: product.darwinApplicationCategoryType, // Finder: View-->Arrange by Application Category
darwinBundleDocumentTypes: product.darwinBundleDocumentTypes,
darwinApplicationCategoryType: 'public.app-category.developer-tools',
darwinBundleDocumentTypes: [{
name: product.nameLong + ' document',
role: 'Editor',
ostypes: ["TEXT", "utxt", "TUTX", "****"],
extensions: ["ascx", "asp", "aspx", "bash", "bash_login", "bash_logout", "bash_profile", "bashrc", "bat", "bowerrc", "c", "cc", "clj", "cljs", "cljx", "clojure", "cmd", "coffee", "config", "cpp", "cs", "cshtml", "csproj", "css", "csx", "ctp", "cxx", "dockerfile", "dot", "dtd", "editorconfig", "edn", "eyaml", "eyml", "fs", "fsi", "fsscript", "fsx", "gemspec", "gitattributes", "gitconfig", "gitignore", "go", "h", "handlebars", "hbs", "hh", "hpp", "htm", "html", "hxx", "ini", "jade", "jav", "java", "js", "jscsrc", "jshintrc", "jshtm", "json", "jsp", "less", "lua", "m", "makefile", "markdown", "md", "mdoc", "mdown", "mdtext", "mdtxt", "mdwn", "mkd", "mkdn", "ml", "mli", "nqp", "p6", "php", "phtml", "pl", "pl6", "pm", "pm6", "pod", "pp", "profile", "properties", "ps1", "psd1", "psgi", "psm1", "py", "r", "rb", "rhistory", "rprofile", "rs", "rt", "scss", "sh", "shtml", "sql", "svg", "svgz", "t", "ts", "txt", "vb", "wxi", "wxl", "wxs", "xaml", "xml", "yaml", "yml", "zsh"],
iconFile: 'resources/darwin/code_file.icns'
}],
darwinCredits: darwinCreditsTemplate ? new Buffer(darwinCreditsTemplate({ commit: commit, date: new Date().toISOString() })) : void 0,
winIcon: product.icons.application.ico,
winIcon: 'resources/win32/code.ico',
token: process.env['GITHUB_TOKEN'] || void 0
};
@@ -175,12 +181,22 @@ function packageTask(platform, arch, opts) {
pluginHostSourceMap
).pipe(util.handleAzureJson({ platform: platform }));
var packageJson = gulp.src(['package.json'], { base: '.' }).pipe(json({ name: product.nameShort }));
var version = packageJson.version;
var quality = product.quality;
if (quality && quality !== 'stable') {
version += '-' + quality;
}
var packageJsonStream = gulp.src(['package.json'], { base: '.' }).pipe(json({
name: product.nameShort,
version: version
}));
var license = gulp.src(['Credits_*', 'LICENSE.txt', 'ThirdPartyNotices.txt'], { base: '.' });
var api = gulp.src('src/vs/vscode.d.ts').pipe(rename('out/vs/vscode.d.ts'));
var depsSrc = _.flatten(Object.keys(packagejson.dependencies).concat(Object.keys(packagejson.optionalDependencies))
var depsSrc = _.flatten(Object.keys(packageJson.dependencies).concat(Object.keys(packageJson.optionalDependencies))
.map(function (d) { return ['node_modules/' + d + '/**', '!node_modules/' + d + '/**/{test,tests}/**']; })
);
@@ -193,9 +209,9 @@ function packageTask(platform, arch, opts) {
var resources = gulp.src('resources/*', { base: '.' });
if (platform === 'win32') {
resources = es.merge(resources, gulp.src(product.icons.file.ico, { base: '.' }));
resources = es.merge(resources, gulp.src('resources/win32/code_file.ico', { base: '.' }));
} else if (platform === 'linux') {
resources = es.merge(resources, gulp.src(product.icons.application.png, { base: '.' }));
resources = es.merge(resources, gulp.src('resources/linux/code.png', { base: '.' }));
}
var extraExtensions = util.downloadExtensions(builtInExtensions)
@@ -205,7 +221,7 @@ function packageTask(platform, arch, opts) {
var all = es.merge(
api,
packageJson,
packageJsonStream,
mixinProduct(),
license,
sources,
@@ -3,7 +3,7 @@
"displayName": "Colorful Default Themes - Please provide feedback in issue 1849",
"description": "The default VS Code Light and Dark themes with a touch of color. We are considering adding these to the default themes in the January release. Please provide feedback in issue 1849.",
"categories": [ "Themes" ],
"version": "0.1.8",
"version": "0.1.10",
"publisher": "aeschli",
"engines": { "vscode": "*" },
"contributes": {
@@ -21,7 +21,12 @@
<key>name</key>
<string>Types declaration and references</string>
<key>scope</key>
<string>meta.parameter.type, name.class, storage.type, meta.return.type, meta.object.type, return-type, meta.cast, new.storage.type.ts, cast.storage.type.ts, heritage.storage.type.ts, annotation.storage.type.ts, var.annotation.type.ts, field.storage.type.ts</string>
<string>meta.parameter.type, name.class, storage.type, meta.return.type, meta.object.type, return-type, meta.cast,
new.storage.type.ts, cast.storage.type.ts, heritage.storage.type.ts, annotation.storage.type.ts, var.annotation.type.ts, field.storage.type.ts,
new.storage.type.js, cast.storage.type.js, heritage.storage.type.js, annotation.storage.type.js, var.annotation.type.js, field.storage.type.js,
new.storage.type.tsx, cast.storage.type.tsx, heritage.storage.type.tsx, annotation.storage.type.tsx, var.annotation.type.tsx, field.storage.type.tsx,
new.storage.type.jsx, cast.storage.type.jsx, heritage.storage.type.jsx, annotation.storage.type.jsx, var.annotation.type.jsx, field.storage.type.jsx
</string>
<key>settings</key>
<dict>
<key>foreground</key>
@@ -32,7 +37,7 @@
<key>name</key>
<string>TS storage type workaround</string>
<key>scope</key>
<string>storage.type.ts</string>
<string>storage.type.ts, storage.type.js, storage.type.tsx, storage.type.jsx</string>
<key>settings</key>
<dict>
<key>foreground</key>
@@ -21,7 +21,12 @@
<key>name</key>
<string>Types declaration and references</string>
<key>scope</key>
<string>meta.parameter.type, name.class, storage.type, meta.return.type, meta.object.type, return-type, meta.cast, new.storage.type.ts, cast.storage.type.ts, heritage.storage.type.ts, annotation.storage.type.ts, var.annotation.type.ts, field.storage.type.ts</string>
<string>meta.parameter.type, name.class, storage.type, meta.return.type, meta.object.type, return-type, meta.cast,
new.storage.type.ts, cast.storage.type.ts, heritage.storage.type.ts, annotation.storage.type.ts, var.annotation.type.ts, field.storage.type.ts,
new.storage.type.js, cast.storage.type.js, heritage.storage.type.js, annotation.storage.type.js, var.annotation.type.js, field.storage.type.js,
new.storage.type.tsx, cast.storage.type.tsx, heritage.storage.type.tsx, annotation.storage.type.tsx, var.annotation.type.tsx, field.storage.type.tsx,
new.storage.type.jsx, cast.storage.type.jsx, heritage.storage.type.jsx, annotation.storage.type.jsx, var.annotation.type.jsx, field.storage.type.jsx
</string>
<key>settings</key>
<dict>
<key>foreground</key>
@@ -32,7 +37,7 @@
<key>name</key>
<string>TS storage type workaround</string>
<key>scope</key>
<string>storage.type.ts</string>
<string>storage.type.ts, storage.type.js, storage.type.tsx, storage.type.jsx</string>
<key>settings</key>
<dict>
<key>foreground</key>
@@ -21,7 +21,7 @@ class MyCompletionItem extends CompletionItem {
constructor(entry: CompletionEntry) {
super(entry.name);
this.sortText = `${entry.name}-${entry.sortText}`; // tsserver sortText is "0" and "1" which is not good when comparing to snippets for instance
this.sortText = entry.sortText;
this.kind = MyCompletionItem.convertKind(entry.kind);
}
@@ -300,7 +300,7 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
let p = this.callbacks[response.request_seq];
if (p) {
if (TypeScriptServiceClient.Trace) {
console.log('TypeScript Service: request ' + response.command + '(' + response.request_seq + ') took ' + (Date.now() - p.start) + 'ms. Success: ' + response.success);
console.log('TypeScript Service: request ' + response.command + '(' + response.request_seq + ') took ' + (Date.now() - p.start) + 'ms. Success: ' + response.success + ((!response.success) ? ('. Message: ' + response.message) : ''));
}
delete this.callbacks[response.request_seq];
this.pendingResponses--;
@@ -49,7 +49,7 @@ suite("commands namespace tests", () => {
let virtualDocumentUri = Uri.parse('speciale://authority/path')
return commands.executeCommand('workbench.html.preview', virtualDocumentUri).then(success => {
return commands.executeCommand('vscode.previewHtml', virtualDocumentUri).then(success => {
assert.ok(success);
registration.dispose();
});
+37 -2
View File
@@ -6,7 +6,7 @@
'use strict';
import * as assert from 'assert';
import {workspace, window} from 'vscode';
import {workspace, window, ViewColumn, TextEditor} from 'vscode';
import {join} from 'path';
import {cleanUp, pathEquals} from './utils';
@@ -14,7 +14,7 @@ suite("window namespace tests", () => {
teardown(cleanUp);
test('active text editor', () => {
test('editor, active text editor', () => {
return workspace.openTextDocument(join(workspace.rootPath, './far.js')).then(doc => {
return window.showTextDocument(doc).then((editor) => {
const active = window.activeTextEditor;
@@ -23,4 +23,39 @@ suite("window namespace tests", () => {
});
});
});
test('editor, assign and check view columns', () => {
return workspace.openTextDocument(join(workspace.rootPath, './far.js')).then(doc => {
let p1 = window.showTextDocument(doc, ViewColumn.One).then(editor => {
assert.equal(editor.viewColumn, ViewColumn.One);
});
let p2 = window.showTextDocument(doc, ViewColumn.Two).then(editor => {
assert.equal(editor.viewColumn, ViewColumn.Two);
});
let p3 = window.showTextDocument(doc, ViewColumn.Three).then(editor => {
assert.equal(editor.viewColumn, ViewColumn.Three);
});
return Promise.all([p1, p2, p3]);
});
});
test('editor, onDidChangeTextEditorViewColumn', () => {
let actualTextEditor: TextEditor;
let actualViewColumn: ViewColumn;
let registration = window.onDidChangeTextEditorViewColumn(event => {
actualTextEditor = event.textEditor;
actualViewColumn = event.viewColumn;
});
return workspace.openTextDocument(join(workspace.rootPath, './far.js')).then(doc => {
return window.showTextDocument(doc, ViewColumn.One).then(editor => {
assert.ok(actualTextEditor === editor);
assert.ok(actualViewColumn === editor.viewColumn);
registration.dispose();
});
});
});
});
+3 -3
View File
@@ -45,7 +45,7 @@
"ghooks": "^1.0.1",
"glob": "^5.0.13",
"gulp": "^3.8.9",
"gulp-atom-electron": "^1.1.0",
"gulp-atom-electron": "^1.2.0",
"gulp-azure-storage": "^0.3.0",
"gulp-bom": "^1.0.0",
"gulp-buffer": "0.0.2",
@@ -80,9 +80,9 @@
"rimraf": "^2.2.8",
"sinon": "^1.17.2",
"source-map": "^0.4.4",
"tslint": "^3.2.2",
"tslint-microsoft-contrib": "^2.0.0",
"tslint": "^3.2.2",
"typescript": "^1.7.3",
"typescript": "^1.7.3",
"uglify-js": "2.4.8",
"underscore": "^1.8.2",
"vinyl": "^0.4.5"
+1 -22
View File
@@ -2,27 +2,6 @@
"nameShort": "Code [OSS Build]",
"nameLong": "Code [OSS Build]",
"win32MutexName": "vscodeoss",
"companyName": "Microsoft Corporation",
"copyright": "Copyright (C) 2015 Microsoft. All rights reserved",
"licenseUrl": "https://github.com/Microsoft/vscode/blob/master/LICENSE.txt",
"darwinBundleIdentifier": "com.visualstudio.code.oss",
"darwinApplicationCategoryType": "public.app-category.developer-tools",
"darwinBundleDocumentTypes": [{
"name": "Code OSS Build document",
"role": "Editor",
"ostypes": ["TEXT", "utxt", "TUTX", "****"],
"extensions": ["ascx", "asp", "aspx", "bash", "bash_login", "bash_logout", "bash_profile", "bashrc", "bat", "bowerrc", "c", "cc", "clj", "cljs", "cljx", "clojure", "cmd", "coffee", "config", "cpp", "cs", "cshtml", "csproj", "css", "csx", "ctp", "cxx", "dockerfile", "dot", "dtd", "editorconfig", "edn", "eyaml", "eyml", "fs", "fsi", "fsscript", "fsx", "gemspec", "gitattributes", "gitconfig", "gitignore", "go", "h", "handlebars", "hbs", "hh", "hpp", "htm", "html", "hxx", "ini", "jade", "jav", "java", "js", "jscsrc", "jshintrc", "jshtm", "json", "jsp", "less", "lua", "m", "makefile", "markdown", "md", "mdoc", "mdown", "mdtext", "mdtxt", "mdwn", "mkd", "mkdn", "ml", "mli", "nqp", "p6", "php", "phtml", "pl", "pl6", "pm", "pm6", "pod", "pp", "profile", "properties", "ps1", "psd1", "psgi", "psm1", "py", "r", "rb", "rhistory", "rprofile", "rs", "rt", "scss", "sh", "shtml", "sql", "svg", "svgz", "t", "ts", "txt", "vb", "wxi", "wxl", "wxs", "xaml", "xml", "yaml", "yml", "zsh"],
"iconFile": "resources/darwin/code_file.icns"
}],
"icons": {
"application": {
"png": "resources/linux/code.png",
"icns": "resources/darwin/code.icns",
"ico": "resources/win32/code.ico"
},
"file": {
"icns": "resources/darwin/code_file.icns",
"ico": "resources/win32/code_file.ico"
}
}
"darwinBundleIdentifier": "com.visualstudio.code.oss"
}
@@ -48,14 +48,6 @@
margin-right: 0.3em;
}
.monaco-action-bar:focus {
outline: 0;
}
.monaco-action-bar .action-label:focus {
outline: 0;
}
.monaco-action-bar .action-item.disabled .action-label,
.monaco-action-bar .action-item.disabled .action-label:hover {
opacity: 0.4;
@@ -183,7 +175,6 @@
.monaco-workbench .action-bar-select {
height: 20px;
margin: 5px 4px;
outline: none;
}
.vs-dark.monaco-workbench .action-bar-select {
+109 -78
View File
@@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import 'vs/css!./actionbar';
@@ -11,7 +10,7 @@ import nls = require('vs/nls');
import lifecycle = require('vs/base/common/lifecycle');
import {Promise} from 'vs/base/common/winjs.base';
import {Builder, $} from 'vs/base/browser/builder';
import actions = require('vs/base/common/actions');
import {IAction, IActionRunner, Action, ActionRunner} from 'vs/base/common/actions';
import DOM = require('vs/base/browser/dom');
import {EventType as CommonEventType} from 'vs/base/common/events';
import types = require('vs/base/common/types');
@@ -21,7 +20,7 @@ import {StandardKeyboardEvent} from 'vs/base/browser/keyboardEvent';
import {CommonKeybindings} from 'vs/base/common/keyCodes';
export interface IActionItem extends IEventEmitter {
actionRunner: actions.IActionRunner;
actionRunner: IActionRunner;
setActionContext(context: any): void;
render(element: HTMLElement): void;
isEnabled(): boolean;
@@ -33,21 +32,22 @@ export interface IActionItem extends IEventEmitter {
export class BaseActionItem extends EventEmitter implements IActionItem {
public builder: Builder;
private gesture: Gesture;
private _actionRunner: actions.IActionRunner;
public _callOnDispose: Function[];
public _context: any;
public _action: actions.IAction;
public _action: IAction;
constructor(context: any, action: actions.IAction) {
private gesture: Gesture;
private _actionRunner: IActionRunner;
constructor(context: any, action: IAction) {
super();
this._callOnDispose = [];
this._context = context || this;
this._action = action;
if (action instanceof actions.Action) {
var l = (<actions.Action>action).addBulkListener((events: IEmitterEvent[]) => {
if (action instanceof Action) {
let l = (<Action>action).addBulkListener((events: IEmitterEvent[]) => {
if (!this.builder) {
// we have not been rendered yet, so there
@@ -58,20 +58,20 @@ export class BaseActionItem extends EventEmitter implements IActionItem {
events.forEach((event: IEmitterEvent) => {
switch (event.getType()) {
case actions.Action.ENABLED:
case Action.ENABLED:
this._updateEnabled();
break;
case actions.Action.LABEL:
case Action.LABEL:
this._updateLabel();
this._updateTooltip();
break;
case actions.Action.TOOLTIP:
case Action.TOOLTIP:
this._updateTooltip();
break;
case actions.Action.CLASS:
case Action.CLASS:
this._updateClass();
break;
case actions.Action.CHECKED:
case Action.CHECKED:
this._updateChecked();
break;
default:
@@ -88,15 +88,15 @@ export class BaseActionItem extends EventEmitter implements IActionItem {
return this._callOnDispose;
}
public set actionRunner(actionRunner: actions.IActionRunner) {
public set actionRunner(actionRunner: IActionRunner) {
this._actionRunner = actionRunner;
}
public get actionRunner(): actions.IActionRunner {
public get actionRunner(): IActionRunner {
return this._actionRunner;
}
public getAction(): actions.IAction {
public getAction(): IAction {
return this._action;
}
@@ -136,13 +136,12 @@ export class BaseActionItem extends EventEmitter implements IActionItem {
public focus(): void {
if (this.builder) {
this.builder.domFocus();
this.builder.addClass('focused');
}
}
public blur(): void {
if (this.builder) {
this.builder.removeClass('focused');
this.builder.domBlur();
}
}
@@ -187,8 +186,7 @@ export class BaseActionItem extends EventEmitter implements IActionItem {
}
}
export class Separator extends actions.Action {
export class Separator extends Action {
public static ID = 'actions.monaco.separator';
@@ -212,7 +210,7 @@ export class ActionItem extends BaseActionItem {
private cssClass: string;
private options: IActionItemOptions;
constructor(context: any, action: actions.IAction, options: IActionItemOptions = {}) {
constructor(context: any, action: IAction, options: IActionItemOptions = {}) {
super(context, action);
this.options = options;
@@ -224,7 +222,7 @@ export class ActionItem extends BaseActionItem {
public render(container: HTMLElement): void {
super.render(container);
this.$e = $('a.action-label').attr('tabIndex', '-1').appendTo(this.builder);
this.$e = $('a.action-label').appendTo(this.builder);
this.$e.attr({ role: 'menuitem' });
if (this.options.label && this.options.keybinding) {
@@ -250,7 +248,7 @@ export class ActionItem extends BaseActionItem {
}
public _updateTooltip(): void {
var title: string = null;
let title: string = null;
if (this.getAction().tooltip) {
title = this.getAction().tooltip;
@@ -288,9 +286,11 @@ export class ActionItem extends BaseActionItem {
if (this.getAction().enabled) {
this.builder.removeClass('disabled');
this.$e.removeClass('disabled');
this.$e.attr({ tabindex: 0 });
} else {
this.builder.addClass('disabled');
this.$e.addClass('disabled');
this.$e.removeAttribute('tabindex');
}
}
@@ -307,24 +307,24 @@ export class ProgressItem extends BaseActionItem {
public render(parent: HTMLElement): void {
var container = document.createElement('div');
let container = document.createElement('div');
$(container).addClass('progress-item');
var label = document.createElement('div');
let label = document.createElement('div');
$(label).addClass('label');
label.textContent = this.getAction().label;
label.title = this.getAction().label;
super.render(label);
var progress = document.createElement('div');
let progress = document.createElement('div');
progress.textContent = '\u2026';
$(progress).addClass('tag', 'progress');
var done = document.createElement('div');
let done = document.createElement('div');
done.textContent = '\u2713';
$(done).addClass('tag', 'done');
var error = document.createElement('div');
let error = document.createElement('div');
error.textContent = '!';
$(error).addClass('tag', 'error');
@@ -364,18 +364,17 @@ export enum ActionsOrientation {
}
export interface IActionItemProvider {
(action: actions.IAction): IActionItem;
(action: IAction): IActionItem;
}
export interface IActionBarOptions {
orientation?: ActionsOrientation;
context?: any;
disableTabIndex?: boolean;
actionItemProvider?: IActionItemProvider;
actionRunner?: actions.IActionRunner;
actionRunner?: IActionRunner;
}
var defaultOptions: IActionBarOptions = {
let defaultOptions: IActionBarOptions = {
orientation: ActionsOrientation.HORIZONTAL,
context: null
};
@@ -384,7 +383,7 @@ export interface IActionOptions extends IActionItemOptions {
index?: number;
}
export class ActionBar extends EventEmitter implements actions.IActionRunner {
export class ActionBar extends EventEmitter implements IActionRunner {
private static nlsActionBarAccessibleLabel = nls.localize('actionBarAccessibleLabel', "Action Bar");
@@ -393,12 +392,14 @@ export class ActionBar extends EventEmitter implements actions.IActionRunner {
};
public options: IActionBarOptions;
private _actionRunner: actions.IActionRunner;
private _actionRunner: IActionRunner;
private _context: any;
// Items
public items: IActionItem[];
private focusedItem: number;
private focusTracker: DOM.IFocusTracker;
// Elements
public domNode: HTMLElement;
@@ -416,7 +417,7 @@ export class ActionBar extends EventEmitter implements actions.IActionRunner {
this._actionRunner = this.options.actionRunner;
if (!this._actionRunner) {
this._actionRunner = new actions.ActionRunner();
this._actionRunner = new ActionRunner();
this.toDispose.push(this._actionRunner);
}
@@ -428,15 +429,14 @@ export class ActionBar extends EventEmitter implements actions.IActionRunner {
this.domNode = document.createElement('div');
this.domNode.className = 'monaco-action-bar';
var isVertical = this.options.orientation === ActionsOrientation.VERTICAL;
let isVertical = this.options.orientation === ActionsOrientation.VERTICAL;
if (isVertical) {
this.domNode.className += ' vertical';
}
$(this.domNode).on(DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
var event = new StandardKeyboardEvent(e);
var eventHandled = true;
let event = new StandardKeyboardEvent(e);
let eventHandled = true;
if (event.equals(isVertical ? CommonKeybindings.UP_ARROW : CommonKeybindings.LEFT_ARROW)) {
this.focusPrevious();
@@ -444,7 +444,7 @@ export class ActionBar extends EventEmitter implements actions.IActionRunner {
this.focusNext();
} else if (event.equals(CommonKeybindings.ESCAPE)) {
this.cancel();
} else if (event.equals(CommonKeybindings.ENTER)) {
} else if (event.equals(CommonKeybindings.ENTER) || event.equals(CommonKeybindings.SPACE)) {
// Nothing, just staying out of the else branch
} else {
eventHandled = false;
@@ -463,22 +463,31 @@ export class ActionBar extends EventEmitter implements actions.IActionRunner {
});
$(this.domNode).on(DOM.EventType.KEY_UP, (e: KeyboardEvent) => {
var event = new StandardKeyboardEvent(e);
let event = new StandardKeyboardEvent(e);
if (event.equals(CommonKeybindings.ENTER)) {
// Run action on Enter/Space
if (event.equals(CommonKeybindings.ENTER) || event.equals(CommonKeybindings.SPACE)) {
this.doTrigger(event);
event.preventDefault();
event.stopPropagation();
}
});
var focusTracker = DOM.trackFocus(this.domNode);
focusTracker.addBlurListener((e: Event) => {
if (document.activeElement === this.domNode || !DOM.isAncestor(document.activeElement, this.domNode)) {
this.emit('blur', e);
// Recompute focused item
else if (event.equals(CommonKeybindings.TAB) || event.equals(CommonKeybindings.SHIFT_TAB)) {
this.updateFocusedItem();
}
});
this.focusTracker = DOM.trackFocus(this.domNode);
this.focusTracker.addBlurListener((e: Event) => {
if (document.activeElement === this.domNode || !DOM.isAncestor(document.activeElement, this.domNode)) {
this.emit('blur', e);
this.focusedItem = undefined;
}
});
this.focusTracker.addFocusListener(() => this.updateFocusedItem());
this.actionsList = document.createElement('ul');
this.actionsList.className = 'actions-container';
this.actionsList.setAttribute('role', 'menu');
@@ -489,6 +498,16 @@ export class ActionBar extends EventEmitter implements actions.IActionRunner {
container.appendChild(this.domNode);
}
private updateFocusedItem(): void {
for (let i = 0; i < this.actionsList.children.length; i++) {
let elem = this.actionsList.children[i];
if (DOM.isAncestor(document.activeElement, elem)) {
this.focusedItem = i;
break;
}
}
}
public get context(): any {
return this._context;
}
@@ -498,11 +517,11 @@ export class ActionBar extends EventEmitter implements actions.IActionRunner {
this.items.forEach(i => i.setActionContext(context));
}
public get actionRunner(): actions.IActionRunner {
public get actionRunner(): IActionRunner {
return this._actionRunner;
}
public set actionRunner(actionRunner: actions.IActionRunner) {
public set actionRunner(actionRunner: IActionRunner) {
if (actionRunner) {
this._actionRunner = actionRunner;
this.items.forEach(item => item.actionRunner = actionRunner);
@@ -513,21 +532,21 @@ export class ActionBar extends EventEmitter implements actions.IActionRunner {
return $(this.domNode);
}
public push(actions: actions.IAction, options?: IActionOptions): void;
public push(actions: actions.IAction[], options?: IActionOptions): void;
public push(actions: IAction, options?: IActionOptions): void;
public push(actions: IAction[], options?: IActionOptions): void;
public push(actions: any, options: IActionOptions = {}): void {
if (!Array.isArray(actions)) {
actions = [actions];
}
var index = types.isNumber(options.index) ? options.index : null;
let index = types.isNumber(options.index) ? options.index : null;
actions.forEach((action: actions.IAction) => {
var actionItemElement = document.createElement('li');
actions.forEach((action: IAction) => {
let actionItemElement = document.createElement('li');
actionItemElement.className = 'action-item';
actionItemElement.setAttribute('role', 'presentation');
var item: IActionItem = null;
let item: IActionItem = null;
if (this.options.actionItemProvider) {
item = this.options.actionItemProvider(action);
@@ -548,24 +567,16 @@ export class ActionBar extends EventEmitter implements actions.IActionRunner {
this.actionsList.insertBefore(actionItemElement, this.actionsList.children[index++]);
}
if (!this.options.disableTabIndex && !this.domNode.hasAttribute('tabIndex')) {
this.domNode.tabIndex = 0; // make sure an action bar with actions participates in tab navigation
}
this.items.push(item);
});
}
public clear(): void {
var item: IActionItem;
let item: IActionItem;
while (item = this.items.pop()) {
item.dispose();
}
$(this.actionsList).empty();
if (!this.options.disableTabIndex) {
this.domNode.removeAttribute('tabIndex'); // empty action bar does not participate in tab navigation
}
}
public length(): number {
@@ -593,8 +604,8 @@ export class ActionBar extends EventEmitter implements actions.IActionRunner {
this.focusedItem = this.items.length - 1;
}
var startIndex = this.focusedItem;
var item: IActionItem;
let startIndex = this.focusedItem;
let item: IActionItem;
do {
this.focusedItem = (this.focusedItem + 1) % this.items.length;
@@ -613,8 +624,8 @@ export class ActionBar extends EventEmitter implements actions.IActionRunner {
this.focusedItem = 0;
}
var startIndex = this.focusedItem;
var item: IActionItem;
let startIndex = this.focusedItem;
let item: IActionItem;
do {
this.focusedItem = this.focusedItem - 1;
@@ -639,10 +650,10 @@ export class ActionBar extends EventEmitter implements actions.IActionRunner {
return;
}
for (var i = 0; i < this.items.length; i++) {
var item = this.items[i];
for (let i = 0; i < this.items.length; i++) {
let item = this.items[i];
var actionItem = <any>item;
let actionItem = <any>item;
if (i === this.focusedItem) {
if (types.isFunction(actionItem.focus)) {
@@ -657,21 +668,24 @@ export class ActionBar extends EventEmitter implements actions.IActionRunner {
}
private doTrigger(event): void {
//nothing to focus
if (typeof this.focusedItem === 'undefined') {
return;
return; //nothing to focus
}
// trigger action
var actionItem = (<BaseActionItem>this.items[this.focusedItem]);
let actionItem = (<BaseActionItem>this.items[this.focusedItem]);
this.run(actionItem._action, actionItem._context || event).done();
}
private cancel(): void {
if (document.activeElement instanceof HTMLElement) {
(<HTMLElement>document.activeElement).blur(); // remove focus from focussed action
}
this.emit(CommonEventType.CANCEL);
}
public run(action: actions.IAction, context?: any): Promise {
public run(action: IAction, context?: any): Promise {
return this._actionRunner.run(action, context);
}
@@ -681,6 +695,11 @@ export class ActionBar extends EventEmitter implements actions.IActionRunner {
}
this.items = null;
if (this.focusTracker) {
this.focusTracker.dispose();
this.focusTracker = null;
}
this.toDispose = lifecycle.disposeAll(this.toDispose);
this.getContainer().destroy();
@@ -695,7 +714,7 @@ export class SelectActionItem extends BaseActionItem {
private selected: number;
private toDispose: lifecycle.IDisposable[];
constructor(ctx: any, action: actions.IAction, options: string[], selected: number) {
constructor(ctx: any, action: IAction, options: string[], selected: number) {
super(ctx, action);
this.select = document.createElement('select');
@@ -722,6 +741,18 @@ export class SelectActionItem extends BaseActionItem {
}));
}
public focus(): void {
if (this.select) {
this.select.focus();
}
}
public blur(): void {
if (this.select) {
this.select.blur();
}
}
public render(container: HTMLElement): void {
DOM.addClass(container, 'select-container');
container.appendChild(this.select);
@@ -741,7 +772,7 @@ export class SelectActionItem extends BaseActionItem {
}
private createOption(value: string): HTMLOptionElement {
var option = document.createElement('option');
let option = document.createElement('option');
option.value = value;
option.text = value;
+1
View File
@@ -12,6 +12,7 @@
text-align: center;
color: white;
background: #007ACC;
cursor: pointer;
}
.monaco-button.disabled {
+21 -3
View File
@@ -9,6 +9,8 @@ import 'vs/css!./button';
import {EventEmitter} from 'vs/base/common/eventEmitter';
import DOM = require('vs/base/browser/dom');
import {Builder, $} from 'vs/base/browser/builder';
import {StandardKeyboardEvent} from 'vs/base/browser/keyboardEvent';
import {CommonKeybindings} from 'vs/base/common/keyCodes';
export class Button extends EventEmitter {
@@ -19,15 +21,31 @@ export class Button extends EventEmitter {
constructor(container: any) {
super();
this.$el = $('a.monaco-button').href('#').appendTo(container);
this.$el = $('a.monaco-button').attr('tabindex', '0').appendTo(container);
this.$el.on('click', (e) => {
this.$el.on(DOM.EventType.CLICK, (e) => {
if (!this.enabled) {
DOM.EventHelper.stop(e);
return;
}
this.emit('click', e);
this.emit(DOM.EventType.CLICK, e);
});
this.$el.on(DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
let event = new StandardKeyboardEvent(e);
let eventHandled = false;
if (this.enabled && event.equals(CommonKeybindings.ENTER) || event.equals(CommonKeybindings.SPACE)) {
this.emit(DOM.EventType.CLICK, e);
eventHandled = true;
} else if (event.equals(CommonKeybindings.ESCAPE)) {
this.$el.domBlur();
eventHandled = true;
}
if (eventHandled) {
DOM.EventHelper.stop(event, true);
}
});
}
+1 -1
View File
@@ -90,7 +90,7 @@ export class Checkbox extends Widget {
}
public disable(): void {
this.domNode.tabIndex = -1;
this.domNode.removeAttribute('tabIndex');
this.domNode.setAttribute('aria-disabled', String(true));
}
}
@@ -7,12 +7,10 @@
'use strict';
import 'vs/css!./contextview';
import Builder = require('vs/base/browser/builder');
import {Builder, $} from 'vs/base/browser/builder';
import DOM = require('vs/base/browser/dom');
import Lifecycle = require('vs/base/common/lifecycle');
import EventEmitter = require('vs/base/common/eventEmitter');
var $ = Builder.$;
import {IDisposable, disposeAll} from 'vs/base/common/lifecycle';
import {EventEmitter} from 'vs/base/common/eventEmitter';
export interface IAnchor {
x: number;
@@ -30,20 +28,20 @@ export enum AnchorPosition {
}
export interface IDelegate {
getAnchor(): HTMLElement|IAnchor;
render(container: HTMLElement): Lifecycle.IDisposable;
getAnchor(): HTMLElement | IAnchor;
render(container: HTMLElement): IDisposable;
layout?(): void;
anchorAlignment?:AnchorAlignment; // default: left
anchorPosition?:AnchorPosition; // default: below
canRelayout?:boolean; // default: true
onDOMEvent?(e:Event, activeElement: HTMLElement):void;
onHide?(data?: any):void;
anchorAlignment?: AnchorAlignment; // default: left
anchorPosition?: AnchorPosition; // default: below
canRelayout?: boolean; // default: true
onDOMEvent?(e: Event, activeElement: HTMLElement): void;
onHide?(data?: any): void;
}
export interface IContextViewProvider {
showContextView(delegate: IDelegate): void;
hideContextView(): void;
layout():void;
layout(): void;
}
export interface IPosition {
@@ -58,8 +56,8 @@ export interface ISize {
export interface IView extends IPosition, ISize { }
export function layout(view: ISize, around: IView, inside: IView, anchorPosition: AnchorPosition, anchorAlignment: AnchorAlignment) : IPosition {
var top: number, left: number;
export function layout(view: ISize, around: IView, inside: IView, anchorPosition: AnchorPosition, anchorAlignment: AnchorAlignment): IPosition {
let top: number, left: number;
if (anchorPosition === AnchorPosition.BELOW) {
top = around.top + around.height - inside.top;
@@ -88,16 +86,16 @@ export function layout(view: ISize, around: IView, inside: IView, anchorPosition
return { top: top, left: left };
}
export class ContextView extends EventEmitter.EventEmitter {
export class ContextView extends EventEmitter {
private static BUBBLE_UP_EVENTS = ['click', 'keydown', 'focus', 'blur'];
private static BUBBLE_DOWN_EVENTS = ['click'];
private $container: Builder.Builder;
private $view: Builder.Builder;
private $container: Builder;
private $view: Builder;
private delegate: IDelegate;
private toDispose: Lifecycle.IDisposable[];
private toDisposeOnClean: Lifecycle.IDisposable;
private toDispose: IDisposable[];
private toDisposeOnClean: IDisposable;
constructor(container: HTMLElement) {
super();
@@ -122,11 +120,11 @@ export class ContextView extends EventEmitter.EventEmitter {
if (container) {
this.$container = $(container);
this.$view.appendTo(this.$container);
this.$container.on(ContextView.BUBBLE_UP_EVENTS, (e:Event) => {
this.onDOMEvent(e, <HTMLElement> document.activeElement, false);
this.$container.on(ContextView.BUBBLE_UP_EVENTS, (e: Event) => {
this.onDOMEvent(e, <HTMLElement>document.activeElement, false);
});
this.$container.on(ContextView.BUBBLE_DOWN_EVENTS, (e:Event) => {
this.onDOMEvent(e, <HTMLElement> document.activeElement, true);
this.$container.on(ContextView.BUBBLE_DOWN_EVENTS, (e: Event) => {
this.onDOMEvent(e, <HTMLElement>document.activeElement, true);
}, null, true);
}
}
@@ -168,16 +166,16 @@ export class ContextView extends EventEmitter.EventEmitter {
private doLayout(): void {
// Get anchor
var anchor = this.delegate.getAnchor();
let anchor = this.delegate.getAnchor();
// Compute around
var around: IView;
let around: IView;
// Get the element's position and size (to anchor the view)
if (DOM.isHTMLElement(anchor)) {
var $anchor = $(<HTMLElement> anchor);
var elementPosition = $anchor.getPosition();
var elementSize = $anchor.getTotalSize();
let $anchor = $(<HTMLElement>anchor);
let elementPosition = $anchor.getPosition();
let elementSize = $anchor.getTotalSize();
around = {
top: elementPosition.top,
@@ -186,7 +184,7 @@ export class ContextView extends EventEmitter.EventEmitter {
height: elementSize.height
};
} else {
var realAnchor = <IAnchor> anchor;
let realAnchor = <IAnchor>anchor;
around = {
top: realAnchor.y,
@@ -197,8 +195,8 @@ export class ContextView extends EventEmitter.EventEmitter {
}
// Get the container's position
var insidePosition = this.$container.getPosition();
var inside = {
let insidePosition = this.$container.getPosition();
let inside = {
top: insidePosition.top,
left: insidePosition.left,
height: window.innerHeight,
@@ -206,13 +204,13 @@ export class ContextView extends EventEmitter.EventEmitter {
};
// Get the view's size
var viewSize = this.$view.getTotalSize();
var view = { width: viewSize.width, height: viewSize.height };
let viewSize = this.$view.getTotalSize();
let view = { width: viewSize.width, height: viewSize.height };
var anchorPosition = this.delegate.anchorPosition || AnchorPosition.BELOW;
var anchorAlignment = this.delegate.anchorAlignment || AnchorAlignment.LEFT;
let anchorPosition = this.delegate.anchorPosition || AnchorPosition.BELOW;
let anchorAlignment = this.delegate.anchorAlignment || AnchorAlignment.LEFT;
var result = layout(view, around, inside, anchorPosition, anchorAlignment);
let result = layout(view, around, inside, anchorPosition, anchorAlignment);
this.$view.removeClass('top', 'bottom', 'left', 'right');
this.$view.addClass(anchorPosition === AnchorPosition.BELOW ? 'bottom' : 'top');
@@ -242,8 +240,8 @@ export class ContextView extends EventEmitter.EventEmitter {
private onDOMEvent(e: Event, element: HTMLElement, onCapture: boolean): void {
if (this.delegate) {
if (this.delegate.onDOMEvent) {
this.delegate.onDOMEvent(e, <HTMLElement> document.activeElement);
} else if (onCapture && !DOM.isAncestor(<HTMLElement> e.target, this.$container.getHTMLElement())) {
this.delegate.onDOMEvent(e, <HTMLElement>document.activeElement);
} else if (onCapture && !DOM.isAncestor(<HTMLElement>e.target, this.$container.getHTMLElement())) {
this.hide();
}
}
@@ -253,6 +251,6 @@ export class ContextView extends EventEmitter.EventEmitter {
super.dispose();
this.hide();
this.toDispose = Lifecycle.disposeAll(this.toDispose);
this.toDispose = disposeAll(this.toDispose);
}
}
@@ -22,10 +22,6 @@
vertical-align: top;
}
.dropdown > .dropdown-action > .action-label {
outline: none;
}
.dropdown > .dropdown-action > .action-label:hover {
color: inherit;
text-decoration: none;
+49 -51
View File
@@ -6,40 +6,38 @@
'use strict';
import 'vs/css!./dropdown';
import Builder = require('vs/base/browser/builder');
import WinJS = require('vs/base/common/winjs.base');
import Touch = require('vs/base/browser/touch');
import Actions = require('vs/base/common/actions');
import ActionBar = require('vs/base/browser/ui/actionbar/actionbar');
import EventEmitter = require('vs/base/common/eventEmitter');
import Lifecycle = require('vs/base/common/lifecycle');
import ContextView = require('vs/base/browser/ui/contextview/contextview');
import Menu = require('vs/base/browser/ui/menu/menu');
var $ = Builder.$;
import {Builder, $} from 'vs/base/browser/builder';
import {Promise} from 'vs/base/common/winjs.base';
import {Gesture, EventType} from 'vs/base/browser/touch';
import {ActionRunner, IAction} from 'vs/base/common/actions';
import {ActionBar, ActionItem, IActionItem} from 'vs/base/browser/ui/actionbar/actionbar';
import {EventEmitter} from 'vs/base/common/eventEmitter';
import {IDisposable, disposeAll} from 'vs/base/common/lifecycle';
import {ContextView, IContextViewProvider} from 'vs/base/browser/ui/contextview/contextview';
import {Menu, IMenuOptions} from 'vs/base/browser/ui/menu/menu';
export interface ILabelRenderer {
(container: HTMLElement): Lifecycle.IDisposable;
(container: HTMLElement): IDisposable;
}
export interface IBaseDropdownOptions {
tick?: boolean;
label?: string;
labelRenderer?: ILabelRenderer;
action?: Actions.IAction;
action?: IAction;
}
export class BaseDropdown extends Actions.ActionRunner {
export class BaseDropdown extends ActionRunner {
/*protected*/ toDispose: Lifecycle.IDisposable[];
/*protected*/ toDispose: IDisposable[];
/*protected*/ $el: Builder.Builder;
private $boxContainer: Builder.Builder;
private $action: Builder.Builder;
private $label: Builder.Builder;
private $contents: Builder.Builder;
/*protected*/ $el: Builder;
private $boxContainer: Builder;
private $action: Builder;
private $label: Builder;
private $contents: Builder;
constructor (container: HTMLElement, options: IBaseDropdownOptions) {
constructor(container: HTMLElement, options: IBaseDropdownOptions) {
super();
this.toDispose = [];
@@ -52,12 +50,12 @@ export class BaseDropdown extends Actions.ActionRunner {
this.$label.addClass('tick');
}
var labelRenderer = options.labelRenderer;
let labelRenderer = options.labelRenderer;
if (!labelRenderer && options.action) {
this.$action = $('.dropdown-action').appendTo(this.$el);
var item = new ActionBar.ActionItem(null, options.action, {
let item = new ActionItem(null, options.action, {
icon: true,
label: true
});
@@ -65,33 +63,33 @@ export class BaseDropdown extends Actions.ActionRunner {
item.actionRunner = this;
item.render(this.$action.getHTMLElement());
labelRenderer = (container: HTMLElement): Lifecycle.IDisposable => {
labelRenderer = (container: HTMLElement): IDisposable => {
container.innerText = '';
return item;
};
}
if (!labelRenderer) {
labelRenderer = (container: HTMLElement): Lifecycle.IDisposable => {
labelRenderer = (container: HTMLElement): IDisposable => {
$(container).text(options.label || '');
return null;
};
}
this.$label.on(['click', Touch.EventType.Tap], (e:Event) => {
this.$label.on(['click', EventType.Tap], (e: Event) => {
e.preventDefault();
e.stopPropagation();
this.toggleDropdown();
}).appendTo(this.$el);
var cleanupFn = labelRenderer(this.$label.getHTMLElement());
let cleanupFn = labelRenderer(this.$label.getHTMLElement());
if (cleanupFn) {
this.toDispose.push(cleanupFn);
}
this.toDispose.push(new Touch.Gesture(this.$label.getHTMLElement()));
this.toDispose.push(new Gesture(this.$label.getHTMLElement()));
}
public set tooltip(tooltip: string) {
@@ -114,7 +112,7 @@ export class BaseDropdown extends Actions.ActionRunner {
// noop
}
/*protected*/ public onEvent(e:Event, activeElement: HTMLElement): void {
/*protected*/ public onEvent(e: Event, activeElement: HTMLElement): void {
this.hide();
}
@@ -122,7 +120,7 @@ export class BaseDropdown extends Actions.ActionRunner {
super.dispose();
this.hide();
this.toDispose = Lifecycle.disposeAll(this.toDispose);
this.toDispose = disposeAll(this.toDispose);
if (this.$boxContainer) {
this.$boxContainer.destroy();
@@ -142,23 +140,23 @@ export class BaseDropdown extends Actions.ActionRunner {
}
export interface IDropdownOptions extends IBaseDropdownOptions {
contextViewProvider: ContextView.IContextViewProvider;
contextViewProvider: IContextViewProvider;
}
export class Dropdown extends BaseDropdown {
/*protected*/ _contextViewProvider: ContextView.IContextViewProvider;
/*protected*/ _contextViewProvider: IContextViewProvider;
constructor (container: HTMLElement, options: IDropdownOptions) {
constructor(container: HTMLElement, options: IDropdownOptions) {
super(container, options);
this.contextViewProvider = options.contextViewProvider;
}
/*protected*/ public set contextViewProvider(contextViewProvider: ContextView.IContextViewProvider) {
/*protected*/ public set contextViewProvider(contextViewProvider: IContextViewProvider) {
this._contextViewProvider = contextViewProvider;
}
/*protected*/ public get contextViewProvider(): ContextView.IContextViewProvider {
/*protected*/ public get contextViewProvider(): IContextViewProvider {
return this._contextViewProvider;
}
@@ -188,17 +186,17 @@ export class Dropdown extends BaseDropdown {
}
}
/*protected*/ public renderContents(container: HTMLElement): Lifecycle.IDisposable {
/*protected*/ public renderContents(container: HTMLElement): IDisposable {
return null;
}
}
export interface IContextMenuDelegate {
getAnchor(): any;
getActions(): WinJS.Promise;
getActionItem?(action: Actions.IAction): ActionBar.IActionItem;
getActionsContext?():any;
getMenuClassName?():string;
getActions(): Promise;
getActionItem?(action: IAction): IActionItem;
getActionsContext?(): any;
getMenuClassName?(): string;
onHide?(didCancel: boolean): void;
}
@@ -207,12 +205,12 @@ export interface IContextMenuProvider {
}
export interface IActionProvider {
getActions(): Actions.IAction[];
getActions(): IAction[];
}
export interface IDropdownMenuOptions extends IBaseDropdownOptions {
contextMenuProvider: IContextMenuProvider;
actions?: Actions.IAction[];
actions?: IAction[];
actionProvider?: IActionProvider;
menuClassName?: string;
}
@@ -220,13 +218,13 @@ export interface IDropdownMenuOptions extends IBaseDropdownOptions {
export class DropdownMenu extends BaseDropdown {
/*protected*/ _contextMenuProvider: IContextMenuProvider;
private _menuOptions: Menu.IMenuOptions;
private _menuOptions: IMenuOptions;
/*protected*/ currentContainer: HTMLElement;
/*protected*/ _actions: Actions.IAction[];
/*protected*/ _actions: IAction[];
/*protected*/ actionProvider: IActionProvider;
private menuClassName: string;
constructor (container:HTMLElement, options: IDropdownMenuOptions) {
constructor(container: HTMLElement, options: IDropdownMenuOptions) {
super(container, options);
this._contextMenuProvider = options.contextMenuProvider;
@@ -244,15 +242,15 @@ export class DropdownMenu extends BaseDropdown {
return this._contextMenuProvider;
}
public set menuOptions(options: Menu.IMenuOptions) {
public set menuOptions(options: IMenuOptions) {
this._menuOptions = options;
}
public get menuOptions(): Menu.IMenuOptions {
public get menuOptions(): IMenuOptions {
return this._menuOptions;
}
/*protected*/ public get actions(): Actions.IAction[] {
/*protected*/ public get actions(): IAction[] {
if (this.actionProvider) {
return this.actionProvider.getActions();
}
@@ -260,7 +258,7 @@ export class DropdownMenu extends BaseDropdown {
return this._actions;
}
/*protected*/ public set actions(actions:Actions.IAction[]) {
/*protected*/ public set actions(actions: IAction[]) {
this._actions = actions;
}
@@ -269,7 +267,7 @@ export class DropdownMenu extends BaseDropdown {
this._contextMenuProvider.showContextMenu({
getAnchor: () => this.$el.getHTMLElement(),
getActions: () => WinJS.Promise.as(this.actions),
getActions: () => Promise.as(this.actions),
getActionsContext: () => this.menuOptions ? this.menuOptions.context : null,
getActionItem: (action) => this.menuOptions && this.menuOptions.actionItemProvider ? this.menuOptions.actionItemProvider(action) : null,
getMenuClassName: () => this.menuClassName,
@@ -285,7 +283,7 @@ export class DropdownMenu extends BaseDropdown {
}
}
export class DropdownGroup extends EventEmitter.EventEmitter {
export class DropdownGroup extends EventEmitter {
private el: HTMLElement;
@@ -4,26 +4,26 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import WinJS = require('vs/base/common/winjs.base');
import Platform = require('vs/base/common/platform');
import Types = require('vs/base/common/types');
import Actions = require('vs/base/common/actions');
import Dropdown = require('vs/base/browser/ui/dropdown/dropdown');
import {Promise} from 'vs/base/common/winjs.base';
import {isMacintosh} from 'vs/base/common/platform';
import {isFunction} from 'vs/base/common/types';
import {Action} from 'vs/base/common/actions';
import {DropdownMenu, IDropdownMenuOptions} from 'vs/base/browser/ui/dropdown/dropdown';
export interface ILinksDropdownMenuOptions extends Dropdown.IDropdownMenuOptions {
export interface ILinksDropdownMenuOptions extends IDropdownMenuOptions {
tooltip: string;
}
export class LinksDropdownMenu extends Dropdown.DropdownMenu {
export class LinksDropdownMenu extends DropdownMenu {
constructor (container:HTMLElement, options: ILinksDropdownMenuOptions) {
constructor(container: HTMLElement, options: ILinksDropdownMenuOptions) {
super(container, options);
this.tooltip = options.tooltip;
}
/*protected*/ public onEvent(e:Event, activeElement: HTMLElement):void {
if (e instanceof KeyboardEvent && ((<KeyboardEvent>e).ctrlKey || (Platform.isMacintosh && (<KeyboardEvent>e).metaKey))) {
/*protected*/ public onEvent(e: Event, activeElement: HTMLElement): void {
if (e instanceof KeyboardEvent && ((<KeyboardEvent>e).ctrlKey || (isMacintosh && (<KeyboardEvent>e).metaKey))) {
return; // allow to use Ctrl/Meta in workspace dropdown menu
}
@@ -31,25 +31,25 @@ export class LinksDropdownMenu extends Dropdown.DropdownMenu {
}
}
export class LinkDropdownAction extends Actions.Action {
export class LinkDropdownAction extends Action {
constructor(id:string, name:string, clazz:string, url:()=>string, forceOpenInNewTab?:boolean);
constructor(id:string, name:string, clazz:string, url:string, forceOpenInNewTab?:boolean);
constructor(id:string, name:string, clazz:string, url:any, forceOpenInNewTab?:boolean) {
super(id, name, clazz, true, (e:Event)=>{
var urlString = url;
constructor(id: string, name: string, clazz: string, url: () => string, forceOpenInNewTab?: boolean);
constructor(id: string, name: string, clazz: string, url: string, forceOpenInNewTab?: boolean);
constructor(id: string, name: string, clazz: string, url: any, forceOpenInNewTab?: boolean) {
super(id, name, clazz, true, (e: Event) => {
let urlString = url;
if (Types.isFunction(url)) {
if (isFunction(url)) {
urlString = url();
}
if (forceOpenInNewTab || (e instanceof MouseEvent && ((<MouseEvent>e).ctrlKey || (Platform.isMacintosh && (<MouseEvent>e).metaKey)))) {
if (forceOpenInNewTab || (e instanceof MouseEvent && ((<MouseEvent>e).ctrlKey || (isMacintosh && (<MouseEvent>e).metaKey)))) {
window.open(urlString, '_blank');
} else {
window.location.href = urlString;
}
return WinJS.Promise.as(true);
return Promise.as(true);
});
}
}
@@ -15,10 +15,6 @@
height: 25px;
}
.monaco-findInput .monaco-inputbox > .wrapper > .input {
outline: none;
}
.fl:after {
clear: both;
content: '';
@@ -15,6 +15,7 @@ import {Widget} from 'vs/base/browser/ui/widget';
import Event, {Emitter} from 'vs/base/common/event';
import {StandardKeyboardEvent} from 'vs/base/browser/keyboardEvent';
import {StandardMouseEvent} from 'vs/base/browser/mouseEvent';
import {CommonKeybindings} from 'vs/base/common/keyCodes';
export interface IFindInputOptions {
placeholder?:string;
@@ -48,6 +49,8 @@ export class FindInput extends Widget {
private validation:IInputValidator;
private label:string;
private optionsKeyListener: () => void;
private regex:Checkbox;
private wholeWords:Checkbox;
private caseSensitive:Checkbox;
@@ -248,6 +251,35 @@ export class FindInput extends Widget {
}
}));
// Arrow-Key support to navigate between options
let indexes = [this.caseSensitive.domNode, this.wholeWords.domNode, this.regex.domNode];
this.optionsKeyListener = dom.addListener(this.domNode, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => {
let event = new StandardKeyboardEvent(e);
if (event.equals(CommonKeybindings.LEFT_ARROW) || event.equals(CommonKeybindings.RIGHT_ARROW) || event.equals(CommonKeybindings.ESCAPE)) {
let index = indexes.indexOf(<HTMLElement>document.activeElement);
if (index >= 0) {
let newIndex: number;
if (event.equals(CommonKeybindings.RIGHT_ARROW)) {
newIndex = (index + 1) % indexes.length;
} else if (event.equals(CommonKeybindings.LEFT_ARROW)) {
if (index === 0) {
newIndex = indexes.length - 1;
} else {
newIndex = index - 1;
}
}
if (event.equals(CommonKeybindings.ESCAPE)) {
indexes[index].blur();
} else if (newIndex >= 0) {
indexes[newIndex].focus();
}
dom.EventHelper.stop(event, true);
}
}
});
this.setInputWidth();
let controls = document.createElement('div');
@@ -275,6 +307,15 @@ export class FindInput extends Widget {
private clearValidation(): void {
this.inputBox.hideMessage();
}
public dispose(): void {
if (this.optionsKeyListener) {
this.optionsKeyListener();
this.optionsKeyListener = null;
}
super.dispose();
}
}
interface IMatchCountOpts {
@@ -58,10 +58,6 @@
overflow: hidden;
}
.monaco-inputbox > .wrapper > .input:focus {
outline: none;
}
.monaco-inputbox > .wrapper > .mirror {
position: absolute;
display: inline-block;
@@ -6,23 +6,21 @@
'use strict';
import 'vs/css!./leftRightWidget';
import Builder = require('vs/base/browser/builder');
import Lifecycle = require('vs/base/common/lifecycle');
var $ = Builder.$;
import {Builder, $} from 'vs/base/browser/builder';
import {IDisposable} from 'vs/base/common/lifecycle';
export interface IRenderer {
(container:HTMLElement): Lifecycle.IDisposable;
(container: HTMLElement): IDisposable;
}
export class LeftRightWidget {
private $el: Builder.Builder;
private toDispose: Lifecycle.IDisposable[];
private $el: Builder;
private toDispose: IDisposable[];
constructor (container:Builder.Builder, renderLeftFn:IRenderer, renderRightFn:IRenderer);
constructor (container:HTMLElement, renderLeftFn:IRenderer, renderRightFn:IRenderer);
constructor (container:any, renderLeftFn:IRenderer, renderRightFn:IRenderer) {
constructor(container: Builder, renderLeftFn: IRenderer, renderRightFn: IRenderer);
constructor(container: HTMLElement, renderLeftFn: IRenderer, renderRightFn: IRenderer);
constructor(container: any, renderLeftFn: IRenderer, renderRightFn: IRenderer) {
this.$el = $('.monaco-left-right-widget').appendTo(container);
this.toDispose = [
+15 -17
View File
@@ -6,34 +6,32 @@
'use strict';
import 'vs/css!./menu';
import Lifecycle = require('vs/base/common/lifecycle');
import Builder = require('vs/base/browser/builder');
import Actions = require('vs/base/common/actions');
import ActionBar = require('vs/base/browser/ui/actionbar/actionbar');
import EventEmitter = require('vs/base/common/eventEmitter');
var $ = Builder.$;
import {IDisposable} from 'vs/base/common/lifecycle';
import {Builder, $} from 'vs/base/browser/builder';
import {IActionRunner, IAction} from 'vs/base/common/actions';
import {ActionBar, IActionItemProvider, ActionsOrientation} from 'vs/base/browser/ui/actionbar/actionbar';
import {EventEmitter} from 'vs/base/common/eventEmitter';
export interface IMenuOptions {
context?:any;
actionItemProvider?:ActionBar.IActionItemProvider;
actionRunner?:Actions.IActionRunner;
context?: any;
actionItemProvider?: IActionItemProvider;
actionRunner?: IActionRunner;
}
export class Menu extends EventEmitter.EventEmitter {
export class Menu extends EventEmitter {
private actionBar: ActionBar.ActionBar;
private listener: Lifecycle.IDisposable;
private actionBar: ActionBar;
private listener: IDisposable;
constructor (container:HTMLElement, actions:Actions.IAction[], options:IMenuOptions = {}) {
constructor(container: HTMLElement, actions: IAction[], options: IMenuOptions = {}) {
super();
$(container).addClass('monaco-menu-container');
var $menu = $('.monaco-menu').appendTo(container);
let $menu = $('.monaco-menu').appendTo(container);
this.actionBar = new ActionBar.ActionBar($menu, {
orientation: ActionBar.ActionsOrientation.VERTICAL,
this.actionBar = new ActionBar($menu, {
orientation: ActionsOrientation.VERTICAL,
actionItemProvider: options.actionItemProvider,
context: options.context,
actionRunner: options.actionRunner
@@ -6,12 +6,12 @@
'use strict';
import 'vs/css!./progressbar';
import WinJS = require('vs/base/common/winjs.base');
import Assert = require('vs/base/common/assert');
import Browser = require('vs/base/browser/browser');
import Builder = require('vs/base/browser/builder');
import {Promise, ValueCallback} from 'vs/base/common/winjs.base';
import assert = require('vs/base/common/assert');
import browser = require('vs/base/browser/browser');
import {Builder, $} from 'vs/base/browser/builder';
import DOM = require('vs/base/browser/dom');
import Uuid = require('vs/base/common/uuid');
import uuid = require('vs/base/common/uuid');
const css_done = 'done';
const css_active = 'active';
@@ -20,8 +20,6 @@ const css_discrete = 'discrete';
const css_progress_container = 'progress-container';
const css_progress_bit = 'progress-bit';
const $ = Builder.$;
/**
* A progress bar with support for infinite or discrete progress.
*/
@@ -29,21 +27,21 @@ export class ProgressBar {
private toUnbind: { (): void; }[];
private workedVal: number;
private element: Builder.Builder;
private element: Builder;
private animationRunning: boolean;
private bit: HTMLElement;
private totalWork: number;
private animationStopToken: WinJS.ValueCallback;
private animationStopToken: ValueCallback;
private currentProgressToken: string;
constructor(builder: Builder.Builder) {
constructor(builder: Builder) {
this.toUnbind = [];
this.workedVal = 0;
this.create(builder);
}
private create(parent: Builder.Builder): void {
private create(parent: Builder): void {
parent.div({ 'class': css_progress_container }, (builder) => {
this.element = builder.clone();
@@ -100,7 +98,7 @@ export class ProgressBar {
this.bit.style.width = 'inherit';
if (delayed) {
WinJS.Promise.timeout(200).then(() => this.off());
Promise.timeout(200).then(() => this.off());
} else {
this.off();
}
@@ -110,7 +108,7 @@ export class ProgressBar {
else {
this.bit.style.opacity = '0';
if (delayed) {
WinJS.Promise.timeout(200).then(() => this.off());
Promise.timeout(200).then(() => this.off());
} else {
this.off();
}
@@ -131,10 +129,10 @@ export class ProgressBar {
this.element.addClass(css_active);
this.element.addClass(css_infinite);
if (!Browser.hasCSSAnimationSupport()) {
if (!browser.hasCSSAnimationSupport()) {
// Use a generated token to avoid race conditions from reentrant calls to this function
let currentProgressToken = Uuid.v4().asHex();
let currentProgressToken = uuid.v4().asHex();
this.currentProgressToken = currentProgressToken;
this.manualInfinite(currentProgressToken);
@@ -144,13 +142,12 @@ export class ProgressBar {
}
private manualInfinite(currentProgressToken: string): void {
this.bit.style.width = '5%';
this.bit.style.display = 'inherit';
let counter = 0;
let animationFn: () => void = () => {
WinJS.Promise.timeout(50).then(() => {
Promise.timeout(50).then(() => {
// Return if another manualInfinite() call was made
if (currentProgressToken !== this.currentProgressToken) {
@@ -203,10 +200,10 @@ export class ProgressBar {
* Tells the progress bar that an amount of work has been completed.
*/
public worked(value: number): ProgressBar {
Assert.ok(!isNaN(this.totalWork), 'Total work not set');
assert.ok(!isNaN(this.totalWork), 'Total work not set');
value = Number(value);
Assert.ok(!isNaN(value), 'Value is not a number');
assert.ok(!isNaN(value), 'Value is not a number');
value = Math.max(1, value);
this.workedVal += value;
@@ -236,7 +233,7 @@ export class ProgressBar {
/**
* Returns the builder this progress bar is building in.
*/
public getContainer(): Builder.Builder {
public getContainer(): Builder {
return $(this.element);
}
+36 -38
View File
@@ -6,16 +6,14 @@
'use strict';
import 'vs/css!./sash';
import Lifecycle = require('vs/base/common/lifecycle');
import Builder = require('vs/base/browser/builder');
import Browser = require('vs/base/browser/browser');
import Types = require('vs/base/common/types');
import {IDisposable, disposeAll} from 'vs/base/common/lifecycle';
import {Builder, $} from 'vs/base/browser/builder';
import {isIPad} from 'vs/base/browser/browser';
import types = require('vs/base/common/types');
import DOM = require('vs/base/browser/dom');
import Touch = require('vs/base/browser/touch');
import Events = require('vs/base/common/eventEmitter');
import Mouse = require('vs/base/browser/mouseEvent');
var $ = <Builder.QuickBuilder> Builder.$;
import {Gesture, EventType, GestureEvent} from 'vs/base/browser/touch';
import {EventEmitter} from 'vs/base/common/eventEmitter';
import {StandardMouseEvent} from 'vs/base/browser/mouseEvent';
export interface ISashLayoutProvider { }
@@ -50,10 +48,10 @@ export enum Orientation {
HORIZONTAL
}
export class Sash extends Events.EventEmitter {
export class Sash extends EventEmitter {
private $e: Builder.Builder;
private gesture: Touch.Gesture;
private $e: Builder;
private gesture: Gesture;
private layoutProvider: ISashLayoutProvider;
private isDisabled: boolean;
private hidden: boolean;
@@ -65,17 +63,17 @@ export class Sash extends Events.EventEmitter {
this.$e = $('.monaco-sash').appendTo(container);
this.gesture = new Touch.Gesture(this.$e.getHTMLElement());
this.gesture = new Gesture(this.$e.getHTMLElement());
this.$e.on('mousedown', (e: MouseEvent) => { this.onMouseDown(e); });
this.$e.on(Touch.EventType.Start, (e: Touch.GestureEvent) => { this.onTouchStart(e); });
this.$e.on(EventType.Start, (e: GestureEvent) => { this.onTouchStart(e); });
this.orientation = options.orientation || Orientation.VERTICAL;
this.$e.addClass(this.orientation === Orientation.HORIZONTAL ? 'horizontal' : 'vertical');
this.size = options.baseSize || 5;
if (Browser.isIPad) {
if (isIPad) {
this.size *= 4; // see also http://ux.stackexchange.com/questions/39023/what-is-the-optimum-button-size-of-touch-screen-applications
this.$e.addClass('touch');
}
@@ -102,11 +100,11 @@ export class Sash extends Events.EventEmitter {
return;
}
var mouseDownEvent = new Mouse.StandardMouseEvent(e);
var startX = mouseDownEvent.posx;
var startY = mouseDownEvent.posy;
let mouseDownEvent = new StandardMouseEvent(e);
let startX = mouseDownEvent.posx;
let startY = mouseDownEvent.posy;
var startEvent: ISashEvent = {
let startEvent: ISashEvent = {
startX: startX,
currentX: startX,
instantDiffX: 0,
@@ -118,7 +116,7 @@ export class Sash extends Events.EventEmitter {
this.$e.addClass('active');
this.emit('start', startEvent);
var overlayDiv = $('div').style({
let overlayDiv = $('div').style({
position: 'absolute',
top: 0,
left: 0,
@@ -128,16 +126,16 @@ export class Sash extends Events.EventEmitter {
cursor: this.orientation === Orientation.VERTICAL ? 'ew-resize' : 'ns-resize'
});
var $window = $(window);
let $window = $(window);
var lastCurrentX = startX;
var lastCurrentY = startY;
let lastCurrentX = startX;
let lastCurrentY = startY;
$window.on('mousemove', (e: MouseEvent) => {
DOM.EventHelper.stop(e, false);
var mouseMoveEvent = new Mouse.StandardMouseEvent(e);
let mouseMoveEvent = new StandardMouseEvent(e);
var event: ISashEvent = {
let event: ISashEvent = {
startX: startX,
currentX: mouseMoveEvent.posx,
instantDiffX: mouseMoveEvent.posx - lastCurrentX,
@@ -162,13 +160,13 @@ export class Sash extends Events.EventEmitter {
overlayDiv.appendTo(document.body);
}
private onTouchStart(event: Touch.GestureEvent): void {
private onTouchStart(event: GestureEvent): void {
DOM.EventHelper.stop(event);
var listeners: Lifecycle.IDisposable[] = [];
let listeners: IDisposable[] = [];
var startX = event.pageX;
var startY = event.pageY;
let startX = event.pageX;
let startY = event.pageY;
this.emit('start', {
startX: startX,
@@ -179,11 +177,11 @@ export class Sash extends Events.EventEmitter {
instantDiffY: 0
});
var lastCurrentX = startX;
var lastCurrentY = startY;
let lastCurrentX = startX;
let lastCurrentY = startY;
listeners.push(DOM.addDisposableListener(this.$e.getHTMLElement(), Touch.EventType.Change, (event: Touch.GestureEvent) => {
if (Types.isNumber(event.pageX) && Types.isNumber(event.pageY)) {
listeners.push(DOM.addDisposableListener(this.$e.getHTMLElement(), EventType.Change, (event: GestureEvent) => {
if (types.isNumber(event.pageX) && types.isNumber(event.pageY)) {
this.emit('change', {
startX: startX,
currentX: event.pageX,
@@ -198,17 +196,17 @@ export class Sash extends Events.EventEmitter {
}
}));
listeners.push(DOM.addDisposableListener(this.$e.getHTMLElement(), Touch.EventType.End, (event: Touch.GestureEvent) => {
listeners.push(DOM.addDisposableListener(this.$e.getHTMLElement(), EventType.End, (event: GestureEvent) => {
this.emit('end');
Lifecycle.disposeAll(listeners);
disposeAll(listeners);
}));
}
public layout(): void {
var style: { top?: string; left?: string; height?: string; width?: string; };
let style: { top?: string; left?: string; height?: string; width?: string; };
if (this.orientation === Orientation.VERTICAL) {
var verticalProvider = (<IVerticalSashLayoutProvider>this.layoutProvider);
let verticalProvider = (<IVerticalSashLayoutProvider>this.layoutProvider);
style = { left: verticalProvider.getVerticalSashLeft(this) - (this.size / 2) + 'px' };
if (verticalProvider.getVerticalSashTop) {
@@ -219,7 +217,7 @@ export class Sash extends Events.EventEmitter {
style.height = verticalProvider.getVerticalSashHeight(this) + 'px';
}
} else {
var horizontalProvider = (<IHorizontalSashLayoutProvider>this.layoutProvider);
let horizontalProvider = (<IHorizontalSashLayoutProvider>this.layoutProvider);
style = { top: horizontalProvider.getHorizontalSashTop(this) - (this.size / 2) + 'px' };
if (horizontalProvider.getHorizontalSashLeft) {
+101 -57
View File
@@ -14,6 +14,8 @@ import objects = require('vs/base/common/objects');
import dom = require('vs/base/browser/dom');
import numbers = require('vs/base/common/numbers');
import sash = require('vs/base/browser/ui/sash/sash');
import {StandardKeyboardEvent} from 'vs/base/browser/keyboardEvent';
import {CommonKeybindings} from 'vs/base/common/keyCodes';
export enum Orientation {
VERTICAL,
@@ -115,7 +117,7 @@ export class HeaderView extends View {
this.header = document.createElement('div');
this.header.className = 'header';
var headerSize = this.headerSize + 'px';
let headerSize = this.headerSize + 'px';
if (orientation === Orientation.HORIZONTAL) {
this.header.style.width = headerSize;
@@ -148,7 +150,7 @@ export class HeaderView extends View {
}
private layoutBodyContainer(orientation: Orientation): void {
var size = `calc(100% - ${this.headerSize}px)`;
let size = `calc(100% - ${this.headerSize}px)`;
if (orientation === Orientation.HORIZONTAL) {
this.body.style.width = size;
@@ -184,7 +186,10 @@ export enum CollapsibleState {
export class AbstractCollapsibleView extends HeaderView {
protected state: CollapsibleState;
private headerClickListener: () => void;
private headerKeyListener: () => void;
private focusTracker: dom.IFocusTracker;
constructor(opts: ICollapsibleViewOptions) {
super(opts);
@@ -198,7 +203,37 @@ export class AbstractCollapsibleView extends HeaderView {
dom.addClass(this.header, 'collapsible');
dom.addClass(this.body, 'collapsible');
this.headerClickListener = dom.addListener(this.header, 'click', () => this.toggleExpansion());
// Keyboard access
this.header.setAttribute('tabindex', '0');
this.headerKeyListener = dom.addListener(this.header, dom.EventType.KEY_DOWN, (e) => {
let event = new StandardKeyboardEvent(e);
let eventHandled = false;
if (event.equals(CommonKeybindings.ENTER) || event.equals(CommonKeybindings.SPACE) || event.equals(CommonKeybindings.LEFT_ARROW) || event.equals(CommonKeybindings.RIGHT_ARROW)) {
this.toggleExpansion();
eventHandled = true;
} else if (event.equals(CommonKeybindings.ESCAPE)) {
this.header.blur();
eventHandled = true;
}
if (eventHandled) {
dom.EventHelper.stop(event, true);
}
});
// Mouse access
this.headerClickListener = dom.addListener(this.header, dom.EventType.CLICK, () => this.toggleExpansion());
// Track state of focus in header so that other components can adjust styles based on that
// (for example show or hide actions based on the state of being focused or not)
this.focusTracker = dom.trackFocus(this.header);
this.focusTracker.addFocusListener(() => {
dom.addClass(this.header, 'focused');
});
this.focusTracker.addBlurListener(() => {
setTimeout(() => dom.removeClass(this.header, 'focused')); // delay to give other components a chance to react
});
}
public layout(size: number, orientation: Orientation): void {
@@ -257,6 +292,16 @@ export class AbstractCollapsibleView extends HeaderView {
this.headerClickListener = null;
}
if (this.headerKeyListener) {
this.headerKeyListener();
this.headerKeyListener = null;
}
if (this.focusTracker) {
this.focusTracker.dispose();
this.focusTracker = null;
}
super.dispose();
}
}
@@ -321,8 +366,7 @@ function sum(a: number, b: number): number { return a + b; }
export class SplitView implements
sash.IHorizontalSashLayoutProvider,
sash.IVerticalSashLayoutProvider
{
sash.IVerticalSashLayoutProvider {
private orientation: Orientation;
private el: HTMLElement;
private size: number;
@@ -333,9 +377,9 @@ export class SplitView implements
private sashOrientation: sash.Orientation;
private sashes: sash.Sash[];
private sashesListeners: lifecycle.IDisposable[];
private measureContainerSize: ()=>number;
private layoutViewElement: (viewElement: HTMLElement, size: number)=>void;
private eventWrapper: (event: sash.ISashEvent)=>ISashEvent;
private measureContainerSize: () => number;
private layoutViewElement: (viewElement: HTMLElement, size: number) => void;
private eventWrapper: (event: sash.ISashEvent) => ISashEvent;
private animationTimeout: number;
private state: IState;
@@ -386,10 +430,10 @@ export class SplitView implements
throw new Error('Initial weight must be a positive number.');
}
var viewCount = this.views.length;
let viewCount = this.views.length;
// Create view container
var viewElement = document.createElement('div');
let viewElement = document.createElement('div');
dom.addClass(viewElement, 'split-view-view');
this.viewElements.splice(index, 0, viewElement);
@@ -409,7 +453,7 @@ export class SplitView implements
// Add sash
if (this.views.length > 2) {
var s = new sash.Sash(this.el, this, { orientation: this.sashOrientation });
let s = new sash.Sash(this.el, this, { orientation: this.sashOrientation });
this.sashes.splice(index - 1, 0, s);
this.sashesListeners.push(s.addListener2('start', e => this.onSashStart(s, this.eventWrapper(e))));
this.sashesListeners.push(s.addListener2('change', e => this.onSashChange(s, this.eventWrapper(e))));
@@ -420,17 +464,17 @@ export class SplitView implements
}
public removeView(view: View): void {
var index = this.views.indexOf(view);
let index = this.views.indexOf(view);
if (index < 0) {
return;
}
var deadView = new DeadView(view);
let deadView = new DeadView(view);
this.views[index] = deadView;
this.onViewChange(deadView, 0);
var sashIndex = Math.max(index - 1, 0);
let sashIndex = Math.max(index - 1, 0);
this.sashes[sashIndex].dispose();
this.sashes.splice(sashIndex, 1);
@@ -456,11 +500,11 @@ export class SplitView implements
size = Math.max(size, this.views.reduce((t, v) => t + v.minimumSize, 0));
var diff = Math.abs(this.size - size);
var up = numbers.countToArray(this.views.length - 1, -1);
let diff = Math.abs(this.size - size);
let up = numbers.countToArray(this.views.length - 1, -1);
var collapses = this.views.map(v => v.size - v.minimumSize);
var expands = this.views.map(v => v.maximumSize - v.size);
let collapses = this.views.map(v => v.size - v.minimumSize);
let expands = this.views.map(v => v.maximumSize - v.size);
if (size < this.size) {
this.expandCollapse(Math.min(diff, collapses.reduce(sum, 0)), collapses, expands, up, []);
@@ -473,17 +517,17 @@ export class SplitView implements
}
private onSashStart(sash: sash.Sash, event: ISashEvent): void {
var i = this.sashes.indexOf(sash);
var collapses = this.views.map(v => v.size - v.minimumSize);
var expands = this.views.map(v => v.maximumSize - v.size);
let i = this.sashes.indexOf(sash);
let collapses = this.views.map(v => v.size - v.minimumSize);
let expands = this.views.map(v => v.maximumSize - v.size);
var up = numbers.countToArray(i, -1);
var down = numbers.countToArray(i + 1, this.views.length);
let up = numbers.countToArray(i, -1);
let down = numbers.countToArray(i + 1, this.views.length);
var collapsesUp = up.map(i => collapses[i]);
var collapsesDown = down.map(i => collapses[i]);
var expandsUp = up.map(i => expands[i]);
var expandsDown = down.map(i => expands[i]);
let collapsesUp = up.map(i => collapses[i]);
let collapsesDown = down.map(i => collapses[i]);
let expandsUp = up.map(i => expands[i]);
let expandsDown = down.map(i => expands[i]);
this.state = {
start: event.start,
@@ -498,10 +542,10 @@ export class SplitView implements
}
private onSashChange(sash: sash.Sash, event: ISashEvent): void {
var i = this.sashes.indexOf(sash);
var diff = event.current - this.state.start;
let i = this.sashes.indexOf(sash);
let diff = event.current - this.state.start;
for (var i = 0; i < this.views.length; i++) {
for (let i = 0; i < this.views.length; i++) {
this.views[i].size = this.state.sizes[i];
}
@@ -516,25 +560,25 @@ export class SplitView implements
// Main algorithm
private expandCollapse(collapse: number, collapses: number[], expands: number[], collapseIndexes: number[], expandIndexes: number[]): void {
var totalCollapse = collapse;
var totalExpand = totalCollapse;
let totalCollapse = collapse;
let totalExpand = totalCollapse;
collapseIndexes.forEach(i => {
var collapse = Math.min(collapses[i], totalCollapse);
let collapse = Math.min(collapses[i], totalCollapse);
totalCollapse -= collapse;
this.views[i].size -= collapse;
});
expandIndexes.forEach(i => {
var expand = Math.min(expands[i], totalExpand);
let expand = Math.min(expands[i], totalExpand);
totalExpand -= expand;
this.views[i].size += expand;
});
}
private initialLayout(): void {
var totalWeight = 0;
var fixedSize = 0;
let totalWeight = 0;
let fixedSize = 0;
this.views.forEach((v, i) => {
if (v.sizing === ViewSizing.Flexible) {
@@ -544,7 +588,7 @@ export class SplitView implements
}
});
var flexibleSize = this.size - fixedSize;
let flexibleSize = this.size - fixedSize;
this.views.forEach((v, i) => {
if (v.sizing === ViewSizing.Flexible) {
@@ -555,7 +599,7 @@ export class SplitView implements
});
// Leftover
var index = this.getLastFlexibleViewIndex();
let index = this.getLastFlexibleViewIndex();
if (index >= 0) {
this.views[index].size += this.size - this.views.reduce((t, v) => t + v.size, 0);
}
@@ -565,7 +609,7 @@ export class SplitView implements
}
private getLastFlexibleViewIndex(exceptIndex: number = null): number {
for (var i = this.views.length - 1; i >= 0; i--) {
for (let i = this.views.length - 1; i >= 0; i--) {
if (exceptIndex === i) {
continue;
}
@@ -578,7 +622,7 @@ export class SplitView implements
}
private layoutViews(): void {
for (var i = 0; i < this.views.length; i++) {
for (let i = 0; i < this.views.length; i++) {
// Layout the view elements
this.layoutViewElement(this.viewElements[i], this.views[i].size);
@@ -590,18 +634,18 @@ export class SplitView implements
this.sashes.forEach(s => s.layout());
// Update sashes enablement
var previous = false;
var collapsesDown = this.views.map(v => previous = (v.size - v.minimumSize > 0) || previous);
let previous = false;
let collapsesDown = this.views.map(v => previous = (v.size - v.minimumSize > 0) || previous);
previous = false;
var expandsDown = this.views.map(v => previous = (v.maximumSize - v.size > 0) || previous);
let expandsDown = this.views.map(v => previous = (v.maximumSize - v.size > 0) || previous);
var reverseViews = this.views.slice().reverse();
let reverseViews = this.views.slice().reverse();
previous = false;
var collapsesUp = reverseViews.map(v => previous = (v.size - v.minimumSize > 0) || previous).reverse();
let collapsesUp = reverseViews.map(v => previous = (v.size - v.minimumSize > 0) || previous).reverse();
previous = false;
var expandsUp = reverseViews.map(v => previous = (v.maximumSize - v.size > 0) || previous).reverse();
let expandsUp = reverseViews.map(v => previous = (v.maximumSize - v.size > 0) || previous).reverse();
this.sashes.forEach((s, i) => {
if ((collapsesDown[i] && expandsUp[i + 1]) || (expandsDown[i] && collapsesUp[i + 1])) {
@@ -631,16 +675,16 @@ export class SplitView implements
this.setupAnimation();
var index = this.views.indexOf(view);
var diff = Math.abs(size - view.size);
var up = numbers.countToArray(index - 1, -1);
var down = numbers.countToArray(index + 1, this.views.length);
var downUp = down.concat(up);
let index = this.views.indexOf(view);
let diff = Math.abs(size - view.size);
let up = numbers.countToArray(index - 1, -1);
let down = numbers.countToArray(index + 1, this.views.length);
let downUp = down.concat(up);
var collapses = this.views.map(v => Math.max(v.size - v.minimumSize, 0));
var expands = this.views.map(v => Math.max(v.maximumSize - v.size, 0));
let collapses = this.views.map(v => Math.max(v.size - v.minimumSize, 0));
let expands = this.views.map(v => Math.max(v.maximumSize - v.size, 0));
var collapse: number, collapseIndexes: number[], expandIndexes: number[];
let collapse: number, collapseIndexes: number[], expandIndexes: number[];
if (size < view.size) {
collapse = Math.min(downUp.reduce((t, i) => t + expands[i], 0), diff);
@@ -688,10 +732,10 @@ export class SplitView implements
}
private getSashPosition(sash: sash.Sash): number {
var index = this.sashes.indexOf(sash);
var position = 0;
let index = this.sashes.indexOf(sash);
let position = 0;
for (var i = 0; i <= index; i++) {
for (let i = 0; i <= index; i++) {
position += this.views[i].size;
}
+54 -54
View File
@@ -6,38 +6,38 @@
'use strict';
import 'vs/css!./timer';
import Timer = require('vs/base/common/timer');
import eventEmitter = require('vs/base/common/eventEmitter');
import {TimeKeeper, ITimerEvent, getTimeKeeper} from 'vs/base/common/timer';
import {ListenerUnbind} from 'vs/base/common/eventEmitter';
import DomUtils = require('vs/base/browser/dom');
interface IUnmatchedStartTimerEvent {
event: Timer.ITimerEvent;
event: ITimerEvent;
domNode: HTMLElement;
}
export class TimeKeeperRenderer {
private listenersToRemove:eventEmitter.ListenerUnbind[];
private timeKeeper:Timer.TimeKeeper;
private outerDomNode:HTMLElement;
private domNode:HTMLElement;
private renderCnt:number;
private lastEventIndex:number;
private listenersToRemove: ListenerUnbind[];
private timeKeeper: TimeKeeper;
private outerDomNode: HTMLElement;
private domNode: HTMLElement;
private renderCnt: number;
private lastEventIndex: number;
private textFilter:string;
private textFilterDomNode:HTMLInputElement;
private timeFilter:number;
private timeFilterDomNode:HTMLInputElement;
private intervalTokenId:number;
private textFilter: string;
private textFilterDomNode: HTMLInputElement;
private timeFilter: number;
private timeFilterDomNode: HTMLInputElement;
private intervalTokenId: number;
private renderedEvents:{
[key:string]:Timer.ITimerEvent;
private renderedEvents: {
[key: string]: ITimerEvent;
};
private onHide:()=>void;
private onHide: () => void;
constructor (onHide:()=>void) {
this.timeKeeper = Timer.getTimeKeeper();
constructor(onHide: () => void) {
this.timeKeeper = getTimeKeeper();
this.onHide = onHide;
this.lastEventIndex = 0;
this.renderedEvents = {};
@@ -50,7 +50,7 @@ export class TimeKeeperRenderer {
public destroy(): void {
document.body.removeChild(this.outerDomNode);
window.clearInterval(this.intervalTokenId);
this.listenersToRemove.forEach(function (element) {
this.listenersToRemove.forEach(function(element) {
element();
});
this.listenersToRemove = [];
@@ -61,7 +61,7 @@ export class TimeKeeperRenderer {
this.outerDomNode.className = 'benchmarktimerbox';
// Clear
var cancel:HTMLInputElement = <HTMLInputElement>document.createElement('input');
let cancel: HTMLInputElement = <HTMLInputElement>document.createElement('input');
cancel.type = 'button';
cancel.value = 'Clear';
this.listenersToRemove.push(DomUtils.addListener(cancel, 'click', () => this._onClear()));
@@ -86,7 +86,7 @@ export class TimeKeeperRenderer {
this.outerDomNode.appendChild(document.createTextNode('Hide time under'));
this.outerDomNode.appendChild(this.timeFilterDomNode);
var hide:HTMLInputElement = <HTMLInputElement>document.createElement('input');
let hide: HTMLInputElement = <HTMLInputElement>document.createElement('input');
hide.type = 'button';
hide.value = 'Close';
this.listenersToRemove.push(DomUtils.addListener(hide, 'click', () => {
@@ -94,12 +94,12 @@ export class TimeKeeperRenderer {
}));
this.outerDomNode.appendChild(hide);
var heading = document.createElement('pre');
let heading = document.createElement('pre');
heading.appendChild(document.createTextNode(this.renderRow('TOPIC', 'NAME', 'TOOK', 'START', 'END')));
this.outerDomNode.appendChild(heading);
this.outerDomNode.appendChild(document.createElement('hr'));
var domNode = document.createElement('div');
let domNode = document.createElement('div');
domNode.className = 'inner';
this.outerDomNode.appendChild(domNode);
@@ -120,7 +120,7 @@ export class TimeKeeperRenderer {
});
}
private matchesTextFilter(event:Timer.ITimerEvent): boolean {
private matchesTextFilter(event: ITimerEvent): boolean {
if (!this.textFilter) {
return true;
}
@@ -133,7 +133,7 @@ export class TimeKeeperRenderer {
return false;
}
private matchesTimeFilter(event:Timer.ITimerEvent): boolean {
private matchesTimeFilter(event: ITimerEvent): boolean {
if (!this.timeFilter) {
return true;
}
@@ -143,7 +143,7 @@ export class TimeKeeperRenderer {
return false;
}
private shouldShow(event:Timer.ITimerEvent): boolean {
private shouldShow(event: ITimerEvent): boolean {
return this.matchesTextFilter(event) && this.matchesTimeFilter(event);
}
@@ -151,17 +151,17 @@ export class TimeKeeperRenderer {
this.textFilter = this.textFilterDomNode.value;
this.timeFilter = parseInt(this.timeFilterDomNode.value, 10);
var domNodes = Array.prototype.slice.call(this.domNode.children, 0);
for (var i = 0; i < domNodes.length; i++) {
var eventId = domNodes[i].getAttribute('data-event-id');
var event = this.renderedEvents[eventId];
let domNodes = Array.prototype.slice.call(this.domNode.children, 0);
for (let i = 0; i < domNodes.length; i++) {
let eventId = domNodes[i].getAttribute('data-event-id');
let event = this.renderedEvents[eventId];
if (this.shouldShow(event)) {
domNodes[i].style.display = 'inherit';
} else {
domNodes[i].style.display = 'none';
}
if (this.shouldShow(event)) {
domNodes[i].style.display = 'inherit';
} else {
domNodes[i].style.display = 'none';
}
}
}
private _onClear(): void {
@@ -171,18 +171,18 @@ export class TimeKeeperRenderer {
DomUtils.clearNode(this.domNode);
}
private leftPaddedString(size:number, padChar:string, str:string): string {
var spaces = this._repeatStr(padChar, Math.max(0, size - str.length));
private leftPaddedString(size: number, padChar: string, str: string): string {
let spaces = this._repeatStr(padChar, Math.max(0, size - str.length));
return spaces + str;
}
private rightPaddedString(size:number, padChar:string, str:string): string {
var spaces = this._repeatStr(padChar, Math.max(0, size - str.length));
private rightPaddedString(size: number, padChar: string, str: string): string {
let spaces = this._repeatStr(padChar, Math.max(0, size - str.length));
return str + spaces;
}
private renderRow(topic:string, name:string, timeTook:string, timeStart:string, timerEnd:string): string {
var result = ' ';
private renderRow(topic: string, name: string, timeTook: string, timeStart: string, timerEnd: string): string {
let result = ' ';
result += this.rightPaddedString(10, ' ', topic);
result += this.rightPaddedString(30, ' ', name);
result += ' ' + this.leftPaddedString(15, ' ', timeTook);
@@ -220,10 +220,10 @@ export class TimeKeeperRenderer {
return this._twoPrecision(t) + ' h';
}
private _renderEvent(domNode:HTMLElement, event:Timer.ITimerEvent): void {
var start = event.startTime.getTime() - Timer.TimeKeeper.PARSE_TIME.getTime();
private _renderEvent(domNode: HTMLElement, event: ITimerEvent): void {
let start = event.startTime.getTime() - TimeKeeper.PARSE_TIME.getTime();
var result = this.renderRow(
let result = this.renderRow(
event.topic,
event.name,
this._twoPrecision(event.timeTaken()),
@@ -234,11 +234,11 @@ export class TimeKeeperRenderer {
domNode.appendChild(document.createTextNode(result));
}
private _renderStartTimerEvent(event:Timer.ITimerEvent): void {
var domNode = document.createElement('pre');
private _renderStartTimerEvent(event: ITimerEvent): void {
let domNode = document.createElement('pre');
this._renderEvent(domNode, event);
this.domNode.appendChild(domNode);
var idString = event.id.toString();
let idString = event.id.toString();
domNode.setAttribute('data-event-id', idString);
domNode.className = 'timer-event-' + (event.id % 2);
@@ -254,10 +254,10 @@ export class TimeKeeperRenderer {
}
private _render(): void {
var allEvents = this.timeKeeper.getCollectedEvents(), didSomething = false;;
let allEvents = this.timeKeeper.getCollectedEvents(), didSomething = false;;
for (var i = this.lastEventIndex; i < allEvents.length; i++) {
var ev = allEvents[i];
for (let i = this.lastEventIndex; i < allEvents.length; i++) {
let ev = allEvents[i];
if (!ev.stopTime) {
// This event is not yet finished => block
@@ -278,9 +278,9 @@ export class TimeKeeperRenderer {
this.lastEventIndex = allEvents.length;
}
private _repeatStr(str:string, cnt:number): string {
var r = '';
for (var i = 0; i < cnt; i++) {
private _repeatStr(str: string, cnt: number): string {
let r = '';
for (let i = 0; i < cnt; i++) {
r += str;
}
return r;
+2 -28
View File
@@ -33,24 +33,6 @@
background-image: url('ellipsis-inverse.svg');
}
/*.monaco-toolbar .monaco-action-bar:focus:after {
content: "";
position: relative;
top: -5px;
height: 0;
width: 100%;
border-top: 2px solid #39F;
display: block;
}
.vs .monaco-toolbar .monaco-action-bar .action-label:focus {
background-color: #DCEBFC;
}
.vs-dark .monaco-toolbar .monaco-action-bar .action-label:focus {
background-color: #073655;
}*/
/* High Contrast Theming */
.hc-black .monaco-toolbar .action-label.toolbar-toggle-more {
background: none;
@@ -61,14 +43,6 @@
position: absolute;
top: 12px;
left: 8px;
height: 16px;
height: 16px;
width: 16px;
}
/*.hc-black .monaco-toolbar .monaco-action-bar:focus:after {
border-color: #DF740C;
}
.hc-black .monaco-toolbar .monaco-action-bar .action-label:focus {
border: 1px solid #DF740C;
}*/
}
+31 -35
View File
@@ -7,6 +7,7 @@
import 'vs/css!./toolbar';
import nls = require('vs/nls');
import {Promise} from 'vs/base/common/winjs.base';
import {IDisposable} from 'vs/base/common/lifecycle';
import {Builder, $} from 'vs/base/browser/builder';
import types = require('vs/base/common/types');
@@ -15,7 +16,7 @@ import {ActionBar, ActionsOrientation, IActionItemProvider, BaseActionItem} from
import {IContextMenuProvider, DropdownMenu, IActionProvider, ILabelRenderer, IDropdownMenuOptions} from 'vs/base/browser/ui/dropdown/dropdown';
import {ListenerUnbind} from 'vs/base/common/eventEmitter';
export var CONTEXT = 'context.toolbar';
export const CONTEXT = 'context.toolbar';
export interface IToolBarOptions {
orientation?: ActionsOrientation;
@@ -34,9 +35,9 @@ export class ToolBar {
constructor(container: HTMLElement, contextMenuProvider: IContextMenuProvider, options: IToolBarOptions = { orientation: ActionsOrientation.HORIZONTAL }) {
this.options = options;
this.toggleMenuAction = new ToggleMenuAction();
this.toggleMenuAction = new ToggleMenuAction(() => this.toggleMenuActionItem && this.toggleMenuActionItem.show());
var element = document.createElement('div');
let element = document.createElement('div');
element.className = 'monaco-toolbar';
container.appendChild(element);
@@ -58,7 +59,6 @@ export class ToolBar {
(<ToggleMenuAction>action).menuActions,
contextMenuProvider,
this.options.actionItemProvider,
this.options.orientation === ActionsOrientation.HORIZONTAL,
this.actionRunner,
'toolbar-toggle-more'
);
@@ -85,7 +85,7 @@ export class ToolBar {
public setActions(primaryActions: IAction[], secondaryActions?: IAction[]): () => void {
return () => {
var primaryActionsToSet = primaryActions ? primaryActions.slice(0) : [];
let primaryActionsToSet = primaryActions ? primaryActions.slice(0) : [];
// Inject additional action to open secondary actions if present
this.hasSecondaryActions = secondaryActions && secondaryActions.length > 0;
@@ -104,7 +104,7 @@ export class ToolBar {
// Add after the "..." action if we have secondary actions
if (this.hasSecondaryActions) {
var itemCount = this.actionBar.length();
let itemCount = this.actionBar.length();
this.actionBar.push(primaryActions, { icon: true, label: false, index: itemCount });
}
@@ -130,9 +130,18 @@ class ToggleMenuAction extends Action {
public static ID = 'toolbar.toggle.more';
private _menuActions: IAction[];
private toggleDropdownMenu: () => void;
constructor() {
constructor(toggleDropdownMenu: () => void) {
super(ToggleMenuAction.ID, nls.localize('more', "More"), null, true);
this.toggleDropdownMenu = toggleDropdownMenu;
}
public run(): Promise {
this.toggleDropdownMenu();
return Promise.as(true);
}
public get menuActions() {
@@ -145,59 +154,40 @@ class ToggleMenuAction extends Action {
}
export class DropdownMenuActionItem extends BaseActionItem {
private menuActionsOrProvider: any;
private animateClick: boolean;
private dropdownMenu: DropdownMenu;
private toUnbind: ListenerUnbind;
private contextMenuProvider: IContextMenuProvider;
private actionItemProvider: IActionItemProvider;
private clazz: string;
constructor(action: IAction, menuActions: IAction[], contextMenuProvider: IContextMenuProvider, actionItemProvider: IActionItemProvider, animateClick: boolean, actionRunner: IActionRunner, clazz: string);
constructor(action: IAction, actionProvider: IActionProvider, contextMenuProvider: IContextMenuProvider, actionItemProvider: IActionItemProvider, animateClick: boolean, actionRunner: IActionRunner, clazz: string);
constructor(action: IAction, menuActionsOrProvider: any, contextMenuProvider: IContextMenuProvider, actionItemProvider: IActionItemProvider, animateClick: boolean, actionRunner: IActionRunner, clazz: string) {
constructor(action: IAction, menuActions: IAction[], contextMenuProvider: IContextMenuProvider, actionItemProvider: IActionItemProvider, actionRunner: IActionRunner, clazz: string);
constructor(action: IAction, actionProvider: IActionProvider, contextMenuProvider: IContextMenuProvider, actionItemProvider: IActionItemProvider, actionRunner: IActionRunner, clazz: string);
constructor(action: IAction, menuActionsOrProvider: any, contextMenuProvider: IContextMenuProvider, actionItemProvider: IActionItemProvider, actionRunner: IActionRunner, clazz: string) {
super(null, action);
this.menuActionsOrProvider = menuActionsOrProvider;
this.contextMenuProvider = contextMenuProvider;
this.actionItemProvider = actionItemProvider;
this.animateClick = animateClick;
this.actionRunner = actionRunner;
this.clazz = clazz;
}
public render(container: HTMLElement): void {
super.render(container);
var labelRenderer: ILabelRenderer = (el: HTMLElement): IDisposable => {
var e = $('a.action-label').attr({
tabIndex: '-1',
let labelRenderer: ILabelRenderer = (el: HTMLElement): IDisposable => {
this.builder = $('a.action-label').attr({
tabIndex: '0',
role: 'menuitem',
title: this._action.label || '',
class: this.clazz
}).appendTo(el);
});
$('span.label').text(this.getAction().label).appendTo(e);
if (this.animateClick) {
$(el).on('mousedown', (e: MouseEvent) => {
if (e.button === 0) {
$(el).addClass('active');
}
});
$(el).on(['mouseup', 'mouseout'], (e: MouseEvent) => {
if (e.button === 0) {
$(el).removeClass('active');
}
});
}
this.builder.appendTo(el);
return null;
};
var options: IDropdownMenuOptions = {
let options: IDropdownMenuOptions = {
contextMenuProvider: this.contextMenuProvider,
labelRenderer: labelRenderer
};
@@ -220,6 +210,12 @@ export class DropdownMenuActionItem extends BaseActionItem {
this.toUnbind = this.addEmitter(this.dropdownMenu);
}
public show(): void {
if (this.dropdownMenu) {
this.dropdownMenu.show();
}
}
public dispose(): void {
this.toUnbind();
this.dropdownMenu.dispose();
+7 -4
View File
@@ -27,10 +27,13 @@ function fifo(array:any[], size:number) {
}
}
export function register(what:string, fn:Function):(...args:any[])=>void {
return () => {
// Intentional empty, disable for now because it is leaking memory
};
export function register(what: string, fn: Function): (...args: any[]) => void {
if (true) {
return () => {
// Intentional empty, disable for now because it is leaking memory
};
}
// register switch
var flag = switches[what] || false;
+25 -15
View File
@@ -233,7 +233,7 @@ export class ConnectionError implements Error {
// Bug: Can not subclass a JS Type. Do it manually (as done in WinJS.Class.derive)
objects.derive(Error, ConnectionError);
function _xhrToErrorMessage(xhr: IConnectionErrorData, verbose: boolean): string {
function xhrToErrorMessage(xhr: IConnectionErrorData, verbose: boolean): string {
let ce = new ConnectionError(xhr);
if (verbose) {
return ce.verboseMessage;
@@ -242,18 +242,28 @@ function _xhrToErrorMessage(xhr: IConnectionErrorData, verbose: boolean): string
}
}
function _exceptionToErrorMessage(exception: any, verbose: boolean): string {
if (verbose && exception.message && (exception.stack || exception.stacktrace)) {
return nls.localize('stackTrace.format', "{0}: {1}", exception.message, exception.stack || exception.stacktrace);
}
function exceptionToErrorMessage(exception: any, verbose: boolean): string {
if (exception.message) {
return exception.message;
if (verbose && (exception.stack || exception.stacktrace)) {
return nls.localize('stackTrace.format', "{0}: {1}", detectSystemErrorMessage(exception), exception.stack || exception.stacktrace);
}
return detectSystemErrorMessage(exception);
}
return nls.localize('error.defaultMessage', "An unknown error occurred. Please consult the log for more details.");
}
function detectSystemErrorMessage(exception: any): string {
// See https://nodejs.org/api/errors.html#errors_class_system_error
if (typeof exception.code === 'string' && typeof exception.errno === 'number' && typeof exception.syscall === 'string') {
return nls.localize('nodeExceptionMessage', "A system error occured ({0})", exception.message);
}
return exception.message;
}
/**
* Tries to generate a human readable error message out of the error. If the verbose parameter
* is set to true, the error message will include stacktrace details if provided.
@@ -280,7 +290,7 @@ export function toErrorMessage(error: any = null, verbose: boolean = false): str
}
if (!types.isUndefinedOrNull(error.status)) {
return _xhrToErrorMessage(error, verbose);
return xhrToErrorMessage(error, verbose);
}
if (error.detail) {
@@ -288,33 +298,33 @@ export function toErrorMessage(error: any = null, verbose: boolean = false): str
if (detail.error) {
if (detail.error && !types.isUndefinedOrNull(detail.error.status)) {
return _xhrToErrorMessage(detail.error, verbose);
return xhrToErrorMessage(detail.error, verbose);
}
if (types.isArray(detail.error)) {
for (let i = 0; i < detail.error.length; i++) {
if (detail.error[i] && !types.isUndefinedOrNull(detail.error[i].status)) {
return _xhrToErrorMessage(detail.error[i], verbose);
return xhrToErrorMessage(detail.error[i], verbose);
}
}
}
else {
return _exceptionToErrorMessage(detail.error, verbose);
return exceptionToErrorMessage(detail.error, verbose);
}
}
if (detail.exception) {
if (!types.isUndefinedOrNull(detail.exception.status)) {
return _xhrToErrorMessage(detail.exception, verbose);
return xhrToErrorMessage(detail.exception, verbose);
}
return _exceptionToErrorMessage(detail.exception, verbose);
return exceptionToErrorMessage(detail.exception, verbose);
}
}
if (error.stack) {
return _exceptionToErrorMessage(error, verbose);
return exceptionToErrorMessage(error, verbose);
}
if (error.message) {
@@ -324,7 +334,7 @@ export function toErrorMessage(error: any = null, verbose: boolean = false): str
return nls.localize('error.defaultMessage', "An unknown error occurred. Please consult the log for more details.");
}
let canceledName = 'Canceled';
const canceledName = 'Canceled';
/**
* Checks if the given error is a promise in canceled state
+1 -1
View File
@@ -198,7 +198,7 @@ export function createScanner(text:string, ignoreTrivia:boolean = false):JSONSca
function scanNext():SyntaxKind {
value = '';
scanError = ScanError.None,
scanError = ScanError.None;
tokenOffset = pos;
+25 -24
View File
@@ -7,6 +7,7 @@
import paths = require('vs/base/common/paths');
import types = require('vs/base/common/types');
import strings = require('vs/base/common/strings');
import {match} from 'vs/base/common/glob';
export let MIME_TEXT = 'text/plain';
export let MIME_BINARY = 'application/octet-stream';
@@ -71,12 +72,12 @@ export function generateKnownFilenames(onlyExtensions: boolean = true): any {
/**
* Allow to register extra text mimes dynamically based on filename
*/
export function registerTextMimeByFilename(nameOrExtensionOrPrefix: string, mime: string): void {
if (nameOrExtensionOrPrefix && mime) {
if (registeredTextMimesByFilename[nameOrExtensionOrPrefix] && registeredTextMimesByFilename[nameOrExtensionOrPrefix] !== mime) {
console.warn('Overwriting filename <<' + nameOrExtensionOrPrefix + '>> to now point to mime <<' + mime + '>>');
export function registerTextMimeByFilename(nameOrPatternOrPrefix: string, mime: string): void {
if (nameOrPatternOrPrefix && mime) {
if (registeredTextMimesByFilename[nameOrPatternOrPrefix] && registeredTextMimesByFilename[nameOrPatternOrPrefix] !== mime) {
console.warn('Overwriting filename <<' + nameOrPatternOrPrefix + '>> to now point to mime <<' + mime + '>>');
}
registeredTextMimesByFilename[nameOrExtensionOrPrefix] = mime;
registeredTextMimesByFilename[nameOrPatternOrPrefix] = mime;
}
}
@@ -142,29 +143,29 @@ export function guessMimeTypes(path: string, firstLine?: string): string[] {
let exactNameMatch: string;
let extensionMatch: string;
let prefixMatch: string;
let patternNameMatch: string;
// Check for dynamically registered match based on filename and extension
for (let nameOrExtensionOrPrefix in registeredTextMimesByFilename) {
let nameOrExtensionOrPrefixLower: string = nameOrExtensionOrPrefix.toLowerCase();
for (let nameOrPatternOrPrefix in registeredTextMimesByFilename) {
let nameOrPatternOrExtensionLower: string = nameOrPatternOrPrefix.toLowerCase();
// First exact name match
if (!exactNameMatch && filename === nameOrExtensionOrPrefixLower) {
exactNameMatch = nameOrExtensionOrPrefix;
if (!exactNameMatch && filename === nameOrPatternOrExtensionLower) {
exactNameMatch = nameOrPatternOrPrefix;
break; // take it!
}
// Longest extension match
if (nameOrExtensionOrPrefix[0] === '.' && strings.endsWith(filename, nameOrExtensionOrPrefixLower)) {
if (!extensionMatch || nameOrExtensionOrPrefixLower.length > extensionMatch.length) {
extensionMatch = nameOrExtensionOrPrefix;
// Longest pattern match
if (match(nameOrPatternOrExtensionLower, filename)) {
if (!patternNameMatch || nameOrPatternOrExtensionLower.length > patternNameMatch.length) {
patternNameMatch = nameOrPatternOrPrefix;
}
}
// Longest prefix match
if (nameOrExtensionOrPrefixLower.slice(-1) === '*' && strings.startsWith(filename, nameOrExtensionOrPrefixLower.slice(0, -1))) {
if (!prefixMatch || nameOrExtensionOrPrefixLower.length > prefixMatch.length) {
prefixMatch = nameOrExtensionOrPrefix;
// Longest extension match
if (nameOrPatternOrPrefix[0] === '.' && strings.endsWith(filename, nameOrPatternOrExtensionLower)) {
if (!extensionMatch || nameOrPatternOrExtensionLower.length > extensionMatch.length) {
extensionMatch = nameOrPatternOrPrefix;
}
}
}
@@ -174,14 +175,14 @@ export function guessMimeTypes(path: string, firstLine?: string): string[] {
return [registeredTextMimesByFilename[exactNameMatch], MIME_TEXT];
}
// 3.) Match on extension comes next
if (extensionMatch) {
return [registeredTextMimesByFilename[extensionMatch], MIME_TEXT];
// 3.) Match on pattern
if (patternNameMatch) {
return [registeredTextMimesByFilename[patternNameMatch], MIME_TEXT];
}
// 4.) Match on prefix
if (prefixMatch) {
return [registeredTextMimesByFilename[prefixMatch], MIME_TEXT];
// 4.) Match on extension comes next
if (extensionMatch) {
return [registeredTextMimesByFilename[extensionMatch], MIME_TEXT];
}
return [MIME_UNKNOWN];
+1 -1
View File
@@ -133,7 +133,7 @@ export class Client implements IDisposable {
this.child = cp.fork(this.modulePath, args, forkOpts);
this._client = new IPCClient({
send: r => this.child.connected && this.child.send(r),
send: r => this.child && this.child.connected && this.child.send(r),
onMessage: cb => {
this.child.on('message', (msg) => {
@@ -182,7 +182,7 @@ export class QuickOpenEntry {
return compareAnything(nameA, nameB, lookFor);
}
public static compareByScore(elementA: QuickOpenEntry, elementB: QuickOpenEntry, lookFor: string, scorerCache?: { [key: string]: number }): number {
public static compareByScore(elementA: QuickOpenEntry, elementB: QuickOpenEntry, lookFor: string, lookForNormalizedLower: string, scorerCache?: { [key: string]: number }): number {
const labelA = elementA.getLabel();
const labelB = elementB.getLabel();
@@ -229,7 +229,12 @@ export class QuickOpenEntry {
return resourceA.fsPath.length < resourceB.fsPath.length ? -1 : 1;
}
return QuickOpenEntry.compare(elementA, elementB, lookFor);
// Finally compare by label or resource path
if (labelA === labelB && resourceA && resourceB) {
return compareAnything(resourceA.fsPath, resourceB.fsPath, lookForNormalizedLower);
}
return compareAnything(labelA, labelB, lookForNormalizedLower);
}
/**
@@ -130,8 +130,14 @@ export class QuickOpenWidget implements IModelProvider {
DOM.addDisposableListener(this.inputBox.inputElement, DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
let keyboardEvent: StandardKeyboardEvent = new StandardKeyboardEvent(e);
// Do not handle Tab: It is used to navigate between elements without mouse
if (keyboardEvent.keyCode === KeyCode.Tab) {
return;
}
// Pass tree navigation keys to the tree but leave focus in input field
if (keyboardEvent.keyCode === KeyCode.Tab || keyboardEvent.keyCode === KeyCode.DownArrow || keyboardEvent.keyCode === KeyCode.UpArrow || keyboardEvent.keyCode === KeyCode.PageDown || keyboardEvent.keyCode === KeyCode.PageUp) {
else if (keyboardEvent.keyCode === KeyCode.Tab || keyboardEvent.keyCode === KeyCode.DownArrow || keyboardEvent.keyCode === KeyCode.UpArrow || keyboardEvent.keyCode === KeyCode.PageDown || keyboardEvent.keyCode === KeyCode.PageUp) {
DOM.EventHelper.stop(e, true);
this.navigateInTree(keyboardEvent.keyCode, keyboardEvent.shiftKey);
@@ -825,7 +831,6 @@ export class QuickOpenWidget implements IModelProvider {
const relatedTarget = (<any>e).relatedTarget;
if (!this.quickNavigateConfiguration && DOM.isAncestor(relatedTarget, this.builder.getHTMLElement())) {
this.inputBox.focus(); // user clicked somewhere into quick open, so we restore focus to input
return;
}
@@ -28,7 +28,6 @@
width: 588px;
border: none;
margin: 6px;
outline: 0;
}
.quick-open-widget .quick-open-input .monaco-inputbox {
@@ -24,6 +24,7 @@
}
.monaco-tree .monaco-tree-row:hover:not(.highlighted) > .content.actions > .primary-action-bar,
.monaco-tree.focused .monaco-tree-row.focused > .content.actions > .primary-action-bar,
.monaco-tree .monaco-tree-row > .content.actions.more > .primary-action-bar {
display: inherit;
}
@@ -46,7 +47,6 @@
.monaco-tree.focused .monaco-tree-row.focused:not(.highlighted) > .content.actions > .primary-action-bar { background-color: #DCEBFC; }
.monaco-tree.focused .monaco-tree-row.selected:not(.highlighted) > .content.actions > .primary-action-bar { background-color: #4FA7FF; color: white; }
.monaco-tree.focused .monaco-tree-row.focused.selected:not(.highlighted) > .content.actions > .primary-action-bar { background-color: #3399FF; color: white; }
.monaco-tree .monaco-tree-row.focused:not(.highlighted) > .content.actions > .primary-action-bar { background-color: #eaeaea; }
.monaco-tree .monaco-tree-row.selected:not(.highlighted) > .content.actions > .primary-action-bar { background-color: #CCCEDB; }
.monaco-tree .monaco-tree-row:hover:not(.highlighted):not(.selected):not(.focused) > .content.actions > .primary-action-bar { background-color: #F0F0F0; }
.monaco-tree .monaco-tree-row.drop-target > .content.actions > .primary-action-bar { background-color: #DDECFF; }
@@ -56,7 +56,6 @@
.vs-dark .monaco-tree.focused .monaco-tree-row.focused:not(.highlighted) > .content.actions > .primary-action-bar { background-color: #073655; }
.vs-dark .monaco-tree.focused .monaco-tree-row.selected:not(.highlighted) > .content.actions > .primary-action-bar { background-color: #0E639C; color: white; }
.vs-dark .monaco-tree.focused .monaco-tree-row.focused.selected:not(.highlighted) > .content.actions > .primary-action-bar { background-color: #094771; color: white; }
.vs-dark .monaco-tree .monaco-tree-row.focused:not(.highlighted) > .content.actions > .primary-action-bar { background-color: #2f3334; }
.vs-dark .monaco-tree .monaco-tree-row.selected:not(.highlighted) > .content.actions > .primary-action-bar { background-color: #3F3F46; }
.vs-dark .monaco-tree .monaco-tree-row:hover:not(.highlighted):not(.selected):not(.focused) > .content.actions > .primary-action-bar { background-color: #2A2D2E; }
.vs-dark .monaco-tree .monaco-tree-row.drop-target > .content.actions > .primary-action-bar { background-color: #383B3D; }
@@ -65,7 +64,6 @@
/* High Contrast Theming */
.hc-black .monaco-tree.focused .monaco-tree-row.focused:not(.highlighted) > .content.actions > .primary-action-bar,
.hc-black .monaco-tree.focused .monaco-tree-row.selected:not(.highlighted) > .content.actions > .primary-action-bar,
.hc-black .monaco-tree .monaco-tree-row.focused:not(.highlighted) > .content.actions > .primary-action-bar,
.hc-black .monaco-tree .monaco-tree-row.selected:not(.highlighted) > .content.actions > .primary-action-bar,
.hc-black .monaco-tree .monaco-tree-row:hover:not(.highlighted):not(.selected):not(.focused) > .content.actions > .primary-action-bar,
.hc-black .monaco-tree .monaco-tree-row.drop-target > .content.actions > .primary-action-bar,
+2 -16
View File
@@ -15,10 +15,6 @@
position: relative;
}
.monaco-tree:focus {
outline: 0;
}
.monaco-tree > .monaco-scrollable-element {
height: 100%;
}
@@ -32,6 +28,7 @@
.monaco-tree .monaco-tree-rows {
position: absolute;
width: 100%;
height: 100%;
}
.monaco-tree .monaco-tree-rows > .monaco-tree-row {
@@ -151,14 +148,6 @@
opacity: 0.3;
}
/* Fake row */
.monaco-tree .monaco-tree-rows > .monaco-tree-row.fake {
position: absolute;
visibility: hidden;
top: -1000px;
left: -1000px;
z-index: -100;
}
/* Bare row */
.monaco-tree.bare .monaco-tree-wrapper.drop-target,
@@ -171,7 +160,6 @@
.monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.focused:not(.highlighted) { background-color: #DCEBFC; }
.monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.selected:not(.highlighted) { background-color: #4FA7FF; color: white; }
.monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.focused.selected:not(.highlighted) { background-color: #3399FF; color: white; }
.monaco-tree .monaco-tree-rows > .monaco-tree-row.focused:not(.highlighted) { background-color: #eaeaea; }
.monaco-tree .monaco-tree-rows > .monaco-tree-row.selected:not(.highlighted) { background-color: #CCCEDB; }
.monaco-tree .monaco-tree-rows > .monaco-tree-row:hover:not(.highlighted):not(.selected):not(.focused) { background-color: #F0F0F0; }
.monaco-tree .monaco-tree-wrapper.drop-target,
@@ -194,7 +182,6 @@
.vs-dark .monaco-tree.focused .monaco-tree-row.focused:not(.highlighted) { background-color: #073655; }
.vs-dark .monaco-tree.focused .monaco-tree-row.selected:not(.highlighted) { background-color: #0E639C; color: white; }
.vs-dark .monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.focused.selected:not(.highlighted) { background-color: #094771; color: white; }
.vs-dark .monaco-tree .monaco-tree-row.focused:not(.highlighted) { background-color: #2f3334; }
.vs-dark .monaco-tree .monaco-tree-row.selected:not(.highlighted) { background-color: #3F3F46; }
.vs-dark .monaco-tree .monaco-tree-row:hover:not(.highlighted):not(.selected):not(.focused) { background-color: #2A2D2E; }
.vs-dark .monaco-tree-wrapper.drop-target,
@@ -214,7 +201,6 @@
.hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row { background: none !important; }
.hc-black .monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.focused:not(.highlighted) { border: 1px dotted #DF740C; }
.hc-black .monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.selected:not(.highlighted) { border: 1px solid #DF740C; }
.hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row.focused:not(.highlighted) { border: 1px dotted #DF740C; }
.hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row.selected:not(.highlighted) { border: 1px solid #DF740C; }
.hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row:hover:not(.highlighted):not(.selected):not(.focused) { border: 1px dashed #DF740C; }
.hc-black .monaco-tree .monaco-tree-wrapper.drop-target,
@@ -235,4 +221,4 @@
border: none;
content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTExIDEwLjA3aC01LjY1Nmw1LjY1Ni01LjY1NnY1LjY1NnoiLz48L3N2Zz4=");
top: 3px;
}
}
-6
View File
@@ -309,12 +309,6 @@ export interface ITree extends Events.IEventEmitter {
*/
hasTrait(trait: string, element: any): boolean;
/**
* Allows to render an invisible fake row, for measurement purposes.
* Returns whatever fn(...) returns.
*/
withFakeRow(fn:(container:HTMLElement)=>any):any;
/**
* Returns a navigator which allows to discover the visible and
* expanded elements in the tree.
@@ -307,10 +307,6 @@ export class Tree extends Events.EventEmitter implements _.ITree {
return this.model.hasTrait(trait, element);
}
public withFakeRow(fn:(container:HTMLElement)=>any):any {
return this.view.withFakeRow(fn);
}
getNavigator(): INavigator<any> {
return new MappedNavigator(this.model.getNavigator(), i => i && i.getElement());
}
+7 -16
View File
@@ -390,9 +390,6 @@ export class TreeView extends HeightMap implements IScrollable {
private lastPointerType:string;
private lastClickTimeStamp: number = 0;
private fakeRow: HTMLElement;
private fakeContent: HTMLElement;
private _viewHeight: number;
private renderTop: number;
private renderHeight: number;
@@ -480,15 +477,6 @@ export class TreeView extends HeightMap implements IScrollable {
this.rowsContainer = document.createElement('div');
this.rowsContainer.className = 'monaco-tree-rows';
this.fakeRow = document.createElement('div');
this.fakeRow.className = 'monaco-tree-row fake';
this.fakeContent = document.createElement('div');
this.fakeContent.className = 'content';
this.fakeRow.appendChild(this.fakeContent);
this.rowsContainer.appendChild(this.fakeRow);
var focusTracker = DOM.trackFocus(this.domNode);
focusTracker.addFocusListener((e: FocusEvent) => this.onFocus(e));
focusTracker.addBlurListener((e: FocusEvent) => this.onBlur(e));
@@ -705,6 +693,9 @@ export class TreeView extends HeightMap implements IScrollable {
case 'item:removeTrait':
this.onItemRemoveTrait(data);
break;
case 'focus':
this.onModelFocusChange();
break;
}
}
@@ -731,10 +722,6 @@ export class TreeView extends HeightMap implements IScrollable {
this.scrollableElement.onElementInternalDimensions();
}
public withFakeRow(fn:(container:HTMLElement)=>any):any {
return fn(this.fakeContent);
}
public focusNextPage(eventPayload?:any): void {
var lastPageIndex = this.indexAt(this.scrollTop + this.viewHeight);
lastPageIndex = lastPageIndex === 0 ? 0 : lastPageIndex - 1;
@@ -1065,6 +1052,10 @@ export class TreeView extends HeightMap implements IScrollable {
}
}
private onModelFocusChange(): void {
DOM.toggleClass(this.domNode, 'no-item-focus', !this.model || !this.model.getFocus());
}
// HeightMap "events"
public onInsertItem(item: ViewItem): void {
@@ -240,23 +240,23 @@ export class KeyboardHandler extends ViewEventHandler implements Lifecycle.IDisp
let visibleRange = this.viewHelper.visibleRangeForPositionRelativeToEditor(lineNumber, column);
if (visibleRange) {
this.textArea.actual.style.top = visibleRange.top + 'px';
this.textArea.actual.style.left = this.contentLeft + visibleRange.left - this.scrollLeft + 'px';
DomUtils.StyleMutator.setTop(this.textArea.actual, visibleRange.top);
DomUtils.StyleMutator.setLeft(this.textArea.actual, this.contentLeft + visibleRange.left - this.scrollLeft);
}
if (Browser.isIE11orEarlier) {
this.textArea.actual.style.width = this.contentWidth + 'px';
DomUtils.StyleMutator.setWidth(this.textArea.actual, this.contentWidth);
}
// Show the textarea
this.textArea.actual.style.height = this.context.configuration.editor.lineHeight + 'px';
DomUtils.StyleMutator.setHeight(this.textArea.actual, this.context.configuration.editor.lineHeight);
DomUtils.addClass(this.viewHelper.viewDomNode, 'ime-input');
}));
this._toDispose.push(this.textAreaHandler.onCompositionEnd((e) => {
this.textArea.actual.style.height = '';
this.textArea.actual.style.width = '';
this.textArea.actual.style.left = '0px';
this.textArea.actual.style.top = '0px';
DomUtils.StyleMutator.setLeft(this.textArea.actual, 0);
DomUtils.StyleMutator.setTop(this.textArea.actual, 0);
DomUtils.removeClass(this.viewHelper.viewDomNode, 'ime-input');
}));
@@ -271,6 +271,17 @@ export class KeyboardHandler extends ViewEventHandler implements Lifecycle.IDisp
this._toDispose = Lifecycle.disposeAll(this._toDispose);
}
public focusTextArea(): void {
this.textAreaHandler.writePlaceholderAndSelectTextAreaSync();
}
public onConfigurationChanged(e: EditorCommon.IConfigurationChangedEvent): boolean {
// Give textarea same font size & line height as editor, for the IME case (when the textarea is visible)
DomUtils.StyleMutator.setFontSize(this.textArea.actual, this.context.configuration.editor.fontSize);
DomUtils.StyleMutator.setLineHeight(this.textArea.actual, this.context.configuration.editor.lineHeight);
return false;
}
public onScrollChanged(e:EditorCommon.IScrollEvent): boolean {
this.scrollLeft = e.scrollLeft;
return false;
+1 -9
View File
@@ -431,9 +431,6 @@ export class View extends ViewEventHandler implements EditorBrowser.IView, Lifec
if (e.stylingInfo) {
Configuration.applyEditorStyling(this.domNode, this.context.configuration.editor.stylingInfo);
}
// Give textarea same font size & line height as editor, for the IME case (when the textarea is visible)
DomUtils.StyleMutator.setFontSize(this.textArea, this.context.configuration.editor.fontSize);
DomUtils.StyleMutator.setLineHeight(this.textArea, this.context.configuration.editor.lineHeight);
return false;
}
public onScrollChanged(e:EditorCommon.IScrollEvent): boolean {
@@ -619,12 +616,7 @@ export class View extends ViewEventHandler implements EditorBrowser.IView, Lifec
if (this._isDisposed) {
throw new Error('ViewImpl.focus: View is disposed');
}
// Chrome does not trigger the focus event at all if focus is in url bar and clicking into the editor
// Calling .focus() and then .select() seems to be a good workaround for Chrome in this case
var state = DomUtils.saveParentsScrollTop(this.textArea);
this.textArea.focus();
DomUtils.selectTextInInputElement(this.textArea);
DomUtils.restoreParentsScrollTop(this.textArea, state);
this.keyboardHandler.focusTextArea();
// IE does not trigger the focus event immediately, so we must help it a little bit
this._setHasFocus(true);
@@ -10,7 +10,7 @@ import {Disposable} from 'vs/base/common/lifecycle';
import {Range} from 'vs/editor/common/core/range';
import {Position} from 'vs/editor/common/core/position';
import {CommonKeybindings} from 'vs/base/common/keyCodes';
import {IKeyboardEventWrapper, ITextAreaWrapper, IClipboardEvent, ISimpleModel, TextAreaState} from 'vs/editor/common/controller/textAreaState';
import {IKeyboardEventWrapper, ITextAreaWrapper, IClipboardEvent, ISimpleModel, TextAreaState, IENarratorTextAreaState, NVDATextAreaState} from 'vs/editor/common/controller/textAreaState';
import Event, {Emitter} from 'vs/base/common/event';
enum ReadFromTextArea {
@@ -79,7 +79,6 @@ export class TextAreaHandler extends Disposable {
private hasFocus:boolean;
private asyncReadFromTextArea: RunOnceScheduler;
private asyncSetSelectionToTextArea: RunOnceScheduler;
private asyncTriggerCut: RunOnceScheduler;
private lastKeyPressTime:number;
@@ -104,12 +103,12 @@ export class TextAreaHandler extends Disposable {
this.cursorPosition = new Position(1, 1);
this.asyncReadFromTextArea = new RunOnceScheduler(null, 0);
this.asyncSetSelectionToTextArea = new RunOnceScheduler(() => this._writePlaceholderAndSelectTextArea(), 0);
this.asyncTriggerCut = new RunOnceScheduler(() => this._onCut.fire(), 0);
this.lastCopiedValue = null;
this.lastCopiedValueIsFromEmptySelection = false;
this.textAreaState = TextAreaState.EMPTY;
this.textAreaState = IENarratorTextAreaState.EMPTY;
// this.textAreaState = NVDATextAreaState.EMPTY;
this.hasFocus = false;
@@ -136,7 +135,7 @@ export class TextAreaHandler extends Disposable {
let shouldEmptyTextArea = (timeSinceLastCompositionEnd >= 100);
if (shouldEmptyTextArea) {
if (!this.Browser.isIE11orEarlier) {
this.setTextAreaState(TextAreaState.EMPTY);
this.setTextAreaState('compositionstart', this.textAreaState.toEmpty());
}
}
@@ -254,8 +253,6 @@ export class TextAreaHandler extends Disposable {
text: replacedChar,
replacePreviousCharacter: true
});
this.asyncSetSelectionToTextArea.schedule();
}));
}
@@ -276,18 +273,17 @@ export class TextAreaHandler extends Disposable {
} else {
if (this.textArea.selectionStart !== this.textArea.selectionEnd) {
// Clean up the textarea, to get a clean paste
this.setTextAreaState(TextAreaState.EMPTY);
this.setTextAreaState('paste', this.textAreaState.toEmpty());
}
this._scheduleReadFromTextArea(ReadFromTextArea.Paste);
}
}));
this._writePlaceholderAndSelectTextArea();
this._writePlaceholderAndSelectTextArea('ctor');
}
public dispose(): void {
this.asyncReadFromTextArea.dispose();
this.asyncSetSelectionToTextArea.dispose();
this.asyncTriggerCut.dispose();
super.dispose();
}
@@ -295,16 +291,20 @@ export class TextAreaHandler extends Disposable {
// --- begin event handlers
public setHasFocus(isFocused:boolean): void {
if (this.hasFocus === isFocused) {
// no change
return;
}
this.hasFocus = isFocused;
if (this.hasFocus) {
this.asyncSetSelectionToTextArea.schedule();
this._writePlaceholderAndSelectTextArea('focusgain');
}
}
public setCursorSelections(primary: IEditorRange, secondary: IEditorRange[]): void {
this.selection = primary;
this.selections = [primary].concat(secondary);
this.asyncSetSelectionToTextArea.schedule();
this._writePlaceholderAndSelectTextArea('selection changed');
}
public setCursorPosition(primary: IEditorPosition): void {
@@ -313,13 +313,13 @@ export class TextAreaHandler extends Disposable {
// --- end event handlers
private setTextAreaState(textAreaState:TextAreaState): void {
private setTextAreaState(reason:string, textAreaState:TextAreaState): void {
if (!this.hasFocus) {
textAreaState = textAreaState.resetSelection();
}
this.lastValueWrittenToTheTextArea = textAreaState.getValue();
textAreaState.applyToTextArea(this.textArea, this.hasFocus);
textAreaState.applyToTextArea(reason, this.textArea, this.hasFocus);
this.textAreaState = textAreaState;
}
@@ -346,9 +346,7 @@ export class TextAreaHandler extends Disposable {
setTimeout(() => {
// cancel reading if previous keydown was canceled, but a keypress/input were still generated
if (e.isDefaultPrevented()) {
// this._scheduleReadFromTextArea
this.asyncReadFromTextArea.cancel();
this.asyncSetSelectionToTextArea.schedule();
}
}, 0);
}
@@ -371,7 +369,6 @@ export class TextAreaHandler extends Disposable {
// ------------- Operations that are always executed asynchronously
private _scheduleReadFromTextArea(command:ReadFromTextArea): void {
this.asyncSetSelectionToTextArea.cancel();
this.asyncReadFromTextArea.setRunner(() => this._readFromTextArea(command));
this.asyncReadFromTextArea.schedule();
}
@@ -394,8 +391,6 @@ export class TextAreaHandler extends Disposable {
} else {
this.executePaste(txt);
}
this.asyncSetSelectionToTextArea.schedule();
}
private executePaste(txt:string): void {
@@ -413,14 +408,18 @@ export class TextAreaHandler extends Disposable {
});
}
private _writePlaceholderAndSelectTextArea(): void {
public writePlaceholderAndSelectTextAreaSync(): void {
this._writePlaceholderAndSelectTextArea('focusTextArea');
}
private _writePlaceholderAndSelectTextArea(reason:string): void {
if (!this.textareaIsShownAtCursor) {
// Do not write to the textarea if it is visible.
if (this.Browser.isIPad) {
// Do not place anything in the textarea for the iPad
this.setTextAreaState(TextAreaState.EMPTY);
this.setTextAreaState(reason, this.textAreaState.toEmpty());
} else {
this.setTextAreaState(this.textAreaState.fromEditorSelection(this.model, this.selection));
this.setTextAreaState(reason, this.textAreaState.fromEditorSelection(this.model, this.selection));
}
}
}
@@ -432,7 +431,7 @@ export class TextAreaHandler extends Disposable {
if (e.canUseTextData()) {
e.setTextData(whatToCopy);
} else {
this.setTextAreaState(this.textAreaState.fromText(whatToCopy));
this.setTextAreaState('copy or cut', this.textAreaState.fromText(whatToCopy));
}
if (this.Browser.enableEmptySelectionClipboard) {
+168 -84
View File
@@ -49,104 +49,37 @@ export interface ISimpleModel {
convertViewPositionToModelPosition(viewLineNumber:number, viewColumn:number): EditorCommon.IEditorPosition;
}
export class TextAreaState {
export abstract class TextAreaState {
public static EMPTY = new TextAreaState(null, '', 0, 0, false, 0);
protected previousState:TextAreaState;
protected value:string;
protected selectionStart:number;
protected selectionEnd:number;
protected isInOverwriteMode:boolean;
private previousState:TextAreaState;
private value:string;
private selectionStart:number;
private selectionEnd:number;
private isInOverwriteMode:boolean;
private selectionToken:number;
constructor(previousState:TextAreaState, value:string, selectionStart:number, selectionEnd:number, isInOverwriteMode:boolean, selectionToken:number) {
constructor(previousState:TextAreaState, value:string, selectionStart:number, selectionEnd:number, isInOverwriteMode:boolean) {
this.previousState = previousState ? previousState.shallowClone() : null;
this.value = value;
this.selectionStart = selectionStart;
this.selectionEnd = selectionEnd;
this.isInOverwriteMode = isInOverwriteMode;
this.selectionToken = selectionToken;
}
private shallowClone(): TextAreaState {
return new TextAreaState(null, this.value, this.selectionStart, this.selectionEnd, this.isInOverwriteMode, this.selectionToken);
}
protected abstract shallowClone(): TextAreaState;
public toString(): string {
return '[ <' + this.value + '>, selectionStart: ' + this.selectionStart + ', selectionEnd: ' + this.selectionEnd + ', isInOverwriteMode: ' + this.isInOverwriteMode + ', selectionToken: ' + this.selectionToken + ']';
}
public abstract toEmpty(): TextAreaState;
public equals(other:TextAreaState): boolean {
return (
this.value === other.value
&& this.selectionStart === other.selectionStart
&& this.selectionEnd === other.selectionEnd
&& this.isInOverwriteMode === other.isInOverwriteMode
&& this.selectionToken === other.selectionToken
);
}
public abstract toString(): string;
public fromTextArea(textArea:ITextAreaWrapper): TextAreaState {
return new TextAreaState(this, textArea.value, textArea.selectionStart, textArea.selectionEnd, textArea.isInOverwriteMode(), this.selectionToken);
}
public abstract equals(other:TextAreaState): boolean;
public fromEditorSelection(model:ISimpleModel, selection:EditorCommon.IEditorRange): TextAreaState {
let LIMIT_CHARS = 100;
let PADDING_LINES_COUNT = 0;
public abstract fromTextArea(textArea:ITextAreaWrapper): TextAreaState;
let selectionStartLineNumber = selection.startLineNumber,
selectionStartColumn = selection.startColumn,
selectionEndLineNumber = selection.endLineNumber,
selectionEndColumn = selection.endColumn,
selectionEndLineNumberMaxColumn = model.getLineMaxColumn(selectionEndLineNumber);
public abstract fromEditorSelection(model:ISimpleModel, selection:EditorCommon.IEditorRange);
// If the selection is empty and we have switched line numbers, expand selection to full line (helps Narrator trigger a full line read)
if (selection.isEmpty() && this.selectionToken !== selectionStartLineNumber) {
selectionStartColumn = 1;
selectionEndColumn = selectionEndLineNumberMaxColumn;
}
public abstract fromText(text:string): TextAreaState;
// `pretext` contains the text before the selection
let pretext = '';
let startLineNumber = Math.max(1, selectionStartLineNumber - PADDING_LINES_COUNT);
if (startLineNumber < selectionStartLineNumber) {
pretext = model.getValueInRange(new Range(startLineNumber, 1, selectionStartLineNumber, 1), EditorCommon.EndOfLinePreference.LF);
}
pretext += model.getValueInRange(new Range(selectionStartLineNumber, 1, selectionStartLineNumber, selectionStartColumn), EditorCommon.EndOfLinePreference.LF);
if (pretext.length > LIMIT_CHARS) {
pretext = pretext.substring(pretext.length - LIMIT_CHARS, pretext.length);
}
// `posttext` contains the text after the selection
let posttext = '';
let endLineNumber = Math.min(selectionEndLineNumber + PADDING_LINES_COUNT, model.getLineCount());
posttext += model.getValueInRange(new Range(selectionEndLineNumber, selectionEndColumn, selectionEndLineNumber, selectionEndLineNumberMaxColumn), EditorCommon.EndOfLinePreference.LF);
if (endLineNumber > selectionEndLineNumber) {
posttext = '\n' + model.getValueInRange(new Range(selectionEndLineNumber + 1, 1, endLineNumber, model.getLineMaxColumn(endLineNumber)), EditorCommon.EndOfLinePreference.LF);
}
if (posttext.length > LIMIT_CHARS) {
posttext = posttext.substring(0, LIMIT_CHARS);
}
// `text` contains the text of the selection
let text = model.getValueInRange(new Range(selectionStartLineNumber, selectionStartColumn, selectionEndLineNumber, selectionEndColumn), EditorCommon.EndOfLinePreference.LF);
if (text.length > 2 * LIMIT_CHARS) {
text = text.substring(0, LIMIT_CHARS) + String.fromCharCode(8230) + text.substring(text.length - LIMIT_CHARS, text.length);
}
return new TextAreaState(this, pretext + text + posttext, pretext.length, pretext.length + text.length, false, selectionStartLineNumber);
}
public fromText(text:string): TextAreaState {
return new TextAreaState(this, text, 0, text.length, false, 0)
}
public resetSelection(): TextAreaState {
return new TextAreaState(this.previousState, this.value, this.value.length, this.value.length, this.isInOverwriteMode, this.selectionToken);
}
public abstract resetSelection(): TextAreaState;
public getSelectionStart(): number {
return this.selectionStart;
@@ -156,8 +89,8 @@ export class TextAreaState {
return this.value;
}
public applyToTextArea(textArea:ITextAreaWrapper, select:boolean): void {
// console.log('applyToTextArea: ' + this.toString());
public applyToTextArea(reason:string, textArea:ITextAreaWrapper, select:boolean): void {
// console.log(Date.now() + ': applyToTextArea ' + reason + ': ' + this.toString());
if (textArea.value !== this.value) {
textArea.value = this.value;
}
@@ -216,3 +149,154 @@ export class TextAreaState {
return this.value.charAt(prefixLength);
}
}
export class IENarratorTextAreaState extends TextAreaState {
public static EMPTY = new IENarratorTextAreaState(null, '', 0, 0, false, 0);
private selectionToken:number;
constructor(previousState:TextAreaState, value:string, selectionStart:number, selectionEnd:number, isInOverwriteMode:boolean, selectionToken:number) {
super(previousState, value, selectionStart, selectionEnd, isInOverwriteMode);
this.selectionToken = selectionToken;
}
protected shallowClone(): TextAreaState {
return new IENarratorTextAreaState(null, this.value, this.selectionStart, this.selectionEnd, this.isInOverwriteMode, this.selectionToken);
}
public toEmpty(): TextAreaState {
return IENarratorTextAreaState.EMPTY;
}
public toString(): string {
return '[ <' + this.value + '>, selectionStart: ' + this.selectionStart + ', selectionEnd: ' + this.selectionEnd + ', isInOverwriteMode: ' + this.isInOverwriteMode + ', selectionToken: ' + this.selectionToken + ']';
}
public equals(other:TextAreaState): boolean {
if (other instanceof IENarratorTextAreaState) {
return (
this.value === other.value
&& this.selectionStart === other.selectionStart
&& this.selectionEnd === other.selectionEnd
&& this.isInOverwriteMode === other.isInOverwriteMode
&& this.selectionToken === other.selectionToken
);
}
return false;
}
public fromTextArea(textArea:ITextAreaWrapper): TextAreaState {
return new IENarratorTextAreaState(this, textArea.value, textArea.selectionStart, textArea.selectionEnd, textArea.isInOverwriteMode(), this.selectionToken);
}
public fromEditorSelection(model:ISimpleModel, selection:EditorCommon.IEditorRange): TextAreaState {
let LIMIT_CHARS = 100;
let PADDING_LINES_COUNT = 0;
let selectionStartLineNumber = selection.startLineNumber,
selectionStartColumn = selection.startColumn,
selectionEndLineNumber = selection.endLineNumber,
selectionEndColumn = selection.endColumn,
selectionEndLineNumberMaxColumn = model.getLineMaxColumn(selectionEndLineNumber);
// If the selection is empty and we have switched line numbers, expand selection to full line (helps Narrator trigger a full line read)
if (selection.isEmpty() && this.selectionToken !== selectionStartLineNumber) {
selectionStartColumn = 1;
selectionEndColumn = selectionEndLineNumberMaxColumn;
}
// `pretext` contains the text before the selection
let pretext = '';
let startLineNumber = Math.max(1, selectionStartLineNumber - PADDING_LINES_COUNT);
if (startLineNumber < selectionStartLineNumber) {
pretext = model.getValueInRange(new Range(startLineNumber, 1, selectionStartLineNumber, 1), EditorCommon.EndOfLinePreference.LF);
}
pretext += model.getValueInRange(new Range(selectionStartLineNumber, 1, selectionStartLineNumber, selectionStartColumn), EditorCommon.EndOfLinePreference.LF);
if (pretext.length > LIMIT_CHARS) {
pretext = pretext.substring(pretext.length - LIMIT_CHARS, pretext.length);
}
// `posttext` contains the text after the selection
let posttext = '';
let endLineNumber = Math.min(selectionEndLineNumber + PADDING_LINES_COUNT, model.getLineCount());
posttext += model.getValueInRange(new Range(selectionEndLineNumber, selectionEndColumn, selectionEndLineNumber, selectionEndLineNumberMaxColumn), EditorCommon.EndOfLinePreference.LF);
if (endLineNumber > selectionEndLineNumber) {
posttext = '\n' + model.getValueInRange(new Range(selectionEndLineNumber + 1, 1, endLineNumber, model.getLineMaxColumn(endLineNumber)), EditorCommon.EndOfLinePreference.LF);
}
if (posttext.length > LIMIT_CHARS) {
posttext = posttext.substring(0, LIMIT_CHARS);
}
// `text` contains the text of the selection
let text = model.getValueInRange(new Range(selectionStartLineNumber, selectionStartColumn, selectionEndLineNumber, selectionEndColumn), EditorCommon.EndOfLinePreference.LF);
if (text.length > 2 * LIMIT_CHARS) {
text = text.substring(0, LIMIT_CHARS) + String.fromCharCode(8230) + text.substring(text.length - LIMIT_CHARS, text.length);
}
return new IENarratorTextAreaState(this, pretext + text + posttext, pretext.length, pretext.length + text.length, false, selectionStartLineNumber);
}
public fromText(text:string): TextAreaState {
return new IENarratorTextAreaState(this, text, 0, text.length, false, 0)
}
public resetSelection(): TextAreaState {
return new IENarratorTextAreaState(this.previousState, this.value, this.value.length, this.value.length, this.isInOverwriteMode, this.selectionToken);
}
}
export class NVDATextAreaState extends TextAreaState {
public static EMPTY = new NVDATextAreaState(null, '', 0, 0, false);
constructor(previousState:TextAreaState, value:string, selectionStart:number, selectionEnd:number, isInOverwriteMode:boolean) {
super(previousState, value, selectionStart, selectionEnd, isInOverwriteMode);
}
protected shallowClone(): TextAreaState {
return new NVDATextAreaState(null, this.value, this.selectionStart, this.selectionEnd, this.isInOverwriteMode);
}
public toEmpty(): TextAreaState {
return NVDATextAreaState.EMPTY;
}
public toString(): string {
return '[ <ENTIRE TEXT' + /*this.value +*/ '>, selectionStart: ' + this.selectionStart + ', selectionEnd: ' + this.selectionEnd + ', isInOverwriteMode: ' + this.isInOverwriteMode + ']';
}
public equals(other:TextAreaState): boolean {
if (other instanceof NVDATextAreaState) {
return (
this.value === other.value
&& this.selectionStart === other.selectionStart
&& this.selectionEnd === other.selectionEnd
&& this.isInOverwriteMode === other.isInOverwriteMode
);
}
return false;
}
public fromTextArea(textArea:ITextAreaWrapper): TextAreaState {
return new NVDATextAreaState(this, textArea.value, textArea.selectionStart, textArea.selectionEnd, textArea.isInOverwriteMode());
}
public fromEditorSelection(model:ISimpleModel, selection:EditorCommon.IEditorRange): TextAreaState {
let pretext = model.getValueInRange(new Range(1, 1, selection.startLineNumber, selection.startColumn), EditorCommon.EndOfLinePreference.LF);
let text = model.getValueInRange(selection, EditorCommon.EndOfLinePreference.LF);
let lastLine = model.getLineCount();
let lastLineMaxColumn = model.getLineMaxColumn(lastLine);
let posttext = model.getValueInRange(new Range(selection.endLineNumber, selection.endColumn, lastLine, lastLineMaxColumn), EditorCommon.EndOfLinePreference.LF);
return new NVDATextAreaState(this, pretext + text + posttext, pretext.length, pretext.length + text.length, false);
}
public fromText(text:string): TextAreaState {
return new NVDATextAreaState(this, text, 0, text.length, false)
}
public resetSelection(): TextAreaState {
return new NVDATextAreaState(this.previousState, this.value, this.value.length, this.value.length, this.isInOverwriteMode);
}
}
@@ -62,9 +62,9 @@ let languagesExtPoint = PluginsRegistry.registerExtensionPoint<ILanguageExtensio
type: 'string'
}
},
prefixes: {
description: nls.localize('vscode.extension.contributes.languages.prefixes', 'File name prefixes associated to the language.'),
default: ['foo*'],
filenamePatterns: {
description: nls.localize('vscode.extension.contributes.languages.filenamePatterns', 'File name glob patterns associated to the language.'),
default: ['bar*foo.txt'],
type: 'array',
item: {
type: 'string'
@@ -93,7 +93,7 @@ export interface ILanguageExtensionPoint {
id: string;
extensions?: string[];
filenames?: string[];
prefixes?: string[];
filenamePatterns?: string[];
firstLine?: string;
aliases?: string[];
mimetypes?: string[];
@@ -341,9 +341,9 @@ class LanguageExtensionPointHandler implements IThreadSynchronizableObject<ILang
}
}
if (Array.isArray(lang.prefixes)) {
for (let prefix of lang.prefixes) {
Mime.registerTextMimeByFilename(prefix, primaryMime);
if (Array.isArray(lang.filenamePatterns)) {
for (let filenamePattern of lang.filenamePatterns) {
Mime.registerTextMimeByFilename(filenamePattern, primaryMime);
}
}
@@ -28,10 +28,6 @@
background-color: black;
}
.monaco-checkbox .checkbox:focus + .label {
outline: auto 5px rgb(229, 151, 0);
}
/* Find widget */
.monaco-editor .find-widget {
position: absolute;
@@ -11,7 +11,6 @@
margin: 0;
padding: 0;
position: absolute;
outline: none;
resize: none;
overflow: hidden;
background: url('keyboard.svg') center center no-repeat;
@@ -61,10 +61,6 @@
font-size: 13px;
}
.monaco-editor .reference-zone-widget .tree .monaco-tree {
outline: none;
}
.monaco-editor .reference-zone-widget .tree .monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.selected:not(.highlighted) {
background-color: rgba(51, 153, 255, .2);
color: #6C6C6C !important;
@@ -330,10 +330,9 @@ class Renderer extends treeDefaults.LegacyRenderer {
var fileReferences = <model.FileReferences> element,
fileReferencesContainer = builder.$('.reference-file');
new leftRightWidget.LeftRightWidget(fileReferencesContainer, (left: HTMLElement) => {
let lrwidget = new leftRightWidget.LeftRightWidget(fileReferencesContainer, (left: HTMLElement) => {
var resource = fileReferences.resource;
new fileLabel.FileLabel(left, resource, this._contextService);
let label = new fileLabel.FileLabel(left, resource, this._contextService);
return <lifecycle.IDisposable> null;
@@ -24,9 +24,4 @@
.monaco-editor.vs-dark .rename-box .rename-input {
border: 1px solid #0E639C;
}
.monaco-editor .rename-box .rename-input,
.monaco-editor .rename-box .rename-input:focus {
outline: none;
}
@@ -247,7 +247,15 @@ class Sorter implements Tree.ISorter {
}
private static suggestionCompare(a: ISuggestion, b: ISuggestion): number {
return (a.sortText || a.label).localeCompare((b.sortText || b.label));
let cmp = 0;
if (typeof a.sortText === 'string' && typeof b.sortText === 'string') {
cmp = a.sortText.localeCompare(b.sortText);
}
if (cmp === 0) {
cmp = a.label.localeCompare(b.label);
}
return cmp;
}
}
+93 -93
View File
@@ -11,137 +11,137 @@ this.MonacoEditorLanguages = this.MonacoEditorLanguages || [];
let MonacoEditorLanguages: ILanguageDef[] = this.MonacoEditorLanguages;
MonacoEditorLanguages.push({
id: "bat",
extensions: [ ".bat", ".cmd"],
aliases: [ "Batch", "bat" ],
defModule: "vs/editor/standalone-languages/bat"
id: 'bat',
extensions: [ '.bat', '.cmd'],
aliases: [ 'Batch', 'bat' ],
defModule: 'vs/editor/standalone-languages/bat'
});
MonacoEditorLanguages.push({
id: "coffeescript",
extensions: [ ".coffee" ],
aliases: [ "CoffeeScript", "coffeescript", "coffee" ],
mimetypes: ["text/x-coffeescript", "text/coffeescript"],
defModule: "vs/editor/standalone-languages/coffee"
id: 'coffeescript',
extensions: [ '.coffee' ],
aliases: [ 'CoffeeScript', 'coffeescript', 'coffee' ],
mimetypes: ['text/x-coffeescript', 'text/coffeescript'],
defModule: 'vs/editor/standalone-languages/coffee'
});
MonacoEditorLanguages.push({
id: "c",
extensions: [ ".c", ".h" ],
aliases: [ "C", "c" ],
defModule: "vs/editor/standalone-languages/cpp"
id: 'c',
extensions: [ '.c', '.h' ],
aliases: [ 'C', 'c' ],
defModule: 'vs/editor/standalone-languages/cpp'
});
MonacoEditorLanguages.push({
id: "cpp",
extensions: [ ".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx" ],
aliases: [ "C++", "Cpp", "cpp"],
defModule: "vs/editor/standalone-languages/cpp"
id: 'cpp',
extensions: [ '.cpp', '.cc', '.cxx', '.hpp', '.hh', '.hxx' ],
aliases: [ 'C++', 'Cpp', 'cpp'],
defModule: 'vs/editor/standalone-languages/cpp'
});
MonacoEditorLanguages.push({
id: "csharp",
extensions: [ ".cs", ".csx" ],
aliases: [ "C#", "csharp" ],
defModule: "vs/editor/standalone-languages/csharp"
id: 'csharp',
extensions: [ '.cs', '.csx' ],
aliases: [ 'C#', 'csharp' ],
defModule: 'vs/editor/standalone-languages/csharp'
});
MonacoEditorLanguages.push({
id: "dockerfile",
extensions: [ ".dockerfile" ],
filenames: [ "Dockerfile" ],
aliases: [ "Dockerfile" ],
defModule: "vs/editor/standalone-languages/dockerfile"
id: 'dockerfile',
extensions: [ '.dockerfile' ],
filenames: [ 'Dockerfile' ],
aliases: [ 'Dockerfile' ],
defModule: 'vs/editor/standalone-languages/dockerfile'
});
MonacoEditorLanguages.push({
id: "fsharp",
extensions: [ ".fs", ".fsi", ".ml", ".mli", ".fsx", ".fsscript" ],
aliases: [ "F#", "FSharp", "fsharp" ],
defModule: "vs/editor/standalone-languages/fsharp"
id: 'fsharp',
extensions: [ '.fs', '.fsi', '.ml', '.mli', '.fsx', '.fsscript' ],
aliases: [ 'F#', 'FSharp', 'fsharp' ],
defModule: 'vs/editor/standalone-languages/fsharp'
});
MonacoEditorLanguages.push({
id: "go",
extensions: [ ".go" ],
aliases: [ "Go" ],
defModule: "vs/editor/standalone-languages/go"
id: 'go',
extensions: [ '.go' ],
aliases: [ 'Go' ],
defModule: 'vs/editor/standalone-languages/go'
});
MonacoEditorLanguages.push({
id: "ini",
extensions: [ ".ini", ".properties", ".gitconfig" ],
filenames: ["config", ".gitattributes", ".gitconfig", ".editorconfig"],
aliases: [ "Ini", "ini" ],
defModule: "vs/editor/standalone-languages/ini"
id: 'ini',
extensions: [ '.ini', '.properties', '.gitconfig' ],
filenames: ['config', '.gitattributes', '.gitconfig', '.editorconfig'],
aliases: [ 'Ini', 'ini' ],
defModule: 'vs/editor/standalone-languages/ini'
});
MonacoEditorLanguages.push({
id: "jade",
extensions: [ ".jade" ],
aliases: [ "Jade", "jade" ],
defModule: "vs/editor/standalone-languages/jade"
id: 'jade',
extensions: [ '.jade' ],
aliases: [ 'Jade', 'jade' ],
defModule: 'vs/editor/standalone-languages/jade'
});
MonacoEditorLanguages.push({
id: "java",
extensions: [ ".java", ".jav" ],
aliases: [ "Java", "java" ],
mimetypes: ["text/x-java-source", "text/x-java"],
defModule: "vs/editor/standalone-languages/java"
id: 'java',
extensions: [ '.java', '.jav' ],
aliases: [ 'Java', 'java' ],
mimetypes: ['text/x-java-source', 'text/x-java'],
defModule: 'vs/editor/standalone-languages/java'
});
MonacoEditorLanguages.push({
id: "lua",
extensions: [ ".lua" ],
aliases: [ "Lua", "lua" ],
defModule: "vs/editor/standalone-languages/lua"
id: 'lua',
extensions: [ '.lua' ],
aliases: [ 'Lua', 'lua' ],
defModule: 'vs/editor/standalone-languages/lua'
});
MonacoEditorLanguages.push({
id: "objective-c",
extensions: [ ".m" ],
aliases: [ "Objective-C"],
defModule: "vs/editor/standalone-languages/objective-c"
id: 'objective-c',
extensions: [ '.m' ],
aliases: [ 'Objective-C'],
defModule: 'vs/editor/standalone-languages/objective-c'
});
MonacoEditorLanguages.push({
id: "powershell",
extensions: [ ".ps1", ".psm1", ".psd1" ],
aliases: [ "PowerShell", "powershell", "ps", "ps1" ],
defModule: "vs/editor/standalone-languages/powershell"
id: 'powershell',
extensions: [ '.ps1', '.psm1', '.psd1' ],
aliases: [ 'PowerShell', 'powershell', 'ps', 'ps1' ],
defModule: 'vs/editor/standalone-languages/powershell'
});
MonacoEditorLanguages.push({
id: "python",
extensions: [ ".py", ".rpy", ".pyw", ".cpy", ".gyp", ".gypi" ],
aliases: [ "Python", "py" ],
firstLine: "^#!/.*\\bpython[0-9.-]*\\b",
defModule: "vs/editor/standalone-languages/python"
id: 'python',
extensions: [ '.py', '.rpy', '.pyw', '.cpy', '.gyp', '.gypi' ],
aliases: [ 'Python', 'py' ],
firstLine: '^#!/.*\\bpython[0-9.-]*\\b',
defModule: 'vs/editor/standalone-languages/python'
});
MonacoEditorLanguages.push({
id: "r",
extensions: [ ".r", ".rhistory", ".rprofile", ".rt" ],
aliases: [ "R", "r" ],
defModule: "vs/editor/standalone-languages/r"
id: 'r',
extensions: [ '.r', '.rhistory', '.rprofile', '.rt' ],
aliases: [ 'R', 'r' ],
defModule: 'vs/editor/standalone-languages/r'
});
MonacoEditorLanguages.push({
id: "ruby",
extensions: [ ".rb", ".rbx", ".rjs", ".gemspec", ".pp" ],
filenames: [ "rakefile" ],
aliases: [ "Ruby", "rb" ],
defModule: "vs/editor/standalone-languages/ruby"
id: 'ruby',
extensions: [ '.rb', '.rbx', '.rjs', '.gemspec', '.pp' ],
filenames: [ 'rakefile' ],
aliases: [ 'Ruby', 'rb' ],
defModule: 'vs/editor/standalone-languages/ruby'
});
MonacoEditorLanguages.push({
id: "swift",
aliases: ["Swift","swift"],
extensions: [".swift"],
mimetypes: ["text/swift"],
defModule: "vs/editor/standalone-languages/swift"
id: 'swift',
aliases: ['Swift','swift'],
extensions: ['.swift'],
mimetypes: ['text/swift'],
defModule: 'vs/editor/standalone-languages/swift'
});
MonacoEditorLanguages.push({
id: "sql",
extensions: [ ".sql" ],
aliases: [ "SQL" ],
defModule: "vs/editor/standalone-languages/sql"
id: 'sql',
extensions: [ '.sql' ],
aliases: [ 'SQL' ],
defModule: 'vs/editor/standalone-languages/sql'
});
MonacoEditorLanguages.push({
id: "vb",
extensions: [ ".vb" ],
aliases: [ "Visual Basic", "vb" ],
defModule: "vs/editor/standalone-languages/vb"
id: 'vb',
extensions: [ '.vb' ],
aliases: [ 'Visual Basic', 'vb' ],
defModule: 'vs/editor/standalone-languages/vb'
});
MonacoEditorLanguages.push({
id: "xml",
extensions: [ ".xml", ".dtd", ".ascx", ".csproj", ".config", ".wxi", ".wxl", ".wxs", ".xaml", ".svg", ".svgz" ],
firstLine : "(\\<\\?xml.*)|(\\<svg)|(\\<\\!doctype\\s+svg)",
aliases: [ "XML", "xml" ],
mimetypes: ["text/xml", "application/xml", "application/xaml+xml", "application/xml-dtd"],
defModule: "vs/editor/standalone-languages/xml"
id: 'xml',
extensions: [ '.xml', '.dtd', '.ascx', '.csproj', '.config', '.wxi', '.wxl', '.wxs', '.xaml', '.svg', '.svgz' ],
firstLine : '(\\<\\?xml.*)|(\\<svg)|(\\<\\!doctype\\s+svg)',
aliases: [ 'XML', 'xml' ],
mimetypes: ['text/xml', 'application/xml', 'application/xaml+xml', 'application/xml-dtd'],
defModule: 'vs/editor/standalone-languages/xml'
});
@@ -8,13 +8,13 @@ import assert = require('assert');
import {Position} from 'vs/editor/common/core/position';
import {Range} from 'vs/editor/common/core/range';
import {EndOfLinePreference, IEditorRange, IRange, IEditorPosition} from 'vs/editor/common/editorCommon';
import {ISimpleModel, TextAreaState} from 'vs/editor/common/controller/textAreaState';
import {ISimpleModel, TextAreaState, IENarratorTextAreaState} from 'vs/editor/common/controller/textAreaState';
import {MockTextAreaWrapper} from 'vs/editor/test/common/mocks/mockTextAreaWrapper';
suite('TextAreaState', () => {
function assertTextAreaState(actual:TextAreaState, value:string, selectionStart:number, selectionEnd:number, isInOverwriteMode:boolean, selectionToken:number): void {
let desired = new TextAreaState(null, value, selectionStart, selectionEnd, isInOverwriteMode, selectionToken);
let desired = new IENarratorTextAreaState(null, value, selectionStart, selectionEnd, isInOverwriteMode, selectionToken);
assert.ok(desired.equals(actual), desired.toString() + ' == ' + actual.toString());
}
@@ -24,7 +24,7 @@ suite('TextAreaState', () => {
textArea._selectionStart = 1;
textArea._selectionEnd = 12;
textArea._isInOverwriteMode = false;
let actual = TextAreaState.EMPTY.fromTextArea(textArea);
let actual = IENarratorTextAreaState.EMPTY.fromTextArea(textArea);
assertTextAreaState(actual, 'Hello world!', 1, 12, false, 0);
assert.equal(actual.getValue(), 'Hello world!');
@@ -43,22 +43,22 @@ suite('TextAreaState', () => {
textArea._selectionEnd = 12;
textArea._isInOverwriteMode = false;
let state = new TextAreaState(null, 'Hi world!', 2, 2, false, 0);
state.applyToTextArea(textArea, false);
let state = new IENarratorTextAreaState(null, 'Hi world!', 2, 2, false, 0);
state.applyToTextArea('test', textArea, false);
assert.equal(textArea._value, 'Hi world!');
assert.equal(textArea._selectionStart, 9);
assert.equal(textArea._selectionEnd, 9);
state = new TextAreaState(null, 'Hi world!', 3, 3, false, 0);
state.applyToTextArea(textArea, false);
state = new IENarratorTextAreaState(null, 'Hi world!', 3, 3, false, 0);
state.applyToTextArea('test', textArea, false);
assert.equal(textArea._value, 'Hi world!');
assert.equal(textArea._selectionStart, 9);
assert.equal(textArea._selectionEnd, 9);
state = new TextAreaState(null, 'Hi world!', 0, 2, false, 0);
state.applyToTextArea(textArea, true);
state = new IENarratorTextAreaState(null, 'Hi world!', 0, 2, false, 0);
state.applyToTextArea('test', textArea, true);
assert.equal(textArea._value, 'Hi world!');
assert.equal(textArea._selectionStart, 0);
@@ -74,7 +74,7 @@ suite('TextAreaState', () => {
textArea._selectionEnd = selectionEnd;
textArea._isInOverwriteMode = isInOverwriteMode;
let newState = (prevState || TextAreaState.EMPTY).fromTextArea(textArea);
let newState = (prevState || IENarratorTextAreaState.EMPTY).fromTextArea(textArea);
let actual = newState.extractNewText();
@@ -103,7 +103,7 @@ suite('TextAreaState', () => {
test('extractNewText - typing does not cause a selection', () => {
testExtractNewText(
new TextAreaState(null, '', 0, 0, false, 0),
new IENarratorTextAreaState(null, '', 0, 0, false, 0),
'a',
0, 1, false,
''
@@ -112,7 +112,7 @@ suite('TextAreaState', () => {
test('extractNewText - had the textarea empty', () => {
testExtractNewText(
new TextAreaState(null, '', 0, 0, false, 0),
new IENarratorTextAreaState(null, '', 0, 0, false, 0),
'a',
1, 1, false,
'a'
@@ -121,7 +121,7 @@ suite('TextAreaState', () => {
test('extractNewText - had the entire line selected', () => {
testExtractNewText(
new TextAreaState(null, 'Hello world!', 0, 12, false, 0),
new IENarratorTextAreaState(null, 'Hello world!', 0, 12, false, 0),
'H',
1, 1, false,
'H'
@@ -130,7 +130,7 @@ suite('TextAreaState', () => {
test('extractNewText - had previous text 1', () => {
testExtractNewText(
new TextAreaState(null, 'Hello world!', 12, 12, false, 0),
new IENarratorTextAreaState(null, 'Hello world!', 12, 12, false, 0),
'Hello world!a',
13, 13, false,
'a'
@@ -139,7 +139,7 @@ suite('TextAreaState', () => {
test('extractNewText - had previous text 2', () => {
testExtractNewText(
new TextAreaState(null, 'Hello world!', 0, 0, false, 0),
new IENarratorTextAreaState(null, 'Hello world!', 0, 0, false, 0),
'aHello world!',
1, 1, false,
'a'
@@ -148,7 +148,7 @@ suite('TextAreaState', () => {
test('extractNewText - had previous text 3', () => {
testExtractNewText(
new TextAreaState(null, 'Hello world!', 6, 11, false, 0),
new IENarratorTextAreaState(null, 'Hello world!', 6, 11, false, 0),
'Hello other!',
11, 11, false,
'other'
@@ -157,7 +157,7 @@ suite('TextAreaState', () => {
test('extractNewText - IME', () => {
testExtractNewText(
new TextAreaState(null, '', 0, 0, false, 0),
new IENarratorTextAreaState(null, '', 0, 0, false, 0),
'これは',
3, 3, false,
'これは'
@@ -166,7 +166,7 @@ suite('TextAreaState', () => {
test('extractNewText - isInOverwriteMode', () => {
testExtractNewText(
new TextAreaState(null, 'Hello world!', 0, 0, false, 0),
new IENarratorTextAreaState(null, 'Hello world!', 0, 0, false, 0),
'Aello world!',
1, 1, true,
'A'
@@ -180,7 +180,7 @@ suite('TextAreaState', () => {
textArea._selectionEnd = selectionEnd;
textArea._isInOverwriteMode = isInOverwriteMode;
let newState = (prevState || TextAreaState.EMPTY).fromTextArea(textArea);
let newState = (prevState || IENarratorTextAreaState.EMPTY).fromTextArea(textArea);
let actual = newState.extractMacReplacedText();
@@ -191,7 +191,7 @@ suite('TextAreaState', () => {
test('extractMacReplacedText - does nothing if there is selection', () => {
testExtractMacReplacedText(
new TextAreaState(null, 'Hello world!', 0, 0, false, 0),
new IENarratorTextAreaState(null, 'Hello world!', 0, 0, false, 0),
'Hellö world!',
4, 5, false,
''
@@ -200,7 +200,7 @@ suite('TextAreaState', () => {
test('extractMacReplacedText - does nothing if there is more than one extra char', () => {
testExtractMacReplacedText(
new TextAreaState(null, 'Hello world!', 0, 0, false, 0),
new IENarratorTextAreaState(null, 'Hello world!', 0, 0, false, 0),
'Hellöö world!',
6, 6, false,
''
@@ -209,7 +209,7 @@ suite('TextAreaState', () => {
test('extractMacReplacedText - does nothing if there is more than one changed char', () => {
testExtractMacReplacedText(
new TextAreaState(null, 'Hello world!', 0, 0, false, 0),
new IENarratorTextAreaState(null, 'Hello world!', 0, 0, false, 0),
'Helöö world!',
6, 6, false,
''
@@ -218,7 +218,7 @@ suite('TextAreaState', () => {
test('extractMacReplacedText', () => {
testExtractMacReplacedText(
new TextAreaState(null, 'Hello world!', 0, 0, false, 0),
new IENarratorTextAreaState(null, 'Hello world!', 0, 0, false, 0),
'Hellö world!',
5, 5, false,
'ö'
@@ -227,7 +227,7 @@ suite('TextAreaState', () => {
function testFromEditorSelectionAndPreviousState(eol:string, lines:string[], range:Range, prevSelectionToken:number): TextAreaState {
let model = new SimpleModel(lines, eol);
let previousState = new TextAreaState(null, '', 0, 0, false, prevSelectionToken);
let previousState = new IENarratorTextAreaState(null, '', 0, 0, false, prevSelectionToken);
return previousState.fromEditorSelection(model, range);
}
@@ -277,6 +277,8 @@ export class Scanner {
}
}
let tokenType: TokenType = void 0;
// Comment - CSS
if (this._comment()) {
if (!this.ignoreComment) {
@@ -302,7 +304,7 @@ export class Scanner {
}
// URL
var tokenType = this._url();
tokenType = this._url();
if (tokenType !== null) {
return this.finishToken(result, tokenType);
}
@@ -349,8 +351,8 @@ export class Scanner {
// Percentage 43%
return this.finishToken(result, TokenType.Percentage);
} else if (this.ident(content)) {
var dim = this.stream.substring(pos).toLowerCase();
var tokenType = <TokenType>staticUnitTable[dim];
let dim = this.stream.substring(pos).toLowerCase();
tokenType = <TokenType>staticUnitTable[dim];
if (typeof tokenType !== 'undefined') {
// Known dimension 43px
return this.finishToken(result, tokenType, content.join(''));
@@ -365,13 +367,13 @@ export class Scanner {
// String, BadString
content = [];
var tokenType = this._string(content);
tokenType = this._string(content);
if (tokenType !== null) {
return this.finishToken(result, tokenType, content.join(''));
}
// single character tokens
var tokenType = <TokenType>staticTokenTable[this.stream.peekChar()];
tokenType = <TokenType>staticTokenTable[this.stream.peekChar()];
if (typeof tokenType !== 'undefined') {
this.stream.advance(1);
return this.finishToken(result, tokenType);
@@ -40,7 +40,7 @@ export class Scope {
return this.findInScope(offset, length);
}
return null;
}
}
private findInScope(offset: number, length: number = 0): Scope {
// find the first scope child that has an offset larger than offset + length
@@ -67,7 +67,7 @@ export class Scope {
var symbol = this.symbols[index];
if (symbol.name === name && symbol.type === type) {
return symbol;
}
}
}
return null;
}
@@ -141,33 +141,35 @@ export class ScopeBuilder implements nodes.IVisitor {
return true;
case nodes.NodeType.VariableDeclaration:
this.addSymbol(node, (<nodes.VariableDeclaration> node).getName(), nodes.ReferenceType.Variable);
return true;
return true;
case nodes.NodeType.Ruleset:
return this.visitRuleSet(<nodes.RuleSet> node);
case nodes.NodeType.MixinDeclaration:
this.addSymbol(node, (<nodes.MixinDeclaration> node).getName(), nodes.ReferenceType.Mixin);
return true;
return true;
case nodes.NodeType.FunctionDeclaration:
this.addSymbol(node, (<nodes.FunctionDeclaration> node).getName(), nodes.ReferenceType.Function);
return true;
case nodes.NodeType.FunctionParameter:
return true;
case nodes.NodeType.FunctionParameter: {
// parameters are part of the body scope
var scopeNode = (<nodes.BodyDeclaration> node.getParent()).getDeclarations();
let scopeNode = (<nodes.BodyDeclaration> node.getParent()).getDeclarations();
if (scopeNode) {
this.addSymbolToChildScope(scopeNode, node, (<nodes.FunctionParameter> node).getName(), nodes.ReferenceType.Variable);
}
return true;
return true;
}
case nodes.NodeType.Declarations:
this.addScope(node);
return true;
case nodes.NodeType.For:
case nodes.NodeType.Each:
case nodes.NodeType.Each: {
var forOrEachNode = <nodes.ForStatement | nodes.EachStatement> node;
var scopeNode = forOrEachNode.getDeclarations();
let scopeNode = forOrEachNode.getDeclarations();
if (scopeNode) {
this.addSymbolToChildScope(scopeNode, forOrEachNode.variable, forOrEachNode.variable.getName(), nodes.ReferenceType.Variable);
}
return true;
return true;
}
}
return true;
}
@@ -245,7 +247,7 @@ export class Symbols {
return null;
}
private evaluateReferenceTypes(node: nodes.Node) : nodes.ReferenceType[] {
private evaluateReferenceTypes(node: nodes.Node) : nodes.ReferenceType[] {
if (node instanceof nodes.Identifier) {
var referenceTypes = (<nodes.Identifier> node).referenceTypes;
if (referenceTypes) {
@@ -258,7 +260,7 @@ export class Symbols {
if ((propertyName === 'animation' || propertyName === 'animation-name')
&& decl.getValue() && decl.getValue().offset === node.offset) {
return [ nodes.ReferenceType.Keyframe ];
}
}
}
}
} else if (node instanceof nodes.Variable) {
@@ -285,7 +287,7 @@ export class Symbols {
var referenceTypes = this.evaluateReferenceTypes(node);
if (referenceTypes) {
return this.internalFindSymbol(node, referenceTypes);
return this.internalFindSymbol(node, referenceTypes);
}
return null;
}
@@ -299,7 +301,7 @@ export class Symbols {
}
if (symbol.name.length !== node.length || symbol.name !== node.getText()) {
return false;
}
}
var referenceTypes = this.evaluateReferenceTypes(node);
if (!referenceTypes || referenceTypes.indexOf(symbol.type) === -1) {
@@ -320,6 +322,6 @@ export class Symbols {
}
scope = scope.parent;
}
return null;
return null;
}
}
+3 -3
View File
@@ -287,7 +287,7 @@ export class LintVisitor implements nodes.IVisitor {
/////////////////////////////////////////////////////////////
// With 'display: inline', the width, height, margin-top, margin-bottom, and float properties have no effect
var displayElems = this.fetchWithValue(propertyTable, 'display', 'inline');
let displayElems = this.fetchWithValue(propertyTable, 'display', 'inline');
if (displayElems.length > 0) {
[ 'width', 'height', 'margin-top', 'margin-bottom', 'float'].forEach(function(prop) {
var elem = self.fetch(propertyTable, prop);
@@ -298,7 +298,7 @@ export class LintVisitor implements nodes.IVisitor {
}
// With 'display: inline-block', 'float' has no effect
var displayElems = this.fetchWithValue(propertyTable, 'display', 'inline-block');
displayElems = this.fetchWithValue(propertyTable, 'display', 'inline-block');
if (displayElems.length > 0) {
var elem = this.fetch(propertyTable, 'float');
for (var index = 0; index < elem.length; index++) {
@@ -307,7 +307,7 @@ export class LintVisitor implements nodes.IVisitor {
}
// With 'display: block', 'vertical-align' has no effect
var displayElems = this.fetchWithValue(propertyTable, 'display', 'block');
displayElems = this.fetchWithValue(propertyTable, 'display', 'block');
if (displayElems.length > 0) {
var elem = this.fetch(propertyTable, 'vertical-align');
for (var index = 0; index < elem.length; index++) {
@@ -157,7 +157,7 @@ function tokenize(mode:Modes.IMode, comments:boolean, line:string, state:JSONSta
lastWasColon = false;
break;
case json.SyntaxKind.StringLiteral:
type = lastWasColon ? jsonTokenTypes.TOKEN_VALUE_STRING : jsonTokenTypes.TOKEN_PROPERTY_NAME,
type = lastWasColon ? jsonTokenTypes.TOKEN_VALUE_STRING : jsonTokenTypes.TOKEN_PROPERTY_NAME;
lastWasColon = false;
break;
case json.SyntaxKind.NumericLiteral:
@@ -20,6 +20,14 @@ a {
text-decoration: none;
}
a:focus,
input:focus,
select:focus,
textarea:focus {
outline: 2px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
hr {
border: 0;
height: 2px;
@@ -535,8 +535,8 @@ class CSSimpleHTML extends CSState {
this.state = htmlMode.States.OpeningStartTag;
return { type: htmlTokenTypes.DELIM_START, bracket: Modes.Bracket.Open };
case htmlMode.States.OpeningEndTag:
var tagName = this.nextName(stream);
case htmlMode.States.OpeningEndTag: {
let tagName = this.nextName(stream);
if (tagName.length > 0) {
return {
type: htmlTokenTypes.getTag(tagName),
@@ -549,9 +549,10 @@ class CSSimpleHTML extends CSState {
}
stream.advanceUntil('>', false);
return { type: '' };
}
case htmlMode.States.OpeningStartTag:
var tagName = this.nextName(stream);
case htmlMode.States.OpeningStartTag: {
let tagName = this.nextName(stream);
if (tagName.length > 0) {
this.state = htmlMode.States.WithinTag;
return {
@@ -560,6 +561,7 @@ class CSSimpleHTML extends CSState {
};
}
break;
}
case htmlMode.States.WithinTag:
if (stream.skipWhitespace().length > 0) {
@@ -29,16 +29,16 @@ export function evaluate(languageService: ts.LanguageService, resource: URI, ran
var [command] = quickFix.command.arguments;
switch (command.type) {
case 'rename': {
var start = sourceFile.getLineAndCharacterOfPosition(token.getStart());
var end = sourceFile.getLineAndCharacterOfPosition(token.getEnd());
var renameRange: EditorCommon.IRange = { startLineNumber: start.line + 1, startColumn: start.character + 1, endLineNumber: end.line + 1, endColumn: end.character + 1 };
let start = sourceFile.getLineAndCharacterOfPosition(token.getStart());
let end = sourceFile.getLineAndCharacterOfPosition(token.getEnd());
let renameRange: EditorCommon.IRange = { startLineNumber: start.line + 1, startColumn: start.character + 1, endLineNumber: end.line + 1, endColumn: end.character + 1 };
return {
edits: [{ resource, range: renameRange, newText: command.name }]
};
}
case 'addglobal': {
var content = strings.format('/* global {0} */\n', command.name);
var renameRange: EditorCommon.IRange = { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 };
let content = strings.format('/* global {0} */\n', command.name);
let renameRange: EditorCommon.IRange = { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 };
return {
edits: [{ resource, range: renameRange, newText: content }]
};
@@ -85,8 +85,10 @@ export function translate(_rewriter: ISyntaxRewriter[], snapshot:string|ts.IScri
var result = textEdits.apply(context.edits, value);
$perf['_apply'] = Date.now() - $t1;
$perf['_total'] = Date.now() - $perf['_total'];
$measurePerf && console.info($perf);
$measurePerf && console.info(result.value);
if ($measurePerf) {
console.info($perf);
console.info(result.value);
}
return result;
}
@@ -174,7 +176,9 @@ export function decodeVariableNames(name: string|htmlContent.IHTMLContentElement
while (stack.length) {
var element = stack.shift();
element.text = element.text && _doDecodeVariableName(element.text, sourceFile);
element.children && stack.push.apply(stack, element.children);
if(element.children){
stack.push.apply(stack, element.children);
}
}
}
}
+29 -1
View File
@@ -509,6 +509,20 @@ declare namespace vscode {
options: TextEditorOptions;
}
/**
* Represents an event describing the change of a [text editor's view column](#TextEditor.viewColumn).
*/
export interface TextEditorViewColumnChangeEvent {
/**
* The [text editor](#TextEditor) for which the options have changed.
*/
textEditor: TextEditor;
/**
* The new value for the [text editor's view column](#TextEditor.viewColumn).
*/
viewColumn: ViewColumn;
}
/**
* Represents a [text editor](#TextEditor)'s [options](#TextEditor.options).
*/
@@ -725,6 +739,12 @@ declare namespace vscode {
*/
options: TextEditorOptions;
/**
* The column in which this editor shows. Will be `undefined` in case this
* isn't one of the three main editors, e.g an embedded editor.
*/
viewColumn: ViewColumn;
/**
* Perform an edit on the document associated with this text editor.
*
@@ -1453,7 +1473,10 @@ declare namespace vscode {
String,
Number,
Boolean,
Array
Array,
Object,
Key,
Null
}
/**
@@ -2761,6 +2784,11 @@ declare namespace vscode {
*/
export const onDidChangeTextEditorOptions: Event<TextEditorOptionsChangeEvent>;
/**
* An [event](#Event) which fires when the view column of an editor das changed.
*/
export const onDidChangeTextEditorViewColumn: Event<TextEditorViewColumnChangeEvent>
/**
* Show the given document in a text editor. A [column](#ViewColumn) can be provided
* to control where the editor is being shown. Might change the [active editor](#window.activeTextEditor).
@@ -191,6 +191,9 @@ export class ExtHostAPIImplementation {
onDidChangeTextEditorOptions: (listener: (e: vscode.TextEditorOptionsChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => {
return pluginHostEditors.onDidChangeTextEditorOptions(listener, thisArgs, disposables);
},
onDidChangeTextEditorViewColumn(listener, thisArg?, disposables?) {
return pluginHostEditors.onDidChangeTextEditorViewColumn(listener, thisArg, disposables);
},
showInformationMessage: (message, ...items) => {
return pluginHostMessageService.showMessage(Severity.Info, message, items);
},
@@ -22,7 +22,7 @@ import {IThreadService} from 'vs/platform/thread/common/thread';
export function registerApiCommands(threadService: IThreadService) {
const commands = threadService.getRemotable(ExtHostCommands);
new ExtHostApiCommands(commands);
new ExtHostApiCommands(commands).registerCommands();
}
class ExtHostApiCommands {
@@ -32,7 +32,9 @@ class ExtHostApiCommands {
constructor(commands: ExtHostCommands) {
this._commands = commands;
}
registerCommands() {
this._register('vscode.executeWorkspaceSymbolProvider', this._executeWorkspaceSymbolProvider, {
description: 'Execute all workspace symbol provider.',
args: [{ name: 'query', constraint: String }],
@@ -145,6 +147,19 @@ class ExtHostApiCommands {
],
returns: 'A promise that resolves to an array of TextEdits.'
});
this._register('vscode.previewHtml', (uri: URI, position?: vscode.ViewColumn) => {
return this._commands.executeCommand('_workbench.previewHtml', uri,
typeof position === 'number' ? typeConverters.fromViewColumn(position) : void 0);
}, {
description: 'Preview an html document.',
args: [
{ name: 'uri', description: 'Uri of the document to preview.', constraint: URI },
{ name: 'column', description: '(optional) Column in which to preview.' },
]
});
}
// --- command impl
+87 -11
View File
@@ -18,17 +18,23 @@ import {Position as EditorPosition} from 'vs/platform/editor/common/editor';
import {IModelService} from 'vs/editor/common/services/modelService';
import {MainThreadEditorsTracker, TextEditorRevealType, MainThreadTextEditor, ITextEditorConfiguration} from 'vs/workbench/api/node/mainThreadEditors';
import * as TypeConverters from './extHostTypeConverters';
import {TextDocument, TextEditorSelectionChangeEvent, TextEditorOptionsChangeEvent, TextEditorOptions, ViewColumn} from 'vscode';
import {TextDocument, TextEditorSelectionChangeEvent, TextEditorOptionsChangeEvent, TextEditorOptions, TextEditorViewColumnChangeEvent, ViewColumn} from 'vscode';
import {EventType} from 'vs/workbench/common/events';
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {IEventService} from 'vs/platform/event/common/event';
import {equals as arrayEquals} from 'vs/base/common/arrays';
import {equals as objectEquals} from 'vs/base/common/objects';
export interface ITextEditorAddData {
id: string;
document: URI;
options: ITextEditorConfiguration;
selections: ISelection[];
editorPosition: EditorPosition;
}
export interface ITextEditorPositionData {
[id: string]: EditorPosition;
}
@Remotable.PluginHostContext('ExtHostEditors')
@@ -40,6 +46,9 @@ export class ExtHostEditors {
public onDidChangeTextEditorOptions: Event<TextEditorOptionsChangeEvent>;
private _onDidChangeTextEditorOptions: Emitter<TextEditorOptionsChangeEvent>;
public onDidChangeTextEditorViewColumn: Event<TextEditorViewColumnChangeEvent>;
private _onDidChangeTextEditorViewColumn: Emitter<TextEditorViewColumnChangeEvent>;
private _editors: { [id: string]: ExtHostTextEditor };
private _proxy: MainThreadEditors;
private _onDidChangeActiveTextEditor: Emitter<vscode.TextEditor>;
@@ -56,6 +65,9 @@ export class ExtHostEditors {
this._onDidChangeTextEditorOptions = new Emitter<TextEditorOptionsChangeEvent>();
this.onDidChangeTextEditorOptions = this._onDidChangeTextEditorOptions.event;
this._onDidChangeTextEditorViewColumn = new Emitter<TextEditorViewColumnChangeEvent>();
this.onDidChangeTextEditorViewColumn = this._onDidChangeTextEditorViewColumn.event;
this._modelService = threadService.getRemotable(ExtHostModelService);
this._proxy = threadService.getRemotable(MainThreadEditors);
this._onDidChangeActiveTextEditor = new Emitter<vscode.TextEditor>();
@@ -95,7 +107,7 @@ export class ExtHostEditors {
_acceptTextEditorAdd(data: ITextEditorAddData): void {
let document = this._modelService.getDocumentData(data.document);
let newEditor = new ExtHostTextEditor(this._proxy, data.id, document, data.selections.map(TypeConverters.toSelection), data.options);
let newEditor = new ExtHostTextEditor(this._proxy, data.id, document, data.selections.map(TypeConverters.toSelection), data.options, TypeConverters.toViewColumn(data.editorPosition));
this._editors[data.id] = newEditor;
}
@@ -129,6 +141,17 @@ export class ExtHostEditors {
this._onDidChangeActiveTextEditor.fire(this.getActiveTextEditor());
}
_acceptEditorPositionData(data: ITextEditorPositionData): void {
for (let id in data) {
let textEditor = this._editors[id];
let viewColumn = TypeConverters.toViewColumn(data[id]);
if (textEditor.viewColumn !== viewColumn) {
textEditor._acceptViewColumn(viewColumn);
this._onDidChangeTextEditorViewColumn.fire({ textEditor, viewColumn });
}
}
}
_acceptTextEditorRemove(id: string): void {
// make sure the removed editor is not visible
let newVisibleEditors = this._visibleEditorIds.filter(visibleEditorId => visibleEditorId !== id);
@@ -271,13 +294,15 @@ class ExtHostTextEditor implements vscode.TextEditor {
private _documentData: ExtHostDocumentData;
private _selections: Selection[];
private _options: TextEditorOptions;
private _viewColumn: vscode.ViewColumn;
constructor(proxy: MainThreadEditors, id: string, document: ExtHostDocumentData, selections: Selection[], options: EditorOptions) {
constructor(proxy: MainThreadEditors, id: string, document: ExtHostDocumentData, selections: Selection[], options: EditorOptions, viewColumn: vscode.ViewColumn) {
this._proxy = proxy;
this._id = id;
this._documentData = document;
this._selections = selections;
this._options = options;
this._viewColumn = viewColumn;
}
dispose() {
@@ -319,6 +344,20 @@ class ExtHostTextEditor implements vscode.TextEditor {
this._options = options;
}
// ---- view column
get viewColumn(): vscode.ViewColumn {
return this._viewColumn;
}
set viewColumn(value) {
throw readonly('viewColumn');
}
_acceptViewColumn(value: vscode.ViewColumn) {
this._viewColumn = value;
}
// ---- selections
get selection(): Selection {
@@ -423,6 +462,7 @@ export class MainThreadEditors {
private _textEditorsMap: { [editorId: string]: MainThreadTextEditor; };
private _activeTextEditor: string;
private _visibleEditors: string[];
private _editorPositionData: ITextEditorPositionData;
constructor(
@IThreadService threadService: IThreadService,
@@ -440,6 +480,7 @@ export class MainThreadEditors {
this._textEditorsMap = Object.create(null);
this._activeTextEditor = null;
this._visibleEditors = [];
this._editorPositionData = null;
this._editorTracker = new MainThreadEditorsTracker(editorService, modelService);
this._toDispose.push(this._editorTracker);
@@ -450,6 +491,7 @@ export class MainThreadEditors {
this._toDispose.push(this._editorTracker.onDidUpdateTextEditors(() => this._updateActiveAndVisibleTextEditors()));
this._toDispose.push(this._editorTracker.onChangedFocusedTextEditor((focusedTextEditorId) => this._updateActiveAndVisibleTextEditors()));
this._toDispose.push(eventService.addListener2(EventType.EDITOR_INPUT_CHANGED, () => this._updateActiveAndVisibleTextEditors()));
this._toDispose.push(eventService.addListener2(EventType.EDITOR_POSITION_CHANGED, () => this._updateActiveAndVisibleTextEditors()));
}
public dispose(): void {
@@ -473,7 +515,8 @@ export class MainThreadEditors {
id: id,
document: textEditor.getModel().getAssociatedResource(),
options: textEditor.getConfiguration(),
selections: textEditor.getSelections()
selections: textEditor.getSelections(),
editorPosition: this._findEditorPosition(textEditor)
});
this._textEditorsListenersMap[id] = toDispose;
@@ -489,16 +532,22 @@ export class MainThreadEditors {
}
private _updateActiveAndVisibleTextEditors(): void {
// active and visible editors
let visibleEditors = this._editorTracker.getVisibleTextEditorIds();
let activeEditor = this._findActiveTextEditorId();
if (activeEditor === this._activeTextEditor && arrayEquals(this._visibleEditors, visibleEditors, (a, b) => a === b)) {
// no change
return;
if (activeEditor !== this._activeTextEditor || !arrayEquals(this._visibleEditors, visibleEditors, (a, b) => a === b)) {
this._activeTextEditor = activeEditor;
this._visibleEditors = visibleEditors;
this._proxy._acceptActiveEditorAndVisibleEditors(this._activeTextEditor, this._visibleEditors);
}
// editor columns
let editorPositionData = this._getTextEditorPositionData();
if (!objectEquals(this._editorPositionData, editorPositionData)) {
this._editorPositionData = editorPositionData;
this._proxy._acceptEditorPositionData(this._editorPositionData);
}
this._activeTextEditor = activeEditor;
this._visibleEditors = visibleEditors;
this._proxy._acceptActiveEditorAndVisibleEditors(this._activeTextEditor, this._visibleEditors);
}
private _findActiveTextEditorId(): string {
@@ -527,6 +576,33 @@ export class MainThreadEditors {
return this._editorTracker.findTextEditorIdFor((<ICommonDiffEditor>editor).getModifiedEditor());
}
private _findEditorPosition(editor: MainThreadTextEditor): EditorPosition {
for (let workbenchEditor of this._workbenchEditorService.getVisibleEditors()) {
if (editor.matches(workbenchEditor)) {
return workbenchEditor.position;
}
}
}
private _getTextEditorPositionData(): ITextEditorPositionData {
let result: ITextEditorPositionData = Object.create(null);
for (let workbenchEditor of this._workbenchEditorService.getVisibleEditors()) {
let editor = <IEditor>workbenchEditor.getControl();
// Substitute for (editor instanceof ICodeEditor)
if (!editor || typeof editor.getEditorType !== 'function') {
// Not a text editor...
continue;
}
if (editor.getEditorType() === EditorType.ICodeEditor) {
let id = this._editorTracker.findTextEditorIdFor(<ICommonCodeEditor>editor);
if (id) {
result[id] = workbenchEditor.position;
}
}
}
return result;
}
// --- from plugin host process
_tryShowTextDocument(resource: URI, position: EditorPosition, preserveFocus: boolean): TPromise<string> {
@@ -111,6 +111,18 @@ export function fromViewColumn(column?: vscode.ViewColumn): EditorPosition {
return editorColumn;
}
export function toViewColumn(position?: EditorPosition): vscode.ViewColumn {
if (typeof position !== 'number') {
return;
}
if (position === EditorPosition.LEFT) {
return <number> types.ViewColumn.One;
} else if (position === EditorPosition.CENTER) {
return <number> types.ViewColumn.Two;
} else if (position === EditorPosition.RIGHT) {
return <number> types.ViewColumn.Three;
}
}
export function fromFormattedString(value: vscode.MarkedString): IHTMLContentElement {
if (typeof value === 'string') {
@@ -198,9 +210,11 @@ export namespace SymbolKind {
return 'class';
case types.SymbolKind.Interface:
return 'interface';
case types.SymbolKind.Module:
case types.SymbolKind.Namespace:
return 'namespace';
case types.SymbolKind.Package:
return 'package';
case types.SymbolKind.Module:
return 'module';
case types.SymbolKind.Property:
return 'property';
@@ -216,6 +230,12 @@ export namespace SymbolKind {
return 'number';
case types.SymbolKind.Boolean:
return 'boolean';
case types.SymbolKind.Object:
return 'object';
case types.SymbolKind.Key:
return 'key';
case types.SymbolKind.Null:
return 'null';
}
return 'property';
}
@@ -234,9 +254,11 @@ export namespace SymbolKind {
return types.SymbolKind.Class;
case 'interface':
return types.SymbolKind.Interface;
case 'namespace':
return types.SymbolKind.Namespace;
case 'package':
return types.SymbolKind.Package;
case 'module':
// case types.SymbolKind.Namespace:
// case types.SymbolKind.Package:
return types.SymbolKind.Module;
case 'property':
return types.SymbolKind.Property;
@@ -252,6 +274,12 @@ export namespace SymbolKind {
return types.SymbolKind.Number;
case 'boolean':
return types.SymbolKind.Boolean;
case 'object':
return types.SymbolKind.Object;
case 'key':
return types.SymbolKind.Key;
case 'null':
return types.SymbolKind.Null;
}
return types.SymbolKind.Property;
}
@@ -536,6 +536,9 @@ export enum SymbolKind {
Number,
Boolean,
Array,
Object,
Key,
Null
}
export class SymbolInformation {
@@ -118,7 +118,7 @@ export class ActivitybarPart extends Part implements IActivityService {
// Viewlet switcher is on top
this.viewletSwitcherBar = new ActionBar(div, {
actionItemProvider: (action: Action) => this.activityActionItems[action.id],
disableTabIndex: true // we handle this
orientation: ActionsOrientation.VERTICAL
});
this.viewletSwitcherBar.getContainer().addClass('position-top');
@@ -159,7 +159,6 @@ export class ActivitybarPart extends Part implements IActivityService {
actionItemProvider: (action: Action) => this.activityActionItems[action.id],
orientation: ActionsOrientation.VERTICAL
});
this.globalToolBar.getContainer().removeAttribute('tabindex');
this.globalToolBar.getContainer().addClass('global');
this.globalToolBar.actionRunner.addListener(events.EventType.RUN, (e: any) => {
@@ -29,6 +29,35 @@
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.8);
}
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item .action-label:focus:before {
content: "";
position: absolute;
top: 4px;
height: 32px;
width: 0;
border-left: 2px solid;
}
.monaco-workbench.vs > .activitybar > .content .monaco-action-bar .action-item .action-label:focus:before {
border-left-color: #1E8AE5;
}
.monaco-workbench.vs-dark > .activitybar > .content .monaco-action-bar .action-item .action-label:focus:before {
border-left-color: #1E8AE5;
}
.monaco-workbench.hc-black > .activitybar > .content .monaco-action-bar .action-item .action-label:focus:before {
border-left-color: #DF740C;
}
.monaco-workbench > .activitybar.left > .content .monaco-action-bar .action-item .action-label:focus:before {
left: 1px;
}
.monaco-workbench > .activitybar.right > .content .monaco-action-bar .action-item .action-label:focus:before {
right: 1px;
}
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-label > .label {
-ms-flex: 1 1 auto;
flex: 1 1 auto;
@@ -82,12 +111,11 @@
}
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item .action-label.active,
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item:hover .action-label,
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item .action-label:focus {
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item:hover .action-label {
opacity: 1;
}
.monaco-workbench.vs > .activitybar.left:not(.help) > .content > .monaco-action-bar.position-top .action-label.active:after {
.monaco-workbench.vs > .activitybar.left > .content > .monaco-action-bar.position-top .action-label.active:after {
content: '';
position: absolute;
top: 15px;
@@ -99,7 +127,7 @@
border-right: 5px solid #F6F6F6;
}
.monaco-workbench.vs-dark > .activitybar.left:not(.help) > .content > .monaco-action-bar.position-top .action-label.active:after {
.monaco-workbench.vs-dark > .activitybar.left > .content > .monaco-action-bar.position-top .action-label.active:after {
content: '';
position: absolute;
top: 15px;
@@ -111,7 +139,7 @@
border-right: 5px solid #252526;
}
.monaco-workbench.vs > .activitybar.right:not(.help) > .content > .monaco-action-bar.position-top .action-label.active:before {
.monaco-workbench.vs > .activitybar.right > .content > .monaco-action-bar.position-top .action-label.active:before {
content: '';
position: absolute;
top: 15px;
@@ -123,7 +151,7 @@
border-left: 5px solid #F6F6F6;
}
.monaco-workbench.vs-dark > .activitybar.right:not(.help) > .content > .monaco-action-bar.position-top .action-label.active:before {
.monaco-workbench.vs-dark > .activitybar.right > .content > .monaco-action-bar.position-top .action-label.active:before {
content: '';
position: absolute;
top: 15px;
@@ -160,7 +188,6 @@
/* High Contrast Theming */
.monaco-workbench.hc-black > .activitybar > .content .monaco-action-bar .action-label,
.monaco-workbench.hc-black > .activitybar > .content .monaco-action-bar .action-label.active {
background: none;
opacity: 1;
}
@@ -9,6 +9,7 @@ import {Action, IAction} from 'vs/base/common/actions';
import {ActionBarContributor} from 'vs/workbench/browser/actionBarRegistry';
import types = require('vs/base/common/types');
import {Builder} from 'vs/base/browser/builder';
import {EventType, EditorEvent} from 'vs/workbench/common/events';
import {Registry} from 'vs/platform/platform';
import {Panel} from 'vs/workbench/browser/panel';
import {EditorInput, IFileEditorInput, EditorOptions} from 'vs/workbench/common/editor';
@@ -113,6 +114,7 @@ export abstract class BaseEditor extends Panel implements IEditor {
*/
public changePosition(position: Position): void {
this._position = position;
this.emit(EventType.EDITOR_POSITION_CHANGED, new EditorEvent(this, this.getId(), this.input, this.options, this.position));
}
/**
@@ -51,7 +51,6 @@ export class IFrameEditor extends BaseEditor {
let iframeContainerElement = document.createElement('div');
iframeContainerElement.className = 'iframe-container monaco-editor-background'; // Inherit the background color from selected theme
this.iframeContainer = $(iframeContainerElement);
this.iframeContainer.tabindex(0); // enable focus support
// IFrame
this.iframeBuilder = $(this.iframeContainer).element('iframe').addClass('iframe');
@@ -139,6 +138,7 @@ export class IFrameEditor extends BaseEditor {
'<script>',
'var ignoredKeys = [9 /* tab */, 32 /* space */, 33 /* page up */, 34 /* page down */, 38 /* up */, 40 /* down */];',
'var ignoredCtrlCmdKeys = [65 /* a */, 67 /* c */];',
'var ignoredShiftKeys = [9 /* tab */];',
'window.document.body.addEventListener("keydown", function(event) {', // Listen to keydown events in the iframe
' try {',
' if (ignoredKeys.some(function(i) { return i === event.keyCode; })) {',
@@ -153,6 +153,12 @@ export class IFrameEditor extends BaseEditor {
' }',
' }',
'',
' if (ignoredShiftKeys.some(function(i) { return i === event.keyCode; })) {',
' if (event.shiftKey) {',
' return;', // we want some shift keys to be supported (e.g. Shift+Tab for copy)
' }',
' }',
'',
' event.preventDefault();', // very important to not get duplicate actions when this one bubbles up!
'',
' var fakeEvent = document.createEvent("KeyboardEvent");', // create a keyboard event
@@ -33,14 +33,14 @@
/* CSS checkerbox pattern (learnt from http://lea.verou.me/2011/02/checkerboard-pattern-with-css3/*/
.monaco-workbench.vs .binary-container img {
background-image:
linear-gradient(45deg, rgb(220, 220, 220) 25%, transparent 25%, transparent 75%, rgb(220, 220, 220) 75%, rgb(220, 220, 220)),
background-image:
linear-gradient(45deg, rgb(220, 220, 220) 25%, transparent 25%, transparent 75%, rgb(220, 220, 220) 75%, rgb(220, 220, 220)),
linear-gradient(45deg, rgb(220, 220, 220) 25%, transparent 25%, transparent 75%, rgb(220, 220, 220) 75%, rgb(220, 220, 220));
}
.monaco-workbench.vs-dark .binary-container img {
background-image:
linear-gradient(45deg, rgb(80, 80, 80) 25%, transparent 25%, transparent 75%, rgb(80, 80, 80) 75%, rgb(80, 80, 80)),
background-image:
linear-gradient(45deg, rgb(80, 80, 80) 25%, transparent 25%, transparent 75%, rgb(80, 80, 80) 75%, rgb(80, 80, 80)),
linear-gradient(45deg, rgb(80, 80, 80) 25%, transparent 25%, transparent 75%, rgb(80, 80, 80) 75%, rgb(80, 80, 80));
}
@@ -58,8 +58,4 @@
.monaco-workbench.vs-dark .binary-container a:hover {
color: #4080D0;
}
.monaco-workbench .binary-container:focus {
outline: 0;
}
@@ -21,14 +21,14 @@
/* CSS checkerbox pattern (learnt from http://lea.verou.me/2011/02/checkerboard-pattern-with-css3/*/
.monaco-workbench.vs .binary-container img {
background-image:
linear-gradient(45deg, rgb(220, 220, 220) 25%, transparent 25%, transparent 75%, rgb(220, 220, 220) 75%, rgb(220, 220, 220)),
background-image:
linear-gradient(45deg, rgb(220, 220, 220) 25%, transparent 25%, transparent 75%, rgb(220, 220, 220) 75%, rgb(220, 220, 220)),
linear-gradient(45deg, rgb(220, 220, 220) 25%, transparent 25%, transparent 75%, rgb(220, 220, 220) 75%, rgb(220, 220, 220));
}
.monaco-workbench.vs-dark .binary-container img {
background-image:
linear-gradient(45deg, rgb(80, 80, 80) 25%, transparent 25%, transparent 75%, rgb(80, 80, 80) 75%, rgb(80, 80, 80)),
background-image:
linear-gradient(45deg, rgb(80, 80, 80) 25%, transparent 25%, transparent 75%, rgb(80, 80, 80) 75%, rgb(80, 80, 80)),
linear-gradient(45deg, rgb(80, 80, 80) 25%, transparent 25%, transparent 75%, rgb(80, 80, 80) 75%, rgb(80, 80, 80));
}
@@ -38,8 +38,4 @@
.monaco-workbench.vs-dark .binary-container {
background-color: #1E1E1E;
}
.monaco-workbench .binary-container:focus {
outline: 0;
}
@@ -5,8 +5,8 @@
.monaco-workbench .iframe-container .iframe {
-webkit-box-sizing: border-box;
-o-box-sizing: border-box;
-moz-box-sizing: border-box;
-o-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
@@ -14,8 +14,4 @@
.monaco-workbench .iframe-container.ipad-touch-enabled {
-webkit-overflow-scrolling: touch;
overflow: auto;
}
.monaco-workbench .iframe-container:focus {
outline: 0;
}
@@ -9,6 +9,7 @@
.monaco-workbench > .part.panel > .title {
display: block;
text-transform: uppercase;
border-top: 1px solid #007ACC;
}
@@ -80,13 +80,6 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
return this.openComposite(id, focus);
}
public createTitleArea(parent: Builder): Builder {
const result = super.createTitleArea(parent);
result.addClass('monaco-editor-background');
return result;
}
private get activePanel(): IPanel {
return this.getActivePanel();
}
@@ -52,7 +52,8 @@
display: none;
}
.monaco-workbench .viewlet .collapsible.header:hover .actions {
.monaco-workbench .viewlet .collapsible.header:hover .actions,
.monaco-workbench .viewlet .collapsible.header.focused .actions {
display: block;
}
+26 -1
View File
@@ -333,6 +333,12 @@ export class AdaptiveCollapsibleViewletView extends FixedCollapsibleView impleme
});
}
protected changeState(state: CollapsibleState): void {
changeState(state, this.tree);
super.changeState(state);
}
protected renderViewTree(container: HTMLElement): HTMLElement {
return renderViewTree(container);
}
@@ -434,6 +440,12 @@ export class CollapsibleViewletView extends CollapsibleView implements IViewletV
this.toDispose = [];
}
protected changeState(state: CollapsibleState): void {
changeState(state, this.tree);
super.changeState(state);
}
public create(): TPromise<void> {
return Promise.as(null);
}
@@ -517,7 +529,7 @@ export class CollapsibleViewletView extends CollapsibleView implements IViewletV
this.isDisposed = true;
this.treeContainer = null;
this.tree.dispose();
this.dragHandler.dispose();
this.toDispose = disposeAll(this.toDispose);
@@ -538,6 +550,19 @@ function renderViewTree(container: HTMLElement): HTMLElement {
return treeContainer;
}
function changeState(state: CollapsibleState, tree: ITree): void {
if (!tree) {
return;
}
if (state == CollapsibleState.EXPANDED) {
$(tree.getHTMLElement()).show();
tree.DOMFocus(); // make the tree have focus once a view gets expanded
} else {
$(tree.getHTMLElement()).hide(); // make sure the tree goes out of the tabindex world by hiding it
}
}
function focus(tree: ITree): void {
if (!tree) {
return; // return early if viewlet has not yet been created
+2 -2
View File
@@ -752,8 +752,8 @@ export class Workbench implements IPartService {
// Create Parts
this.createActivityBarPart();
this.createSidebarPart();
this.createPanelPart();
this.createEditorPart();
this.createPanelPart();
this.createStatusbarPart();
// Create QuickOpen
@@ -804,7 +804,7 @@ export class Workbench implements IPartService {
private createPanelPart(): void {
let panelPartContainer = $(this.workbench)
.div({
'class': ['part', 'panel'],
'class': ['part', 'panel', 'monaco-editor-background'],
id: Identifiers.PANEL_PART
});
+5
View File
@@ -69,6 +69,11 @@ export class EventType {
*/
static EDITOR_SET_INPUT_ERROR = 'editorSetInputError';
/**
* Event type for when the editor position has been changed
*/
static EDITOR_POSITION_CHANGED = 'editorPositionChanged';
/**
* An event type that fires when a text editor changes its selection.
*/
@@ -47,6 +47,73 @@
text-decoration: none;
}
/* START Keyboard Focus Indication Styles */
.monaco-shell.vs [tabindex="0"]:focus,
.monaco-shell.vs select:focus,
.monaco-shell.vs input[type="button"]:focus,
.monaco-shell.vs input[type="submit"]:focus,
.monaco-shell.vs input[type="checkbox"]:focus {
outline: 1px auto #1E8AE5;
outline-offset: -3px;
opacity: 1 !important; /* prevent components from dimming focus feedback */
}
.monaco-shell.vs-dark [tabindex="0"]:focus,
.monaco-shell.vs-dark select:focus,
.monaco-shell.vs-dark input[type="button"]:focus,
.monaco-shell.vs-dark input[type="submit"]:focus,
.monaco-shell.vs-dark input[type="checkbox"]:focus {
outline: 1px auto #1E8AE5;
outline-offset: -3px;
opacity: 1 !important; /* prevent components from dimming focus feedback */
}
.monaco-shell.hc-black [tabindex="0"]:focus,
.monaco-shell.hc-black select:focus,
.monaco-shell.hc-black input[type="button"]:focus,
.monaco-shell.hc-black input[type="submit"]:focus,
.monaco-shell.hc-black input[type="checkbox"]:focus {
outline: 2px auto #DF740C;
outline-offset: -2px;
}
.monaco-shell.vs .monaco-tree.focused .monaco-tree-rows:empty,
.monaco-shell.vs .monaco-tree.focused.no-item-focus .monaco-tree-rows {
outline: 1px auto #1E8AE5; /* we still need to handle the empty tree or no focus item case */
outline-offset: -3px;
}
.monaco-shell.vs-dark .monaco-tree.focused .monaco-tree-rows:empty,
.monaco-shell.vs-dark .monaco-tree.focused.no-item-focus .monaco-tree-rows {
outline: 1px auto #1E8AE5; /* we still need to handle the empty tree or no focus item case */
outline-offset: -3px;
}
.monaco-shell.hc-black .monaco-tree.focused .monaco-tree-rows:empty,
.monaco-shell.hc-black .monaco-tree.focused.no-item-focus .monaco-tree-rows {
outline: 2px auto #DF740C; /* we still need to handle the empty tree or no focus item case */
outline-offset: -2px;
}
.monaco-shell .quick-open-widget .quick-open-tree .monaco-tree-rows {
outline: 0 !important; /* quick open is special because focus is always in the input field */
}
.monaco-shell input[type="text"], .monaco-shell textarea {
outline: 0; /* do not show outline in input fields and textarea */
}
.monaco-shell .monaco-tree:focus {
outline: 0 !important; /* tree indicates focus not via outline but through the focussed item */
}
.monaco-shell .activitybar [tabindex="0"]:focus {
outline: 0 !important; /* activity bar indicates focus customly */
}
/* END Keyboard Focus Indication Styles */
.monaco-shell a.prominent {
text-decoration: underline;
}
+4 -4
View File
@@ -1008,9 +1008,9 @@ export class WindowsManager {
dialog.showMessageBox(vscodeWindow.win, {
title: env.product.nameLong,
type: 'warning',
buttons: [nls.localize('reload', "Reload"), nls.localize('wait', "Keep Waiting"), nls.localize('close', "Close")],
buttons: [nls.localize('reopen', "Reopen"), nls.localize('wait', "Keep Waiting"), nls.localize('close', "Close")],
message: nls.localize('appStalled', "The window is no longer responding"),
detail: nls.localize('appStalledDetail', "You can reload or close the window or keep waiting."),
detail: nls.localize('appStalledDetail', "You can reopen or close the window or keep waiting."),
noLink: true
}, (result) => {
if (result === 0) {
@@ -1026,9 +1026,9 @@ export class WindowsManager {
dialog.showMessageBox(vscodeWindow.win, {
title: env.product.nameLong,
type: 'warning',
buttons: [nls.localize('reload', "Reload"), nls.localize('close', "Close")],
buttons: [nls.localize('reopen', "Reopen"), nls.localize('close', "Close")],
message: nls.localize('appCrashed', "The window has crashed"),
detail: nls.localize('appCrashedDetail', "We are sorry for the inconvenience! Do you want to reload or close the window?"),
detail: nls.localize('appCrashedDetail', "We are sorry for the inconvenience! You can reopen the window to continue where you left off."),
noLink: true
}, (result) => {
if (result === 0) {
@@ -49,6 +49,18 @@ export class SelectConfigActionItem extends BaseActionItem {
this.setOptions().done(null, errors.onUnexpectedError);
}
public focus(): void {
if (this.select) {
this.select.focus();
}
}
public blur(): void {
if (this.select) {
this.select.blur();
}
}
private setOptions(): Promise {
let previousSelectedIndex = this.select.selectedIndex;
this.select.options.length = 0;
@@ -1 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g fill="#E89208"><circle cx="8" cy="8" r="5"/></g></g></svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{fill:#CC1100;}
</style>
<path class="st0" d="M8,3C5.2,3,3,5.2,3,8s2.2,5,5,5s5-2.2,5-5S10.8,3,8,3z M10.8,9.9H5.2V8.7h5.7V9.9z M10.8,7.3H5.2V6.1h5.7V7.3z"
/>
</svg>

Before

Width:  |  Height:  |  Size: 179 B

After

Width:  |  Height:  |  Size: 539 B

@@ -1 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g fill="#E89208"><circle cx="8" cy="8" r="5"/></g></g></svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{fill:#E51400;}
</style>
<path class="st0" d="M8,3C5.2,3,3,5.2,3,8s2.2,5,5,5s5-2.2,5-5S10.8,3,8,3z M10.8,9.9H5.2V8.7h5.7V9.9z M10.8,7.3H5.2V6.1h5.7V7.3z"
/>
</svg>

Before

Width:  |  Height:  |  Size: 179 B

After

Width:  |  Height:  |  Size: 539 B

@@ -46,7 +46,8 @@
height: 16px;
}
.debug-viewlet .monaco-tree .monaco-tree-row:hover .content .monaco-action-bar {
.debug-viewlet .monaco-tree .monaco-tree-row:hover .content .monaco-action-bar,
.debug-viewlet .monaco-tree.focused .monaco-tree-row.focused .content .monaco-action-bar {
display: block;
}
@@ -117,7 +117,6 @@
width: 100%;
border: 0;
padding: 0;
outline: none;
font-family: Monaco, Menlo, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback";
line-height: 18px;
}
+1 -2
View File
@@ -97,11 +97,10 @@ export class Repl extends Panel {
public create(parent: builder.Builder): TPromise<void> {
super.create(parent);
const container = dom.append(parent.getHTMLElement(), $('.repl'));
// inherit the background color from selected theme.
dom.addClass(container, 'monaco-editor-background');
this.treeContainer = dom.append(container, $('.repl-tree'));
const replInputContainer = dom.append(container, $(platform.isWindows ? '.repl-input-wrapper.windows' : platform.isMacintosh ? '.repl-input-wrapper.mac' : '.repl-input-wrapper.linux'));
this.replInput = <HTMLInputElement>dom.append(replInputContainer, $('input.repl-input'));
this.replInput.type = 'text';
dom.addStandardDisposableListener(this.replInput, 'keydown', (e: dom.IKeyboardEvent) => {
let trimmedValue = this.replInput.value.trim();
@@ -75,7 +75,7 @@ const openViewletKb: IKeybindings = {
'vs/workbench/parts/debug/browser/repl',
'Repl',
debug.REPL_ID,
nls.localize('debugConsole', "DEBUG CONSOLE"),
nls.localize('debugConsole', "Debug Console"),
'repl'
));
(<panel.PanelRegistry>platform.Registry.as(panel.Extensions.Panels)).setDefaultPanelId(debug.REPL_ID);
@@ -106,7 +106,7 @@ export class FeedbackDropdown extends Dropdown {
$('h2.title').text(nls.localize("label.sendASmile", "Let us know how we're doing")).appendTo($form);
this.invoke($('div.cancel'), () => {
this.invoke($('div.cancel').attr('tabindex', '0'), () => {
this.hide();
}).appendTo($form);
@@ -146,10 +146,10 @@ export class FeedbackDropdown extends Dropdown {
let $contactUsContainer = $('div.channels').appendTo($contactUs);
$('div').append($('a').attr('target', '_blank').attr('href', this.reportIssueLink).text(nls.localize("submit a bug", "Submit a bug")))
$('div').append($('a').attr('target', '_blank').attr('href', this.reportIssueLink).text(nls.localize("submit a bug", "Submit a bug")).attr('tabindex', '0'))
.appendTo($contactUsContainer);
$('div').append($('a').attr('target', '_blank').attr('href', this.requestFeatureLink).text(nls.localize("request a missing feature", "Request a missing feature")))
$('div').append($('a').attr('target', '_blank').attr('href', this.requestFeatureLink).text(nls.localize("request a missing feature", "Request a missing feature")).attr('tabindex', '0'))
.appendTo($contactUsContainer);
let $charCounter = $('span.char-counter').text('(' + FeedbackDropdown.MAX_FEEDBACK_CHARS + ' ' + nls.localize("characters left", "characters left") + ')');
@@ -117,6 +117,8 @@ export class ExplorerViewlet extends Viewlet {
if (this.explorerView) {
this.explorerView.focus();
} else if (this.workingFilesView) {
this.workingFilesView.focus();
}
}
@@ -49,7 +49,8 @@
height: 16px;
}
.git-viewlet > .changes-view > .status-view > .monaco-tree .monaco-tree-row:hover .content .monaco-action-bar {
.git-viewlet > .changes-view > .status-view > .monaco-tree .monaco-tree-row:hover .content .monaco-action-bar,
.git-viewlet > .changes-view > .status-view > .monaco-tree.focused .monaco-tree-row.focused .content .monaco-action-bar {
display: block;
}
@@ -409,12 +409,12 @@ export class ChangesView extends EventEmitter.EventEmitter implements GitView.IV
const resource = fileInput.getResource();
const workspaceRoot = this.contextService.getWorkspace().resource.fsPath;
if (!paths.isEqualOrParent(resource.fsPath, workspaceRoot)) {
if (!workspaceRoot || !paths.isEqualOrParent(resource.fsPath, workspaceRoot)) {
return null; // out of workspace not yet supported
}
const repositoryRoot = this.gitService.getModel().getRepositoryRoot();
if (!paths.isEqualOrParent(resource.fsPath, repositoryRoot)) {
if (!repositoryRoot || !paths.isEqualOrParent(resource.fsPath, repositoryRoot)) {
return null; // out of repository not supported
}
@@ -27,36 +27,4 @@
min-width: inherit;
padding: 4px 4px 4px 0;
margin-bottom: 10px;
}
.git-viewlet > .empty-view .button {
-moz-box-sizing: border-box;
box-sizing: border-box;
display: inline-block;
width: 100%;
padding: 4px;
text-align: center;
color: white;
background: #007ACC;
}
.git-viewlet > .empty-view .button.disabled {
opacity: 0.4;
cursor: default;
}
.git-viewlet > .empty-view .button:hover {
text-decoration: none;
}
.git-viewlet > .empty-view .button:not(.disabled):hover {
background: #006BB3;
}
.git-viewlet > .empty-view .button:not(.disabled):active {
background: #005F9E;
}
.vs-dark .git-viewlet > .empty-view .button {
background: #0E639C;
}
}
@@ -12,6 +12,7 @@ import EventEmitter = require('vs/base/common/eventEmitter');
import DOM = require('vs/base/browser/dom');
import Errors = require('vs/base/common/errors');
import Keyboard = require('vs/base/browser/keyboardEvent');
import {Button} from 'vs/base/browser/ui/button/button';
import WinJS = require('vs/base/common/winjs.base');
import Builder = require('vs/base/browser/builder');
import Actions = require('vs/base/common/actions');
@@ -29,53 +30,6 @@ import IGitService = git.IGitService;
var $ = Builder.$;
export class Button extends EventEmitter.EventEmitter {
private $el: Builder.Builder;
constructor(container: Builder.Builder);
constructor(container: HTMLElement);
constructor(container: any) {
super();
this.$el = $('a.button.clone').href('#').appendTo(container);
this.$el.on('click', (e) => {
if (!this.enabled) {
DOM.EventHelper.stop(e);
return;
}
this.emit('click', e);
});
}
public set label(value: string) {
this.$el.text(value);
}
public set enabled(value: boolean) {
if (value) {
this.$el.removeClass('disabled');
} else {
this.$el.addClass('disabled');
}
}
public get enabled() {
return !this.$el.hasClass('disabled');
}
public dispose(): void {
if (this.$el) {
this.$el.dispose();
this.$el = null;
}
super.dispose();
}
}
export class EmptyView extends EventEmitter.EventEmitter implements GitView.IView {
public ID = 'empty';
@@ -47,26 +47,26 @@ export class GitlessView
if (platform.isMacintosh) {
instructions = nls.localize('macInstallWith',
"You can either install it with {0}, download it from {1} or install the {2} command line developer tools, by simply typing {3} on a Terminal prompt.",
'<a href="http://brew.sh/" target="_blank">Homebrew</a>',
'<a href="http://git-scm.com/download/mac" target="_blank">git-scm.com</a>',
'<a href="https://developer.apple.com/xcode/" target="_blank">XCode</a>',
'<a href="http://brew.sh/" tabindex="0" target="_blank">Homebrew</a>',
'<a href="http://git-scm.com/download/mac" tabindex="0" target="_blank">git-scm.com</a>',
'<a href="https://developer.apple.com/xcode/" tabindex="0" target="_blank">XCode</a>',
'<code>git</code>'
);
} else if (platform.isWindows) {
instructions = nls.localize('winInstallWith',
"You can either install it with {0} or download it from {1}.",
'<a href="https://chocolatey.org/packages/git" target="_blank">Chocolatey</a>',
'<a href="http://git-scm.com/download/win" target="_blank">git-scm.com</a>'
'<a href="https://chocolatey.org/packages/git" tabindex="0" target="_blank">Chocolatey</a>',
'<a href="http://git-scm.com/download/win" tabindex="0" target="_blank">git-scm.com</a>'
);
} else if (platform.isLinux) {
instructions = nls.localize('linuxDownloadFrom',
"You can download it from {0}.",
'<a href="http://git-scm.com/download/linux" target="_blank">git-scm.com</a>'
'<a href="http://git-scm.com/download/linux" tabindex="0" target="_blank">git-scm.com</a>'
);
} else {
instructions = nls.localize('downloadFrom',
"You can download it from {0}.",
'<a href="http://git-scm.com/download" target="_blank">git-scm.com</a>'
'<a href="http://git-scm.com/download" tabindex="0" target="_blank">git-scm.com</a>'
);
}
@@ -9,6 +9,7 @@ import {KeybindingsRegistry} from 'vs/platform/keybinding/common/keybindingsRegi
import {IInstantiationService, ServicesAccessor} from 'vs/platform/instantiation/common/instantiation';
import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService';
import URI from 'vs/base/common/uri';
import {Position as EditorPosition} from 'vs/platform/editor/common/editor';
import {HtmlInput} from '../common/htmlInput';
import {HtmlPreviewPart} from 'vs/workbench/parts/html/browser/htmlPreviewPart';
import {Registry} from 'vs/platform/platform';
@@ -27,19 +28,15 @@ import {SyncDescriptor} from 'vs/platform/instantiation/common/descriptors';
// --- Register Commands
KeybindingsRegistry.registerCommandDesc({
id: 'workbench.html.preview',
id: '_workbench.previewHtml',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(0),
description: {
description: 'Preview an html document.',
args: [{ name: 'uri', description: 'Uri of the document to preview.', constraint: URI }]
},
handler(accessor: ServicesAccessor, args: [URI]) {
handler(accessor: ServicesAccessor, args: [URI, EditorPosition]) {
let [resource] = args;
let [resource, position] = args;
let name = resource.fsPath;
let input = accessor.get(IInstantiationService).createInstance(HtmlInput, name, undefined, resource);
return accessor.get(IWorkbenchEditorService).openEditor(input)
return accessor.get(IWorkbenchEditorService).openEditor(input, null, position)
.then(editor => true);
},
context: undefined,

Some files were not shown because too many files have changed in this diff Show More