mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-22 12:50:29 -04:00
Merge VS Code 1.23.1 (#1520)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,14 +14,6 @@
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
.fl:after {
|
||||
clear: both;
|
||||
content: '';
|
||||
display: block;
|
||||
visibility: hidden;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.monaco-findInput > .controls {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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 } {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) } }
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 = {};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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}}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import Json = require('./json');
|
||||
import * as Json from './json';
|
||||
|
||||
export interface FormattingOptions {
|
||||
/**
|
||||
|
||||
@@ -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: '+',
|
||||
}
|
||||
);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
[{
|
||||
"name": "chjj-marked",
|
||||
"repositoryURL": "https://github.com/npmcomponent/chjj-marked",
|
||||
"version": "0.3.12",
|
||||
"version": "0.3.18",
|
||||
"license": "MIT"
|
||||
}]
|
||||
|
||||
2
src/vs/base/common/marked/marked.d.ts
vendored
2
src/vs/base/common/marked/marked.d.ts
vendored
@@ -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
@@ -16,7 +16,7 @@ export function parse(text: string): any {
|
||||
return data;
|
||||
}
|
||||
|
||||
interface MarshalledObject {
|
||||
export interface MarshalledObject {
|
||||
$mid: number;
|
||||
}
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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));
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import sd = require('string_decoder');
|
||||
import * as sd from 'string_decoder';
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import net = require('net');
|
||||
import * as net from 'net';
|
||||
|
||||
/**
|
||||
* @returns Returns a random port between 1025 and 65535.
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import fs = require('fs');
|
||||
import * as fs from 'fs';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -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;
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 };
|
||||
}
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user