Merge VS Code 1.23.1 (#1520)

This commit is contained in:
Matt Irvine
2018-06-05 11:24:51 -07:00
committed by GitHub
parent e3baf5c443
commit 0c58f09e59
3651 changed files with 74249 additions and 48599 deletions

View File

@@ -5,7 +5,7 @@
'use strict';
import * as Platform from 'vs/base/common/platform';
import Event, { Emitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
class WindowManager {
@@ -15,9 +15,9 @@ class WindowManager {
// --- Zoom Level
private _zoomLevel: number = 0;
private _lastZoomLevelChangeTime: number = 0;
private _onDidChangeZoomLevel: Emitter<number> = new Emitter<number>();
private readonly _onDidChangeZoomLevel: Emitter<number> = new Emitter<number>();
public onDidChangeZoomLevel: Event<number> = this._onDidChangeZoomLevel.event;
public readonly onDidChangeZoomLevel: Event<number> = this._onDidChangeZoomLevel.event;
public getZoomLevel(): number {
return this._zoomLevel;
}
@@ -61,9 +61,9 @@ class WindowManager {
// --- Fullscreen
private _fullscreen: boolean;
private _onDidChangeFullscreen: Emitter<void> = new Emitter<void>();
private readonly _onDidChangeFullscreen: Emitter<void> = new Emitter<void>();
public onDidChangeFullscreen: Event<void> = this._onDidChangeFullscreen.event;
public readonly onDidChangeFullscreen: Event<void> = this._onDidChangeFullscreen.event;
public setFullscreen(fullscreen: boolean): void {
if (this._fullscreen === fullscreen) {
return;
@@ -78,9 +78,9 @@ class WindowManager {
// --- Accessibility
private _accessibilitySupport = Platform.AccessibilitySupport.Unknown;
private _onDidChangeAccessibilitySupport: Emitter<void> = new Emitter<void>();
private readonly _onDidChangeAccessibilitySupport: Emitter<void> = new Emitter<void>();
public onDidChangeAccessibilitySupport: Event<void> = this._onDidChangeAccessibilitySupport.event;
public readonly onDidChangeAccessibilitySupport: Event<void> = this._onDidChangeAccessibilitySupport.event;
public setAccessibilitySupport(accessibilitySupport: Platform.AccessibilitySupport): void {
if (this._accessibilitySupport === accessibilitySupport) {
return;
@@ -155,6 +155,7 @@ export const isWebKit = (userAgent.indexOf('AppleWebKit') >= 0);
export const isChrome = (userAgent.indexOf('Chrome') >= 0);
export const isSafari = (userAgent.indexOf('Chrome') === -1) && (userAgent.indexOf('Safari') >= 0);
export const isIPad = (userAgent.indexOf('iPad') >= 0);
export const isEdgeWebView = isEdge && (userAgent.indexOf('WebView/') >= 0);
export const isChromev56 = (
userAgent.indexOf('Chrome/56.') >= 0

View File

@@ -3,12 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.builder-hidden {
.monaco-builder-hidden {
display: none !important;
visibility: hidden !important;
}
.builder-visible {
display: inherit;
visibility: visible;
}
}

View File

@@ -6,11 +6,11 @@
import 'vs/css!./builder';
import { TPromise } from 'vs/base/common/winjs.base';
import types = require('vs/base/common/types');
import * as types from 'vs/base/common/types';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import strings = require('vs/base/common/strings');
import assert = require('vs/base/common/assert');
import DOM = require('vs/base/browser/dom');
import * as strings from 'vs/base/common/strings';
import * as assert from 'vs/base/common/assert';
import * as DOM from 'vs/base/browser/dom';
/**
* Welcome to the monaco builder. The recommended way to use it is:
@@ -43,26 +43,6 @@ export interface QuickBuilder {
(builder: Builder): Builder;
}
/**
* Create a new builder from the element that is uniquely identified by the given identifier. If the
* second parameter "offdom" is set to true, the created elements will only be added to the provided
* element when the build() method is called.
*/
export function withElementById(id: string, offdom?: boolean): Builder {
assert.ok(types.isString(id), 'Expected String as parameter');
let element = document.getElementById(id);
if (element) {
return new Builder(element, offdom);
}
return null;
}
export const Build = {
withElementById: withElementById
};
// --- Implementation starts here
let MS_DATA_KEY = '_msDataKey';
@@ -70,16 +50,6 @@ let DATA_BINDING_ID = '__$binding';
let LISTENER_BINDING_ID = '__$listeners';
let VISIBILITY_BINDING_ID = '__$visibility';
export class Dimension {
public width: number;
public height: number;
constructor(width: number, height: number) {
this.width = width;
this.height = height;
}
}
function data(element: any): any {
if (!element[MS_DATA_KEY]) {
element[MS_DATA_KEY] = {};
@@ -927,50 +897,6 @@ export class Builder implements IDisposable {
return this;
}
/**
* Sets the CSS property min-size.
*/
public minSize(size: string): Builder;
public minSize(width: number, height?: number): Builder;
public minSize(width: string, height?: string): Builder;
public minSize(width: any, height?: any): Builder {
if (types.isString(width) && width.indexOf(' ') >= 0) {
return this.minSize.apply(this, width.split(' '));
}
if (!types.isUndefinedOrNull(width)) {
this.currentElement.style.minWidth = this.toPixel(width);
}
if (!types.isUndefinedOrNull(height)) {
this.currentElement.style.minHeight = this.toPixel(height);
}
return this;
}
/**
* Sets the CSS property max-size.
*/
public maxSize(size: string): Builder;
public maxSize(width: number, height?: number): Builder;
public maxSize(width: string, height?: string): Builder;
public maxSize(width: any, height?: any): Builder {
if (types.isString(width) && width.indexOf(' ') >= 0) {
return this.maxSize.apply(this, width.split(' '));
}
if (!types.isUndefinedOrNull(width)) {
this.currentElement.style.maxWidth = this.toPixel(width);
}
if (!types.isUndefinedOrNull(height)) {
this.currentElement.style.maxHeight = this.toPixel(height);
}
return this;
}
/**
* Sets the CSS property display.
*/
@@ -984,8 +910,8 @@ export class Builder implements IDisposable {
* Shows the current element of the builder.
*/
public show(): Builder {
if (this.hasClass('builder-hidden')) {
this.removeClass('builder-hidden');
if (this.hasClass('monaco-builder-hidden')) {
this.removeClass('monaco-builder-hidden');
}
this.attr('aria-hidden', 'false');
@@ -1023,8 +949,8 @@ export class Builder implements IDisposable {
* Hides the current element of the builder.
*/
public hide(): Builder {
if (!this.hasClass('builder-hidden')) {
this.addClass('builder-hidden');
if (!this.hasClass('monaco-builder-hidden')) {
this.addClass('monaco-builder-hidden');
}
this.attr('aria-hidden', 'true');
@@ -1038,7 +964,7 @@ export class Builder implements IDisposable {
* Returns true if the current element of the builder is hidden.
*/
public isHidden(): boolean {
return this.hasClass('builder-hidden') || this.currentElement.style.display === 'none';
return this.hasClass('monaco-builder-hidden') || this.currentElement.style.display === 'none';
}
private cancelVisibilityPromise(): void {
@@ -1049,121 +975,6 @@ export class Builder implements IDisposable {
}
}
/**
* Sets the CSS property border.
*/
public border(border: string): Builder;
public border(width: number, style?: string, color?: string): Builder;
public border(width: any, style?: string, color?: string): Builder {
if (types.isString(width) && width.indexOf(' ') >= 0) {
return this.border.apply(this, width.split(' '));
}
this.currentElement.style.borderWidth = this.toPixel(width);
if (color) {
this.currentElement.style.borderColor = color;
}
if (style) {
this.currentElement.style.borderStyle = style;
}
return this;
}
/**
* Sets the CSS property border-top.
*/
public borderTop(border: string): Builder;
public borderTop(width: number, style: string, color: string): Builder;
public borderTop(width: any, style?: string, color?: string): Builder {
if (types.isString(width) && width.indexOf(' ') >= 0) {
return this.borderTop.apply(this, width.split(' '));
}
this.currentElement.style.borderTopWidth = this.toPixel(width);
if (color) {
this.currentElement.style.borderTopColor = color;
}
if (style) {
this.currentElement.style.borderTopStyle = style;
}
return this;
}
/**
* Sets the CSS property border-bottom.
*/
public borderBottom(border: string): Builder;
public borderBottom(width: number, style: string, color: string): Builder;
public borderBottom(width: any, style?: string, color?: string): Builder {
if (types.isString(width) && width.indexOf(' ') >= 0) {
return this.borderBottom.apply(this, width.split(' '));
}
this.currentElement.style.borderBottomWidth = this.toPixel(width);
if (color) {
this.currentElement.style.borderBottomColor = color;
}
if (style) {
this.currentElement.style.borderBottomStyle = style;
}
return this;
}
/**
* Sets the CSS property border-left.
*/
public borderLeft(border: string): Builder;
public borderLeft(width: number, style: string, color: string): Builder;
public borderLeft(width: any, style?: string, color?: string): Builder {
if (types.isString(width) && width.indexOf(' ') >= 0) {
return this.borderLeft.apply(this, width.split(' '));
}
this.currentElement.style.borderLeftWidth = this.toPixel(width);
if (color) {
this.currentElement.style.borderLeftColor = color;
}
if (style) {
this.currentElement.style.borderLeftStyle = style;
}
return this;
}
/**
* Sets the CSS property border-right.
*/
public borderRight(border: string): Builder;
public borderRight(width: number, style: string, color: string): Builder;
public borderRight(width: any, style?: string, color?: string): Builder {
if (types.isString(width) && width.indexOf(' ') >= 0) {
return this.borderRight.apply(this, width.split(' '));
}
this.currentElement.style.borderRightWidth = this.toPixel(width);
if (color) {
this.currentElement.style.borderRightColor = color;
}
if (style) {
this.currentElement.style.borderRightStyle = style;
}
return this;
}
private toPixel(obj: any): string {
if (obj.toString().indexOf('px') === -1) {
return obj.toString() + 'px';
@@ -1375,39 +1186,18 @@ export class Builder implements IDisposable {
/**
* Gets the size (in pixels) of an element, including the margin.
*/
public getTotalSize(): Dimension {
public getTotalSize(): DOM.Dimension {
let totalWidth = DOM.getTotalWidth(this.currentElement);
let totalHeight = DOM.getTotalHeight(this.currentElement);
return new Dimension(totalWidth, totalHeight);
return new DOM.Dimension(totalWidth, totalHeight);
}
/**
* Another variant of getting the inner dimensions of an element.
*/
public getClientArea(): Dimension {
// 0.) Try with DOM clientWidth / clientHeight
if (this.currentElement !== document.body) {
return new Dimension(this.currentElement.clientWidth, this.currentElement.clientHeight);
}
// 1.) Try innerWidth / innerHeight
if (window.innerWidth && window.innerHeight) {
return new Dimension(window.innerWidth, window.innerHeight);
}
// 2.) Try with document.body.clientWidth / document.body.clientHeigh
if (document.body && document.body.clientWidth && document.body.clientWidth) {
return new Dimension(document.body.clientWidth, document.body.clientHeight);
}
// 3.) Try with document.documentElement.clientWidth / document.documentElement.clientHeight
if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientHeight) {
return new Dimension(document.documentElement.clientWidth, document.documentElement.clientHeight);
}
throw new Error('Unable to figure out browser width and height');
public getClientArea(): DOM.Dimension {
return DOM.getClientArea(this.currentElement);
}
}
@@ -1653,7 +1443,3 @@ export const $: QuickBuilder = function (arg?: any): Builder {
throw new Error('Bad use of $');
}
};
(<any>$).Dimension = Dimension;
(<any>$).Builder = Builder;
(<any>$).Build = Build;

View File

@@ -5,18 +5,19 @@
'use strict';
import { $ } from 'vs/base/browser/builder';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { addDisposableListener } from 'vs/base/browser/dom';
/**
* A helper that will execute a provided function when the provided HTMLElement receives
* dragover event for 800ms. If the drag is aborted before, the callback will not be triggered.
*/
export class DelayedDragHandler {
private toDispose: IDisposable[] = [];
private timeout: number;
constructor(container: HTMLElement, callback: () => void) {
$(container).on('dragover', () => {
this.toDispose.push(addDisposableListener(container, 'dragover', () => {
if (!this.timeout) {
this.timeout = setTimeout(() => {
callback();
@@ -24,9 +25,13 @@ export class DelayedDragHandler {
this.timeout = null;
}, 800);
}
});
}));
$(container).on(['dragleave', 'drop', 'dragend'], () => this.clearDragTimeout());
['dragleave', 'drop', 'dragend'].forEach(type => {
this.toDispose.push(addDisposableListener(container, type, () => {
this.clearDragTimeout();
}));
});
}
private clearDragTimeout(): void {
@@ -37,6 +42,7 @@ export class DelayedDragHandler {
}
public dispose(): void {
this.toDispose = dispose(this.toDispose);
this.clearDragTimeout();
}
}

View File

@@ -13,7 +13,7 @@ import * as browser from 'vs/base/browser/browser';
import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { IMouseEvent, StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { CharCode } from 'vs/base/common/charCode';
import Event, { Emitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
export function clearNode(node: HTMLElement) {
@@ -35,7 +35,9 @@ export function isInDOM(node: Node): boolean {
interface IDomClassList {
hasClass(node: HTMLElement, className: string): boolean;
addClass(node: HTMLElement, className: string): void;
addClasses(node: HTMLElement, ...classNames: string[]): void;
removeClass(node: HTMLElement, className: string): void;
removeClasses(node: HTMLElement, ...classNames: string[]): void;
toggleClass(node: HTMLElement, className: string, shouldHaveIt?: boolean): void;
}
@@ -110,6 +112,10 @@ const _manualClassList = new class implements IDomClassList {
return this._lastStart !== -1;
}
addClasses(node: HTMLElement, ...classNames: string[]): void {
classNames.forEach(nameValue => nameValue.split(' ').forEach(name => this.addClass(node, name)));
}
addClass(node: HTMLElement, className: string): void {
if (!node.className) { // doesn't have it for sure
node.className = className;
@@ -130,6 +136,10 @@ const _manualClassList = new class implements IDomClassList {
}
}
removeClasses(node: HTMLElement, ...classNames: string[]): void {
classNames.forEach(nameValue => nameValue.split(' ').forEach(name => this.removeClass(node, name)));
}
toggleClass(node: HTMLElement, className: string, shouldHaveIt?: boolean): void {
this._findClassName(node, className);
if (this._lastStart !== -1 && (shouldHaveIt === void 0 || !shouldHaveIt)) {
@@ -146,6 +156,10 @@ const _nativeClassList = new class implements IDomClassList {
return className && node.classList && node.classList.contains(className);
}
addClasses(node: HTMLElement, ...classNames: string[]): void {
classNames.forEach(nameValue => nameValue.split(' ').forEach(name => this.addClass(node, name)));
}
addClass(node: HTMLElement, className: string): void {
if (className && node.classList) {
node.classList.add(className);
@@ -158,6 +172,10 @@ const _nativeClassList = new class implements IDomClassList {
}
}
removeClasses(node: HTMLElement, ...classNames: string[]): void {
classNames.forEach(nameValue => nameValue.split(' ').forEach(name => this.removeClass(node, name)));
}
toggleClass(node: HTMLElement, className: string, shouldHaveIt?: boolean): void {
if (node.classList) {
node.classList.toggle(className, shouldHaveIt);
@@ -170,7 +188,9 @@ const _nativeClassList = new class implements IDomClassList {
const _classList: IDomClassList = browser.isIE ? _manualClassList : _nativeClassList;
export const hasClass: (node: HTMLElement, className: string) => boolean = _classList.hasClass.bind(_classList);
export const addClass: (node: HTMLElement, className: string) => void = _classList.addClass.bind(_classList);
export const addClasses: (node: HTMLElement, ...classNames: string[]) => void = _classList.addClasses.bind(_classList);
export const removeClass: (node: HTMLElement, className: string) => void = _classList.removeClass.bind(_classList);
export const removeClasses: (node: HTMLElement, ...classNames: string[]) => void = _classList.removeClasses.bind(_classList);
export const toggleClass: (node: HTMLElement, className: string, shouldHaveIt?: boolean) => void = _classList.toggleClass.bind(_classList);
class DomListener implements IDisposable {
@@ -269,7 +289,7 @@ function doRequestAnimationFrame(callback: (time: number) => void): number {
|| emulatedRequestAnimationFrame
);
}
return _animationFrame(callback);
return _animationFrame.call(self, callback);
}
/**
@@ -454,11 +474,39 @@ function getDimension(element: HTMLElement, cssPropertyName: string, jsPropertyN
return convertToPixels(element, value);
}
export function getClientArea(element: HTMLElement): Dimension {
// Try with DOM clientWidth / clientHeight
if (element !== document.body) {
return new Dimension(element.clientWidth, element.clientHeight);
}
// Try innerWidth / innerHeight
if (window.innerWidth && window.innerHeight) {
return new Dimension(window.innerWidth, window.innerHeight);
}
// Try with document.body.clientWidth / document.body.clientHeigh
if (document.body && document.body.clientWidth && document.body.clientWidth) {
return new Dimension(document.body.clientWidth, document.body.clientHeight);
}
// Try with document.documentElement.clientWidth / document.documentElement.clientHeight
if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientHeight) {
return new Dimension(document.documentElement.clientWidth, document.documentElement.clientHeight);
}
throw new Error('Unable to figure out browser width and height');
}
const sizeUtils = {
getBorderLeftWidth: function (element: HTMLElement): number {
return getDimension(element, 'border-left-width', 'borderLeftWidth');
},
getBorderRightWidth: function (element: HTMLElement): number {
return getDimension(element, 'border-right-width', 'borderRightWidth');
},
getBorderTopWidth: function (element: HTMLElement): number {
return getDimension(element, 'border-top-width', 'borderTopWidth');
},
@@ -466,6 +514,12 @@ const sizeUtils = {
return getDimension(element, 'border-bottom-width', 'borderBottomWidth');
},
getPaddingLeft: function (element: HTMLElement): number {
return getDimension(element, 'padding-left', 'paddingLeft');
},
getPaddingRight: function (element: HTMLElement): number {
return getDimension(element, 'padding-right', 'paddingRight');
},
getPaddingTop: function (element: HTMLElement): number {
return getDimension(element, 'padding-top', 'paddingTop');
},
@@ -486,25 +540,22 @@ const sizeUtils = {
return getDimension(element, 'margin-bottom', 'marginBottom');
},
// {{SQL CARBON EDIT}}
getPaddingLeft: function (element: HTMLElement): number {
return getDimension(element, 'padding-left', 'paddingLeft');
},
getPaddingRight: function (element: HTMLElement): number {
return getDimension(element, 'padding-right', 'paddingRight');
},
getBorderRightWidth: function (element: HTMLElement): number {
return getDimension(element, 'border-right-width', 'borderRightWidth');
},
__commaSentinel: false
};
// ----------------------------------------------------------------------------------------
// Position & Dimension
export class Dimension {
public width: number;
public height: number;
constructor(width: number, height: number) {
this.width = width;
this.height = height;
}
}
export function getTopLeftOffset(element: HTMLElement): { left: number; top: number; } {
// Adapted from WinJS.Utilities.getPosition
// and added borders to the mix
@@ -540,6 +591,36 @@ export interface IDomNodePagePosition {
height: number;
}
export function size(element: HTMLElement, width: number, height: number): void {
if (typeof width === 'number') {
element.style.width = `${width}px`;
}
if (typeof height === 'number') {
element.style.height = `${height}px`;
}
}
export function position(element: HTMLElement, top: number, right?: number, bottom?: number, left?: number, position: string = 'absolute'): void {
if (typeof top === 'number') {
element.style.top = `${top}px`;
}
if (typeof right === 'number') {
element.style.right = `${right}px`;
}
if (typeof bottom === 'number') {
element.style.bottom = `${bottom}px`;
}
if (typeof left === 'number') {
element.style.left = `${left}px`;
}
element.style.position = position;
}
/**
* Returns the position of a dom node relative to the entire page.
*/
@@ -585,6 +666,12 @@ export function getTotalWidth(element: HTMLElement): number {
return element.offsetWidth + margin;
}
export function getContentWidth(element: HTMLElement): number {
let border = sizeUtils.getBorderLeftWidth(element) + sizeUtils.getBorderRightWidth(element);
let padding = sizeUtils.getPaddingLeft(element) + sizeUtils.getPaddingRight(element);
return element.offsetWidth - border - padding;
}
export function getTotalScrollWidth(element: HTMLElement): number {
let margin = sizeUtils.getMarginLeft(element) + sizeUtils.getMarginRight(element);
return element.scrollWidth + margin;
@@ -598,16 +685,6 @@ export function getContentHeight(element: HTMLElement): number {
return element.offsetHeight - border - padding;
}
// {{SQL CARBON EDIT}}
// Adapted from WinJS
// Gets the width of the content of the specified element. The content width does not include borders or padding.
export function getContentWidth(element: HTMLElement): number {
let border = sizeUtils.getBorderLeftWidth(element) + sizeUtils.getBorderRightWidth(element);
let padding = sizeUtils.getPaddingLeft(element) + sizeUtils.getPaddingRight(element);
return element.offsetWidth - border - padding;
}
// Adapted from WinJS
// Gets the height of the element, including its margins.
export function getTotalHeight(element: HTMLElement): number {
@@ -948,12 +1025,14 @@ export function join(nodes: Node[], separator: Node | string): Node[] {
export function show(...elements: HTMLElement[]): void {
for (let element of elements) {
element.style.display = '';
element.removeAttribute('aria-hidden');
}
}
export function hide(...elements: HTMLElement[]): void {
for (let element of elements) {
element.style.display = 'none';
element.setAttribute('aria-hidden', 'true');
}
}
@@ -1004,7 +1083,7 @@ export function domContentLoaded(): TPromise<any> {
return new TPromise<any>((c, e) => {
const readyState = document.readyState;
if (readyState === 'complete' || (document && document.body !== null)) {
window.setImmediate(c);
platform.setImmediate(c);
} else {
window.addEventListener('DOMContentLoaded', c, false);
}
@@ -1032,13 +1111,14 @@ export function computeScreenAwareSize(cssPx: number): number {
* See https://mathiasbynens.github.io/rel-noopener/
*/
export function windowOpenNoOpener(url: string): void {
if (platform.isNative) {
if (platform.isNative || browser.isEdgeWebView) {
// In VSCode, window.open() always returns null...
// The same is true for a WebView (see https://github.com/Microsoft/monaco-editor/issues/628)
window.open(url);
} else {
let newTab = window.open();
if (newTab) {
newTab.opener = null;
(newTab as any).opener = null;
newTab.location.href = url;
}
}

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import _Event, { Emitter, mapEvent } from 'vs/base/common/event';
import { Event as _Event, Emitter, mapEvent } from 'vs/base/common/event';
export type EventHandler = HTMLElement | HTMLDocument | Window;
@@ -19,7 +19,6 @@ export interface IDomEvent {
(element: EventHandler, type: 'MSGotPointerCapture', useCapture?: boolean): _Event<MSPointerEvent>;
(element: EventHandler, type: 'MSInertiaStart', useCapture?: boolean): _Event<MSGestureEvent>;
(element: EventHandler, type: 'MSLostPointerCapture', useCapture?: boolean): _Event<MSPointerEvent>;
(element: EventHandler, type: 'MSManipulationStateChanged', useCapture?: boolean): _Event<MSManipulationEvent>;
(element: EventHandler, type: 'MSPointerCancel', useCapture?: boolean): _Event<MSPointerEvent>;
(element: EventHandler, type: 'MSPointerDown', useCapture?: boolean): _Event<MSPointerEvent>;
(element: EventHandler, type: 'MSPointerEnter', useCapture?: boolean): _Event<MSPointerEvent>;

View File

@@ -9,149 +9,160 @@ import { KeyCode, KeyCodeUtils, KeyMod, SimpleKeybinding } from 'vs/base/common/
import * as platform from 'vs/base/common/platform';
import * as browser from 'vs/base/browser/browser';
let KEY_CODE_MAP: { [keyCode: number]: KeyCode } = {};
let KEY_CODE_MAP: { [keyCode: number]: KeyCode } = new Array(230);
let INVERSE_KEY_CODE_MAP: KeyCode[] = new Array(KeyCode.MAX_VALUE);
(function () {
KEY_CODE_MAP[3] = KeyCode.PauseBreak; // VK_CANCEL 0x03 Control-break processing
KEY_CODE_MAP[8] = KeyCode.Backspace;
KEY_CODE_MAP[9] = KeyCode.Tab;
KEY_CODE_MAP[13] = KeyCode.Enter;
KEY_CODE_MAP[16] = KeyCode.Shift;
KEY_CODE_MAP[17] = KeyCode.Ctrl;
KEY_CODE_MAP[18] = KeyCode.Alt;
KEY_CODE_MAP[19] = KeyCode.PauseBreak;
KEY_CODE_MAP[20] = KeyCode.CapsLock;
KEY_CODE_MAP[27] = KeyCode.Escape;
KEY_CODE_MAP[32] = KeyCode.Space;
KEY_CODE_MAP[33] = KeyCode.PageUp;
KEY_CODE_MAP[34] = KeyCode.PageDown;
KEY_CODE_MAP[35] = KeyCode.End;
KEY_CODE_MAP[36] = KeyCode.Home;
KEY_CODE_MAP[37] = KeyCode.LeftArrow;
KEY_CODE_MAP[38] = KeyCode.UpArrow;
KEY_CODE_MAP[39] = KeyCode.RightArrow;
KEY_CODE_MAP[40] = KeyCode.DownArrow;
KEY_CODE_MAP[45] = KeyCode.Insert;
KEY_CODE_MAP[46] = KeyCode.Delete;
for (let i = 0; i < INVERSE_KEY_CODE_MAP.length; i++) {
INVERSE_KEY_CODE_MAP[i] = -1;
}
KEY_CODE_MAP[48] = KeyCode.KEY_0;
KEY_CODE_MAP[49] = KeyCode.KEY_1;
KEY_CODE_MAP[50] = KeyCode.KEY_2;
KEY_CODE_MAP[51] = KeyCode.KEY_3;
KEY_CODE_MAP[52] = KeyCode.KEY_4;
KEY_CODE_MAP[53] = KeyCode.KEY_5;
KEY_CODE_MAP[54] = KeyCode.KEY_6;
KEY_CODE_MAP[55] = KeyCode.KEY_7;
KEY_CODE_MAP[56] = KeyCode.KEY_8;
KEY_CODE_MAP[57] = KeyCode.KEY_9;
function define(code: number, keyCode: KeyCode): void {
KEY_CODE_MAP[code] = keyCode;
INVERSE_KEY_CODE_MAP[keyCode] = code;
}
KEY_CODE_MAP[65] = KeyCode.KEY_A;
KEY_CODE_MAP[66] = KeyCode.KEY_B;
KEY_CODE_MAP[67] = KeyCode.KEY_C;
KEY_CODE_MAP[68] = KeyCode.KEY_D;
KEY_CODE_MAP[69] = KeyCode.KEY_E;
KEY_CODE_MAP[70] = KeyCode.KEY_F;
KEY_CODE_MAP[71] = KeyCode.KEY_G;
KEY_CODE_MAP[72] = KeyCode.KEY_H;
KEY_CODE_MAP[73] = KeyCode.KEY_I;
KEY_CODE_MAP[74] = KeyCode.KEY_J;
KEY_CODE_MAP[75] = KeyCode.KEY_K;
KEY_CODE_MAP[76] = KeyCode.KEY_L;
KEY_CODE_MAP[77] = KeyCode.KEY_M;
KEY_CODE_MAP[78] = KeyCode.KEY_N;
KEY_CODE_MAP[79] = KeyCode.KEY_O;
KEY_CODE_MAP[80] = KeyCode.KEY_P;
KEY_CODE_MAP[81] = KeyCode.KEY_Q;
KEY_CODE_MAP[82] = KeyCode.KEY_R;
KEY_CODE_MAP[83] = KeyCode.KEY_S;
KEY_CODE_MAP[84] = KeyCode.KEY_T;
KEY_CODE_MAP[85] = KeyCode.KEY_U;
KEY_CODE_MAP[86] = KeyCode.KEY_V;
KEY_CODE_MAP[87] = KeyCode.KEY_W;
KEY_CODE_MAP[88] = KeyCode.KEY_X;
KEY_CODE_MAP[89] = KeyCode.KEY_Y;
KEY_CODE_MAP[90] = KeyCode.KEY_Z;
define(3, KeyCode.PauseBreak); // VK_CANCEL 0x03 Control-break processing
define(8, KeyCode.Backspace);
define(9, KeyCode.Tab);
define(13, KeyCode.Enter);
define(16, KeyCode.Shift);
define(17, KeyCode.Ctrl);
define(18, KeyCode.Alt);
define(19, KeyCode.PauseBreak);
define(20, KeyCode.CapsLock);
define(27, KeyCode.Escape);
define(32, KeyCode.Space);
define(33, KeyCode.PageUp);
define(34, KeyCode.PageDown);
define(35, KeyCode.End);
define(36, KeyCode.Home);
define(37, KeyCode.LeftArrow);
define(38, KeyCode.UpArrow);
define(39, KeyCode.RightArrow);
define(40, KeyCode.DownArrow);
define(45, KeyCode.Insert);
define(46, KeyCode.Delete);
KEY_CODE_MAP[93] = KeyCode.ContextMenu;
define(48, KeyCode.KEY_0);
define(49, KeyCode.KEY_1);
define(50, KeyCode.KEY_2);
define(51, KeyCode.KEY_3);
define(52, KeyCode.KEY_4);
define(53, KeyCode.KEY_5);
define(54, KeyCode.KEY_6);
define(55, KeyCode.KEY_7);
define(56, KeyCode.KEY_8);
define(57, KeyCode.KEY_9);
KEY_CODE_MAP[96] = KeyCode.NUMPAD_0;
KEY_CODE_MAP[97] = KeyCode.NUMPAD_1;
KEY_CODE_MAP[98] = KeyCode.NUMPAD_2;
KEY_CODE_MAP[99] = KeyCode.NUMPAD_3;
KEY_CODE_MAP[100] = KeyCode.NUMPAD_4;
KEY_CODE_MAP[101] = KeyCode.NUMPAD_5;
KEY_CODE_MAP[102] = KeyCode.NUMPAD_6;
KEY_CODE_MAP[103] = KeyCode.NUMPAD_7;
KEY_CODE_MAP[104] = KeyCode.NUMPAD_8;
KEY_CODE_MAP[105] = KeyCode.NUMPAD_9;
KEY_CODE_MAP[106] = KeyCode.NUMPAD_MULTIPLY;
KEY_CODE_MAP[107] = KeyCode.NUMPAD_ADD;
KEY_CODE_MAP[108] = KeyCode.NUMPAD_SEPARATOR;
KEY_CODE_MAP[109] = KeyCode.NUMPAD_SUBTRACT;
KEY_CODE_MAP[110] = KeyCode.NUMPAD_DECIMAL;
KEY_CODE_MAP[111] = KeyCode.NUMPAD_DIVIDE;
define(65, KeyCode.KEY_A);
define(66, KeyCode.KEY_B);
define(67, KeyCode.KEY_C);
define(68, KeyCode.KEY_D);
define(69, KeyCode.KEY_E);
define(70, KeyCode.KEY_F);
define(71, KeyCode.KEY_G);
define(72, KeyCode.KEY_H);
define(73, KeyCode.KEY_I);
define(74, KeyCode.KEY_J);
define(75, KeyCode.KEY_K);
define(76, KeyCode.KEY_L);
define(77, KeyCode.KEY_M);
define(78, KeyCode.KEY_N);
define(79, KeyCode.KEY_O);
define(80, KeyCode.KEY_P);
define(81, KeyCode.KEY_Q);
define(82, KeyCode.KEY_R);
define(83, KeyCode.KEY_S);
define(84, KeyCode.KEY_T);
define(85, KeyCode.KEY_U);
define(86, KeyCode.KEY_V);
define(87, KeyCode.KEY_W);
define(88, KeyCode.KEY_X);
define(89, KeyCode.KEY_Y);
define(90, KeyCode.KEY_Z);
KEY_CODE_MAP[112] = KeyCode.F1;
KEY_CODE_MAP[113] = KeyCode.F2;
KEY_CODE_MAP[114] = KeyCode.F3;
KEY_CODE_MAP[115] = KeyCode.F4;
KEY_CODE_MAP[116] = KeyCode.F5;
KEY_CODE_MAP[117] = KeyCode.F6;
KEY_CODE_MAP[118] = KeyCode.F7;
KEY_CODE_MAP[119] = KeyCode.F8;
KEY_CODE_MAP[120] = KeyCode.F9;
KEY_CODE_MAP[121] = KeyCode.F10;
KEY_CODE_MAP[122] = KeyCode.F11;
KEY_CODE_MAP[123] = KeyCode.F12;
KEY_CODE_MAP[124] = KeyCode.F13;
KEY_CODE_MAP[125] = KeyCode.F14;
KEY_CODE_MAP[126] = KeyCode.F15;
KEY_CODE_MAP[127] = KeyCode.F16;
KEY_CODE_MAP[128] = KeyCode.F17;
KEY_CODE_MAP[129] = KeyCode.F18;
KEY_CODE_MAP[130] = KeyCode.F19;
define(93, KeyCode.ContextMenu);
KEY_CODE_MAP[144] = KeyCode.NumLock;
KEY_CODE_MAP[145] = KeyCode.ScrollLock;
define(96, KeyCode.NUMPAD_0);
define(97, KeyCode.NUMPAD_1);
define(98, KeyCode.NUMPAD_2);
define(99, KeyCode.NUMPAD_3);
define(100, KeyCode.NUMPAD_4);
define(101, KeyCode.NUMPAD_5);
define(102, KeyCode.NUMPAD_6);
define(103, KeyCode.NUMPAD_7);
define(104, KeyCode.NUMPAD_8);
define(105, KeyCode.NUMPAD_9);
define(106, KeyCode.NUMPAD_MULTIPLY);
define(107, KeyCode.NUMPAD_ADD);
define(108, KeyCode.NUMPAD_SEPARATOR);
define(109, KeyCode.NUMPAD_SUBTRACT);
define(110, KeyCode.NUMPAD_DECIMAL);
define(111, KeyCode.NUMPAD_DIVIDE);
KEY_CODE_MAP[186] = KeyCode.US_SEMICOLON;
KEY_CODE_MAP[187] = KeyCode.US_EQUAL;
KEY_CODE_MAP[188] = KeyCode.US_COMMA;
KEY_CODE_MAP[189] = KeyCode.US_MINUS;
KEY_CODE_MAP[190] = KeyCode.US_DOT;
KEY_CODE_MAP[191] = KeyCode.US_SLASH;
KEY_CODE_MAP[192] = KeyCode.US_BACKTICK;
KEY_CODE_MAP[193] = KeyCode.ABNT_C1;
KEY_CODE_MAP[194] = KeyCode.ABNT_C2;
KEY_CODE_MAP[219] = KeyCode.US_OPEN_SQUARE_BRACKET;
KEY_CODE_MAP[220] = KeyCode.US_BACKSLASH;
KEY_CODE_MAP[221] = KeyCode.US_CLOSE_SQUARE_BRACKET;
KEY_CODE_MAP[222] = KeyCode.US_QUOTE;
KEY_CODE_MAP[223] = KeyCode.OEM_8;
define(112, KeyCode.F1);
define(113, KeyCode.F2);
define(114, KeyCode.F3);
define(115, KeyCode.F4);
define(116, KeyCode.F5);
define(117, KeyCode.F6);
define(118, KeyCode.F7);
define(119, KeyCode.F8);
define(120, KeyCode.F9);
define(121, KeyCode.F10);
define(122, KeyCode.F11);
define(123, KeyCode.F12);
define(124, KeyCode.F13);
define(125, KeyCode.F14);
define(126, KeyCode.F15);
define(127, KeyCode.F16);
define(128, KeyCode.F17);
define(129, KeyCode.F18);
define(130, KeyCode.F19);
KEY_CODE_MAP[226] = KeyCode.OEM_102;
define(144, KeyCode.NumLock);
define(145, KeyCode.ScrollLock);
define(186, KeyCode.US_SEMICOLON);
define(187, KeyCode.US_EQUAL);
define(188, KeyCode.US_COMMA);
define(189, KeyCode.US_MINUS);
define(190, KeyCode.US_DOT);
define(191, KeyCode.US_SLASH);
define(192, KeyCode.US_BACKTICK);
define(193, KeyCode.ABNT_C1);
define(194, KeyCode.ABNT_C2);
define(219, KeyCode.US_OPEN_SQUARE_BRACKET);
define(220, KeyCode.US_BACKSLASH);
define(221, KeyCode.US_CLOSE_SQUARE_BRACKET);
define(222, KeyCode.US_QUOTE);
define(223, KeyCode.OEM_8);
define(226, KeyCode.OEM_102);
/**
* https://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html
* If an Input Method Editor is processing key input and the event is keydown, return 229.
*/
KEY_CODE_MAP[229] = KeyCode.KEY_IN_COMPOSITION;
define(229, KeyCode.KEY_IN_COMPOSITION);
if (browser.isIE) {
KEY_CODE_MAP[91] = KeyCode.Meta;
define(91, KeyCode.Meta);
} else if (browser.isFirefox) {
KEY_CODE_MAP[59] = KeyCode.US_SEMICOLON;
KEY_CODE_MAP[107] = KeyCode.US_EQUAL;
KEY_CODE_MAP[109] = KeyCode.US_MINUS;
define(59, KeyCode.US_SEMICOLON);
define(107, KeyCode.US_EQUAL);
define(109, KeyCode.US_MINUS);
if (platform.isMacintosh) {
KEY_CODE_MAP[224] = KeyCode.Meta;
define(224, KeyCode.Meta);
}
} else if (browser.isWebKit) {
KEY_CODE_MAP[91] = KeyCode.Meta;
define(91, KeyCode.Meta);
if (platform.isMacintosh) {
// the two meta keys in the Mac have different key codes (91 and 93)
KEY_CODE_MAP[93] = KeyCode.Meta;
define(93, KeyCode.Meta);
} else {
KEY_CODE_MAP[92] = KeyCode.Meta;
define(92, KeyCode.Meta);
}
}
})();
@@ -165,6 +176,10 @@ function extractKeyCode(e: KeyboardEvent): KeyCode {
return KEY_CODE_MAP[e.keyCode] || KeyCode.Unknown;
}
export function getCodeForKeyCode(keyCode: KeyCode): number {
return INVERSE_KEY_CODE_MAP[keyCode];
}
export interface IKeyboardEvent {
readonly browserEvent: KeyboardEvent;
readonly target: HTMLElement;

View File

@@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import arrays = require('vs/base/common/arrays');
import * as arrays from 'vs/base/common/arrays';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import DomUtils = require('vs/base/browser/dom');
import * as DomUtils from 'vs/base/browser/dom';
import { memoize } from 'vs/base/common/decorators';
export namespace EventType {

View File

@@ -6,19 +6,20 @@
'use strict';
import 'vs/css!./actionbar';
import nls = require('vs/nls');
import lifecycle = require('vs/base/common/lifecycle');
import * as platform from 'vs/base/common/platform';
import * as nls from 'vs/nls';
import * as lifecycle from 'vs/base/common/lifecycle';
import { TPromise } from 'vs/base/common/winjs.base';
import { Builder, $ } from 'vs/base/browser/builder';
import { SelectBox } from 'vs/base/browser/ui/selectBox/selectBox';
import { IAction, IActionRunner, Action, IActionChangeEvent, ActionRunner, IRunEvent } from 'vs/base/common/actions';
import DOM = require('vs/base/browser/dom');
import types = require('vs/base/common/types');
import * as DOM from 'vs/base/browser/dom';
import * as types from 'vs/base/common/types';
import { EventType, Gesture } from 'vs/base/browser/touch';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import Event, { Emitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
export interface IActionItem {
actionRunner: IActionRunner;
@@ -139,7 +140,7 @@ export class BaseActionItem implements IActionItem {
if (this.options && this.options.isMenu) {
this.onClick(e);
} else {
setImmediate(() => this.onClick(e));
platform.setImmediate(() => this.onClick(e));
}
});
@@ -386,7 +387,7 @@ export class ActionBar implements IActionRunner {
private _onDidRun = new Emitter<IRunEvent>();
private _onDidBeforeRun = new Emitter<IRunEvent>();
constructor(container: HTMLElement | Builder, options: IActionBarOptions = defaultOptions) {
constructor(container: HTMLElement, options: IActionBarOptions = defaultOptions) {
this.options = options;
this._context = options.context;
this.toDispose = [];
@@ -496,7 +497,7 @@ export class ActionBar implements IActionRunner {
this.domNode.appendChild(this.actionsList);
((container instanceof Builder) ? container.getHTMLElement() : container).appendChild(this.domNode);
container.appendChild(this.domNode);
}
public get onDidBlur(): Event<void> {
@@ -553,8 +554,8 @@ export class ActionBar implements IActionRunner {
}
}
public getContainer(): Builder {
return $(this.domNode);
public getContainer(): HTMLElement {
return this.domNode;
}
public push(arg: IAction | IAction[], options: IActionOptions = {}): void {
@@ -748,7 +749,7 @@ export class ActionBar implements IActionRunner {
this.toDispose = lifecycle.dispose(this.toDispose);
this.getContainer().destroy();
$(this.getContainer()).destroy();
}
}
@@ -766,8 +767,8 @@ export class SelectActionItem extends BaseActionItem {
this.registerListeners();
}
public setOptions(options: string[], selected?: number): void {
this.selectBox.setOptions(options, selected);
public setOptions(options: string[], selected?: number, disabled?: number): void {
this.selectBox.setOptions(options, selected, disabled);
}
public select(index: number): void {

View File

@@ -4,6 +4,6 @@
*--------------------------------------------------------------------------------------------*/
.monaco-aria-container {
position: absolute; /* try to hide from workbench but not from screen readers */
position: absolute; /* try to hide from window but not from screen readers */
left:-999em;
}

View File

@@ -6,7 +6,7 @@
'use strict';
import 'vs/css!./aria';
import nls = require('vs/nls');
import * as nls from 'vs/nls';
import { isMacintosh } from 'vs/base/common/platform';
import * as dom from 'vs/base/browser/dom';

View File

@@ -6,14 +6,15 @@
'use strict';
import 'vs/css!./button';
import DOM = require('vs/base/browser/dom');
import * as DOM from 'vs/base/browser/dom';
import { Builder, $ } from 'vs/base/browser/builder';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Color } from 'vs/base/common/color';
import { mixin } from 'vs/base/common/objects';
import Event, { Emitter } from 'vs/base/common/event';
import { Event as BaseEvent, Emitter } from 'vs/base/common/event';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { Gesture, EventType } from 'vs/base/browser/touch';
export interface IButtonOptions extends IButtonStyles {
title?: boolean;
@@ -44,13 +45,11 @@ export class Button {
private buttonBorder: Color;
private _onDidClick = new Emitter<any>();
readonly onDidClick: Event<any> = this._onDidClick.event;
readonly onDidClick: BaseEvent<Event> = this._onDidClick.event;
private focusTracker: DOM.IFocusTracker;
constructor(container: Builder, options?: IButtonOptions);
constructor(container: HTMLElement, options?: IButtonOptions);
constructor(container: any, options?: IButtonOptions) {
constructor(container: HTMLElement, options?: IButtonOptions) {
this.options = options || Object.create(null);
mixin(this.options, defaultOptions, false);
@@ -64,7 +63,9 @@ export class Button {
'role': 'button'
}).appendTo(container);
this.$el.on(DOM.EventType.CLICK, e => {
Gesture.addTarget(this.$el.getHTMLElement());
this.$el.on([DOM.EventType.CLICK, EventType.Tap], e => {
if (!this.enabled) {
DOM.EventHelper.stop(e);
return;
@@ -196,9 +197,7 @@ export class ButtonGroup {
private _buttons: Button[];
private toDispose: IDisposable[];
constructor(container: Builder, count: number, options?: IButtonOptions);
constructor(container: HTMLElement, count: number, options?: IButtonOptions);
constructor(container: any, count: number, options?: IButtonOptions) {
constructor(container: HTMLElement, count: number, options?: IButtonOptions) {
this._buttons = [];
this.toDispose = [];
@@ -209,9 +208,7 @@ export class ButtonGroup {
return this._buttons;
}
private create(container: Builder, count: number, options?: IButtonOptions): void;
private create(container: HTMLElement, count: number, options?: IButtonOptions): void;
private create(container: any, count: number, options?: IButtonOptions): void {
private create(container: HTMLElement, count: number, options?: IButtonOptions): void {
for (let index = 0; index < count; index++) {
const button = new Button(container, options);
this._buttons.push(button);

View File

@@ -7,7 +7,7 @@
import 'vs/css!./checkbox';
import DOM = require('vs/base/browser/dom');
import * as DOM from 'vs/base/browser/dom';
import * as objects from 'vs/base/common/objects';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Widget } from 'vs/base/browser/ui/widget';
@@ -15,11 +15,11 @@ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { Color } from 'vs/base/common/color';
export interface ICheckboxOpts extends ICheckboxStyles {
actionClassName: string;
title: string;
isChecked: boolean;
onChange: (viaKeyboard: boolean) => void;
onKeyDown?: (e: IKeyboardEvent) => void;
readonly actionClassName: string;
readonly title: string;
readonly isChecked: boolean;
readonly onChange: (viaKeyboard: boolean) => void;
readonly onKeyDown?: (e: IKeyboardEvent) => void;
}
export interface ICheckboxStyles {
@@ -32,8 +32,8 @@ const defaultOpts = {
export class Checkbox extends Widget {
private _opts: ICheckboxOpts;
public domNode: HTMLElement;
private readonly _opts: ICheckboxOpts;
public readonly domNode: HTMLElement;
private _checked: boolean;

View File

@@ -3,12 +3,11 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import 'vs/css!./contextview';
import { Builder, $ } from 'vs/base/browser/builder';
import DOM = require('vs/base/browser/dom');
import * as DOM from 'vs/base/browser/dom';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
export interface IAnchor {

View File

@@ -13,6 +13,7 @@ import { mixin } from 'vs/base/common/objects';
export interface ICountBadgeOptions extends ICountBadgetyles {
count?: number;
countFormat?: string;
titleFormat?: string;
}
@@ -31,6 +32,7 @@ export class CountBadge {
private element: HTMLElement;
private count: number;
private countFormat: string;
private titleFormat: string;
private badgeBackground: Color;
@@ -48,6 +50,7 @@ export class CountBadge {
this.badgeBorder = this.options.badgeBorder;
this.element = append(container, $('.monaco-count-badge'));
this.countFormat = this.options.countFormat || '{0}';
this.titleFormat = this.options.titleFormat || '';
this.setCount(this.options.count || 0);
}
@@ -57,13 +60,18 @@ export class CountBadge {
this.render();
}
setCountFormat(countFormat: string) {
this.countFormat = countFormat;
this.render();
}
setTitleFormat(titleFormat: string) {
this.titleFormat = titleFormat;
this.render();
}
private render() {
this.element.textContent = '' + this.count;
this.element.textContent = format(this.countFormat, this.count);
this.element.title = format(this.titleFormat, this.count);
this.applyStyles();

View File

@@ -3,30 +3,29 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.dropdown {
.monaco-dropdown {
height: 100%;
}
.dropdown, .dropdown-group {
display: inline-block;
padding: 0;
}
.dropdown > .dropdown-label, .dropdown > .dropdown-action {
.monaco-dropdown > .dropdown-label,
.monaco-dropdown > .dropdown-action {
display: inline-block;
cursor: pointer;
height: 100%;
}
.dropdown > .dropdown-action {
.monaco-dropdown > .dropdown-action {
vertical-align: top;
}
.dropdown > .dropdown-action > .action-label:hover {
.monaco-dropdown > .dropdown-action > .action-label:hover {
color: inherit;
text-decoration: none;
}
.dropdown > .dropdown-action, .dropdown > .dropdown-action > .action-label {
.monaco-dropdown > .dropdown-action,
.monaco-dropdown > .dropdown-action > .action-label {
display: inline-block;
}

View File

@@ -12,10 +12,10 @@ import { Gesture, EventType as GestureEventType } from 'vs/base/browser/touch';
import { ActionRunner, IAction, IActionRunner } from 'vs/base/common/actions';
import { BaseActionItem, IActionItemProvider } from 'vs/base/browser/ui/actionbar/actionbar';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import { IContextViewProvider, IAnchor } from 'vs/base/browser/ui/contextview/contextview';
import { IMenuOptions } from 'vs/base/browser/ui/menu/menu';
import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
import { EventHelper, EventType } from 'vs/base/browser/dom';
import { EventHelper, EventType, removeClass, addClass } from 'vs/base/browser/dom';
import { IContextMenuDelegate } from 'vs/base/browser/contextmenu';
export interface ILabelRenderer {
@@ -33,13 +33,14 @@ export class BaseDropdown extends ActionRunner {
private $boxContainer: Builder;
private $label: Builder;
private $contents: Builder;
private visible: boolean;
constructor(container: HTMLElement, options: IBaseDropdownOptions) {
super();
this._toDispose = [];
this.$el = $('.dropdown').appendTo(container);
this.$el = $('.monaco-dropdown').appendTo(container);
this.$label = $('.dropdown-label');
@@ -58,7 +59,11 @@ export class BaseDropdown extends ActionRunner {
return; // prevent multiple clicks to open multiple context menus (https://github.com/Microsoft/vscode/issues/41363)
}
this.show();
if (this.visible) {
this.hide();
} else {
this.show();
}
}).appendTo(this.$el);
let cleanupFn = labelRenderer(this.$label.getHTMLElement());
@@ -74,12 +79,12 @@ export class BaseDropdown extends ActionRunner {
return this._toDispose;
}
public get element(): Builder {
return this.$el;
public get element(): HTMLElement {
return this.$el.getHTMLElement();
}
public get label(): Builder {
return this.$label;
public get label(): HTMLElement {
return this.$label.getHTMLElement();
}
public set tooltip(tooltip: string) {
@@ -87,11 +92,11 @@ export class BaseDropdown extends ActionRunner {
}
public show(): void {
// noop
this.visible = true;
}
public hide(): void {
// noop
this.visible = false;
}
protected onEvent(e: Event, activeElement: HTMLElement): void {
@@ -135,10 +140,12 @@ export class Dropdown extends BaseDropdown {
}
public show(): void {
this.element.addClass('active');
super.show();
addClass(this.element, 'active');
this.contextViewProvider.showContextView({
getAnchor: () => this.element.getHTMLElement(),
getAnchor: () => this.getAnchor(),
render: (container) => {
return this.renderContents(container);
@@ -148,13 +155,21 @@ export class Dropdown extends BaseDropdown {
this.onEvent(e, activeElement);
},
onHide: () => {
this.element.removeClass('active');
}
onHide: () => this.onHide()
});
}
protected getAnchor(): HTMLElement | IAnchor {
return this.element;
}
protected onHide(): void {
removeClass(this.element, 'active');
}
public hide(): void {
super.hide();
if (this.contextViewProvider) {
this.contextViewProvider.hideContextView();
}
@@ -217,22 +232,24 @@ export class DropdownMenu extends BaseDropdown {
}
public show(): void {
this.element.addClass('active');
super.show();
addClass(this.element, 'active');
this._contextMenuProvider.showContextMenu({
getAnchor: () => this.element.getHTMLElement(),
getAnchor: () => this.element,
getActions: () => TPromise.as(this.actions),
getActionsContext: () => this.menuOptions ? this.menuOptions.context : null,
getActionItem: (action) => this.menuOptions && this.menuOptions.actionItemProvider ? this.menuOptions.actionItemProvider(action) : null,
getKeyBinding: (action: IAction) => this.menuOptions && this.menuOptions.getKeyBinding ? this.menuOptions.getKeyBinding(action) : null,
getMenuClassName: () => this.menuClassName,
onHide: () => this.element.removeClass('active'),
onHide: () => removeClass(this.element, 'active'),
actionRunner: this.menuOptions ? this.menuOptions.actionRunner : null
});
}
public hide(): void {
// noop
super.hide();
}
}

View File

@@ -14,14 +14,6 @@
height: 25px;
}
.fl:after {
clear: both;
content: '';
display: block;
visibility: hidden;
height: 0;
}
.monaco-findInput > .controls {
position: absolute;
top: 3px;

View File

@@ -11,7 +11,7 @@ import * as dom from 'vs/base/browser/dom';
import { IMessage as InputBoxMessage, IInputValidator, InputBox, IInputBoxStyles } from 'vs/base/browser/ui/inputbox/inputBox';
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import { Widget } from 'vs/base/browser/ui/widget';
import Event, { Emitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
@@ -20,14 +20,14 @@ import { Color } from 'vs/base/common/color';
import { ICheckboxStyles } from 'vs/base/browser/ui/checkbox/checkbox';
export interface IFindInputOptions extends IFindInputStyles {
placeholder?: string;
width?: number;
validation?: IInputValidator;
label: string;
readonly placeholder?: string;
readonly width?: number;
readonly validation?: IInputValidator;
readonly label: string;
appendCaseSensitiveLabel?: string;
appendWholeWordsLabel?: string;
appendRegexLabel?: string;
readonly appendCaseSensitiveLabel?: string;
readonly appendWholeWordsLabel?: string;
readonly appendRegexLabel?: string;
}
export interface IFindInputStyles extends IInputBoxStyles {
@@ -38,7 +38,7 @@ const NLS_DEFAULT_LABEL = nls.localize('defaultLabel', "input");
export class FindInput extends Widget {
static OPTION_CHANGE: string = 'optionChange';
static readonly OPTION_CHANGE: string = 'optionChange';
private contextViewProvider: IContextViewProvider;
private width: number;
@@ -64,23 +64,23 @@ export class FindInput extends Widget {
public domNode: HTMLElement;
public inputBox: InputBox;
private _onDidOptionChange = this._register(new Emitter<boolean>());
public onDidOptionChange: Event<boolean /* via keyboard */> = this._onDidOptionChange.event;
private readonly _onDidOptionChange = this._register(new Emitter<boolean>());
public readonly onDidOptionChange: Event<boolean /* via keyboard */> = this._onDidOptionChange.event;
private _onKeyDown = this._register(new Emitter<IKeyboardEvent>());
public onKeyDown: Event<IKeyboardEvent> = this._onKeyDown.event;
private readonly _onKeyDown = this._register(new Emitter<IKeyboardEvent>());
public readonly onKeyDown: Event<IKeyboardEvent> = this._onKeyDown.event;
private _onMouseDown = this._register(new Emitter<IMouseEvent>());
public onMouseDown: Event<IMouseEvent> = this._onMouseDown.event;
private readonly _onMouseDown = this._register(new Emitter<IMouseEvent>());
public readonly onMouseDown: Event<IMouseEvent> = this._onMouseDown.event;
private _onInput = this._register(new Emitter<void>());
public onInput: Event<void> = this._onInput.event;
private readonly _onInput = this._register(new Emitter<void>());
public readonly onInput: Event<void> = this._onInput.event;
private _onKeyUp = this._register(new Emitter<IKeyboardEvent>());
public onKeyUp: Event<IKeyboardEvent> = this._onKeyUp.event;
private readonly _onKeyUp = this._register(new Emitter<IKeyboardEvent>());
public readonly onKeyUp: Event<IKeyboardEvent> = this._onKeyUp.event;
private _onCaseSensitiveKeyDown = this._register(new Emitter<IKeyboardEvent>());
public onCaseSensitiveKeyDown: Event<IKeyboardEvent> = this._onCaseSensitiveKeyDown.event;
public readonly onCaseSensitiveKeyDown: Event<IKeyboardEvent> = this._onCaseSensitiveKeyDown.event;
constructor(parent: HTMLElement, contextViewProvider: IContextViewProvider, options?: IFindInputOptions) {
super();

View File

@@ -12,11 +12,11 @@ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { Color } from 'vs/base/common/color';
export interface IFindInputCheckboxOpts {
appendTitle: string;
isChecked: boolean;
onChange: (viaKeyboard: boolean) => void;
onKeyDown?: (e: IKeyboardEvent) => void;
inputActiveOptionBorder?: Color;
readonly appendTitle: string;
readonly isChecked: boolean;
readonly onChange: (viaKeyboard: boolean) => void;
readonly onKeyDown?: (e: IKeyboardEvent) => void;
readonly inputActiveOptionBorder?: Color;
}
const NLS_CASE_SENSITIVE_CHECKBOX_LABEL = nls.localize('caseDescription', "Match Case");

View File

@@ -7,7 +7,7 @@
import { IDisposable } from 'vs/base/common/lifecycle';
import * as dom from 'vs/base/browser/dom';
import * as objects from 'vs/base/common/objects';
import { render as renderOcticons } from 'vs/base/browser/ui/octiconLabel/octiconLabel';
import { renderOcticons } from 'vs/base/browser/ui/octiconLabel/octiconLabel';
export interface IHighlight {
start: number;

View File

@@ -6,11 +6,11 @@
'use strict';
import 'vs/css!./iconlabel';
import dom = require('vs/base/browser/dom');
import * as dom from 'vs/base/browser/dom';
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
import { IMatch } from 'vs/base/common/filters';
import uri from 'vs/base/common/uri';
import paths = require('vs/base/common/paths');
import * as paths from 'vs/base/common/paths';
import { IWorkspaceFolderProvider, getPathLabel, IUserHomeProvider, getBaseLabel } from 'vs/base/common/labels';
import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';

View File

@@ -6,15 +6,15 @@
import 'vs/css!./inputBox';
import nls = require('vs/nls');
import * as nls from 'vs/nls';
import * as Bal from 'vs/base/browser/browser';
import * as dom from 'vs/base/browser/dom';
import { RenderOptions, renderFormattedText, renderText } from 'vs/base/browser/htmlContentRenderer';
import aria = require('vs/base/browser/ui/aria/aria');
import * as aria from 'vs/base/browser/ui/aria/aria';
import { IAction } from 'vs/base/common/actions';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { IContextViewProvider, AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
import Event, { Emitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
import { Widget } from 'vs/base/browser/ui/widget';
import { Color } from 'vs/base/common/color';
import { mixin } from 'vs/base/common/objects';
@@ -112,10 +112,10 @@ export class InputBox extends Widget {
private inputValidationErrorBackground: Color;
private _onDidChange = this._register(new Emitter<string>());
public onDidChange: Event<string> = this._onDidChange.event;
public readonly onDidChange: Event<string> = this._onDidChange.event;
private _onDidHeightChange = this._register(new Emitter<number>());
public onDidHeightChange: Event<number> = this._onDidHeightChange.event;
public readonly onDidHeightChange: Event<number> = this._onDidHeightChange.event;
constructor(container: HTMLElement, contextViewProvider: IContextViewProvider, options?: IInputOptions) {
super();
@@ -351,30 +351,27 @@ export class InputBox extends Widget {
}
public validate(): boolean {
let result: IMessage = null;
let errorMsg: IMessage = null;
if (this.validation) {
result = this.validation(this.value);
errorMsg = this.validation(this.value);
// {{SQL CARBON EDIT}}
if (!result && this.options.useDefaultValidation && this.inputElement.validationMessage) {
result = {
if (!errorMsg && this.options.useDefaultValidation && this.inputElement.validationMessage) {
errorMsg = {
content: this.inputElement.validationMessage,
type: MessageType.ERROR
};
}
if (!result) {
if (!errorMsg) {
this.inputElement.removeAttribute('aria-invalid');
this.hideMessage();
} else {
this.inputElement.setAttribute('aria-invalid', 'true');
this.showMessage(result);
}
}
// {{SQL CARBON EDIT}} Canidate for addition to vscode
return result ? result.type !== MessageType.ERROR : true;
return errorMsg ? errorMsg.type !== MessageType.ERROR : true;
}
private stylesForType(type: MessageType): { border: Color; background: Color } {

View File

@@ -9,7 +9,7 @@ import { range } from 'vs/base/common/arrays';
import { IDelegate, IRenderer, IListEvent, IListOpenEvent } from './list';
import { List, IListStyles, IListOptions } from './listWidget';
import { IPagedModel } from 'vs/base/common/paging';
import Event, { mapEvent } from 'vs/base/common/event';
import { Event, mapEvent } from 'vs/base/common/event';
export interface IPagedRenderer<TElement, TTemplateData> extends IRenderer<TElement, TTemplateData> {
renderPlaceholder(index: number, templateData: TTemplateData): void;
@@ -58,7 +58,7 @@ class PagedRenderer<TElement, TTemplateData> implements IRenderer<number, ITempl
}
}
export class PagedList<T> {
export class PagedList<T> implements IDisposable {
private list: List<number>;
private _model: IPagedModel<T>;
@@ -81,6 +81,10 @@ export class PagedList<T> {
return this.list.getHTMLElement() === document.activeElement;
}
domFocus(): void {
this.list.domFocus();
}
get onDidFocus(): Event<void> {
return this.list.onDidFocus;
}
@@ -93,6 +97,10 @@ export class PagedList<T> {
return this.list;
}
get onDidDispose(): Event<void> {
return this.list.onDidDispose;
}
get onFocusChange(): Event<IListEvent<T>> {
return mapEvent(this.list.onFocusChange, ({ elements, indexes }) => ({ elements: elements.map(e => this._model.get(e)), indexes }));
}
@@ -185,4 +193,8 @@ export class PagedList<T> {
style(styles: IListStyles): void {
this.list.style(styles);
}
}
dispose(): void {
this.list.dispose();
}
}

View File

@@ -7,7 +7,7 @@ import { getOrDefault } from 'vs/base/common/objects';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Gesture, EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
import * as DOM from 'vs/base/browser/dom';
import Event, { mapEvent, filterEvent } from 'vs/base/common/event';
import { Event, mapEvent, filterEvent } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { ScrollEvent, ScrollbarVisibility } from 'vs/base/common/scrollable';
@@ -360,19 +360,22 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
private toMouseEvent(browserEvent: MouseEvent): IListMouseEvent<T> {
const index = this.getItemIndexFromEventTarget(browserEvent.target);
const element = index < 0 ? undefined : this.items[index].element;
const item = index < 0 ? undefined : this.items[index];
const element = item && item.element;
return { browserEvent, index, element };
}
private toTouchEvent(browserEvent: TouchEvent): IListTouchEvent<T> {
const index = this.getItemIndexFromEventTarget(browserEvent.target);
const element = index < 0 ? undefined : this.items[index].element;
const item = index < 0 ? undefined : this.items[index];
const element = item && item.element;
return { browserEvent, index, element };
}
private toGestureEvent(browserEvent: GestureEvent): IListGestureEvent<T> {
const index = this.getItemIndexFromEventTarget(browserEvent.initialTarget);
const element = index < 0 ? undefined : this.items[index].element;
const item = index < 0 ? undefined : this.items[index];
const element = item && item.element;
return { browserEvent, index, element };
}

View File

@@ -13,7 +13,7 @@ import * as platform from 'vs/base/common/platform';
import { Gesture } from 'vs/base/browser/touch';
import { KeyCode } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import Event, { Emitter, EventBufferer, chain, mapEvent, anyEvent } from 'vs/base/common/event';
import { Event, Emitter, EventBufferer, chain, mapEvent, anyEvent } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { IDelegate, IRenderer, IListEvent, IListContextMenuEvent, IListMouseEvent, IListTouchEvent, IListGestureEvent, IListOpenEvent } from './list';
import { ListView, IListViewOptions } from './listView';
@@ -142,7 +142,7 @@ class Trait<T> implements ISpliceable<boolean>, IDisposable {
const end = start + deleteCount;
const indexes = [
...this.indexes.filter(i => i < start),
...elements.reduce((r, hasTrait, i) => hasTrait ? [...r, i + start] : r, []),
...elements.map((hasTrait, i) => hasTrait ? i + start : -1).filter(i => i !== -1),
...this.indexes.filter(i => i >= end).map(i => i + diff)
];
@@ -388,7 +388,7 @@ const DefaultMultipleSelectionContoller = {
isSelectionRangeChangeEvent
};
const DefaultOpenController = {
const DefaultOpenController: IOpenController = {
shouldOpen: (event: UIEvent) => {
if (event instanceof MouseEvent) {
return !isMouseRightClick(event);
@@ -396,7 +396,7 @@ const DefaultOpenController = {
return true;
}
} as IOpenController;
};
class MouseController<T> implements IDisposable {
@@ -580,6 +580,89 @@ export interface IOpenController {
shouldOpen(event: UIEvent): boolean;
}
export interface IStyleController {
style(styles: IListStyles): void;
}
export class DefaultStyleController implements IStyleController {
constructor(private styleElement: HTMLStyleElement, private selectorSuffix?: string) { }
style(styles: IListStyles): void {
const suffix = this.selectorSuffix ? `.${this.selectorSuffix}` : '';
const content: string[] = [];
if (styles.listFocusBackground) {
content.push(`.monaco-list${suffix}:focus .monaco-list-row.focused { background-color: ${styles.listFocusBackground}; }`);
content.push(`.monaco-list${suffix}:focus .monaco-list-row.focused:hover { background-color: ${styles.listFocusBackground}; }`); // overwrite :hover style in this case!
}
if (styles.listFocusForeground) {
content.push(`.monaco-list${suffix}:focus .monaco-list-row.focused { color: ${styles.listFocusForeground}; }`);
}
if (styles.listActiveSelectionBackground) {
content.push(`.monaco-list${suffix}:focus .monaco-list-row.selected { background-color: ${styles.listActiveSelectionBackground}; }`);
content.push(`.monaco-list${suffix}:focus .monaco-list-row.selected:hover { background-color: ${styles.listActiveSelectionBackground}; }`); // overwrite :hover style in this case!
}
if (styles.listActiveSelectionForeground) {
content.push(`.monaco-list${suffix}:focus .monaco-list-row.selected { color: ${styles.listActiveSelectionForeground}; }`);
}
if (styles.listFocusAndSelectionBackground) {
content.push(`.monaco-list${suffix}:focus .monaco-list-row.selected.focused { background-color: ${styles.listFocusAndSelectionBackground}; }`);
}
if (styles.listFocusAndSelectionForeground) {
content.push(`.monaco-list${suffix}:focus .monaco-list-row.selected.focused { color: ${styles.listFocusAndSelectionForeground}; }`);
}
if (styles.listInactiveFocusBackground) {
content.push(`.monaco-list${suffix} .monaco-list-row.focused { background-color: ${styles.listInactiveFocusBackground}; }`);
content.push(`.monaco-list${suffix} .monaco-list-row.focused:hover { background-color: ${styles.listInactiveFocusBackground}; }`); // overwrite :hover style in this case!
}
if (styles.listInactiveSelectionBackground) {
content.push(`.monaco-list${suffix} .monaco-list-row.selected { background-color: ${styles.listInactiveSelectionBackground}; }`);
content.push(`.monaco-list${suffix} .monaco-list-row.selected:hover { background-color: ${styles.listInactiveSelectionBackground}; }`); // overwrite :hover style in this case!
}
if (styles.listInactiveSelectionForeground) {
content.push(`.monaco-list${suffix} .monaco-list-row.selected { color: ${styles.listInactiveSelectionForeground}; }`);
}
if (styles.listHoverBackground) {
content.push(`.monaco-list${suffix} .monaco-list-row:hover { background-color: ${styles.listHoverBackground}; }`);
}
if (styles.listHoverForeground) {
content.push(`.monaco-list${suffix} .monaco-list-row:hover { color: ${styles.listHoverForeground}; }`);
}
if (styles.listSelectionOutline) {
content.push(`.monaco-list${suffix} .monaco-list-row.selected { outline: 1px dotted ${styles.listSelectionOutline}; outline-offset: -1px; }`);
}
if (styles.listFocusOutline) {
content.push(`.monaco-list${suffix}:focus .monaco-list-row.focused { outline: 1px solid ${styles.listFocusOutline}; outline-offset: -1px; }`);
}
if (styles.listInactiveFocusOutline) {
content.push(`.monaco-list${suffix} .monaco-list-row.focused { outline: 1px dotted ${styles.listInactiveFocusOutline}; outline-offset: -1px; }`);
}
if (styles.listHoverOutline) {
content.push(`.monaco-list${suffix} .monaco-list-row:hover { outline: 1px dashed ${styles.listHoverOutline}; outline-offset: -1px; }`);
}
const newStyles = content.join('\n');
if (newStyles !== this.styleElement.innerHTML) {
this.styleElement.innerHTML = newStyles;
}
}
}
export interface IListOptions<T> extends IListViewOptions, IListStyles {
identityProvider?: IIdentityProvider<T>;
ariaLabel?: string;
@@ -591,6 +674,7 @@ export interface IListOptions<T> extends IListViewOptions, IListStyles {
multipleSelectionSupport?: boolean;
multipleSelectionController?: IMultipleSelectionController<T>;
openController?: IOpenController;
styleController?: IStyleController;
}
export interface IListStyles {
@@ -737,7 +821,7 @@ class PipelineRenderer<T> implements IRenderer<T, any> {
let i = 0;
for (const renderer of this.renderers) {
renderer.disposeTemplate(templateData[i]);
renderer.disposeTemplate(templateData[i++]);
}
}
}
@@ -754,6 +838,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
private spliceable: ISpliceable<T>;
protected disposables: IDisposable[];
private styleElement: HTMLStyleElement;
private styleController: IStyleController;
private mouseController: MouseController<T>;
@memoize get onFocusChange(): Event<IListEvent<T>> {
@@ -767,9 +852,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
readonly onContextMenu: Event<IListContextMenuEvent<T>> = Event.None;
private _onOpen = new Emitter<IListOpenEvent<T>>();
@memoize get onOpen(): Event<IListOpenEvent<T>> {
return this._onOpen.event;
}
readonly onOpen: Event<IListOpenEvent<T>> = this._onOpen.event;
private _onPin = new Emitter<number[]>();
@memoize get onPin(): Event<IListEvent<T>> {
@@ -816,6 +899,11 @@ export class List<T> implements ISpliceable<T>, IDisposable {
this.styleElement = DOM.createStyleSheet(this.view.domNode);
this.styleController = options.styleController;
if (!this.styleController) {
this.styleController = new DefaultStyleController(this.styleElement, this.idPrefix);
}
this.spliceable = new CombinedSpliceable([
new TraitSpliceable(this.focus, this.view, options.identityProvider),
new TraitSpliceable(this.selection, this.view, options.identityProvider),
@@ -1087,73 +1175,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
}
style(styles: IListStyles): void {
const content: string[] = [];
if (styles.listFocusBackground) {
content.push(`.monaco-list.${this.idPrefix}:focus .monaco-list-row.focused { background-color: ${styles.listFocusBackground}; }`);
content.push(`.monaco-list.${this.idPrefix}:focus .monaco-list-row.focused:hover { background-color: ${styles.listFocusBackground}; }`); // overwrite :hover style in this case!
}
if (styles.listFocusForeground) {
content.push(`.monaco-list.${this.idPrefix}:focus .monaco-list-row.focused { color: ${styles.listFocusForeground}; }`);
}
if (styles.listActiveSelectionBackground) {
content.push(`.monaco-list.${this.idPrefix}:focus .monaco-list-row.selected { background-color: ${styles.listActiveSelectionBackground}; }`);
content.push(`.monaco-list.${this.idPrefix}:focus .monaco-list-row.selected:hover { background-color: ${styles.listActiveSelectionBackground}; }`); // overwrite :hover style in this case!
}
if (styles.listActiveSelectionForeground) {
content.push(`.monaco-list.${this.idPrefix}:focus .monaco-list-row.selected { color: ${styles.listActiveSelectionForeground}; }`);
}
if (styles.listFocusAndSelectionBackground) {
content.push(`.monaco-list.${this.idPrefix}:focus .monaco-list-row.selected.focused { background-color: ${styles.listFocusAndSelectionBackground}; }`);
}
if (styles.listFocusAndSelectionForeground) {
content.push(`.monaco-list.${this.idPrefix}:focus .monaco-list-row.selected.focused { color: ${styles.listFocusAndSelectionForeground}; }`);
}
if (styles.listInactiveFocusBackground) {
content.push(`.monaco-list.${this.idPrefix} .monaco-list-row.focused { background-color: ${styles.listInactiveFocusBackground}; }`);
content.push(`.monaco-list.${this.idPrefix} .monaco-list-row.focused:hover { background-color: ${styles.listInactiveFocusBackground}; }`); // overwrite :hover style in this case!
}
if (styles.listInactiveSelectionBackground) {
content.push(`.monaco-list.${this.idPrefix} .monaco-list-row.selected { background-color: ${styles.listInactiveSelectionBackground}; }`);
content.push(`.monaco-list.${this.idPrefix} .monaco-list-row.selected:hover { background-color: ${styles.listInactiveSelectionBackground}; }`); // overwrite :hover style in this case!
}
if (styles.listInactiveSelectionForeground) {
content.push(`.monaco-list.${this.idPrefix} .monaco-list-row.selected { color: ${styles.listInactiveSelectionForeground}; }`);
}
if (styles.listHoverBackground) {
content.push(`.monaco-list.${this.idPrefix} .monaco-list-row:hover { background-color: ${styles.listHoverBackground}; }`);
}
if (styles.listHoverForeground) {
content.push(`.monaco-list.${this.idPrefix} .monaco-list-row:hover { color: ${styles.listHoverForeground}; }`);
}
if (styles.listSelectionOutline) {
content.push(`.monaco-list.${this.idPrefix} .monaco-list-row.selected { outline: 1px dotted ${styles.listSelectionOutline}; outline-offset: -1px; }`);
}
if (styles.listFocusOutline) {
content.push(`.monaco-list.${this.idPrefix}:focus .monaco-list-row.focused { outline: 1px solid ${styles.listFocusOutline}; outline-offset: -1px; }`);
}
if (styles.listInactiveFocusOutline) {
content.push(`.monaco-list.${this.idPrefix} .monaco-list-row.focused { outline: 1px dotted ${styles.listInactiveFocusOutline}; outline-offset: -1px; }`);
}
if (styles.listHoverOutline) {
content.push(`.monaco-list.${this.idPrefix} .monaco-list-row:hover { outline: 1px dashed ${styles.listHoverOutline}; outline-offset: -1px; }`);
}
this.styleElement.innerHTML = content.join('\n');
this.styleController.style(styles);
}
private toListEvent({ indexes }: ITraitChangeEvent) {

View File

@@ -7,11 +7,11 @@
import 'vs/css!./menu';
import { IDisposable } from 'vs/base/common/lifecycle';
import { $ } 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 { ResolvedKeybinding } from 'vs/base/common/keyCodes';
import Event from 'vs/base/common/event';
import { Event } from 'vs/base/common/event';
import { addClass } from 'vs/base/browser/dom';
export interface IMenuOptions {
context?: any;
@@ -26,11 +26,13 @@ export class Menu {
private listener: IDisposable;
constructor(container: HTMLElement, actions: IAction[], options: IMenuOptions = {}) {
$(container).addClass('monaco-menu-container');
addClass(container, 'monaco-menu-container');
let $menu = $('.monaco-menu').appendTo(container);
let menuContainer = document.createElement('div');
addClass(menuContainer, 'monaco-menu');
container.appendChild(menuContainer);
this.actionBar = new ActionBar($menu, {
this.actionBar = new ActionBar(menuContainer, {
orientation: ActionsOrientation.VERTICAL,
actionItemProvider: options.actionItemProvider,
context: options.context,

View File

@@ -2,14 +2,14 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import octiconLabel = require('vs/base/browser/ui/octiconLabel/octiconLabel');
import { escape } from 'vs/base/common/strings';
function render(text: string): string {
export function renderOcticons(text: string): string {
return escape(text);
}
class MockOcticonLabel {
export class OcticonLabel {
private _container: HTMLElement;
@@ -18,13 +18,7 @@ class MockOcticonLabel {
}
set text(text: string) {
this._container.innerHTML = render(text || '');
this._container.innerHTML = renderOcticons(text || '');
}
}
var mock: typeof octiconLabel = {
render: render,
OcticonLabel: <any>MockOcticonLabel
};
export = mock;

View File

@@ -14,20 +14,20 @@ function expand(text: string): string {
});
}
export function render(label: string): string {
export function renderOcticons(label: string): string {
return expand(escape(label));
}
export class OcticonLabel {
private _container: HTMLElement;
private readonly _container: HTMLElement;
constructor(container: HTMLElement) {
this._container = container;
}
set text(text: string) {
this._container.innerHTML = render(text || '');
this._container.innerHTML = renderOcticons(text || '');
}
set title(title: string) {

View File

@@ -2,12 +2,14 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.progress-container {
.monaco-progress-container {
width: 100%;
height: 5px;
overflow: hidden; /* keep progress bit in bounds */
}
.progress-container .progress-bit {
.monaco-progress-container .progress-bit {
width: 2%;
height: 5px;
position: absolute;
@@ -15,11 +17,11 @@
display: none;
}
.progress-container.active .progress-bit {
.monaco-progress-container.active .progress-bit {
display: inherit;
}
.progress-container.discrete .progress-bit {
.monaco-progress-container.discrete .progress-bit {
left: 0;
transition: width 100ms linear;
-webkit-transition: width 100ms linear;
@@ -28,11 +30,11 @@
-ms-transition: width 100ms linear;
}
.progress-container.discrete.done .progress-bit {
.monaco-progress-container.discrete.done .progress-bit {
width: 100%;
}
.progress-container.infinite .progress-bit {
.monaco-progress-container.infinite .progress-bit {
animation-name: progress;
animation-duration: 4s;
animation-iteration-count: infinite;
@@ -49,11 +51,17 @@
-moz-animation-duration: 4s;
-moz-animation-iteration-count: infinite;
-moz-animation-timing-function: linear;
will-change: transform;
}
@keyframes progress { from { left: 0; width: 2%; } 50% { left: 50%; width: 5%; } to { left: 98%; width: 2%; } }
@-ms-keyframes progress { from { left: 0; width: 2%; } 50% { left: 50%; width: 5%; } to { left: 98%; width: 2%; } }
@-webkit-keyframes progress { from { left: 0; width: 2%; } 50% { left: 50%; width: 5%; } to { left: 98%; width: 2%; } }
@-moz-keyframes progress { from { left: 0; width: 2%; } 50% { left: 50%; width: 5%; } to { left: 98%; width: 2%; } }
/**
* The progress bit has a width: 2% (1/50) of the parent container. The animation moves it from 0% to 100% of
* that container. Since translateX is relative to the progress bit size, we have to multiple it with
* its relative size to the parent container:
* 50%: 50 * 50 = 2500%
* 100%: 50 * 100 - 50 (do not overflow): 4950%
*/
@keyframes progress { from { transform: translateX(0%) scaleX(1) } 50% { transform: translateX(2500%) scaleX(3) } to { transform: translateX(4950%) scaleX(1) } }
@-ms-keyframes progress { from { transform: translateX(0%) scaleX(1) } 50% { transform: translateX(2500%) scaleX(3) } to { transform: translateX(4950%) scaleX(1) } }
@-webkit-keyframes progress { from { transform: translateX(0%) scaleX(1) } 50% { transform: translateX(2500%) scaleX(3) } to { transform: translateX(4950%) scaleX(1) } }
@-moz-keyframes progress { from { transform: translateX(0%) scaleX(1) } 50% { transform: translateX(2500%) scaleX(3) } to { transform: translateX(4950%) scaleX(1) } }

View File

@@ -7,9 +7,9 @@
import 'vs/css!./progressbar';
import { TPromise, ValueCallback } from 'vs/base/common/winjs.base';
import assert = require('vs/base/common/assert');
import * as assert from 'vs/base/common/assert';
import { Builder, $ } from 'vs/base/browser/builder';
import DOM = require('vs/base/browser/dom');
import * as DOM from 'vs/base/browser/dom';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Color } from 'vs/base/common/color';
import { mixin } from 'vs/base/common/objects';
@@ -18,7 +18,7 @@ const css_done = 'done';
const css_active = 'active';
const css_infinite = 'infinite';
const css_discrete = 'discrete';
const css_progress_container = 'progress-container';
const css_progress_container = 'monaco-progress-container';
const css_progress_bit = 'progress-bit';
export interface IProgressBarOptions extends IProgressBarStyles {
@@ -45,9 +45,7 @@ export class ProgressBar {
private animationStopToken: ValueCallback;
private progressBarBackground: Color;
constructor(container: Builder, options?: IProgressBarOptions);
constructor(container: HTMLElement, options?: IProgressBarOptions);
constructor(container: any, options?: IProgressBarOptions) {
constructor(container: HTMLElement, options?: IProgressBarOptions) {
this.options = options || Object.create(null);
mixin(this.options, defaultOpts, false);
@@ -59,10 +57,8 @@ export class ProgressBar {
this.create(container);
}
private create(container: Builder): void;
private create(container: HTMLElement): void;
private create(container: any): void {
$(container).div({ 'class': css_progress_container }, (builder) => {
private create(container: HTMLElement): void {
$(container).div({ 'class': css_progress_container }, builder => {
this.element = builder.clone();
builder.div({ 'class': css_progress_bit }).on([DOM.EventType.ANIMATION_START, DOM.EventType.ANIMATION_END, DOM.EventType.ANIMATION_ITERATION], (e: Event) => {
@@ -201,11 +197,20 @@ export class ProgressBar {
return this;
}
/**
* Returns the builder this progress bar is building in.
*/
public getContainer(): Builder {
return $(this.element);
public getContainer(): HTMLElement {
return this.element.getHTMLElement();
}
public show(delay?: number): void {
if (typeof delay === 'number') {
this.element.showDelayed(delay);
} else {
this.element.show();
}
}
public hide(): void {
this.element.hide();
}
public style(styles: IProgressBarStyles): void {

View File

@@ -25,22 +25,12 @@
cursor: default !important;
}
.vertical-cursor-container {
cursor: ew-resize;
}
.horizontal-cursor-container {
cursor: ns-resize;
}
/** Custom Mac Cursor */
.monaco-sash.mac.vertical,
.vertical-cursor-container-mac {
.monaco-sash.mac.vertical {
cursor: col-resize;
}
.monaco-sash.mac.horizontal,
.horizontal-cursor-container-mac {
.monaco-sash.mac.horizontal {
cursor: row-resize;
}

View File

@@ -7,14 +7,14 @@
import 'vs/css!./sash';
import { IDisposable, Disposable, dispose } from 'vs/base/common/lifecycle';
import { Builder, $, Dimension } from 'vs/base/browser/builder';
import { Builder, $ } from 'vs/base/browser/builder';
import { isIPad } from 'vs/base/browser/browser';
import { isMacintosh } from 'vs/base/common/platform';
import types = require('vs/base/common/types');
import DOM = require('vs/base/browser/dom');
import * as types from 'vs/base/common/types';
import { EventType, GestureEvent, Gesture } from 'vs/base/browser/touch';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import Event, { Emitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
import { getElementsByTagName, EventHelper, EventType as DOMEventType, createStyleSheet, addDisposableListener, Dimension } from 'vs/base/browser/dom';
export interface ISashLayoutProvider { }
@@ -63,15 +63,14 @@ export class Sash {
private _onDidEnd = new Emitter<void>();
constructor(container: HTMLElement, layoutProvider: ISashLayoutProvider, options: ISashOptions = {}) {
this.$e = $('.monaco-sash').appendTo(container);
if (isMacintosh) {
this.$e.addClass('mac');
}
this.$e.on(DOM.EventType.MOUSE_DOWN, (e) => { this.onMouseDown(e as MouseEvent); });
this.$e.on(DOM.EventType.DBLCLICK, (e) => this._onDidReset.fire());
this.$e.on(DOMEventType.MOUSE_DOWN, (e) => { this.onMouseDown(e as MouseEvent); });
this.$e.on(DOMEventType.DBLCLICK, (e) => this._onDidReset.fire());
Gesture.addTarget(this.$e.getHTMLElement());
this.$e.on(EventType.Start, (e) => { this.onTouchStart(e as GestureEvent); });
@@ -127,23 +126,23 @@ export class Sash {
}
private onMouseDown(e: MouseEvent): void {
DOM.EventHelper.stop(e, false);
EventHelper.stop(e, false);
if (this.isDisabled) {
return;
}
const iframes = $(DOM.getElementsByTagName('iframe'));
const iframes = $(getElementsByTagName('iframe'));
if (iframes) {
iframes.style('pointer-events', 'none'); // disable mouse events on iframes as long as we drag the sash
}
let mouseDownEvent = new StandardMouseEvent(e);
let startX = mouseDownEvent.posx;
let startY = mouseDownEvent.posy;
const mouseDownEvent = new StandardMouseEvent(e);
const startX = mouseDownEvent.posx;
const startY = mouseDownEvent.posy;
const altKey = mouseDownEvent.altKey;
let startEvent: ISashEvent = {
const startEvent: ISashEvent = {
startX: startX,
currentX: startX,
startY: startY,
@@ -154,14 +153,21 @@ export class Sash {
this.$e.addClass('active');
this._onDidStart.fire(startEvent);
let $window = $(window);
let containerCSSClass = `${this.getOrientation()}-cursor-container${isMacintosh ? '-mac' : ''}`;
const $window = $(window);
// fix https://github.com/Microsoft/vscode/issues/21675
const globalStyle = createStyleSheet(this.$e.getHTMLElement());
if (this.orientation === Orientation.HORIZONTAL) {
globalStyle.innerHTML = `* { cursor: ${isMacintosh ? 'row-resize' : 'ns-resize'}; }`;
} else {
globalStyle.innerHTML = `* { cursor: ${isMacintosh ? 'col-resize' : 'ew-resize'}; }`;
}
$window.on('mousemove', (e) => {
DOM.EventHelper.stop(e, false);
let mouseMoveEvent = new StandardMouseEvent(e as MouseEvent);
EventHelper.stop(e, false);
const mouseMoveEvent = new StandardMouseEvent(e as MouseEvent);
let event: ISashEvent = {
const event: ISashEvent = {
startX: startX,
currentX: mouseMoveEvent.posx,
startY: startY,
@@ -171,29 +177,29 @@ export class Sash {
this._onDidChange.fire(event);
}).once('mouseup', (e) => {
DOM.EventHelper.stop(e, false);
EventHelper.stop(e, false);
this.$e.getHTMLElement().removeChild(globalStyle);
this.$e.removeClass('active');
this._onDidEnd.fire();
$window.off('mousemove');
document.body.classList.remove(containerCSSClass);
const iframes = $(DOM.getElementsByTagName('iframe'));
const iframes = $(getElementsByTagName('iframe'));
if (iframes) {
iframes.style('pointer-events', 'auto');
}
});
document.body.classList.add(containerCSSClass);
}
private onTouchStart(event: GestureEvent): void {
DOM.EventHelper.stop(event);
EventHelper.stop(event);
let listeners: IDisposable[] = [];
const listeners: IDisposable[] = [];
let startX = event.pageX;
let startY = event.pageY;
const startX = event.pageX;
const startY = event.pageY;
const altKey = event.altKey;
@@ -205,7 +211,7 @@ export class Sash {
altKey
});
listeners.push(DOM.addDisposableListener(this.$e.getHTMLElement(), EventType.Change, (event: GestureEvent) => {
listeners.push(addDisposableListener(this.$e.getHTMLElement(), EventType.Change, (event: GestureEvent) => {
if (types.isNumber(event.pageX) && types.isNumber(event.pageY)) {
this._onDidChange.fire({
startX: startX,
@@ -217,7 +223,7 @@ export class Sash {
}
}));
listeners.push(DOM.addDisposableListener(this.$e.getHTMLElement(), EventType.End, (event: GestureEvent) => {
listeners.push(addDisposableListener(this.$e.getHTMLElement(), EventType.End, (event: GestureEvent) => {
this._onDidEnd.fire();
dispose(listeners);
}));
@@ -227,7 +233,7 @@ export class Sash {
let style: { top?: string; left?: string; height?: string; width?: string; };
if (this.orientation === Orientation.VERTICAL) {
let verticalProvider = (<IVerticalSashLayoutProvider>this.layoutProvider);
const verticalProvider = (<IVerticalSashLayoutProvider>this.layoutProvider);
style = { left: verticalProvider.getVerticalSashLeft(this) - (this.size / 2) + 'px' };
if (verticalProvider.getVerticalSashTop) {
@@ -238,7 +244,7 @@ export class Sash {
style.height = verticalProvider.getVerticalSashHeight(this) + 'px';
}
} else {
let horizontalProvider = (<IHorizontalSashLayoutProvider>this.layoutProvider);
const horizontalProvider = (<IHorizontalSashLayoutProvider>this.layoutProvider);
style = { top: horizontalProvider.getHorizontalSashTop(this) - (this.size / 2) + 'px' };
if (horizontalProvider.getHorizontalSashLeft) {
@@ -294,18 +300,18 @@ export class Sash {
* Triggers onPositionChange event when the position is changed
*/
export class VSash extends Disposable implements IVerticalSashLayoutProvider {
private sash: Sash;
private ratio: number;
private startPosition: number;
private position: number;
private dimension: Dimension;
private _onPositionChange: Emitter<number> = new Emitter<number>();
private readonly _onPositionChange: Emitter<number> = new Emitter<number>();
public get onPositionChange(): Event<number> { return this._onPositionChange.event; }
constructor(container: HTMLElement, private minWidth: number) {
super();
this.ratio = 0.5;
this.sash = new Sash(container, this);
@@ -357,9 +363,9 @@ export class VSash extends Disposable implements IVerticalSashLayoutProvider {
}
private computeSashPosition(sashRatio: number = this.ratio) {
let contentWidth = this.dimension.width;
const contentWidth = this.dimension.width;
let sashPosition = Math.floor((sashRatio || 0.5) * contentWidth);
let midPoint = Math.floor(0.5 * contentWidth);
const midPoint = Math.floor(0.5 * contentWidth);
if (contentWidth > this.minWidth * 2) {
if (sashPosition < this.minWidth) {

View File

@@ -18,7 +18,7 @@ import { Widget } from 'vs/base/browser/ui/widget';
import { TimeoutTimer } from 'vs/base/common/async';
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
import { ScrollbarHost } from 'vs/base/browser/ui/scrollbar/abstractScrollbar';
import Event, { Emitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
const HIDE_TIMEOUT = 500;
const SCROLL_WHEEL_SENSITIVITY = 50;
@@ -164,7 +164,7 @@ export abstract class AbstractScrollableElement extends Widget {
private _shouldRender: boolean;
private readonly _onScroll = this._register(new Emitter<ScrollEvent>());
public onScroll: Event<ScrollEvent> = this._onScroll.event;
public readonly onScroll: Event<ScrollEvent> = this._onScroll.event;
protected constructor(element: HTMLElement, options: ScrollableElementCreationOptions, scrollable?: Scrollable) {
super();
@@ -336,16 +336,6 @@ export abstract class AbstractScrollableElement extends Widget {
deltaY = 0;
}
if (Platform.isMacintosh) {
// Give preference to vertical scrolling
if (deltaY && Math.abs(deltaX) < 0.2) {
deltaX = 0;
}
if (Math.abs(deltaY) > Math.abs(deltaX) * 0.5) {
deltaX = 0;
}
}
const futureScrollPosition = this._scrollable.getFutureScrollPosition();
let desiredScrollPosition: INewScrollPosition = {};

View File

@@ -3,7 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.monaco-workbench .select-box {
.monaco-select-box {
width: 100%;
height: 20px;
}
}

View File

@@ -6,7 +6,7 @@
import 'vs/css!./selectBox';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import Event, { Emitter } from 'vs/base/common/event';
import { Event } from 'vs/base/common/event';
import { Widget } from 'vs/base/browser/ui/widget';
import { Color } from 'vs/base/common/color';
import { deepClone, mixin } from 'vs/base/common/objects';
@@ -34,6 +34,10 @@ export interface ISelectBoxDelegate {
applyStyles(): void;
}
export interface ISelectBoxOptions {
minBottomMargin?: number;
}
export interface ISelectBoxStyles extends IListStyles {
selectBackground?: Color;
selectListBackground?: Color;
@@ -54,21 +58,16 @@ export interface ISelectData {
}
export class SelectBox extends Widget implements ISelectBoxDelegate {
protected options: string[];
private selected: number;
private _onDidSelect: Emitter<ISelectData>;
// {{SQL CARBON EDIT}}
protected selectElement: HTMLSelectElement;
protected selectBackground: Color;
protected selectForeground: Color;
protected selectBorder: Color;
private toDispose: IDisposable[];
private styles: ISelectBoxStyles;
private selectBoxDelegate: ISelectBoxDelegate;
constructor(options: string[], selected: number, contextViewProvider: IContextViewProvider, styles: ISelectBoxStyles = deepClone(defaultStyles)) {
constructor(options: string[], selected: number, contextViewProvider: IContextViewProvider, styles: ISelectBoxStyles = deepClone(defaultStyles), selectBoxOptions?: ISelectBoxOptions) {
super();
this.toDispose = [];
@@ -79,7 +78,7 @@ export class SelectBox extends Widget implements ISelectBoxDelegate {
if (isMacintosh) {
this.selectBoxDelegate = new SelectBoxNative(options, selected, styles);
} else {
this.selectBoxDelegate = new SelectBoxList(options, selected, contextViewProvider, styles);
this.selectBoxDelegate = new SelectBoxList(options, selected, contextViewProvider, styles, selectBoxOptions);
}
// {{SQL CARBON EDIT}}

View File

@@ -3,13 +3,11 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/* Require .monaco-shell for ContextView dropdown */
.monaco-shell .select-box-dropdown-container {
.monaco-select-box-dropdown-container {
display: none;
}
.monaco-shell .select-box-dropdown-container.visible {
.monaco-select-box-dropdown-container.visible {
display: flex;
flex-direction: column;
text-align: left;
@@ -17,7 +15,7 @@
overflow: hidden;
}
.monaco-shell .select-box-dropdown-container > .select-box-dropdown-list-container {
.monaco-select-box-dropdown-container > .select-box-dropdown-list-container {
flex: 0 0 auto;
align-self: flex-start;
padding-bottom: 1px;
@@ -33,30 +31,30 @@
box-sizing: border-box;
}
.monaco-shell.hc-black .select-box-dropdown-container > .select-box-dropdown-list-container {
.hc-black .monaco-select-box-dropdown-container > .select-box-dropdown-list-container {
padding-bottom: 4px;
padding-top: 3px;
}
.monaco-shell .select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row > .option-text {
.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row > .option-text {
text-overflow: ellipsis;
overflow: hidden;
padding-left: 3.5px;
white-space: nowrap;
}
.monaco-shell .select-box-dropdown-container > .select-box-dropdown-container-width-control {
.monaco-select-box-dropdown-container > .select-box-dropdown-container-width-control {
flex: 1 1 auto;
align-self: flex-start;
opacity: 0;
}
.monaco-shell .select-box-dropdown-container > .select-box-dropdown-container-width-control > .width-control-div {
.monaco-select-box-dropdown-container > .select-box-dropdown-container-width-control > .width-control-div {
overflow: hidden;
max-height: 0px;
}
.monaco-shell .select-box-dropdown-container > .select-box-dropdown-container-width-control > .width-control-div > .option-text-width-control {
.monaco-select-box-dropdown-container > .select-box-dropdown-container-width-control > .width-control-div > .option-text-width-control {
padding-left: 4px;
padding-right: 8px;
white-space: nowrap;

View File

@@ -7,7 +7,7 @@ import 'vs/css!./selectBoxCustom';
import * as nls from 'vs/nls';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import Event, { Emitter, chain } from 'vs/base/common/event';
import { Event, Emitter, chain } from 'vs/base/common/event';
import { KeyCode, KeyCodeUtils } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import * as dom from 'vs/base/browser/dom';
@@ -17,7 +17,7 @@ import { List } from 'vs/base/browser/ui/list/listWidget';
import { IDelegate, IRenderer } from 'vs/base/browser/ui/list/list';
import { domEvent } from 'vs/base/browser/event';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import { ISelectBoxDelegate, ISelectBoxStyles, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
import { ISelectBoxDelegate, ISelectBoxOptions, ISelectBoxStyles, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
import { isMacintosh } from 'vs/base/common/platform';
const $ = dom.$;
@@ -61,6 +61,9 @@ class SelectListRenderer implements IRenderer<ISelectOptionItem, ISelectListTemp
// pseudo-select disabled option
if (optionDisabled) {
dom.addClass((<HTMLElement>data.root), 'option-disabled');
} else {
// Make sure we do class removal from prior template rendering
dom.removeClass((<HTMLElement>data.root), 'option-disabled');
}
}
@@ -71,15 +74,16 @@ class SelectListRenderer implements IRenderer<ISelectOptionItem, ISelectListTemp
export class SelectBoxList implements ISelectBoxDelegate, IDelegate<ISelectOptionItem> {
private static SELECT_DROPDOWN_BOTTOM_MARGIN = 10;
private static readonly DEFAULT_DROPDOWN_MINIMUM_BOTTOM_MARGIN = 32;
private _isVisible: boolean;
private selectBoxOptions: ISelectBoxOptions;
// {{SQL CARBON EDIT}}
public selectElement: HTMLSelectElement;
private options: string[];
private selected: number;
private disabledOptionIndex: number;
private _onDidSelect: Emitter<ISelectData>;
private readonly _onDidSelect: Emitter<ISelectData>;
private toDispose: IDisposable[];
private styles: ISelectBoxStyles;
private listRenderer: SelectListRenderer;
@@ -91,13 +95,20 @@ export class SelectBoxList implements ISelectBoxDelegate, IDelegate<ISelectOptio
private widthControlElement: HTMLElement;
private _currentSelection: number;
constructor(options: string[], selected: number, contextViewProvider: IContextViewProvider, styles: ISelectBoxStyles) {
constructor(options: string[], selected: number, contextViewProvider: IContextViewProvider, styles: ISelectBoxStyles, selectBoxOptions?: ISelectBoxOptions) {
this.toDispose = [];
this._isVisible = false;
this.selectBoxOptions = selectBoxOptions || Object.create(null);
if (typeof this.selectBoxOptions.minBottomMargin !== 'number') {
this.selectBoxOptions.minBottomMargin = SelectBoxList.DEFAULT_DROPDOWN_MINIMUM_BOTTOM_MARGIN;
} else if (this.selectBoxOptions.minBottomMargin < 0) {
this.selectBoxOptions.minBottomMargin = 0;
}
this.selectElement = document.createElement('select');
this.selectElement.className = 'select-box';
this.selectElement.className = 'monaco-select-box';
this._onDidSelect = new Emitter<ISelectData>();
this.styles = styles;
@@ -122,7 +133,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IDelegate<ISelectOptio
// SetUp ContextView container to hold select Dropdown
this.contextViewProvider = contextViewProvider;
this.selectDropDownContainer = dom.$('.select-box-dropdown-container');
this.selectDropDownContainer = dom.$('.monaco-select-box-dropdown-container');
// Setup list for drop-down select
this.createSelectList(this.selectDropDownContainer);
@@ -235,6 +246,10 @@ export class SelectBoxList implements ISelectBoxDelegate, IDelegate<ISelectOptio
if (index >= 0 && index < this.options.length) {
this.selected = index;
} else if (index > this.options.length - 1) {
// Adjust index to end of list
// This could make client out of sync with the select
this.select(this.options.length - 1);
} else if (this.selected < 0) {
this.selected = 0;
}
@@ -271,33 +286,33 @@ export class SelectBoxList implements ISelectBoxDelegate, IDelegate<ISelectOptio
// Style non-native select mode
if (this.styles.listFocusBackground) {
content.push(`.monaco-shell .select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.focused { background-color: ${this.styles.listFocusBackground} !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.focused { background-color: ${this.styles.listFocusBackground} !important; }`);
}
if (this.styles.listFocusForeground) {
content.push(`.monaco-shell .select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.focused:not(:hover) { color: ${this.styles.listFocusForeground} !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.focused:not(:hover) { color: ${this.styles.listFocusForeground} !important; }`);
}
// Hover foreground - ignore for disabled options
if (this.styles.listHoverForeground) {
content.push(`.monaco-shell .select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row:hover { color: ${this.styles.listHoverForeground} !important; }`);
content.push(`.monaco-shell .select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-disabled:hover { background-color: ${this.styles.listActiveSelectionForeground} !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row:hover { color: ${this.styles.listHoverForeground} !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-disabled:hover { background-color: ${this.styles.listActiveSelectionForeground} !important; }`);
}
// Hover background - ignore for disabled options
if (this.styles.listHoverBackground) {
content.push(`.monaco-shell .select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row:not(.option-disabled):not(.focused):hover { background-color: ${this.styles.listHoverBackground} !important; }`);
content.push(`.monaco-shell .select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-disabled:hover { background-color: ${this.styles.selectBackground} !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row:not(.option-disabled):not(.focused):hover { background-color: ${this.styles.listHoverBackground} !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-disabled:hover { background-color: ${this.styles.selectBackground} !important; }`);
}
// Match quickOpen outline styles - ignore for disabled options
if (this.styles.listFocusOutline) {
content.push(`.monaco-shell .select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.focused { outline: 1.6px dotted ${this.styles.listFocusOutline} !important; outline-offset: -1.6px !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.focused { outline: 1.6px dotted ${this.styles.listFocusOutline} !important; outline-offset: -1.6px !important; }`);
}
if (this.styles.listHoverOutline) {
content.push(`.monaco-shell .select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row:hover:not(.focused) { outline: 1.6px dashed ${this.styles.listHoverOutline} !important; outline-offset: -1.6px !important; }`);
content.push(`.monaco-shell .select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-disabled:hover { outline: none !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row:hover:not(.focused) { outline: 1.6px dashed ${this.styles.listHoverOutline} !important; outline-offset: -1.6px !important; }`);
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.option-disabled:hover { outline: none !important; }`);
}
this.styleElement.innerHTML = content.join('\n');
@@ -379,9 +394,12 @@ export class SelectBoxList implements ISelectBoxDelegate, IDelegate<ISelectOptio
}
private renderSelectDropDown(container: HTMLElement): IDisposable {
dom.append(container, this.selectDropDownContainer);
container.appendChild(this.selectDropDownContainer);
this.layoutSelectDropDown();
return null;
return {
dispose: () => container.removeChild(this.selectDropDownContainer) // remove to take out the CSS rules we add
};
}
private layoutSelectDropDown() {
@@ -395,9 +413,12 @@ export class SelectBoxList implements ISelectBoxDelegate, IDelegate<ISelectOptio
const selectWidth = dom.getTotalWidth(this.selectElement);
const selectPosition = dom.getDomNodePagePosition(this.selectElement);
// Set container height to max from select bottom to margin above status bar
const statusBarHeight = dom.getTotalHeight(document.getElementById('workbench.parts.statusbar'));
const maxSelectDropDownHeight = (window.innerHeight - selectPosition.top - selectPosition.height - statusBarHeight - SelectBoxList.SELECT_DROPDOWN_BOTTOM_MARGIN);
// Set container height to max from select bottom to margin (default/minBottomMargin)
let maxSelectDropDownHeight = (window.innerHeight - selectPosition.top - selectPosition.height - this.selectBoxOptions.minBottomMargin);
if (maxSelectDropDownHeight < 0) {
maxSelectDropDownHeight = 0;
}
// SetUp list dimensions and layout - account for container padding
if (this.selectList) {

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import Event, { Emitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import * as dom from 'vs/base/browser/dom';
import * as arrays from 'vs/base/common/arrays';
@@ -17,7 +17,7 @@ export class SelectBoxNative implements ISelectBoxDelegate {
public selectElement: HTMLSelectElement;
private options: string[];
private selected: number;
private _onDidSelect: Emitter<ISelectData>;
private readonly _onDidSelect: Emitter<ISelectData>;
private toDispose: IDisposable[];
private styles: ISelectBoxStyles;
@@ -26,7 +26,7 @@ export class SelectBoxNative implements ISelectBoxDelegate {
this.toDispose = [];
this.selectElement = document.createElement('select');
this.selectElement.className = 'select-box';
this.selectElement.className = 'monaco-select-box';
this._onDidSelect = new Emitter<ISelectData>();
@@ -92,6 +92,10 @@ export class SelectBoxNative implements ISelectBoxDelegate {
public select(index: number): void {
if (index >= 0 && index < this.options.length) {
this.selected = index;
} else if (index > this.options.length - 1) {
// Adjust index to end of list
// This could make client out of sync with the select
this.select(this.options.length - 1);
} else if (this.selected < 0) {
this.selected = 0;
}

View File

@@ -5,7 +5,7 @@
'use strict';
import Event, { anyEvent } from 'vs/base/common/event';
import { Event, anyEvent } from 'vs/base/common/event';
import { Orientation } from 'vs/base/browser/ui/sash/sash';
import { append, $ } from 'vs/base/browser/dom';
import { SplitView, IView } from 'vs/base/browser/ui/splitview/splitview';

View File

@@ -7,7 +7,7 @@
import 'vs/css!./panelview';
import { IDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecycle';
import Event, { Emitter, chain } from 'vs/base/common/event';
import { Event, Emitter, chain } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
@@ -239,7 +239,7 @@ class PanelDraggable implements IDisposable {
private _onDidDrop = new Emitter<{ from: Panel, to: Panel }>();
readonly onDidDrop = this._onDidDrop.event;
constructor(private panel: Panel, private context: IDndContext) {
constructor(private panel: Panel, private dnd: IPanelDndController, private context: IDndContext) {
panel.draggableElement.draggable = true;
domEvent(panel.draggableElement, 'dragstart')(this.onDragStart, this, this.disposables);
domEvent(panel.dropTargetElement, 'dragenter')(this.onDragEnter, this, this.disposables);
@@ -249,6 +249,12 @@ class PanelDraggable implements IDisposable {
}
private onDragStart(e: DragEvent): void {
if (!this.dnd.canDrag(this.panel)) {
e.preventDefault();
e.stopPropagation();
return;
}
e.dataTransfer.effectAllowed = 'move';
const dragImage = append(document.body, $('.monaco-panel-drag-image', {}, this.panel.draggableElement.textContent));
@@ -263,6 +269,10 @@ class PanelDraggable implements IDisposable {
return;
}
if (!this.dnd.canDrop(this.context.draggable.panel, this.panel)) {
return;
}
this.dragOverCounter++;
this.render();
}
@@ -272,6 +282,10 @@ class PanelDraggable implements IDisposable {
return;
}
if (!this.dnd.canDrop(this.context.draggable.panel, this.panel)) {
return;
}
this.dragOverCounter--;
if (this.dragOverCounter === 0) {
@@ -297,7 +311,7 @@ class PanelDraggable implements IDisposable {
this.dragOverCounter = 0;
this.render();
if (this.context.draggable !== this) {
if (this.dnd.canDrop(this.context.draggable.panel, this.panel) && this.context.draggable !== this) {
this._onDidDrop.fire({ from: this.context.draggable.panel, to: this.panel });
}
@@ -319,8 +333,24 @@ class PanelDraggable implements IDisposable {
}
}
export class IPanelViewOptions {
dnd?: boolean;
export interface IPanelDndController {
canDrag(panel: Panel): boolean;
canDrop(panel: Panel, overPanel: Panel): boolean;
}
export class DefaultPanelDndController implements IPanelDndController {
canDrag(panel: Panel): boolean {
return true;
}
canDrop(panel: Panel, overPanel: Panel): boolean {
return true;
}
}
export interface IPanelViewOptions {
dnd?: IPanelDndController;
}
interface IPanelItem {
@@ -330,7 +360,7 @@ interface IPanelItem {
export class PanelView implements IDisposable {
private dnd: boolean;
private dnd: IPanelDndController | null;
private dndContext: IDndContext = { draggable: null };
private el: HTMLElement;
private panelItems: IPanelItem[] = [];
@@ -343,7 +373,7 @@ export class PanelView implements IDisposable {
readonly onDidSashChange: Event<void>;
constructor(container: HTMLElement, options: IPanelViewOptions = {}) {
this.dnd = !!options.dnd;
this.dnd = options.dnd;
this.el = append(container, $('.monaco-panel-view'));
this.splitview = new SplitView(this.el);
this.onDidSashChange = this.splitview.onDidSashChange;
@@ -358,7 +388,7 @@ export class PanelView implements IDisposable {
this.splitview.addView(panel, size, index);
if (this.dnd) {
const draggable = new PanelDraggable(panel, this.dndContext);
const draggable = new PanelDraggable(panel, this.dnd, this.dndContext);
disposables.push(draggable);
draggable.onDidDrop(this._onDidDrop.fire, this._onDidDrop, disposables);
}

View File

@@ -10,15 +10,20 @@
height: 100%;
}
.monaco-split-view2 > .split-view-view {
.monaco-split-view2 > .split-view-container {
width: 100%;
height: 100%;
}
.monaco-split-view2 > .split-view-container > .split-view-view {
overflow: hidden;
}
.monaco-split-view2.vertical > .split-view-view {
.monaco-split-view2.vertical > .split-view-container > .split-view-view {
width: 100%;
}
.monaco-split-view2.horizontal > .split-view-view {
.monaco-split-view2.horizontal > .split-view-container > .split-view-view {
height: 100%;
display: inline-block;
}

View File

@@ -7,9 +7,9 @@
import 'vs/css!./splitview';
import { IDisposable, combinedDisposable, toDisposable } from 'vs/base/common/lifecycle';
import Event, { mapEvent, Emitter } from 'vs/base/common/event';
import types = require('vs/base/common/types');
import dom = require('vs/base/browser/dom');
import { Event, mapEvent, Emitter } from 'vs/base/common/event';
import * as types from 'vs/base/common/types';
import * as dom from 'vs/base/browser/dom';
import { clamp } from 'vs/base/common/numbers';
import { range, firstIndex } from 'vs/base/common/arrays';
import { Sash, Orientation, ISashEvent as IBaseSashEvent } from 'vs/base/browser/ui/sash/sash';
@@ -82,6 +82,7 @@ export class SplitView implements IDisposable {
private orientation: Orientation;
private el: HTMLElement;
private viewContainer: HTMLElement;
private size = 0;
private contentSize = 0;
private viewItems: IViewItem[] = [];
@@ -105,6 +106,10 @@ export class SplitView implements IDisposable {
dom.addClass(this.el, 'monaco-split-view2');
dom.addClass(this.el, this.orientation === Orientation.VERTICAL ? 'vertical' : 'horizontal');
container.appendChild(this.el);
this.viewContainer = document.createElement('div');
dom.addClass(this.viewContainer, 'split-view-container');
this.el.appendChild(this.viewContainer);
}
addView(view: IView, size: number, index = this.viewItems.length): void {
@@ -118,13 +123,13 @@ export class SplitView implements IDisposable {
const container = dom.$('.split-view-view');
if (index === this.viewItems.length) {
this.el.appendChild(container);
this.viewContainer.appendChild(container);
} else {
this.el.insertBefore(container, this.el.children.item(index));
this.viewContainer.insertBefore(container, this.viewContainer.children.item(index));
}
const onChangeDisposable = view.onDidChange(size => this.onViewChange(item, size));
const containerDisposable = toDisposable(() => this.el.removeChild(container));
const containerDisposable = toDisposable(() => this.viewContainer.removeChild(container));
const disposable = combinedDisposable([onChangeDisposable, containerDisposable]);
const layoutContainer = this.orientation === Orientation.VERTICAL
@@ -218,9 +223,9 @@ export class SplitView implements IDisposable {
this.viewItems.splice(to, 0, viewItem);
if (to + 1 < this.viewItems.length) {
this.el.insertBefore(viewItem.container, this.viewItems[to + 1].container);
this.viewContainer.insertBefore(viewItem.container, this.viewItems[to + 1].container);
} else {
this.el.appendChild(viewItem.container);
this.viewContainer.appendChild(viewItem.container);
}
this.layoutViews();

View File

@@ -6,9 +6,8 @@
'use strict';
import 'vs/css!./toolbar';
import nls = require('vs/nls');
import * as nls from 'vs/nls';
import { TPromise } from 'vs/base/common/winjs.base';
import { Builder, $ } from 'vs/base/browser/builder';
import { Action, IActionRunner, IAction } from 'vs/base/common/actions';
import { ActionBar, ActionsOrientation, IActionItemProvider } from 'vs/base/browser/ui/actionbar/actionbar';
import { IContextMenuProvider, DropdownMenuActionItem } from 'vs/base/browser/ui/dropdown/dropdown';
@@ -45,7 +44,7 @@ export class ToolBar {
element.className = 'monaco-toolbar';
container.appendChild(element);
this.actionBar = new ActionBar($(element), {
this.actionBar = new ActionBar(element, {
orientation: options.orientation,
ariaLabel: options.ariaLabel,
actionRunner: options.actionRunner,
@@ -94,10 +93,18 @@ export class ToolBar {
}
}
public getContainer(): Builder {
public getContainer(): HTMLElement {
return this.actionBar.getContainer();
}
public getItemsWidth(): number {
let itemsWidth = 0;
for (let i = 0; i < this.actionBar.length(); i++) {
itemsWidth += this.actionBar.getWidth(i);
}
return itemsWidth;
}
public setAriaLabel(label: string): void {
this.actionBar.setAriaLabel(label);
}

View File

@@ -6,7 +6,7 @@
import { TPromise } from 'vs/base/common/winjs.base';
import { IDisposable } from 'vs/base/common/lifecycle';
import Event, { Emitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
export interface ITelemetryData {
from?: string;

View File

@@ -53,7 +53,7 @@ export function binarySearch<T>(array: T[], key: T, comparator: (op1: T, op2: T)
* are located before all elements where p(x) is true.
* @returns the least x for which p(x) is true or array.length if no element fullfills the given function.
*/
export function findFirst<T>(array: T[], p: (x: T) => boolean): number {
export function findFirstInSorted<T>(array: T[], p: (x: T) => boolean): number {
let low = 0, high = array.length;
if (high === 0) {
return 0; // no children
@@ -267,7 +267,7 @@ function topStep<T>(array: T[], compare: (a: T, b: T) => number, result: T[], i:
const element = array[i];
if (compare(element, result[n - 1]) < 0) {
result.pop();
const j = findFirst(result, e => compare(element, e) < 0);
const j = findFirstInSorted(result, e => compare(element, e) < 0);
result.splice(j, 0, element);
}
}

View File

@@ -9,7 +9,7 @@ import * as errors from 'vs/base/common/errors';
import { Promise, TPromise, ValueCallback, ErrorCallback, ProgressCallback } from 'vs/base/common/winjs.base';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import Event, { Emitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
import URI from 'vs/base/common/uri';
export function isThenable<T>(obj: any): obj is Thenable<T> {
@@ -29,10 +29,23 @@ export function asWinJsPromise<T>(callback: (token: CancellationToken) => T | TP
return new TPromise<T>((resolve, reject, progress) => {
let item = callback(source.token);
if (item instanceof TPromise) {
item.then(resolve, reject, progress);
item.then(result => {
source.dispose();
resolve(result);
}, err => {
source.dispose();
reject(err);
}, progress);
} else if (isThenable<T>(item)) {
item.then(resolve, reject);
item.then(result => {
source.dispose();
resolve(result);
}, err => {
source.dispose();
reject(err);
});
} else {
source.dispose();
resolve(item);
}
}, () => {
@@ -320,6 +333,10 @@ export function timeout(n: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, n));
}
function isWinJSPromise(candidate: any): candidate is TPromise {
return TPromise.is(candidate) && typeof (<TPromise>candidate).done === 'function';
}
/**
* Returns a new promise that joins the provided promise. Upon completion of
* the provided promise the provided function will always be called. This
@@ -327,28 +344,37 @@ export function timeout(n: number): Promise<void> {
* @param promise a promise
* @param f a function that will be call in the success and error case.
*/
export function always<T>(promise: TPromise<T>, f: Function): TPromise<T> {
return new TPromise<T>((c, e, p) => {
promise.done((result) => {
try {
f(result);
} catch (e1) {
errors.onUnexpectedError(e1);
}
c(result);
}, (err) => {
try {
f(err);
} catch (e1) {
errors.onUnexpectedError(e1);
}
e(err);
}, (progress) => {
p(progress);
export function always<T>(thenable: TPromise<T>, f: Function): TPromise<T>;
export function always<T>(promise: Thenable<T>, f: Function): Thenable<T>;
export function always<T>(winjsPromiseOrThenable: Thenable<T> | TPromise<T>, f: Function): TPromise<T> | Thenable<T> {
if (isWinJSPromise(winjsPromiseOrThenable)) {
return new TPromise<T>((c, e, p) => {
winjsPromiseOrThenable.done((result) => {
try {
f(result);
} catch (e1) {
errors.onUnexpectedError(e1);
}
c(result);
}, (err) => {
try {
f(err);
} catch (e1) {
errors.onUnexpectedError(e1);
}
e(err);
}, (progress) => {
p(progress);
});
}, () => {
winjsPromiseOrThenable.cancel();
});
}, () => {
promise.cancel();
});
} else {
// simple
winjsPromiseOrThenable.then(_ => f(), _ => f());
return winjsPromiseOrThenable;
}
}
/**
@@ -424,7 +450,7 @@ export class Limiter<T> {
private runningPromises: number;
private maxDegreeOfParalellism: number;
private outstandingPromises: ILimitedTaskFactory[];
private _onFinished: Emitter<void>;
private readonly _onFinished: Emitter<void>;
constructor(maxDegreeOfParalellism: number) {
this.maxDegreeOfParalellism = maxDegreeOfParalellism;

View File

@@ -5,7 +5,7 @@
'use strict';
import Event, { Emitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
export interface CancellationToken {
@@ -45,7 +45,7 @@ class MutableToken implements CancellationToken {
this._isCancelled = true;
if (this._emitter) {
this._emitter.fire(undefined);
this._emitter = undefined;
this.dispose();
}
}
}
@@ -63,6 +63,13 @@ class MutableToken implements CancellationToken {
}
return this._emitter.event;
}
public dispose(): void {
if (this._emitter) {
this._emitter.dispose();
this._emitter = undefined;
}
}
}
export class CancellationTokenSource {
@@ -92,6 +99,13 @@ export class CancellationTokenSource {
}
dispose(): void {
this.cancel();
if (!this._token) {
// ensure to initialize with an empty token if we had none
this._token = CancellationToken.None;
} else if (this._token instanceof MutableToken) {
// actually dispose
this._token.dispose();
}
}
}

View File

@@ -33,6 +33,10 @@ export function memoize(target: any, key: string, descriptor: any) {
if (typeof descriptor.value === 'function') {
fnKey = 'value';
fn = descriptor.value;
if (fn.length !== 0) {
console.warn('Memoize should only be used in functions with zero parameters');
}
} else if (typeof descriptor.get === 'function') {
fnKey = 'get';
fn = descriptor.get;
@@ -58,13 +62,27 @@ export function memoize(target: any, key: string, descriptor: any) {
};
}
export function debounce(delay: number): Function {
export interface IDebouceReducer<T> {
(previousValue: T, ...args: any[]): T;
}
export function debounce<T>(delay: number, reducer?: IDebouceReducer<T>, initialValueProvider?: () => T): Function {
return createDecorator((fn, key) => {
const timerKey = `$debounce$${key}`;
let result = initialValueProvider ? initialValueProvider() : void 0;
return function (this: any, ...args: any[]) {
clearTimeout(this[timerKey]);
this[timerKey] = setTimeout(() => fn.apply(this, args), delay);
if (reducer) {
result = reducer(result, ...args);
args = [result];
}
this[timerKey] = setTimeout(() => {
fn.apply(this, args);
result = initialValueProvider ? initialValueProvider() : void 0;
}, delay);
};
});
}

View File

@@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import nls = require('vs/nls');
import types = require('vs/base/common/types');
import arrays = require('vs/base/common/arrays');
import * as nls from 'vs/nls';
import * as types from 'vs/base/common/types';
import * as arrays from 'vs/base/common/arrays';
function exceptionToErrorMessage(exception: any, verbose: boolean): string {
if (exception.message) {

View File

@@ -14,17 +14,15 @@ import { LinkedList } from 'vs/base/common/linkedList';
* To an event a function with one or zero parameters
* can be subscribed. The event is the subscriber function itself.
*/
interface Event<T> {
export interface Event<T> {
(listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[]): IDisposable;
}
namespace Event {
export namespace Event {
const _disposable = { dispose() { } };
export const None: Event<any> = function () { return _disposable; };
}
export default Event;
type Listener = [Function, any] | Function;
export interface EmitterOptions {
@@ -163,7 +161,7 @@ export class Emitter<T> {
export class EventMultiplexer<T> implements IDisposable {
private emitter: Emitter<T>;
private readonly emitter: Emitter<T>;
private hasListeners = false;
private events: { event: Event<T>; listener: IDisposable; }[] = [];
@@ -281,7 +279,7 @@ export function debounceEvent<I, O>(event: Event<I>, merger: (last: O, event: I)
let subscription: IDisposable;
let output: O = undefined;
let handle: number = undefined;
let handle: any = undefined;
let numDebouncedCalls = 0;
const emitter = new Emitter<O>({
@@ -367,6 +365,7 @@ export interface IChainableEvent<T> {
map<O>(fn: (i: T) => O): IChainableEvent<O>;
forEach(fn: (i: T) => void): IChainableEvent<T>;
filter(fn: (e: T) => boolean): IChainableEvent<T>;
latch(): IChainableEvent<T>;
on(listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[]): IDisposable;
}
@@ -400,6 +399,10 @@ class ChainableEvent<T> implements IChainableEvent<T> {
return new ChainableEvent(filterEvent(this._event, fn));
}
latch(): IChainableEvent<T> {
return new ChainableEvent(latch(this._event));
}
on(listener: (e: T) => any, thisArgs: any, disposables: IDisposable[]) {
return this._event(listener, thisArgs, disposables);
}
@@ -536,3 +539,15 @@ export function fromNodeEventEmitter<T>(emitter: NodeEventEmitter, eventName: st
return result.event;
}
export function latch<T>(event: Event<T>): Event<T> {
let firstCall = true;
let cache: T;
return filterEvent(event, value => {
let shouldEmit = firstCall || value !== cache;
firstCall = false;
cache = value;
return shouldEmit;
});
}

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import strings = require('vs/base/common/strings');
import * as strings from 'vs/base/common/strings';
import { LRUCache } from 'vs/base/common/map';
import { CharCode } from 'vs/base/common/charCode';
@@ -50,7 +50,7 @@ function _matchesPrefix(ignoreCase: boolean, word: string, wordToMatchAgainst: s
let matches: boolean;
if (ignoreCase) {
matches = strings.beginsWithIgnoreCase(wordToMatchAgainst, word);
matches = strings.startsWithIgnoreCase(wordToMatchAgainst, word);
} else {
matches = wordToMatchAgainst.indexOf(word) === 0;
}

View File

@@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import arrays = require('vs/base/common/arrays');
import strings = require('vs/base/common/strings');
import paths = require('vs/base/common/paths');
import * as arrays from 'vs/base/common/arrays';
import * as strings from 'vs/base/common/strings';
import * as paths from 'vs/base/common/paths';
import { LRUCache } from 'vs/base/common/map';
import { CharCode } from 'vs/base/common/charCode';
import { TPromise } from 'vs/base/common/winjs.base';

View File

@@ -65,6 +65,11 @@ export class HistoryNavigator<T> implements INavigator<T> {
return this._navigator.last();
}
public clear(): void {
this._initialize([]);
this._onChange();
}
private _onChange() {
this._reduceToLimit();
this._navigator = new ArrayNavigator(this._elements);

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import Json = require('./json');
import * as Json from './json';
export interface FormattingOptions {
/**

View File

@@ -54,10 +54,10 @@ export const UILabelProvider = new ModifierLabelProvider(
separator: '',
},
{
ctrlKey: nls.localize('ctrlKey', "Ctrl"),
shiftKey: nls.localize('shiftKey', "Shift"),
altKey: nls.localize('altKey', "Alt"),
metaKey: nls.localize('windowsKey', "Windows"),
ctrlKey: nls.localize({ key: 'ctrlKey', comment: ['This is the short form for the Control key on the keyboard'] }, "Ctrl"),
shiftKey: nls.localize({ key: 'shiftKey', comment: ['This is the short form for the Shift key on the keyboard'] }, "Shift"),
altKey: nls.localize({ key: 'altKey', comment: ['This is the short form for the Alt key on the keyboard'] }, "Alt"),
metaKey: nls.localize({ key: 'windowsKey', comment: ['This is the short form for the Windows key on the keyboard'] }, "Windows"),
separator: '+',
}
);
@@ -67,17 +67,17 @@ export const UILabelProvider = new ModifierLabelProvider(
*/
export const AriaLabelProvider = new ModifierLabelProvider(
{
ctrlKey: nls.localize('ctrlKey.long', "Control"),
shiftKey: nls.localize('shiftKey.long', "Shift"),
altKey: nls.localize('altKey.long', "Alt"),
metaKey: nls.localize('cmdKey.long', "Command"),
ctrlKey: nls.localize({ key: 'ctrlKey.long', comment: ['This is the long form for the Control key on the keyboard'] }, "Control"),
shiftKey: nls.localize({ key: 'shiftKey.long', comment: ['This is the long form for the Shift key on the keyboard'] }, "Shift"),
altKey: nls.localize({ key: 'altKey.long', comment: ['This is the long form for the Alt key on the keyboard'] }, "Alt"),
metaKey: nls.localize({ key: 'cmdKey.long', comment: ['This is the long form for the Command key on the keyboard'] }, "Command"),
separator: '+',
},
{
ctrlKey: nls.localize('ctrlKey.long', "Control"),
shiftKey: nls.localize('shiftKey.long', "Shift"),
altKey: nls.localize('altKey.long', "Alt"),
metaKey: nls.localize('windowsKey.long', "Windows"),
ctrlKey: nls.localize({ key: 'ctrlKey.long', comment: ['This is the long form for the Control key on the keyboard'] }, "Control"),
shiftKey: nls.localize({ key: 'shiftKey.long', comment: ['This is the long form for the Shift key on the keyboard'] }, "Shift"),
altKey: nls.localize({ key: 'altKey.long', comment: ['This is the long form for the Alt key on the keyboard'] }, "Alt"),
metaKey: nls.localize({ key: 'windowsKey.long', comment: ['This is the long form for the Windows key on the keyboard'] }, "Windows"),
separator: '+',
}
);

View File

@@ -5,10 +5,10 @@
'use strict';
import URI from 'vs/base/common/uri';
import platform = require('vs/base/common/platform');
import { nativeSep, normalize, isEqualOrParent, isEqual, basename as pathsBasename, join } from 'vs/base/common/paths';
import { endsWith, ltrim } from 'vs/base/common/strings';
import { nativeSep, normalize, basename as pathsBasename, join, sep } from 'vs/base/common/paths';
import { endsWith, ltrim, equalsIgnoreCase, startsWithIgnoreCase, rtrim, startsWith } from 'vs/base/common/strings';
import { Schemas } from 'vs/base/common/network';
import { isLinux, isWindows, isMacintosh } from 'vs/base/common/platform';
export interface IWorkspaceFolderProvider {
getWorkspaceFolder(resource: URI): { uri: URI };
@@ -30,6 +30,7 @@ export function getPathLabel(resource: URI | string, rootProvider?: IWorkspaceFo
resource = URI.file(resource);
}
// return early if the resource is neither file:// nor untitled://
if (resource.scheme !== Schemas.file && resource.scheme !== Schemas.untitled) {
return resource.with({ query: null, fragment: null }).toString(true);
}
@@ -40,7 +41,7 @@ export function getPathLabel(resource: URI | string, rootProvider?: IWorkspaceFo
const hasMultipleRoots = rootProvider.getWorkspace().folders.length > 1;
let pathLabel: string;
if (isEqual(baseResource.uri.fsPath, resource.fsPath, !platform.isLinux /* ignorecase */)) {
if (isLinux ? baseResource.uri.fsPath === resource.fsPath : equalsIgnoreCase(baseResource.uri.fsPath, resource.fsPath)) {
pathLabel = ''; // no label if pathes are identical
} else {
pathLabel = normalize(ltrim(resource.fsPath.substr(baseResource.uri.fsPath.length), nativeSep), true);
@@ -61,7 +62,7 @@ export function getPathLabel(resource: URI | string, rootProvider?: IWorkspaceFo
// normalize and tildify (macOS, Linux only)
let res = normalize(resource.fsPath, true);
if (!platform.isWindows && userHomeProvider) {
if (!isWindows && userHomeProvider) {
res = tildify(res, userHomeProvider.userHome);
}
@@ -88,7 +89,7 @@ export function getBaseLabel(resource: URI | string): string {
}
function hasDriveLetter(path: string): boolean {
return platform.isWindows && path && path[1] === ':';
return isWindows && path && path[1] === ':';
}
export function normalizeDriveLetter(path: string): string {
@@ -99,9 +100,22 @@ export function normalizeDriveLetter(path: string): string {
return path;
}
let normalizedUserHomeCached: { original: string; normalized: string } = Object.create(null);
export function tildify(path: string, userHome: string): string {
if (path && (platform.isMacintosh || platform.isLinux) && isEqualOrParent(path, userHome, !platform.isLinux /* ignorecase */)) {
path = `~${path.substr(userHome.length)}`;
if (isWindows || !path || !userHome) {
return path; // unsupported
}
// Keep a normalized user home path as cache to prevent accumulated string creation
let normalizedUserHome = normalizedUserHomeCached.original === userHome ? normalizedUserHomeCached.normalized : void 0;
if (!normalizedUserHome) {
normalizedUserHome = `${rtrim(userHome, sep)}${sep}`;
normalizedUserHomeCached = { original: userHome, normalized: normalizedUserHome };
}
// Linux: case sensitive, macOS: case insensitive
if (isLinux ? startsWith(path, normalizedUserHome) : startsWithIgnoreCase(path, normalizedUserHome)) {
path = `~/${path.substr(normalizedUserHome.length)}`;
}
return path;
@@ -325,7 +339,7 @@ export function template(template: string, values: { [key: string]: string | ISe
const left = segments[index - 1];
const right = segments[index + 1];
return [left, right].every(segment => segment && segment.type === Type.VARIABLE && segment.value.length > 0);
return [left, right].every(segment => segment && (segment.type === Type.VARIABLE || segment.type === Type.TEXT) && segment.value.length > 0);
}
// accept any TEXT and VARIABLE
@@ -340,7 +354,7 @@ export function template(template: string, values: { [key: string]: string | ISe
* - macOS: Unsupported (replace && with empty string)
*/
export function mnemonicMenuLabel(label: string, forceDisableMnemonics?: boolean): string {
if (platform.isMacintosh || forceDisableMnemonics) {
if (isMacintosh || forceDisableMnemonics) {
return label.replace(/\(&&\w\)|&&/g, '');
}
@@ -354,11 +368,11 @@ export function mnemonicMenuLabel(label: string, forceDisableMnemonics?: boolean
* - macOS: Unsupported (replace && with empty string)
*/
export function mnemonicButtonLabel(label: string): string {
if (platform.isMacintosh) {
if (isMacintosh) {
return label.replace(/\(&&\w\)|&&/g, '');
}
return label.replace(/&&/g, platform.isWindows ? '&' : '_');
return label.replace(/&&/g, isWindows ? '&' : '_');
}
export function unmnemonicLabel(label: string): string {

View File

@@ -368,10 +368,12 @@ export class TernarySearchTree<E> {
export class ResourceMap<T> {
protected map: Map<string, T>;
protected readonly map: Map<string, T>;
protected readonly ignoreCase?: boolean;
constructor(private ignoreCase?: boolean) {
constructor() {
this.map = new Map<string, T>();
this.ignoreCase = false; // in the future this should be an uri-comparator
}
public set(resource: URI, value: T): void {
@@ -414,18 +416,10 @@ export class ResourceMap<T> {
return key;
}
}
export class StrictResourceMap<T> extends ResourceMap<T> {
constructor() {
super();
}
public keys(): URI[] {
return keys(this.map).map(key => URI.parse(key));
return keys(this.map).map(URI.parse);
}
}
// We should fold BoundedMap and LinkedMap. See https://github.com/Microsoft/vscode/issues/28496
@@ -743,6 +737,24 @@ export class LinkedMap<K, V> {
this._tail = item;
}
}
public toJSON(): [K, V][] {
const data: [K, V][] = [];
this.forEach((value, key) => {
data.push([key, value]);
});
return data;
}
public fromJSON(data: [K, V][]): void {
this.clear();
for (const [key, value] of data) {
this.set(key, value);
}
}
}
export class LRUCache<K, V> extends LinkedMap<K, V> {

View File

@@ -3,6 +3,6 @@
[{
"name": "chjj-marked",
"repositoryURL": "https://github.com/npmcomponent/chjj-marked",
"version": "0.3.12",
"version": "0.3.18",
"license": "MIT"
}]

View File

@@ -73,7 +73,7 @@ export interface MarkedStatic {
export interface Renderer {
prototype: MarkedRenderer;
new (): MarkedRenderer;
new(): MarkedRenderer;
}
export interface MarkedRenderer {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -16,7 +16,7 @@ export function parse(text: string): any {
return data;
}
interface MarshalledObject {
export interface MarshalledObject {
$mid: number;
}

View File

@@ -4,8 +4,8 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import paths = require('vs/base/common/paths');
import strings = require('vs/base/common/strings');
import * as paths from 'vs/base/common/paths';
import * as strings from 'vs/base/common/strings';
import { match } from 'vs/base/common/glob';
export const MIME_TEXT = 'text/plain';

View File

@@ -5,7 +5,7 @@
'use strict';
import { isWindows } from 'vs/base/common/platform';
import { beginsWithIgnoreCase, equalsIgnoreCase } from 'vs/base/common/strings';
import { startsWithIgnoreCase, equalsIgnoreCase } from 'vs/base/common/strings';
import { CharCode } from 'vs/base/common/charCode';
/**
@@ -27,6 +27,8 @@ export function dirname(path: string): string {
return '.';
} else if (~idx === 0) {
return path[0];
} else if (~idx === path.length - 1) {
return dirname(path.substring(0, path.length - 1));
} else {
let res = path.substring(0, ~idx);
if (isWindows && res[res.length - 1] === ':') {
@@ -340,7 +342,7 @@ export function isEqualOrParent(path: string, candidate: string, ignoreCase?: bo
}
if (ignoreCase) {
const beginsWith = beginsWithIgnoreCase(path, candidate);
const beginsWith = startsWithIgnoreCase(path, candidate);
if (!beginsWith) {
return false;
}
@@ -395,4 +397,4 @@ export function isAbsolute_win32(path: string): boolean {
export function isAbsolute_posix(path: string): boolean {
return path && path.charCodeAt(0) === CharCode.Slash;
}
}

View File

@@ -42,7 +42,7 @@ declare let self: any;
export const LANGUAGE_DEFAULT = 'en';
// OS detection
if (typeof process === 'object' && typeof process.nextTick === 'function') {
if (typeof process === 'object' && typeof process.nextTick === 'function' && typeof process.platform === 'string') {
_isWindows = (process.platform === 'win32');
_isMacintosh = (process.platform === 'darwin');
_isLinux = (process.platform === 'linux');
@@ -120,6 +120,20 @@ export const translationsConfigFile = _translationsConfigFile;
const _globals = (typeof self === 'object' ? self : typeof global === 'object' ? global : {} as any);
export const globals: any = _globals;
let _setImmediate: (callback: (...args: any[]) => void) => number = null;
export function setImmediate(callback: (...args: any[]) => void): number {
if (_setImmediate === null) {
if (globals.setImmediate) {
_setImmediate = globals.setImmediate.bind(globals);
} else if (typeof process !== 'undefined' && typeof process.nextTick === 'function') {
_setImmediate = process.nextTick.bind(process);
} else {
_setImmediate = globals.setTimeout.bind(globals);
}
}
return _setImmediate(callback);
}
export const enum OperatingSystem {
Windows = 1,
Macintosh = 2,

View File

@@ -9,12 +9,16 @@ import uri from 'vs/base/common/uri';
import { equalsIgnoreCase } from 'vs/base/common/strings';
export function basenameOrAuthority(resource: uri): string {
return paths.basename(resource.fsPath) || resource.authority;
return paths.basename(resource.path) || resource.authority;
}
export function isEqualOrParent(resource: uri, candidate: uri, ignoreCase?: boolean): boolean {
if (resource.scheme === candidate.scheme && resource.authority === candidate.authority) {
return paths.isEqualOrParent(resource.fsPath, candidate.fsPath, ignoreCase);
if (resource.scheme === 'file') {
return paths.isEqualOrParent(resource.fsPath, candidate.fsPath, ignoreCase);
}
return paths.isEqualOrParent(resource.path, candidate.path, ignoreCase);
}
return false;
@@ -66,4 +70,4 @@ export function distinctParents<T>(items: T[], resourceAccessor: (item: T) => ur
}
return distinctParents;
}
}

View File

@@ -5,7 +5,7 @@
'use strict';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import Event, { Emitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
export enum ScrollbarVisibility {
Auto = 1,
@@ -186,7 +186,7 @@ export class Scrollable extends Disposable {
private _smoothScrolling: SmoothScrollingOperation;
private _onScroll = this._register(new Emitter<ScrollEvent>());
public onScroll: Event<ScrollEvent> = this._onScroll.event;
public readonly onScroll: Event<ScrollEvent> = this._onScroll.event;
constructor(smoothScrollDuration: number, scheduleAtNextAnimationFrame: (callback: () => void) => IDisposable) {
super();

View File

@@ -5,7 +5,7 @@
'use strict';
import Event, { Emitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
export interface ISplice<T> {
readonly start: number;

View File

@@ -4,8 +4,8 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import nls = require('vs/nls');
import strings = require('vs/base/common/strings');
import * as nls from 'vs/nls';
import * as strings from 'vs/base/common/strings';
enum Severity {
Ignore = 0,
@@ -46,17 +46,8 @@ namespace Severity {
if (strings.equalsIgnoreCase(_info, value)) {
return Severity.Info;
}
return Severity.Ignore;
}
export function toString(value: Severity): string {
return _displayStrings[value] || strings.empty;
}
export function compare(a: Severity, b: Severity): number {
return b - a;
}
}
export default Severity;
export default Severity;

View File

@@ -159,6 +159,10 @@ export function startsWith(haystack: string, needle: string): boolean {
return false;
}
if (haystack === needle) {
return true;
}
for (let i = 0; i < needle.length; i++) {
if (haystack[i] !== needle[i]) {
return false;
@@ -427,7 +431,7 @@ function doEqualsIgnoreCase(a: string, b: string, stopAt = a.length): boolean {
return true;
}
export function beginsWithIgnoreCase(str: string, candidate: string): boolean {
export function startsWithIgnoreCase(str: string, candidate: string): boolean {
const candidateLength = candidate.length;
if (candidate.length > str.length) {
return false;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { Promise as WinJSPromise } from './winjs.base';
import * as platform from 'vs/base/common/platform';
/**
* A polyfill for the native promises. The implementation is based on
@@ -53,13 +54,13 @@ export class PolyfillPromise<T = any> implements Promise<T> {
if (!initializing) {
resolve(value);
} else {
setImmediate(resolve, value);
platform.setImmediate(() => resolve(value));
}
}, function (err) {
if (!initializing) {
reject(err);
} else {
setImmediate(reject, err);
platform.setImmediate(() => reject(err));
}
});
initializing = false;
@@ -74,14 +75,14 @@ export class PolyfillPromise<T = any> implements Promise<T> {
if (!sync) {
onFulfilled(value);
} else {
setImmediate(onFulfilled, value);
platform.setImmediate(() => onFulfilled(value));
}
},
onRejected && function (err) {
if (!sync) {
onFulfilled(err);
onRejected(err);
} else {
setImmediate(onFulfilled, err);
platform.setImmediate(() => onRejected(err));
}
}
));

View File

@@ -116,7 +116,7 @@ class SimpleWorkerProtocol {
} catch (e) {
// nothing
}
if (!message.vsWorker) {
if (!message || !message.vsWorker) {
return;
}
if (this._workerId !== -1 && message.vsWorker !== this._workerId) {
@@ -224,10 +224,9 @@ export class SimpleWorkerClient<T> extends Disposable {
// Gather loader configuration
let loaderConfiguration: any = null;
let globalRequire = (<any>self).require;
if (typeof globalRequire.getConfig === 'function') {
if (typeof (<any>self).require !== 'undefined' && typeof (<any>self).require.getConfig === 'function') {
// Get the configuration from the Monaco AMD Loader
loaderConfiguration = globalRequire.getConfig();
loaderConfiguration = (<any>self).require.getConfig();
} else if (typeof (<any>self).requirejs !== 'undefined') {
// Get the configuration from requirejs
loaderConfiguration = (<any>self).requirejs.s.contexts._.config;
@@ -298,10 +297,11 @@ export interface IRequestHandler {
*/
export class SimpleWorkerServer {
private _protocol: SimpleWorkerProtocol;
private _requestHandler: IRequestHandler;
private _protocol: SimpleWorkerProtocol;
constructor(postSerializedMessage: (msg: string) => void) {
constructor(postSerializedMessage: (msg: string) => void, requestHandler: IRequestHandler) {
this._requestHandler = requestHandler;
this._protocol = new SimpleWorkerProtocol({
sendMessage: (msg: string): void => {
postSerializedMessage(msg);
@@ -333,6 +333,17 @@ export class SimpleWorkerServer {
private initialize(workerId: number, moduleId: string, loaderConfig: any): TPromise<any> {
this._protocol.setWorkerId(workerId);
if (this._requestHandler) {
// static request handler
let methods: string[] = [];
for (let prop in this._requestHandler) {
if (typeof this._requestHandler[prop] === 'function') {
methods.push(prop);
}
}
return TPromise.as(methods);
}
if (loaderConfig) {
// Remove 'baseUrl', handling it is beyond scope for now
if (typeof loaderConfig.baseUrl !== 'undefined') {
@@ -379,5 +390,5 @@ export class SimpleWorkerServer {
* Called on the worker side
*/
export function create(postMessage: (msg: string) => void): SimpleWorkerServer {
return new SimpleWorkerServer(postMessage);
return new SimpleWorkerServer(postMessage, null);
}

View File

@@ -9,9 +9,10 @@ import * as fs from 'fs';
import { dirname, basename } from 'path';
import * as objects from 'vs/base/common/objects';
import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
import Event, { Emitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
import * as json from 'vs/base/common/json';
import * as extfs from 'vs/base/node/extfs';
import { isWindows } from 'vs/base/common/platform';
export interface IConfigurationChangeEvent<T> {
config: T;
@@ -49,7 +50,7 @@ export class ConfigWatcher<T> implements IConfigWatcher<T>, IDisposable {
private loaded: boolean;
private timeoutHandle: NodeJS.Timer;
private disposables: IDisposable[];
private _onDidUpdateConfiguration: Emitter<IConfigurationChangeEvent<T>>;
private readonly _onDidUpdateConfiguration: Emitter<IConfigurationChangeEvent<T>>;
private configName: string;
constructor(private _path: string, private options: IConfigOptions<T> = { changeBufferDelay: 0, defaultConfig: Object.create(null), onError: error => console.error(error) }) {
@@ -165,8 +166,18 @@ export class ConfigWatcher<T> implements IConfigWatcher<T>, IDisposable {
}
private onConfigFileChange(eventType: string, filename: string, isParentFolder: boolean): void {
if (isParentFolder && filename !== this.configName) {
return; // a change to a sibling file that is not our config file
if (isParentFolder) {
// Windows: in some cases the filename contains artifacts from the absolute path
// see https://github.com/nodejs/node/issues/19170
// As such, we have to ensure that the filename basename is used for comparison.
if (isWindows && filename !== this.configName) {
filename = basename(filename);
}
if (filename !== this.configName) {
return; // a change to a sibling file that is not our config file
}
}
if (this.timeoutHandle) {

View File

@@ -5,7 +5,7 @@
'use strict';
import sd = require('string_decoder');
import * as sd from 'string_decoder';
import { CharCode } from 'vs/base/common/charCode';
/**

View File

@@ -5,17 +5,106 @@
'use strict';
import stream = require('vs/base/node/stream');
import iconv = require('iconv-lite');
import * as stream from 'vs/base/node/stream';
import * as iconv from 'iconv-lite';
import { TPromise } from 'vs/base/common/winjs.base';
import { isLinux, isMacintosh } from 'vs/base/common/platform';
import { exec } from 'child_process';
import { Readable, Writable, WritableOptions } from 'stream';
export const UTF8 = 'utf8';
export const UTF8_with_bom = 'utf8bom';
export const UTF16be = 'utf16be';
export const UTF16le = 'utf16le';
export interface IDecodeStreamOptions {
guessEncoding?: boolean;
minBytesRequiredForDetection?: number;
overwriteEncoding?(detectedEncoding: string): string;
}
export function toDecodeStream(readable: Readable, options: IDecodeStreamOptions): TPromise<{ detected: IDetectedEncodingResult, stream: NodeJS.ReadableStream }> {
if (!options.minBytesRequiredForDetection) {
options.minBytesRequiredForDetection = options.guessEncoding ? AUTO_GUESS_BUFFER_MAX_LEN : NO_GUESS_BUFFER_MAX_LEN;
}
if (!options.overwriteEncoding) {
options.overwriteEncoding = detected => detected || UTF8;
}
return new TPromise<{ detected: IDetectedEncodingResult, stream: NodeJS.ReadableStream }>((resolve, reject) => {
readable.pipe(new class extends Writable {
private _decodeStream: NodeJS.ReadWriteStream;
private _decodeStreamConstruction: Thenable<any>;
private _buffer: Buffer[] = [];
private _bytesBuffered = 0;
constructor(opts?: WritableOptions) {
super(opts);
this.once('finish', () => this._finish());
}
_write(chunk: any, encoding: string, callback: Function): void {
if (!Buffer.isBuffer(chunk)) {
callback(new Error('data must be a buffer'));
}
if (this._decodeStream) {
// just a forwarder now
this._decodeStream.write(chunk, callback);
return;
}
this._buffer.push(chunk);
this._bytesBuffered += chunk.length;
if (this._decodeStreamConstruction) {
// waiting for the decoder to be ready
this._decodeStreamConstruction.then(_ => callback(), err => callback(err));
} else if (this._bytesBuffered >= options.minBytesRequiredForDetection) {
// buffered enough data, create stream and forward data
this._startDecodeStream(callback);
} else {
// only buffering
callback();
}
}
_startDecodeStream(callback: Function): void {
this._decodeStreamConstruction = TPromise.as(detectEncodingFromBuffer({
buffer: Buffer.concat(this._buffer), bytesRead: this._bytesBuffered
}, options.guessEncoding)).then(detected => {
detected.encoding = options.overwriteEncoding(detected.encoding);
this._decodeStream = decodeStream(detected.encoding);
for (const buffer of this._buffer) {
this._decodeStream.write(buffer);
}
callback();
resolve({ detected, stream: this._decodeStream });
}, err => {
callback(err);
});
}
_finish(): void {
if (this._decodeStream) {
// normal finish
this._decodeStream.end();
} else {
// we were still waiting for data...
this._startDecodeStream(() => this._decodeStream.end());
}
}
});
});
}
export function bomLength(encoding: string): number {
switch (encoding) {
case UTF8:
@@ -172,6 +261,89 @@ export function toCanonicalName(enc: string): string {
}
}
const ZERO_BYTE_DETECTION_BUFFER_MAX_LEN = 512; // number of bytes to look at to decide about a file being binary or not
const NO_GUESS_BUFFER_MAX_LEN = 512; // when not auto guessing the encoding, small number of bytes are enough
const AUTO_GUESS_BUFFER_MAX_LEN = 512 * 8; // with auto guessing we want a lot more content to be read for guessing
export interface IDetectedEncodingResult {
encoding: string;
seemsBinary: boolean;
}
export interface DetectEncodingOption {
autoGuessEncoding?: boolean;
}
export function detectEncodingFromBuffer(readResult: stream.ReadResult, autoGuessEncoding?: false): IDetectedEncodingResult;
export function detectEncodingFromBuffer(readResult: stream.ReadResult, autoGuessEncoding?: boolean): TPromise<IDetectedEncodingResult>;
export function detectEncodingFromBuffer({ buffer, bytesRead }: stream.ReadResult, autoGuessEncoding?: boolean): TPromise<IDetectedEncodingResult> | IDetectedEncodingResult {
// Always first check for BOM to find out about encoding
let encoding = detectEncodingByBOMFromBuffer(buffer, bytesRead);
// Detect 0 bytes to see if file is binary or UTF-16 LE/BE
// unless we already know that this file has a UTF-16 encoding
let seemsBinary = false;
if (encoding !== UTF16be && encoding !== UTF16le) {
let couldBeUTF16LE = true; // e.g. 0xAA 0x00
let couldBeUTF16BE = true; // e.g. 0x00 0xAA
let containsZeroByte = false;
// This is a simplified guess to detect UTF-16 BE or LE by just checking if
// the first 512 bytes have the 0-byte at a specific location. For UTF-16 LE
// this would be the odd byte index and for UTF-16 BE the even one.
// Note: this can produce false positives (a binary file that uses a 2-byte
// encoding of the same format as UTF-16) and false negatives (a UTF-16 file
// that is using 4 bytes to encode a character).
for (let i = 0; i < bytesRead && i < ZERO_BYTE_DETECTION_BUFFER_MAX_LEN; i++) {
const isEndian = (i % 2 === 1); // assume 2-byte sequences typical for UTF-16
const isZeroByte = (buffer.readInt8(i) === 0);
if (isZeroByte) {
containsZeroByte = true;
}
// UTF-16 LE: expect e.g. 0xAA 0x00
if (couldBeUTF16LE && (isEndian && !isZeroByte || !isEndian && isZeroByte)) {
couldBeUTF16LE = false;
}
// UTF-16 BE: expect e.g. 0x00 0xAA
if (couldBeUTF16BE && (isEndian && isZeroByte || !isEndian && !isZeroByte)) {
couldBeUTF16BE = false;
}
// Return if this is neither UTF16-LE nor UTF16-BE and thus treat as binary
if (isZeroByte && !couldBeUTF16LE && !couldBeUTF16BE) {
break;
}
}
// Handle case of 0-byte included
if (containsZeroByte) {
if (couldBeUTF16LE) {
encoding = UTF16le;
} else if (couldBeUTF16BE) {
encoding = UTF16be;
} else {
seemsBinary = true;
}
}
}
// Auto guess encoding if configured
if (autoGuessEncoding && !seemsBinary && !encoding) {
return guessEncodingByBuffer(buffer.slice(0, bytesRead)).then(encoding => {
return {
seemsBinary: false,
encoding
};
});
}
return { seemsBinary, encoding };
}
// https://ss64.com/nt/chcp.html
const windowsTerminalEncodings = {
'437': 'cp437', // United States

View File

@@ -5,7 +5,7 @@
'use strict';
import assert = require('assert');
import * as assert from 'assert';
/**
* Executes the given function (fn) over the given array of items (list) in parallel and returns the resulting errors and results as

View File

@@ -1,106 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import mime = require('vs/base/common/mime');
import { TPromise } from 'vs/base/common/winjs.base';
import stream = require('vs/base/node/stream');
import encoding = require('vs/base/node/encoding');
/**
* Lots of binary file types exists where the type can be determined by matching the first few bytes against some "magic patterns".
* E.g. PDF files always start with %PDF- and the rest of the file contains mostly text, but sometimes binary data (for fonts and images).
* In order to detect these types correctly (and independently from the file's extension), the content base mime type detection must be performed
* on any file, not only on text files.
*
* Here is the original mime type detection in pseudocode:
*
* let mimes = [];
*
* read file extension
*
* if (file extension matches) {
* if (file extension is bogus) {
* // ignore.
* // this covers *.manifest files which can contain arbitrary content, so the extension is of no value.
* // a consequence of this is that the content based mime type becomes the most specific type in the array
* } else {
* mimes.push(associated mime type) // first element: most specific
* }
* }
*
* read file contents
*
* if (content based match found) { // this is independent from text or binary
* mimes.push(associated mime type)
* if (a second mime exists for the match) { // should be rare; text/plain should never be included here
* // e.g. for svg: ['image/svg+xml', 'application/xml']
* mimes.push(second mime)
* }
* }
*
* if (content == text)
* mimes.push('text/plain') // last element: least specific
* else
* mimes.push('application/octet-stream') // last element: least specific
*/
const ZERO_BYTE_DETECTION_BUFFER_MAX_LEN = 512; // number of bytes to look at to decide about a file being binary or not
const NO_GUESS_BUFFER_MAX_LEN = 512; // when not auto guessing the encoding, small number of bytes are enough
const AUTO_GUESS_BUFFER_MAX_LEN = 512 * 8; // with auto guessing we want a lot more content to be read for guessing
export function maxBufferLen(arg1?: DetectMimesOption | boolean): number {
let autoGuessEncoding: boolean;
if (typeof arg1 === 'boolean') {
autoGuessEncoding = arg1;
} else {
autoGuessEncoding = arg1 && arg1.autoGuessEncoding;
}
return autoGuessEncoding ? AUTO_GUESS_BUFFER_MAX_LEN : NO_GUESS_BUFFER_MAX_LEN;
}
export interface IMimeAndEncoding {
encoding: string;
mimes: string[];
}
export interface DetectMimesOption {
autoGuessEncoding?: boolean;
}
export function detectMimeAndEncodingFromBuffer(readResult: stream.ReadResult, autoGuessEncoding?: false): IMimeAndEncoding;
export function detectMimeAndEncodingFromBuffer(readResult: stream.ReadResult, autoGuessEncoding?: boolean): TPromise<IMimeAndEncoding>;
export function detectMimeAndEncodingFromBuffer({ buffer, bytesRead }: stream.ReadResult, autoGuessEncoding?: boolean): TPromise<IMimeAndEncoding> | IMimeAndEncoding {
let enc = encoding.detectEncodingByBOMFromBuffer(buffer, bytesRead);
// Detect 0 bytes to see if file is binary (ignore for UTF 16 though)
let isText = true;
if (enc !== encoding.UTF16be && enc !== encoding.UTF16le) {
for (let i = 0; i < bytesRead && i < ZERO_BYTE_DETECTION_BUFFER_MAX_LEN; i++) {
if (buffer.readInt8(i) === 0) {
isText = false;
break;
}
}
}
if (autoGuessEncoding && isText && !enc) {
return encoding.guessEncodingByBuffer(buffer.slice(0, bytesRead)).then(enc => {
return {
mimes: isText ? [mime.MIME_TEXT] : [mime.MIME_BINARY],
encoding: enc
};
});
}
return {
mimes: isText ? [mime.MIME_TEXT] : [mime.MIME_BINARY],
encoding: enc
};
}

View File

@@ -82,12 +82,6 @@ export function readlink(path: string): TPromise<string> {
return nfcall<string>(fs.readlink, path);
}
export function touch(path: string): TPromise<void> {
const now = Date.now() / 1000; // the value should be a Unix timestamp in seconds
return nfcall(fs.utimes, path, now, now);
}
export function truncate(path: string, len: number): TPromise<void> {
return nfcall(fs.truncate, path, len);
}
@@ -196,3 +190,7 @@ export function whenDeleted(path: string): TPromise<void> {
}, 1000);
});
}
export function copy(source: string, target: string): TPromise<void> {
return nfcall(extfs.copy, source, target);
}

View File

@@ -5,7 +5,7 @@
'use strict';
import net = require('net');
import * as net from 'net';
/**
* @returns Returns a random port between 1025 and 65535.

View File

@@ -4,10 +4,10 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import path = require('path');
import * as path from 'path';
import * as cp from 'child_process';
import { fork } from 'vs/base/node/stdFork';
import nls = require('vs/nls');
import * as nls from 'vs/nls';
import { PPromise, TPromise, TValueCallback, TProgressCallback, ErrorCallback } from 'vs/base/common/winjs.base';
import * as Types from 'vs/base/common/types';
import { IStringDictionary } from 'vs/base/common/collections';
@@ -153,7 +153,7 @@ export abstract class AbstractProcess<TProgressData> {
public start(): PPromise<SuccessData, TProgressData> {
if (Platform.isWindows && ((this.options && this.options.cwd && TPath.isUNC(this.options.cwd)) || !this.options && !this.options.cwd && TPath.isUNC(process.cwd()))) {
return TPromise.wrapError(new Error(nls.localize('TaskRunner.UNC', 'Can\'t execute a shell command on an UNC drive.')));
return TPromise.wrapError(new Error(nls.localize('TaskRunner.UNC', 'Can\'t execute a shell command on a UNC drive.')));
}
return this.useExec().then((useExec) => {
let cc: TValueCallback<SuccessData>;
@@ -381,7 +381,7 @@ export interface IQueuedSender {
// queue is free again to consume messages.
// On Windows we always wait for the send() method to return before sending the next message
// to workaround https://github.com/nodejs/node/issues/7657 (IPC can freeze process)
export function createQueuedSender(childProcess: cp.ChildProcess | NodeJS.Process): IQueuedSender {
export function createQueuedSender(childProcess: cp.ChildProcess): IQueuedSender {
let msgQueue: string[] = [];
let useQueue = false;

View File

@@ -1,183 +0,0 @@
################################################################################################
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the Source EULA. See License.txt in the project root for license information.
################################################################################################
Param(
[string]$ProcessName = "code.exe",
[int]$MaxSamples = 10
)
$processLength = "process(".Length
function Get-MachineInfo {
$model = (Get-WmiObject -Class Win32_Processor).Name
$memory = (Get-WmiObject -Class Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum / 1MB
$wmi_cs = Get-WmiObject -Class Win32_ComputerSystem
return @{
"type" = "machineInfo"
"model" = $model
"processors" = $wmi_cs.NumberOfProcessors
"logicalProcessors" = $wmi_cs.NumberOfLogicalProcessors
"totalMemory" = $memory
}
}
$machineInfo = Get-MachineInfo
function Get-MachineState {
$proc = Get-WmiObject Win32_Processor
$os = Get-WmiObject win32_OperatingSystem
return @{
"type" = 'machineState'
"cpuLoad" = $proc.LoadPercentage
"handles" = (Get-Process | Measure-Object Handles -Sum).Sum
"memory" = @{
"total" = $os.TotalVisibleMemorySize
"free" = $os.FreePhysicalMemory
"swapTotal" = $os.TotalVirtualMemorySize
"swapFree" = $os.FreeVirtualMemory
}
}
}
$machineState = Get-MachineState
$processId2CpuLoad = @{}
function Get-PerformanceCounters ($logicalProcessors) {
$counterError
# In a first round we get the performance counters and the process ids.
$counters = (Get-Counter ("\Process(*)\% Processor Time", "\Process(*)\ID Process") -ErrorAction SilentlyContinue).CounterSamples
$processKey2Id = @{}
foreach ($counter in $counters) {
if ($counter.Status -ne 0) {
continue
}
$path = $counter.path;
$segments = $path.Split("\");
$kind = $segments[4];
$processKey = $segments[3].Substring($processLength, $segments[3].Length - $processLength - 1)
if ($kind -eq "id process") {
$processKey2Id[$processKey] = [uint32]$counter.CookedValue
}
}
foreach ($counter in $counters) {
if ($counter.Status -ne 0) {
continue
}
$path = $counter.path;
$segments = $path.Split("\");
$kind = $segments[4];
$processKey = $segments[3].Substring($processLength, $segments[3].Length - $processLength - 1)
if ($kind -eq "% processor time") {
$array = New-Object double[] ($MaxSamples + 1)
$array[0] = ($counter.CookedValue / $logicalProcessors)
$processId = $processKey2Id[$processKey]
if ($processId) {
$processId2CpuLoad[$processId] = $array
}
}
}
# Now lets sample another 10 times but only the processor time
$samples = Get-Counter "\Process(*)\% Processor Time" -SampleInterval 1 -MaxSamples $MaxSamples -ErrorAction SilentlyContinue
for ($s = 0; $s -lt $samples.Count; $s++) {
$counters = $samples[$s].CounterSamples;
foreach ($counter in $counters) {
if ($counter.Status -ne 0) {
continue
}
$path = $counter.path;
$segments = $path.Split("\");
$processKey = $segments[3].Substring($processLength, $segments[3].Length - $processLength - 1)
$processKey = $processKey2Id[$processKey];
if ($processKey) {
$processId2CpuLoad[$processKey][$s + 1] = ($counter.CookedValue / $logicalProcessors)
}
}
}
}
Get-PerformanceCounters -logicalProcessors $machineInfo.logicalProcessors
$topElements = New-Object PSObject[] $processId2CpuLoad.Keys.Count;
$index = 0;
foreach ($key in $processId2CpuLoad.Keys) {
$obj = [PSCustomObject]@{
ProcessId = $key
Load = ($processId2CpuLoad[$key] | Measure-Object -Sum).Sum / ($MaxSamples + 1)
}
$topElements[$index] = $obj
$index++
}
$topElements = $topElements | Sort-Object Load -Descending
# Get all code processes
$codeProcesses = @{}
foreach ($item in Get-WmiObject Win32_Process -Filter "name = '$ProcessName'") {
$codeProcesses[$item.ProcessId] = $item
}
foreach ($item in Get-WmiObject Win32_Process -Filter "name = 'codeHelper.exe'") {
$codeProcesses[$item.ProcessId] = $item
}
$otherProcesses = @{}
foreach ($item in Get-WmiObject Win32_Process -Filter "name Like '%'") {
if (!($codeProcesses.Contains($item.ProcessId))) {
$otherProcesses[$item.ProcessId] = $item
}
}
$modified = $false
do {
$toDelete = @()
$modified = $false
foreach ($item in $otherProcesses.Values) {
if ($codeProcesses.Contains([uint32]$item.ParentProcessId)) {
$codeProcesses[$item.ProcessId] = $item;
$toDelete += $item
}
}
foreach ($item in $toDelete) {
$otherProcesses.Remove([uint32]$item.ProcessId)
$modified = $true
}
} while ($modified)
$result = New-Object PSObject[] (2 + [math]::Min(5, $topElements.Count) + $codeProcesses.Count)
$result[0] = $machineInfo
$result[1] = $machineState
$index = 2;
for($i = 0; $i -lt 5 -and $i -lt $topElements.Count; $i++) {
$element = $topElements[$i]
$item = $codeProcesses[[uint32]$element.ProcessId]
if (!$item) {
$item = $otherProcesses[[uint32]$element.ProcessId]
}
if ($item) {
$cpuLoad = $processId2CpuLoad[[uint32]$item.ProcessId] | % { [pscustomobject] $_ }
$result[$index] = [pscustomobject]@{
"type" = "topProcess"
"name" = $item.Name
"processId" = $item.ProcessId
"parentProcessId" = $item.ParentProcessId
"commandLine" = $item.CommandLine
"handles" = $item.HandleCount
"cpuLoad" = $cpuLoad
"workingSetSize" = $item.WorkingSetSize
}
$index++
}
}
foreach ($item in $codeProcesses.Values) {
# we need to convert this otherwise to JSON with create a value, count object and not an inline array
$cpuLoad = $processId2CpuLoad[[uint32]$item.ProcessId] | % { [pscustomobject] $_ }
$result[$index] = [pscustomobject]@{
"type" = "processInfo"
"name" = $item.Name
"processId" = $item.ProcessId
"parentProcessId" = $item.ParentProcessId
"commandLine" = $item.CommandLine
"handles" = $item.HandleCount
"cpuLoad" = $cpuLoad
"workingSetSize" = $item.WorkingSetSize
}
$index++
}
$result | ConvertTo-Json -Depth 99

View File

@@ -5,10 +5,7 @@
'use strict';
import { spawn, exec } from 'child_process';
import * as path from 'path';
import * as nls from 'vs/nls';
import URI from 'vs/base/common/uri';
import { exec } from 'child_process';
export interface ProcessItem {
name: string;
@@ -121,32 +118,6 @@ export function listProcesses(rootPid: number): Promise<ProcessItem> {
if (process.platform === 'win32') {
console.log(nls.localize('collecting', 'Collecting CPU and memory information. This might take a couple of seconds.'));
interface ProcessInfo {
type: 'processInfo';
name: string;
processId: number;
parentProcessId: number;
commandLine: string;
handles: number;
cpuLoad: number[];
workingSetSize: number;
}
interface TopProcess {
type: 'topProcess';
name: string;
processId: number;
parentProcessId: number;
commandLine: string;
handles: number;
cpuLoad: number[];
workingSetSize: number;
}
type Item = ProcessInfo | TopProcess;
const cleanUNCPrefix = (value: string): string => {
if (value.indexOf('\\\\?\\') === 0) {
return value.substr(4);
@@ -161,75 +132,45 @@ export function listProcesses(rootPid: number): Promise<ProcessItem> {
}
};
const execMain = path.basename(process.execPath);
const script = URI.parse(require.toUrl('vs/base/node/ps-win.ps1')).fsPath;
const commandLine = `& {& '${script}' -ProcessName '${execMain}' -MaxSamples 3}`;
const cmd = spawn('powershell.exe', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', commandLine]);
let stdout = '';
let stderr = '';
cmd.stdout.on('data', data => {
stdout += data.toString();
});
cmd.stderr.on('data', data => {
stderr += data.toString();
});
cmd.on('exit', () => {
if (stderr.length > 0) {
reject(new Error(stderr));
return;
}
let processItems: Map<number, ProcessItem> = new Map();
try {
const items: Item[] = JSON.parse(stdout);
for (const item of items) {
if (item.type === 'processInfo') {
let load = 0;
if (item.cpuLoad) {
for (let value of item.cpuLoad) {
load += value;
}
load = load / item.cpuLoad.length;
} else {
load = -1;
}
let commandLine = cleanUNCPrefix(item.commandLine);
processItems.set(item.processId, {
(import('windows-process-tree')).then(windowsProcessTree => {
windowsProcessTree.getProcessList(rootPid, (processList) => {
windowsProcessTree.getProcessCpuUsage(processList, (completeProcessList) => {
const processItems: Map<number, ProcessItem> = new Map();
completeProcessList.forEach(process => {
const commandLine = cleanUNCPrefix(process.commandLine);
processItems.set(process.pid, {
name: findName(commandLine),
cmd: commandLine,
pid: item.processId,
ppid: item.parentProcessId,
load: load,
mem: item.workingSetSize
pid: process.pid,
ppid: process.ppid,
load: process.cpu,
mem: process.memory
});
}
}
rootItem = processItems.get(rootPid);
if (rootItem) {
processItems.forEach(item => {
let parent = processItems.get(item.ppid);
if (parent) {
if (!parent.children) {
parent.children = [];
});
rootItem = processItems.get(rootPid);
if (rootItem) {
processItems.forEach(item => {
let parent = processItems.get(item.ppid);
if (parent) {
if (!parent.children) {
parent.children = [];
}
parent.children.push(item);
}
parent.children.push(item);
}
});
processItems.forEach(item => {
if (item.children) {
item.children = item.children.sort((a, b) => a.pid - b.pid);
}
});
resolve(rootItem);
} else {
reject(new Error(`Root process ${rootPid} not found`));
}
} catch (error) {
console.log(stdout);
reject(error);
}
});
processItems.forEach(item => {
if (item.children) {
item.children = item.children.sort((a, b) => a.pid - b.pid);
}
});
resolve(rootItem);
} else {
reject(new Error(`Root process ${rootPid} not found`));
}
});
}, windowsProcessTree.ProcessDataFlag.CommandLine | windowsProcessTree.ProcessDataFlag.Memory);
});
} else { // OS X & Linux

View File

@@ -7,8 +7,8 @@
import { TPromise } from 'vs/base/common/winjs.base';
import { isBoolean, isNumber } from 'vs/base/common/types';
import https = require('https');
import http = require('http');
import * as https from 'https';
import * as http from 'http';
import { Stream } from 'stream';
import { parse as parseUrl } from 'url';
import { createWriteStream } from 'fs';
@@ -96,7 +96,7 @@ export function request(options: IRequestOptions): TPromise<IRequestContext> {
stream = stream.pipe(createGunzip());
}
c({ res, stream });
c({ res, stream } as IRequestContext);
}
});

View File

@@ -5,10 +5,10 @@
'use strict';
import path = require('path');
import os = require('os');
import net = require('net');
import cp = require('child_process');
import * as path from 'path';
import * as os from 'os';
import * as net from 'net';
import * as cp from 'child_process';
import uri from 'vs/base/common/uri';
export interface IForkOpts {

View File

@@ -5,7 +5,7 @@
'use strict';
import fs = require('fs');
import * as fs from 'fs';
import { TPromise } from 'vs/base/common/winjs.base';

View File

@@ -3,14 +3,15 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import nls = require('vs/nls');
import * as nls from 'vs/nls';
import * as path from 'path';
import { createWriteStream } from 'fs';
import { createWriteStream, WriteStream } from 'fs';
import { Readable } from 'stream';
import { nfcall, ninvoke, SimpleThrottler } from 'vs/base/common/async';
import { mkdirp, rimraf } from 'vs/base/node/pfs';
import { TPromise } from 'vs/base/common/winjs.base';
import { open as _openZip, Entry, ZipFile } from 'yauzl';
import { ILogService } from 'vs/platform/log/common/log';
export interface IExtractOptions {
overwrite?: boolean;
@@ -26,10 +27,7 @@ interface IOptions {
sourcePathRegex: RegExp;
}
export enum ExtractErrorType {
Undefined,
CorruptZip
}
export type ExtractErrorType = 'CorruptZip' | 'Incomplete';
export class ExtractError extends Error {
@@ -40,7 +38,7 @@ export class ExtractError extends Error {
let message = cause.message;
switch (type) {
case ExtractErrorType.CorruptZip: message = `Corrupt ZIP: ${message}`; break;
case 'CorruptZip': message = `Corrupt ZIP: ${message}`; break;
}
super(message);
@@ -58,12 +56,14 @@ function modeFromEntry(entry: Entry) {
}
function toExtractError(err: Error): ExtractError {
let type = ExtractErrorType.CorruptZip;
if (err instanceof ExtractError) {
return err;
}
console.log('WHAT');
let type: ExtractErrorType = void 0;
if (/end of central directory record signature not found/.test(err.message)) {
type = ExtractErrorType.CorruptZip;
type = 'CorruptZip';
}
return new ExtractError(type, err);
@@ -74,24 +74,51 @@ function extractEntry(stream: Readable, fileName: string, mode: number, targetPa
const targetDirName = path.join(targetPath, dirName);
const targetFileName = path.join(targetPath, fileName);
let istream: WriteStream;
return mkdirp(targetDirName).then(() => new TPromise((c, e) => {
let istream = createWriteStream(targetFileName, { mode });
istream.once('finish', () => c(null));
istream = createWriteStream(targetFileName, { mode });
istream.once('close', () => c(null));
istream.once('error', e);
stream.once('error', e);
stream.pipe(istream);
}, () => {
if (istream) {
istream.close();
}
}));
}
function extractZip(zipfile: ZipFile, targetPath: string, options: IOptions): TPromise<void> {
function extractZip(zipfile: ZipFile, targetPath: string, options: IOptions, logService: ILogService): TPromise<void> {
let isCanceled = false;
let last = TPromise.wrap<any>(null);
let extractedEntriesCount = 0;
return new TPromise((c, e) => {
const throttler = new SimpleThrottler();
let last = TPromise.as<any>(null);
const readNextEntry = () => {
extractedEntriesCount++;
zipfile.readEntry();
};
zipfile.once('error', e);
zipfile.once('close', () => last.then(c, e));
zipfile.once('close', () => last.then(() => {
if (isCanceled || zipfile.entryCount === extractedEntriesCount) {
c(null);
} else {
e(new ExtractError('Incomplete', new Error(nls.localize('incompleteExtract', "Incomplete. Found {0} of {1} entries", extractedEntriesCount, zipfile.entryCount))));
}
}, e));
zipfile.readEntry();
zipfile.on('entry', (entry: Entry) => {
logService.debug(targetPath, 'Found', entry.fileName);
if (isCanceled) {
return;
}
if (!options.sourcePathRegex.test(entry.fileName)) {
readNextEntry();
return;
}
@@ -100,33 +127,38 @@ function extractZip(zipfile: ZipFile, targetPath: string, options: IOptions): TP
// directory file names end with '/'
if (/\/$/.test(fileName)) {
const targetFileName = path.join(targetPath, fileName);
last = mkdirp(targetFileName);
last = mkdirp(targetFileName).then(() => readNextEntry());
return;
}
const stream = ninvoke(zipfile, zipfile.openReadStream, entry);
const mode = modeFromEntry(entry);
last = throttler.queue(() => stream.then(stream => extractEntry(stream, fileName, mode, targetPath, options)));
last = throttler.queue(() => stream.then(stream => extractEntry(stream, fileName, mode, targetPath, options).then(() => readNextEntry())));
});
}, () => {
logService.debug(targetPath, 'Cancelled.');
isCanceled = true;
last.cancel();
zipfile.close();
}).then(null, err => TPromise.wrapError(toExtractError(err)));
}
function openZip(zipFile: string): TPromise<ZipFile> {
return nfcall<ZipFile>(_openZip, zipFile)
function openZip(zipFile: string, lazy: boolean = false): TPromise<ZipFile> {
return nfcall<ZipFile>(_openZip, zipFile, lazy ? { lazyEntries: true } : void 0)
.then(null, err => TPromise.wrapError(toExtractError(err)));
}
export function extract(zipPath: string, targetPath: string, options: IExtractOptions = {}): TPromise<void> {
export function extract(zipPath: string, targetPath: string, options: IExtractOptions = {}, logService: ILogService): TPromise<void> {
const sourcePathRegex = new RegExp(options.sourcePath ? `^${options.sourcePath}` : '');
let promise = openZip(zipPath);
let promise = openZip(zipPath, true);
if (options.overwrite) {
promise = promise.then(zipfile => rimraf(targetPath).then(() => zipfile));
}
return promise.then(zipfile => extractZip(zipfile, targetPath, { sourcePathRegex }));
return promise.then(zipfile => extractZip(zipfile, targetPath, { sourcePathRegex }, logService));
}
function read(zipPath: string, filePath: string): TPromise<Readable> {

View File

@@ -5,7 +5,7 @@
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc';
import Event, { Emitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
export interface Sender {
send(channel: string, ...args: any[]): void;

View File

@@ -7,7 +7,7 @@
import { Promise, TPromise } from 'vs/base/common/winjs.base';
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import Event, { Emitter, once, filterEvent } from 'vs/base/common/event';
import { Event, Emitter, once, filterEvent } from 'vs/base/common/event';
enum MessageType {
RequestCommon,
@@ -152,7 +152,7 @@ export class ChannelServer implements IChannelServer, IDisposable {
id, data: {
message: data.message,
name: data.name,
stack: data.stack ? data.stack.split('\n') : void 0
stack: data.stack ? (data.stack.split ? data.stack.split('\n') : data.stack) : void 0
}, type: MessageType.ResponseError
});
} else {

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import Event, { filterEvent, mapEvent, fromNodeEventEmitter } from 'vs/base/common/event';
import { Event, filterEvent, mapEvent, fromNodeEventEmitter } from 'vs/base/common/event';
import { IPCServer, ClientConnectionEvent } from 'vs/base/parts/ipc/common/ipc';
import { Protocol } from 'vs/base/parts/ipc/common/ipc.electron';
import { ipcMain } from 'electron';

View File

@@ -7,7 +7,7 @@
import { Socket, Server as NetServer, createConnection, createServer } from 'net';
import { TPromise } from 'vs/base/common/winjs.base';
import Event, { Emitter, once, mapEvent, fromNodeEventEmitter } from 'vs/base/common/event';
import { Event, Emitter, once, mapEvent, fromNodeEventEmitter } from 'vs/base/common/event';
import { IMessagePassingProtocol, ClientConnectionEvent, IPCServer, IPCClient } from 'vs/base/parts/ipc/common/ipc';
import { join } from 'path';
import { tmpdir } from 'os';

View File

@@ -106,9 +106,9 @@ suite('IPC performance', () => {
assert.strictEqual(hits, batches);
assert.strictEqual(count, batches * size);
}, err => assert.fail(err),
batch => {
hits++;
count += batch.length;
});
batch => {
hits++;
count += batch.length;
});
}
});

View File

@@ -6,7 +6,7 @@
import { TPromise, PPromise } from 'vs/base/common/winjs.base';
import { IChannel, eventToCall, eventFromCall } from 'vs/base/parts/ipc/common/ipc';
import Event, { Emitter } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
export interface IMarcoPoloEvent {
answer: string;

View File

@@ -5,9 +5,9 @@
'use strict';
import nls = require('vs/nls');
import * as nls from 'vs/nls';
import { TPromise } from 'vs/base/common/winjs.base';
import types = require('vs/base/common/types');
import * as types from 'vs/base/common/types';
import URI from 'vs/base/common/uri';
import { ITree, IActionProvider } from 'vs/base/parts/tree/browser/tree';
import { IconLabel, IIconLabelValueOptions } from 'vs/base/browser/ui/iconLabel/iconLabel';
@@ -16,7 +16,7 @@ import { Action, IAction, IActionRunner } from 'vs/base/common/actions';
import { compareAnything } from 'vs/base/common/comparers';
import { ActionBar, IActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
import DOM = require('vs/base/browser/dom');
import * as DOM from 'vs/base/browser/dom';
import { IQuickOpenStyles } from 'vs/base/parts/quickopen/browser/quickOpenWidget';
import { KeybindingLabel } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel';
import { OS } from 'vs/base/common/platform';

View File

@@ -5,22 +5,22 @@
'use strict';
import 'vs/css!./quickopen';
import nls = require('vs/nls');
import * as nls from 'vs/nls';
import { TPromise } from 'vs/base/common/winjs.base';
import platform = require('vs/base/common/platform');
import types = require('vs/base/common/types');
import errors = require('vs/base/common/errors');
import * as platform from 'vs/base/common/platform';
import * as types from 'vs/base/common/types';
import * as errors from 'vs/base/common/errors';
import { IQuickNavigateConfiguration, IAutoFocus, IEntryRunContext, IModel, Mode, IKeyMods } from 'vs/base/parts/quickopen/common/quickOpen';
import { Filter, Renderer, DataSource, IModelProvider, AccessibilityProvider } from 'vs/base/parts/quickopen/browser/quickOpenViewer';
import { Dimension, Builder, $ } from 'vs/base/browser/builder';
import { ISelectionEvent, IFocusEvent, ITree, ContextMenuEvent, IActionProvider, ITreeStyles, ITreeOptions, ITreeConfiguration } from 'vs/base/parts/tree/browser/tree';
import { Builder, $ } from 'vs/base/browser/builder';
import { ITree, ContextMenuEvent, IActionProvider, ITreeStyles, ITreeOptions, ITreeConfiguration } from 'vs/base/parts/tree/browser/tree';
import { InputBox, MessageType, IInputBoxStyles, IRange } from 'vs/base/browser/ui/inputbox/inputBox';
import Severity from 'vs/base/common/severity';
import { Tree } from 'vs/base/parts/tree/browser/treeImpl';
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { DefaultController, ClickBehavior } from 'vs/base/parts/tree/browser/treeDefaults';
import DOM = require('vs/base/browser/dom');
import * as DOM from 'vs/base/browser/dom';
import { KeyCode } from 'vs/base/common/keyCodes';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
@@ -113,7 +113,7 @@ export class QuickOpenWidget implements IModelProvider {
private container: HTMLElement;
private treeElement: HTMLElement;
private inputElement: HTMLElement;
private layoutDimensions: Dimension;
private layoutDimensions: DOM.Dimension;
private model: IModel<any>;
private inputChangingTimeoutHandle: number;
private styles: IQuickOpenStyles;
@@ -130,8 +130,8 @@ export class QuickOpenWidget implements IModelProvider {
this.model = null;
}
public getElement(): Builder {
return $(this.builder);
public getElement(): HTMLElement {
return $(this.builder).getHTMLElement();
}
public getModel(): IModel<any> {
@@ -143,10 +143,10 @@ export class QuickOpenWidget implements IModelProvider {
}
public create(): HTMLElement {
this.builder = $().div((div: Builder) => {
this.builder = $().div(div => {
// Eventing
div.on(DOM.EventType.KEY_DOWN, (e) => {
div.on(DOM.EventType.KEY_DOWN, e => {
const keyboardEvent: StandardKeyboardEvent = new StandardKeyboardEvent(e as KeyboardEvent);
if (keyboardEvent.keyCode === KeyCode.Escape) {
DOM.EventHelper.stop(e, true);
@@ -160,10 +160,10 @@ export class QuickOpenWidget implements IModelProvider {
// Progress Bar
this.progressBar = new ProgressBar(div.clone(), { progressBarBackground: this.styles.progressBarBackground });
this.progressBar.getContainer().hide();
this.progressBar.hide();
// Input Field
div.div({ 'class': 'quick-open-input' }, (inputContainer) => {
div.div({ 'class': 'quick-open-input' }, inputContainer => {
this.inputContainer = inputContainer;
this.inputBox = new InputBox(inputContainer.getHTMLElement(), null, {
placeholder: this.options.inputPlaceHolder || '',
@@ -226,7 +226,7 @@ export class QuickOpenWidget implements IModelProvider {
// Tree
this.treeContainer = div.div({
'class': 'quick-open-tree'
}, (div: Builder) => {
}, div => {
const createTree = this.options.treeCreator || ((container, config, opts) => new Tree(container, config, opts));
this.tree = createTree(div.getHTMLElement(), {
@@ -240,6 +240,7 @@ export class QuickOpenWidget implements IModelProvider {
indentPixels: 0,
alwaysFocused: true,
verticalScrollMode: ScrollbarVisibility.Visible,
horizontalScrollMode: ScrollbarVisibility.Hidden,
ariaLabel: nls.localize('treeAriaLabel', "Quick Picker"),
keyboardSupport: this.options.keyboardSupport,
preventRootFocus: true
@@ -248,11 +249,11 @@ export class QuickOpenWidget implements IModelProvider {
this.treeElement = this.tree.getHTMLElement();
// Handle Focus and Selection event
this.toUnbind.push(this.tree.onDidChangeFocus((event: IFocusEvent) => {
this.toUnbind.push(this.tree.onDidChangeFocus(event => {
this.elementFocused(event.focus, event);
}));
this.toUnbind.push(this.tree.onDidChangeSelection((event: ISelectionEvent) => {
this.toUnbind.push(this.tree.onDidChangeSelection(event => {
if (event.selection && event.selection.length > 0) {
const mouseEvent: StandardMouseEvent = event.payload && event.payload.originalEvent instanceof StandardMouseEvent ? event.payload.originalEvent : void 0;
const shouldOpenInBackground = mouseEvent ? this.shouldOpenInBackground(mouseEvent) : false;
@@ -261,7 +262,7 @@ export class QuickOpenWidget implements IModelProvider {
}
}));
}).
on(DOM.EventType.KEY_DOWN, (e) => {
on(DOM.EventType.KEY_DOWN, e => {
const keyboardEvent: StandardKeyboardEvent = new StandardKeyboardEvent(e as KeyboardEvent);
// Only handle when in quick navigation mode
@@ -276,7 +277,7 @@ export class QuickOpenWidget implements IModelProvider {
this.navigateInTree(keyboardEvent.keyCode);
}
}).
on(DOM.EventType.KEY_UP, (e) => {
on(DOM.EventType.KEY_UP, e => {
const keyboardEvent: StandardKeyboardEvent = new StandardKeyboardEvent(e as KeyboardEvent);
const keyCode = keyboardEvent.keyCode;
@@ -287,7 +288,7 @@ export class QuickOpenWidget implements IModelProvider {
// Select element when keys are pressed that signal it
const quickNavKeys = this.quickNavigateConfiguration.keybindings;
const wasTriggerKeyPressed = keyCode === KeyCode.Enter || quickNavKeys.some((k) => {
const wasTriggerKeyPressed = keyCode === KeyCode.Enter || quickNavKeys.some(k => {
const [firstPart, chordPart] = k.getParts();
if (chordPart) {
return false;
@@ -327,7 +328,7 @@ export class QuickOpenWidget implements IModelProvider {
})
// Widget Attributes
.addClass('quick-open-widget')
.addClass('monaco-quick-open-widget')
.build(this.container);
// Support layout
@@ -447,7 +448,7 @@ export class QuickOpenWidget implements IModelProvider {
// Transition into quick navigate mode if not yet done
if (!this.quickNavigateConfiguration && quickNavigate) {
this.quickNavigateConfiguration = quickNavigate;
this.tree.DOMFocus();
this.tree.domFocus();
}
// Navigate
@@ -558,7 +559,7 @@ export class QuickOpenWidget implements IModelProvider {
if (this.quickNavigateConfiguration) {
this.inputContainer.hide();
this.builder.show();
this.tree.DOMFocus();
this.tree.domFocus();
}
// Otherwise use normal UI
@@ -779,11 +780,11 @@ export class QuickOpenWidget implements IModelProvider {
this.treeContainer.style({ height: (this.options.minItemsToShow ? this.options.minItemsToShow * 22 : 0) + 'px' });
// Clear any running Progress
this.progressBar.stop().getContainer().hide();
this.progressBar.stop().hide();
// Clear Focus
if (this.tree.isDOMFocused()) {
this.tree.DOMBlur();
this.tree.domBlur();
} else if (this.inputBox.hasFocus()) {
this.inputBox.blur();
}
@@ -810,11 +811,13 @@ export class QuickOpenWidget implements IModelProvider {
}
}
public setValue(value: string, selection?: [number, number]): void {
public setValue(value: string, selectionOrStableHint?: [number, number] | null): void {
if (this.inputBox) {
this.inputBox.value = value;
if (Array.isArray(selection)) {
const [start, end] = selection;
if (selectionOrStableHint === null) {
// null means stable-selection
} else if (Array.isArray(selectionOrStableHint)) {
const [start, end] = selectionOrStableHint;
this.inputBox.select({ start, end });
} else {
this.inputBox.select();
@@ -918,7 +921,7 @@ export class QuickOpenWidget implements IModelProvider {
return this.visible;
}
public layout(dimension: Dimension): void {
public layout(dimension: DOM.Dimension): void {
this.layoutDimensions = dimension;
// Apply to quick open width (height is dynamic by number of items to show)

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.quick-open-widget {
.monaco-quick-open-widget {
position: absolute;
width: 600px;
z-index: 2000;
@@ -12,7 +12,7 @@
margin-left: -300px;
}
.quick-open-widget .progress-container {
.monaco-quick-open-widget .monaco-progress-container {
position: absolute;
left: 0;
top: 38px;
@@ -20,34 +20,34 @@
height: 2px;
}
.quick-open-widget .progress-container .progress-bit {
.monaco-quick-open-widget .monaco-progress-container .progress-bit {
height: 2px;
}
.quick-open-widget .quick-open-input {
.monaco-quick-open-widget .quick-open-input {
width: 588px;
border: none;
margin: 6px;
}
.quick-open-widget .quick-open-input .monaco-inputbox {
.monaco-quick-open-widget .quick-open-input .monaco-inputbox {
width: 100%;
height: 25px;
}
.quick-open-widget .quick-open-tree {
.monaco-quick-open-widget .quick-open-tree {
line-height: 22px;
}
.quick-open-widget .quick-open-tree .monaco-tree-row > .content > .sub-content {
.monaco-quick-open-widget .quick-open-tree .monaco-tree-row > .content > .sub-content {
overflow: hidden;
}
.quick-open-widget.content-changing .quick-open-tree .monaco-scrollable-element .slider {
.monaco-quick-open-widget.content-changing .quick-open-tree .monaco-scrollable-element .slider {
display: none; /* scrollbar slider causes some hectic updates when input changes quickly, so hide it while quick open changes */
}
.quick-open-widget .quick-open-tree .quick-open-entry {
.monaco-quick-open-widget .quick-open-tree .quick-open-entry {
overflow: hidden;
text-overflow: ellipsis;
display: flex;
@@ -55,12 +55,12 @@
height: 100%;
}
.quick-open-widget .quick-open-tree .quick-open-entry > .quick-open-row {
.monaco-quick-open-widget .quick-open-tree .quick-open-entry > .quick-open-row {
display: flex;
align-items: center;
}
.quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon {
.monaco-quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon {
overflow: hidden;
width: 16px;
height: 16px;
@@ -70,39 +70,39 @@
flex-shrink: 0;
}
.quick-open-widget .quick-open-tree .monaco-icon-label,
.quick-open-widget .quick-open-tree .monaco-icon-label .monaco-icon-label-description-container {
.monaco-quick-open-widget .quick-open-tree .monaco-icon-label,
.monaco-quick-open-widget .quick-open-tree .monaco-icon-label .monaco-icon-label-description-container {
flex: 1; /* make sure the icon label grows within the row */
}
.quick-open-widget .quick-open-tree .quick-open-entry .monaco-highlighted-label span {
.monaco-quick-open-widget .quick-open-tree .quick-open-entry .monaco-highlighted-label span {
opacity: 1;
}
.quick-open-widget .quick-open-tree .quick-open-entry-meta {
.monaco-quick-open-widget .quick-open-tree .quick-open-entry-meta {
opacity: 0.7;
line-height: normal;
}
.quick-open-widget .quick-open-tree .content.has-group-label .quick-open-entry-keybinding {
.monaco-quick-open-widget .quick-open-tree .content.has-group-label .quick-open-entry-keybinding {
margin-right: 8px;
}
.quick-open-widget .quick-open-tree .quick-open-entry-keybinding .monaco-keybinding-key {
.monaco-quick-open-widget .quick-open-tree .quick-open-entry-keybinding .monaco-keybinding-key {
vertical-align: text-bottom;
}
.quick-open-widget .quick-open-tree .results-group {
.monaco-quick-open-widget .quick-open-tree .results-group {
margin-right: 18px;
}
.quick-open-widget .quick-open-tree .monaco-tree-row.focused > .content.has-actions > .results-group,
.quick-open-widget .quick-open-tree .monaco-tree-row:hover:not(.highlighted) > .content.has-actions > .results-group,
.quick-open-widget .quick-open-tree .focused .monaco-tree-row.focused > .content.has-actions > .results-group {
.monaco-quick-open-widget .quick-open-tree .monaco-tree-row.focused > .content.has-actions > .results-group,
.monaco-quick-open-widget .quick-open-tree .monaco-tree-row:hover:not(.highlighted) > .content.has-actions > .results-group,
.monaco-quick-open-widget .quick-open-tree .focused .monaco-tree-row.focused > .content.has-actions > .results-group {
margin-right: 0px;
}
.quick-open-widget .quick-open-tree .results-group-separator {
.monaco-quick-open-widget .quick-open-tree .results-group-separator {
border-top-width: 1px;
border-top-style: solid;
box-sizing: border-box;
@@ -154,6 +154,6 @@
height: 16px;
}
.quick-open-widget .quick-open-tree .monaco-highlighted-label .highlight {
.monaco-quick-open-widget .quick-open-tree .monaco-highlighted-label .highlight {
font-weight: bold;
}

View File

@@ -7,9 +7,9 @@
import { compareAnything } from 'vs/base/common/comparers';
import { matchesPrefix, IMatch, createMatches, matchesCamelCase, isUpper } from 'vs/base/common/filters';
import { isEqual, nativeSep } from 'vs/base/common/paths';
import { isWindows } from 'vs/base/common/platform';
import { stripWildcards } from 'vs/base/common/strings';
import { nativeSep } from 'vs/base/common/paths';
import { isWindows, isLinux } from 'vs/base/common/platform';
import { stripWildcards, equalsIgnoreCase } from 'vs/base/common/strings';
import { CharCode } from 'vs/base/common/charCode';
export type Score = [number /* score */, number[] /* match positions */];
@@ -313,7 +313,7 @@ export function prepareQuery(original: string): IPreparedQuery {
if (original) {
value = stripWildcards(original).replace(/\s/g, ''); // get rid of all wildcards and whitespace
if (isWindows) {
value = value.replace(/\//g, '\\'); // Help Windows users to search for paths when using slash
value = value.replace(/\//g, nativeSep); // Help Windows users to search for paths when using slash
}
lowercase = value.toLowerCase();
@@ -356,7 +356,7 @@ export function scoreItem<T>(item: T, query: IPreparedQuery, fuzzy: boolean, acc
function doScoreItem(label: string, description: string, path: string, query: IPreparedQuery, fuzzy: boolean): IItemScore {
// 1.) treat identity matches on full path highest
if (path && isEqual(query.original, path, true)) {
if (path && isLinux ? query.original === path : equalsIgnoreCase(query.original, path)) {
return { score: PATH_IDENTITY_SCORE, labelMatch: [{ start: 0, end: label.length }], descriptionMatch: description ? [{ start: 0, end: description.length }] : void 0 };
}

View File

@@ -4,13 +4,13 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import WinJS = require('vs/base/common/winjs.base');
import Touch = require('vs/base/browser/touch');
import Mouse = require('vs/base/browser/mouseEvent');
import Keyboard = require('vs/base/browser/keyboardEvent');
import * as WinJS from 'vs/base/common/winjs.base';
import * as Touch from 'vs/base/browser/touch';
import * as Mouse from 'vs/base/browser/mouseEvent';
import * as Keyboard from 'vs/base/browser/keyboardEvent';
import { INavigator } from 'vs/base/common/iterator';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import Event from 'vs/base/common/event';
import { Event } from 'vs/base/common/event';
import { IAction, IActionItem } from 'vs/base/common/actions';
import { Color } from 'vs/base/common/color';
import { IItemCollapseEvent, IItemExpandEvent } from 'vs/base/parts/tree/browser/treeModel';
@@ -60,7 +60,7 @@ export interface ITree {
/**
* Sets DOM focus on the tree.
*/
DOMFocus(): void;
domFocus(): void;
/**
* Returns whether the tree has DOM focus.
@@ -70,7 +70,7 @@ export interface ITree {
/**
* Removes DOM focus from the tree.
*/
DOMBlur(): void;
domBlur(): void;
/**
* Refreshes an element.
@@ -78,6 +78,11 @@ export interface ITree {
*/
refresh(element?: any, recursive?: boolean): WinJS.Promise;
/**
* Updates an element's width.
*/
updateWidth(element: any): void;
/**
* Expands an element.
* The returned promise returns a boolean for whether the element was expanded or not.
@@ -674,6 +679,7 @@ export interface ITreeConfiguration {
filter?: IFilter;
sorter?: ISorter;
accessibilityProvider?: IAccessibilityProvider;
styler?: ITreeStyler;
}
export interface ITreeOptions extends ITreeStyles {
@@ -681,6 +687,7 @@ export interface ITreeOptions extends ITreeStyles {
showTwistie?: boolean;
indentPixels?: number;
verticalScrollMode?: ScrollbarVisibility;
horizontalScrollMode?: ScrollbarVisibility;
alwaysFocused?: boolean;
autoExpandSingleChildren?: boolean;
useShadows?: boolean;
@@ -690,6 +697,10 @@ export interface ITreeOptions extends ITreeStyles {
preventRootFocus?: boolean;
}
export interface ITreeStyler {
style(styles: ITreeStyles): void;
}
export interface ITreeStyles {
listFocusBackground?: Color;
listFocusForeground?: Color;

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