mirror of
https://github.com/Microsoft/vscode
synced 2024-10-30 21:52:24 +00:00
debt - more builder cleanup
This commit is contained in:
parent
c4aa2b5da3
commit
dbd3e70395
17 changed files with 276 additions and 301 deletions
|
@ -5,7 +5,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import * as arrays from 'vs/base/common/arrays';
|
import * as arrays from 'vs/base/common/arrays';
|
||||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||||
import * as DomUtils from 'vs/base/browser/dom';
|
import * as DomUtils from 'vs/base/browser/dom';
|
||||||
import { memoize } from 'vs/base/common/decorators';
|
import { memoize } from 'vs/base/common/decorators';
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ interface TouchEvent extends Event {
|
||||||
changedTouches: TouchList;
|
changedTouches: TouchList;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Gesture implements IDisposable {
|
export class Gesture extends Disposable {
|
||||||
|
|
||||||
private static readonly SCROLL_FRICTION = -0.005;
|
private static readonly SCROLL_FRICTION = -0.005;
|
||||||
private static INSTANCE: Gesture;
|
private static INSTANCE: Gesture;
|
||||||
|
@ -72,19 +72,19 @@ export class Gesture implements IDisposable {
|
||||||
|
|
||||||
private dispatched: boolean;
|
private dispatched: boolean;
|
||||||
private targets: HTMLElement[];
|
private targets: HTMLElement[];
|
||||||
private toDispose: IDisposable[];
|
|
||||||
private handle: IDisposable;
|
private handle: IDisposable;
|
||||||
|
|
||||||
private activeTouches: { [id: number]: TouchData; };
|
private activeTouches: { [id: number]: TouchData; };
|
||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
this.toDispose = [];
|
super();
|
||||||
|
|
||||||
this.activeTouches = {};
|
this.activeTouches = {};
|
||||||
this.handle = null;
|
this.handle = null;
|
||||||
this.targets = [];
|
this.targets = [];
|
||||||
this.toDispose.push(DomUtils.addDisposableListener(document, 'touchstart', (e) => this.onTouchStart(e)));
|
this._register(DomUtils.addDisposableListener(document, 'touchstart', (e) => this.onTouchStart(e)));
|
||||||
this.toDispose.push(DomUtils.addDisposableListener(document, 'touchend', (e) => this.onTouchEnd(e)));
|
this._register(DomUtils.addDisposableListener(document, 'touchend', (e) => this.onTouchEnd(e)));
|
||||||
this.toDispose.push(DomUtils.addDisposableListener(document, 'touchmove', (e) => this.onTouchMove(e)));
|
this._register(DomUtils.addDisposableListener(document, 'touchmove', (e) => this.onTouchMove(e)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static addTarget(element: HTMLElement): void {
|
public static addTarget(element: HTMLElement): void {
|
||||||
|
@ -106,9 +106,10 @@ export class Gesture implements IDisposable {
|
||||||
public dispose(): void {
|
public dispose(): void {
|
||||||
if (this.handle) {
|
if (this.handle) {
|
||||||
this.handle.dispose();
|
this.handle.dispose();
|
||||||
dispose(this.toDispose);
|
|
||||||
this.handle = null;
|
this.handle = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private onTouchStart(e: TouchEvent): void {
|
private onTouchStart(e: TouchEvent): void {
|
||||||
|
|
|
@ -35,23 +35,23 @@ export interface IBaseActionItemOptions {
|
||||||
isMenu?: boolean;
|
isMenu?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BaseActionItem implements IActionItem {
|
export class BaseActionItem extends lifecycle.Disposable implements IActionItem {
|
||||||
|
|
||||||
public builder: HTMLElement;
|
public element: HTMLElement;
|
||||||
public _callOnDispose: lifecycle.IDisposable[];
|
|
||||||
public _context: any;
|
public _context: any;
|
||||||
public _action: IAction;
|
public _action: IAction;
|
||||||
|
|
||||||
private _actionRunner: IActionRunner;
|
private _actionRunner: IActionRunner;
|
||||||
|
|
||||||
constructor(context: any, action: IAction, protected options?: IBaseActionItemOptions) {
|
constructor(context: any, action: IAction, protected options?: IBaseActionItemOptions) {
|
||||||
this._callOnDispose = [];
|
super();
|
||||||
|
|
||||||
this._context = context || this;
|
this._context = context || this;
|
||||||
this._action = action;
|
this._action = action;
|
||||||
|
|
||||||
if (action instanceof Action) {
|
if (action instanceof Action) {
|
||||||
this._callOnDispose.push(action.onDidChange(event => {
|
this._register(action.onDidChange(event => {
|
||||||
if (!this.builder) {
|
if (!this.element) {
|
||||||
// we have not been rendered yet, so there
|
// we have not been rendered yet, so there
|
||||||
// is no point in updating the UI
|
// is no point in updating the UI
|
||||||
return;
|
return;
|
||||||
|
@ -80,10 +80,6 @@ export class BaseActionItem implements IActionItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public get callOnDispose() {
|
|
||||||
return this._callOnDispose;
|
|
||||||
}
|
|
||||||
|
|
||||||
public set actionRunner(actionRunner: IActionRunner) {
|
public set actionRunner(actionRunner: IActionRunner) {
|
||||||
this._actionRunner = actionRunner;
|
this._actionRunner = actionRunner;
|
||||||
}
|
}
|
||||||
|
@ -105,7 +101,7 @@ export class BaseActionItem implements IActionItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(container: HTMLElement): void {
|
public render(container: HTMLElement): void {
|
||||||
this.builder = container;
|
this.element = container;
|
||||||
Gesture.addTarget(container);
|
Gesture.addTarget(container);
|
||||||
|
|
||||||
const enableDragging = this.options && this.options.draggable;
|
const enableDragging = this.options && this.options.draggable;
|
||||||
|
@ -113,20 +109,20 @@ export class BaseActionItem implements IActionItem {
|
||||||
container.draggable = true;
|
container.draggable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._callOnDispose.push(DOM.addDisposableListener(this.builder, EventType.Tap, e => this.onClick(e)));
|
this._register(DOM.addDisposableListener(this.element, EventType.Tap, e => this.onClick(e)));
|
||||||
|
|
||||||
this._callOnDispose.push(DOM.addDisposableListener(this.builder, DOM.EventType.MOUSE_DOWN, e => {
|
this._register(DOM.addDisposableListener(this.element, DOM.EventType.MOUSE_DOWN, e => {
|
||||||
if (!enableDragging) {
|
if (!enableDragging) {
|
||||||
DOM.EventHelper.stop(e, true); // do not run when dragging is on because that would disable it
|
DOM.EventHelper.stop(e, true); // do not run when dragging is on because that would disable it
|
||||||
}
|
}
|
||||||
|
|
||||||
const mouseEvent = e as MouseEvent;
|
const mouseEvent = e as MouseEvent;
|
||||||
if (this._action.enabled && mouseEvent.button === 0) {
|
if (this._action.enabled && mouseEvent.button === 0) {
|
||||||
DOM.addClass(this.builder, 'active');
|
DOM.addClass(this.element, 'active');
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._callOnDispose.push(DOM.addDisposableListener(this.builder, DOM.EventType.CLICK, e => {
|
this._register(DOM.addDisposableListener(this.element, DOM.EventType.CLICK, e => {
|
||||||
DOM.EventHelper.stop(e, true);
|
DOM.EventHelper.stop(e, true);
|
||||||
// See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Interact_with_the_clipboard
|
// See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Interact_with_the_clipboard
|
||||||
// > Writing to the clipboard
|
// > Writing to the clipboard
|
||||||
|
@ -144,9 +140,9 @@ export class BaseActionItem implements IActionItem {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
[DOM.EventType.MOUSE_UP, DOM.EventType.MOUSE_OUT].forEach(event => {
|
[DOM.EventType.MOUSE_UP, DOM.EventType.MOUSE_OUT].forEach(event => {
|
||||||
this._callOnDispose.push(DOM.addDisposableListener(this.builder, event, e => {
|
this._register(DOM.addDisposableListener(this.element, event, e => {
|
||||||
DOM.EventHelper.stop(e);
|
DOM.EventHelper.stop(e);
|
||||||
DOM.removeClass(this.builder, 'active');
|
DOM.removeClass(this.element, 'active');
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -169,16 +165,16 @@ export class BaseActionItem implements IActionItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
public focus(): void {
|
public focus(): void {
|
||||||
if (this.builder) {
|
if (this.element) {
|
||||||
this.builder.focus();
|
this.element.focus();
|
||||||
DOM.addClass(this.builder, 'focused');
|
DOM.addClass(this.element, 'focused');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public blur(): void {
|
public blur(): void {
|
||||||
if (this.builder) {
|
if (this.element) {
|
||||||
this.builder.blur();
|
this.element.blur();
|
||||||
DOM.removeClass(this.builder, 'focused');
|
DOM.removeClass(this.element, 'focused');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,12 +199,12 @@ export class BaseActionItem implements IActionItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
public dispose(): void {
|
public dispose(): void {
|
||||||
if (this.builder) {
|
if (this.element) {
|
||||||
DOM.removeNode(this.builder);
|
DOM.removeNode(this.element);
|
||||||
this.builder = null;
|
this.element = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._callOnDispose = lifecycle.dispose(this._callOnDispose);
|
super.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,8 +229,9 @@ export interface IActionItemOptions extends IBaseActionItemOptions {
|
||||||
|
|
||||||
export class ActionItem extends BaseActionItem {
|
export class ActionItem extends BaseActionItem {
|
||||||
|
|
||||||
protected $e: HTMLElement;
|
protected label: HTMLElement;
|
||||||
protected options: IActionItemOptions;
|
protected options: IActionItemOptions;
|
||||||
|
|
||||||
private cssClass: string;
|
private cssClass: string;
|
||||||
|
|
||||||
constructor(context: any, action: IAction, options: IActionItemOptions = {}) {
|
constructor(context: any, action: IAction, options: IActionItemOptions = {}) {
|
||||||
|
@ -249,20 +246,20 @@ export class ActionItem extends BaseActionItem {
|
||||||
public render(container: HTMLElement): void {
|
public render(container: HTMLElement): void {
|
||||||
super.render(container);
|
super.render(container);
|
||||||
|
|
||||||
this.$e = DOM.append(this.builder, DOM.$('a.action-label'));
|
this.label = DOM.append(this.element, DOM.$('a.action-label'));
|
||||||
if (this._action.id === Separator.ID) {
|
if (this._action.id === Separator.ID) {
|
||||||
// A separator is a presentation item
|
// A separator is a presentation item
|
||||||
this.$e.setAttribute('role', 'presentation');
|
this.label.setAttribute('role', 'presentation');
|
||||||
} else {
|
} else {
|
||||||
if (this.options.isMenu) {
|
if (this.options.isMenu) {
|
||||||
this.$e.setAttribute('role', 'menuitem');
|
this.label.setAttribute('role', 'menuitem');
|
||||||
} else {
|
} else {
|
||||||
this.$e.setAttribute('role', 'button');
|
this.label.setAttribute('role', 'button');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.options.label && this.options.keybinding) {
|
if (this.options.label && this.options.keybinding) {
|
||||||
DOM.append(this.builder, DOM.$('span.keybinding')).textContent = this.options.keybinding;
|
DOM.append(this.element, DOM.$('span.keybinding')).textContent = this.options.keybinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._updateClass();
|
this._updateClass();
|
||||||
|
@ -274,12 +271,12 @@ export class ActionItem extends BaseActionItem {
|
||||||
|
|
||||||
public focus(): void {
|
public focus(): void {
|
||||||
super.focus();
|
super.focus();
|
||||||
this.$e.focus();
|
this.label.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
public _updateLabel(): void {
|
public _updateLabel(): void {
|
||||||
if (this.options.label) {
|
if (this.options.label) {
|
||||||
this.$e.textContent = this.getAction().label;
|
this.label.textContent = this.getAction().label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,43 +295,43 @@ export class ActionItem extends BaseActionItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (title) {
|
if (title) {
|
||||||
this.$e.title = title;
|
this.label.title = title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public _updateClass(): void {
|
public _updateClass(): void {
|
||||||
if (this.cssClass) {
|
if (this.cssClass) {
|
||||||
DOM.removeClasses(this.$e, this.cssClass);
|
DOM.removeClasses(this.label, this.cssClass);
|
||||||
}
|
}
|
||||||
if (this.options.icon) {
|
if (this.options.icon) {
|
||||||
this.cssClass = this.getAction().class;
|
this.cssClass = this.getAction().class;
|
||||||
DOM.addClass(this.$e, 'icon');
|
DOM.addClass(this.label, 'icon');
|
||||||
if (this.cssClass) {
|
if (this.cssClass) {
|
||||||
DOM.addClasses(this.$e, this.cssClass);
|
DOM.addClasses(this.label, this.cssClass);
|
||||||
}
|
}
|
||||||
this._updateEnabled();
|
this._updateEnabled();
|
||||||
} else {
|
} else {
|
||||||
DOM.removeClass(this.$e, 'icon');
|
DOM.removeClass(this.label, 'icon');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public _updateEnabled(): void {
|
public _updateEnabled(): void {
|
||||||
if (this.getAction().enabled) {
|
if (this.getAction().enabled) {
|
||||||
DOM.removeClass(this.builder, 'disabled');
|
DOM.removeClass(this.element, 'disabled');
|
||||||
DOM.removeClass(this.$e, 'disabled');
|
DOM.removeClass(this.label, 'disabled');
|
||||||
this.$e.tabIndex = 0;
|
this.label.tabIndex = 0;
|
||||||
} else {
|
} else {
|
||||||
DOM.addClass(this.builder, 'disabled');
|
DOM.addClass(this.element, 'disabled');
|
||||||
DOM.addClass(this.$e, 'disabled');
|
DOM.addClass(this.label, 'disabled');
|
||||||
DOM.removeTabIndexAndUpdateFocus(this.$e);
|
DOM.removeTabIndexAndUpdateFocus(this.label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public _updateChecked(): void {
|
public _updateChecked(): void {
|
||||||
if (this.getAction().checked) {
|
if (this.getAction().checked) {
|
||||||
DOM.addClass(this.$e, 'checked');
|
DOM.addClass(this.label, 'checked');
|
||||||
} else {
|
} else {
|
||||||
DOM.removeClass(this.$e, 'checked');
|
DOM.removeClass(this.label, 'checked');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -368,7 +365,7 @@ export interface IActionOptions extends IActionItemOptions {
|
||||||
index?: number;
|
index?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ActionBar implements IActionRunner {
|
export class ActionBar extends lifecycle.Disposable implements IActionRunner {
|
||||||
|
|
||||||
public options: IActionBarOptions;
|
public options: IActionBarOptions;
|
||||||
|
|
||||||
|
@ -384,26 +381,25 @@ export class ActionBar implements IActionRunner {
|
||||||
public domNode: HTMLElement;
|
public domNode: HTMLElement;
|
||||||
protected actionsList: HTMLElement;
|
protected actionsList: HTMLElement;
|
||||||
|
|
||||||
private toDispose: lifecycle.IDisposable[];
|
|
||||||
|
|
||||||
private _onDidBlur = new Emitter<void>();
|
private _onDidBlur = new Emitter<void>();
|
||||||
private _onDidCancel = new Emitter<void>();
|
private _onDidCancel = new Emitter<void>();
|
||||||
private _onDidRun = new Emitter<IRunEvent>();
|
private _onDidRun = new Emitter<IRunEvent>();
|
||||||
private _onDidBeforeRun = new Emitter<IRunEvent>();
|
private _onDidBeforeRun = new Emitter<IRunEvent>();
|
||||||
|
|
||||||
constructor(container: HTMLElement, options: IActionBarOptions = defaultOptions) {
|
constructor(container: HTMLElement, options: IActionBarOptions = defaultOptions) {
|
||||||
|
super();
|
||||||
|
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this._context = options.context;
|
this._context = options.context;
|
||||||
this.toDispose = [];
|
|
||||||
this._actionRunner = this.options.actionRunner;
|
this._actionRunner = this.options.actionRunner;
|
||||||
|
|
||||||
if (!this._actionRunner) {
|
if (!this._actionRunner) {
|
||||||
this._actionRunner = new ActionRunner();
|
this._actionRunner = new ActionRunner();
|
||||||
this.toDispose.push(this._actionRunner);
|
this._register(this._actionRunner);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.toDispose.push(this._actionRunner.onDidRun(e => this._onDidRun.fire(e)));
|
this._register(this._actionRunner.onDidRun(e => this._onDidRun.fire(e)));
|
||||||
this.toDispose.push(this._actionRunner.onDidBeforeRun(e => this._onDidBeforeRun.fire(e)));
|
this._register(this._actionRunner.onDidBeforeRun(e => this._onDidBeforeRun.fire(e)));
|
||||||
|
|
||||||
this.items = [];
|
this.items = [];
|
||||||
this.focusedItem = undefined;
|
this.focusedItem = undefined;
|
||||||
|
@ -440,7 +436,7 @@ export class ActionBar implements IActionRunner {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.toDispose.push(DOM.addDisposableListener(this.domNode, DOM.EventType.KEY_DOWN, e => {
|
this._register(DOM.addDisposableListener(this.domNode, DOM.EventType.KEY_DOWN, e => {
|
||||||
let event = new StandardKeyboardEvent(e as KeyboardEvent);
|
let event = new StandardKeyboardEvent(e as KeyboardEvent);
|
||||||
let eventHandled = true;
|
let eventHandled = true;
|
||||||
|
|
||||||
|
@ -462,7 +458,7 @@ export class ActionBar implements IActionRunner {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.toDispose.push(DOM.addDisposableListener(this.domNode, DOM.EventType.KEY_UP, e => {
|
this._register(DOM.addDisposableListener(this.domNode, DOM.EventType.KEY_UP, e => {
|
||||||
let event = new StandardKeyboardEvent(e as KeyboardEvent);
|
let event = new StandardKeyboardEvent(e as KeyboardEvent);
|
||||||
|
|
||||||
// Run action on Enter/Space
|
// Run action on Enter/Space
|
||||||
|
@ -478,15 +474,15 @@ export class ActionBar implements IActionRunner {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.focusTracker = DOM.trackFocus(this.domNode);
|
this.focusTracker = this._register(DOM.trackFocus(this.domNode));
|
||||||
this.toDispose.push(this.focusTracker.onDidBlur(() => {
|
this._register(this.focusTracker.onDidBlur(() => {
|
||||||
if (document.activeElement === this.domNode || !DOM.isAncestor(document.activeElement, this.domNode)) {
|
if (document.activeElement === this.domNode || !DOM.isAncestor(document.activeElement, this.domNode)) {
|
||||||
this._onDidBlur.fire();
|
this._onDidBlur.fire();
|
||||||
this.focusedItem = undefined;
|
this.focusedItem = undefined;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.toDispose.push(this.focusTracker.onDidFocus(() => this.updateFocusedItem()));
|
this._register(this.focusTracker.onDidFocus(() => this.updateFocusedItem()));
|
||||||
|
|
||||||
this.actionsList = document.createElement('ul');
|
this.actionsList = document.createElement('ul');
|
||||||
this.actionsList.className = 'actions-container';
|
this.actionsList.className = 'actions-container';
|
||||||
|
@ -571,7 +567,7 @@ export class ActionBar implements IActionRunner {
|
||||||
actionItemElement.setAttribute('role', 'presentation');
|
actionItemElement.setAttribute('role', 'presentation');
|
||||||
|
|
||||||
// Prevent native context menu on actions
|
// Prevent native context menu on actions
|
||||||
this.toDispose.push(DOM.addDisposableListener(actionItemElement, DOM.EventType.CONTEXT_MENU, (e: DOM.EventLike) => {
|
this._register(DOM.addDisposableListener(actionItemElement, DOM.EventType.CONTEXT_MENU, (e: DOM.EventLike) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}));
|
}));
|
||||||
|
@ -750,28 +746,22 @@ export class ActionBar implements IActionRunner {
|
||||||
}
|
}
|
||||||
this.items = null;
|
this.items = null;
|
||||||
|
|
||||||
if (this.focusTracker) {
|
|
||||||
this.focusTracker.dispose();
|
|
||||||
this.focusTracker = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.toDispose = lifecycle.dispose(this.toDispose);
|
|
||||||
|
|
||||||
DOM.removeNode(this.getContainer());
|
DOM.removeNode(this.getContainer());
|
||||||
|
|
||||||
|
super.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SelectActionItem extends BaseActionItem {
|
export class SelectActionItem extends BaseActionItem {
|
||||||
protected selectBox: SelectBox;
|
protected selectBox: SelectBox;
|
||||||
protected toDispose: lifecycle.IDisposable[];
|
|
||||||
|
|
||||||
constructor(ctx: any, action: IAction, options: string[], selected: number, contextViewProvider: IContextViewProvider, selectBoxOptions?: ISelectBoxOptions
|
constructor(ctx: any, action: IAction, options: string[], selected: number, contextViewProvider: IContextViewProvider, selectBoxOptions?: ISelectBoxOptions
|
||||||
) {
|
) {
|
||||||
super(ctx, action);
|
super(ctx, action);
|
||||||
|
|
||||||
this.selectBox = new SelectBox(options, selected, contextViewProvider, null, selectBoxOptions);
|
this.selectBox = new SelectBox(options, selected, contextViewProvider, null, selectBoxOptions);
|
||||||
|
|
||||||
this.toDispose = [];
|
this._register(this.selectBox);
|
||||||
this.toDispose.push(this.selectBox);
|
|
||||||
this.registerListeners();
|
this.registerListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -784,7 +774,7 @@ export class SelectActionItem extends BaseActionItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerListeners(): void {
|
private registerListeners(): void {
|
||||||
this.toDispose.push(this.selectBox.onDidSelect(e => {
|
this._register(this.selectBox.onDidSelect(e => {
|
||||||
this.actionRunner.run(this._action, this.getActionContext(e.selected)).done();
|
this.actionRunner.run(this._action, this.getActionContext(e.selected)).done();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -808,10 +798,4 @@ export class SelectActionItem extends BaseActionItem {
|
||||||
public render(container: HTMLElement): void {
|
public render(container: HTMLElement): void {
|
||||||
this.selectBox.render(container);
|
this.selectBox.render(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
public dispose(): void {
|
|
||||||
this.toDispose = lifecycle.dispose(this.toDispose);
|
|
||||||
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -34,7 +34,7 @@ const defaultOptions: IButtonStyles = {
|
||||||
|
|
||||||
export class Button extends Disposable {
|
export class Button extends Disposable {
|
||||||
|
|
||||||
private $el: HTMLElement;
|
private _element: HTMLElement;
|
||||||
private options: IButtonOptions;
|
private options: IButtonOptions;
|
||||||
|
|
||||||
private buttonBackground: Color;
|
private buttonBackground: Color;
|
||||||
|
@ -58,16 +58,16 @@ export class Button extends Disposable {
|
||||||
this.buttonForeground = this.options.buttonForeground;
|
this.buttonForeground = this.options.buttonForeground;
|
||||||
this.buttonBorder = this.options.buttonBorder;
|
this.buttonBorder = this.options.buttonBorder;
|
||||||
|
|
||||||
this.$el = document.createElement('a');
|
this._element = document.createElement('a');
|
||||||
DOM.addClass(this.$el, 'monaco-button');
|
DOM.addClass(this._element, 'monaco-button');
|
||||||
this.$el.tabIndex = 0;
|
this._element.tabIndex = 0;
|
||||||
this.$el.setAttribute('role', 'button');
|
this._element.setAttribute('role', 'button');
|
||||||
|
|
||||||
container.appendChild(this.$el);
|
container.appendChild(this._element);
|
||||||
|
|
||||||
Gesture.addTarget(this.$el);
|
Gesture.addTarget(this._element);
|
||||||
|
|
||||||
this._register(DOM.addDisposableListener(this.$el, DOM.EventType.CLICK, e => {
|
this._register(DOM.addDisposableListener(this._element, DOM.EventType.CLICK, e => {
|
||||||
if (!this.enabled) {
|
if (!this.enabled) {
|
||||||
DOM.EventHelper.stop(e);
|
DOM.EventHelper.stop(e);
|
||||||
return;
|
return;
|
||||||
|
@ -76,14 +76,14 @@ export class Button extends Disposable {
|
||||||
this._onDidClick.fire(e);
|
this._onDidClick.fire(e);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._register(DOM.addDisposableListener(this.$el, DOM.EventType.KEY_DOWN, e => {
|
this._register(DOM.addDisposableListener(this._element, DOM.EventType.KEY_DOWN, e => {
|
||||||
const event = new StandardKeyboardEvent(e as KeyboardEvent);
|
const event = new StandardKeyboardEvent(e as KeyboardEvent);
|
||||||
let eventHandled = false;
|
let eventHandled = false;
|
||||||
if (this.enabled && event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) {
|
if (this.enabled && event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) {
|
||||||
this._onDidClick.fire(e);
|
this._onDidClick.fire(e);
|
||||||
eventHandled = true;
|
eventHandled = true;
|
||||||
} else if (event.equals(KeyCode.Escape)) {
|
} else if (event.equals(KeyCode.Escape)) {
|
||||||
this.$el.blur();
|
this._element.blur();
|
||||||
eventHandled = true;
|
eventHandled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,18 +92,18 @@ export class Button extends Disposable {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._register(DOM.addDisposableListener(this.$el, DOM.EventType.MOUSE_OVER, e => {
|
this._register(DOM.addDisposableListener(this._element, DOM.EventType.MOUSE_OVER, e => {
|
||||||
if (!DOM.hasClass(this.$el, 'disabled')) {
|
if (!DOM.hasClass(this._element, 'disabled')) {
|
||||||
this.setHoverBackground();
|
this.setHoverBackground();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._register(DOM.addDisposableListener(this.$el, DOM.EventType.MOUSE_OUT, e => {
|
this._register(DOM.addDisposableListener(this._element, DOM.EventType.MOUSE_OUT, e => {
|
||||||
this.applyStyles(); // restore standard styles
|
this.applyStyles(); // restore standard styles
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Also set hover background when button is focused for feedback
|
// Also set hover background when button is focused for feedback
|
||||||
this.focusTracker = this._register(DOM.trackFocus(this.$el));
|
this.focusTracker = this._register(DOM.trackFocus(this._element));
|
||||||
this._register(this.focusTracker.onDidFocus(() => this.setHoverBackground()));
|
this._register(this.focusTracker.onDidFocus(() => this.setHoverBackground()));
|
||||||
this._register(this.focusTracker.onDidBlur(() => this.applyStyles())); // restore standard styles
|
this._register(this.focusTracker.onDidBlur(() => this.applyStyles())); // restore standard styles
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ export class Button extends Disposable {
|
||||||
private setHoverBackground(): void {
|
private setHoverBackground(): void {
|
||||||
const hoverBackground = this.buttonHoverBackground ? this.buttonHoverBackground.toString() : null;
|
const hoverBackground = this.buttonHoverBackground ? this.buttonHoverBackground.toString() : null;
|
||||||
if (hoverBackground) {
|
if (hoverBackground) {
|
||||||
this.$el.style.backgroundColor = hoverBackground;
|
this._element.style.backgroundColor = hoverBackground;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,56 +127,56 @@ export class Button extends Disposable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private applyStyles(): void {
|
private applyStyles(): void {
|
||||||
if (this.$el) {
|
if (this._element) {
|
||||||
const background = this.buttonBackground ? this.buttonBackground.toString() : null;
|
const background = this.buttonBackground ? this.buttonBackground.toString() : null;
|
||||||
const foreground = this.buttonForeground ? this.buttonForeground.toString() : null;
|
const foreground = this.buttonForeground ? this.buttonForeground.toString() : null;
|
||||||
const border = this.buttonBorder ? this.buttonBorder.toString() : null;
|
const border = this.buttonBorder ? this.buttonBorder.toString() : null;
|
||||||
|
|
||||||
this.$el.style.color = foreground;
|
this._element.style.color = foreground;
|
||||||
this.$el.style.backgroundColor = background;
|
this._element.style.backgroundColor = background;
|
||||||
|
|
||||||
this.$el.style.borderWidth = border ? '1px' : null;
|
this._element.style.borderWidth = border ? '1px' : null;
|
||||||
this.$el.style.borderStyle = border ? 'solid' : null;
|
this._element.style.borderStyle = border ? 'solid' : null;
|
||||||
this.$el.style.borderColor = border;
|
this._element.style.borderColor = border;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get element(): HTMLElement {
|
get element(): HTMLElement {
|
||||||
return this.$el;
|
return this._element;
|
||||||
}
|
}
|
||||||
|
|
||||||
set label(value: string) {
|
set label(value: string) {
|
||||||
if (!DOM.hasClass(this.$el, 'monaco-text-button')) {
|
if (!DOM.hasClass(this._element, 'monaco-text-button')) {
|
||||||
DOM.addClass(this.$el, 'monaco-text-button');
|
DOM.addClass(this._element, 'monaco-text-button');
|
||||||
}
|
}
|
||||||
this.$el.innerText = value;
|
this._element.textContent = value;
|
||||||
if (this.options.title) {
|
if (this.options.title) {
|
||||||
this.$el.title = value;
|
this._element.title = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set icon(iconClassName: string) {
|
set icon(iconClassName: string) {
|
||||||
DOM.addClass(this.$el, iconClassName);
|
DOM.addClass(this._element, iconClassName);
|
||||||
}
|
}
|
||||||
|
|
||||||
set enabled(value: boolean) {
|
set enabled(value: boolean) {
|
||||||
if (value) {
|
if (value) {
|
||||||
DOM.removeClass(this.$el, 'disabled');
|
DOM.removeClass(this._element, 'disabled');
|
||||||
this.$el.setAttribute('aria-disabled', String(false));
|
this._element.setAttribute('aria-disabled', String(false));
|
||||||
this.$el.tabIndex = 0;
|
this._element.tabIndex = 0;
|
||||||
} else {
|
} else {
|
||||||
DOM.addClass(this.$el, 'disabled');
|
DOM.addClass(this._element, 'disabled');
|
||||||
this.$el.setAttribute('aria-disabled', String(true));
|
this._element.setAttribute('aria-disabled', String(true));
|
||||||
DOM.removeTabIndexAndUpdateFocus(this.$el);
|
DOM.removeTabIndexAndUpdateFocus(this._element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get enabled() {
|
get enabled() {
|
||||||
return !DOM.hasClass(this.$el, 'disabled');
|
return !DOM.hasClass(this._element, 'disabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
focus(): void {
|
focus(): void {
|
||||||
this.$el.focus();
|
this._element.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
import 'vs/css!./contextview';
|
import 'vs/css!./contextview';
|
||||||
import * as DOM from 'vs/base/browser/dom';
|
import * as DOM from 'vs/base/browser/dom';
|
||||||
import { IDisposable, dispose, toDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
|
import { IDisposable, dispose, toDisposable, combinedDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||||
|
|
||||||
export interface IAnchor {
|
export interface IAnchor {
|
||||||
x: number;
|
x: number;
|
||||||
|
@ -95,55 +95,54 @@ export function layout(viewportSize: number, viewSize: number, anchor: ILayoutAn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ContextView {
|
export class ContextView extends Disposable {
|
||||||
|
|
||||||
private static readonly BUBBLE_UP_EVENTS = ['click', 'keydown', 'focus', 'blur'];
|
private static readonly BUBBLE_UP_EVENTS = ['click', 'keydown', 'focus', 'blur'];
|
||||||
private static readonly BUBBLE_DOWN_EVENTS = ['click'];
|
private static readonly BUBBLE_DOWN_EVENTS = ['click'];
|
||||||
|
|
||||||
private $container: HTMLElement;
|
private container: HTMLElement;
|
||||||
private $view: HTMLElement;
|
private view: HTMLElement;
|
||||||
private delegate: IDelegate;
|
private delegate: IDelegate;
|
||||||
private toDispose: IDisposable[];
|
|
||||||
private toDisposeOnClean: IDisposable;
|
private toDisposeOnClean: IDisposable;
|
||||||
private toDisposeOnSetContainer: IDisposable;
|
private toDisposeOnSetContainer: IDisposable;
|
||||||
|
|
||||||
constructor(container: HTMLElement) {
|
constructor(container: HTMLElement) {
|
||||||
this.$view = DOM.$('.context-view');
|
super();
|
||||||
|
|
||||||
DOM.hide(this.$view);
|
this.view = DOM.$('.context-view');
|
||||||
|
|
||||||
|
DOM.hide(this.view);
|
||||||
|
|
||||||
this.setContainer(container);
|
this.setContainer(container);
|
||||||
|
|
||||||
this.toDispose = [toDisposable(() => {
|
this._register(toDisposable(() => this.setContainer(null)));
|
||||||
this.setContainer(null);
|
|
||||||
})];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public setContainer(container: HTMLElement): void {
|
public setContainer(container: HTMLElement): void {
|
||||||
if (this.$container) {
|
if (this.container) {
|
||||||
this.toDisposeOnSetContainer = dispose(this.toDisposeOnSetContainer);
|
this.toDisposeOnSetContainer = dispose(this.toDisposeOnSetContainer);
|
||||||
this.$container.removeChild(this.$view);
|
this.container.removeChild(this.view);
|
||||||
this.$container = null;
|
this.container = null;
|
||||||
}
|
}
|
||||||
if (container) {
|
if (container) {
|
||||||
this.$container = container;
|
this.container = container;
|
||||||
this.$container.appendChild(this.$view);
|
this.container.appendChild(this.view);
|
||||||
|
|
||||||
const toDispose: IDisposable[] = [];
|
const toDisposeOnSetContainer: IDisposable[] = [];
|
||||||
|
|
||||||
ContextView.BUBBLE_UP_EVENTS.forEach(event => {
|
ContextView.BUBBLE_UP_EVENTS.forEach(event => {
|
||||||
toDispose.push(DOM.addStandardDisposableListener(this.$container, event, (e: Event) => {
|
toDisposeOnSetContainer.push(DOM.addStandardDisposableListener(this.container, event, (e: Event) => {
|
||||||
this.onDOMEvent(e, <HTMLElement>document.activeElement, false);
|
this.onDOMEvent(e, <HTMLElement>document.activeElement, false);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
ContextView.BUBBLE_DOWN_EVENTS.forEach(event => {
|
ContextView.BUBBLE_DOWN_EVENTS.forEach(event => {
|
||||||
toDispose.push(DOM.addStandardDisposableListener(this.$container, event, (e: Event) => {
|
toDisposeOnSetContainer.push(DOM.addStandardDisposableListener(this.container, event, (e: Event) => {
|
||||||
this.onDOMEvent(e, <HTMLElement>document.activeElement, true);
|
this.onDOMEvent(e, <HTMLElement>document.activeElement, true);
|
||||||
}, true));
|
}, true));
|
||||||
});
|
});
|
||||||
|
|
||||||
this.toDisposeOnSetContainer = combinedDisposable(toDispose);
|
this.toDisposeOnSetContainer = combinedDisposable(toDisposeOnSetContainer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,14 +152,14 @@ export class ContextView {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show static box
|
// Show static box
|
||||||
DOM.clearNode(this.$view);
|
DOM.clearNode(this.view);
|
||||||
this.$view.className = 'context-view';
|
this.view.className = 'context-view';
|
||||||
this.$view.style.top = '0px';
|
this.view.style.top = '0px';
|
||||||
this.$view.style.left = '0px';
|
this.view.style.left = '0px';
|
||||||
DOM.show(this.$view);
|
DOM.show(this.view);
|
||||||
|
|
||||||
// Render content
|
// Render content
|
||||||
this.toDisposeOnClean = delegate.render(this.$view);
|
this.toDisposeOnClean = delegate.render(this.view);
|
||||||
|
|
||||||
// Set active delegate
|
// Set active delegate
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
|
@ -219,8 +218,8 @@ export class ContextView {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const viewSizeWidth = DOM.getTotalWidth(this.$view);
|
const viewSizeWidth = DOM.getTotalWidth(this.view);
|
||||||
const viewSizeHeight = DOM.getTotalHeight(this.$view);
|
const viewSizeHeight = DOM.getTotalHeight(this.view);
|
||||||
|
|
||||||
const anchorPosition = this.delegate.anchorPosition || AnchorPosition.BELOW;
|
const anchorPosition = this.delegate.anchorPosition || AnchorPosition.BELOW;
|
||||||
const anchorAlignment = this.delegate.anchorAlignment || AnchorAlignment.LEFT;
|
const anchorAlignment = this.delegate.anchorAlignment || AnchorAlignment.LEFT;
|
||||||
|
@ -235,17 +234,17 @@ export class ContextView {
|
||||||
horizontalAnchor = { offset: around.left + around.width, size: 0, position: LayoutAnchorPosition.After };
|
horizontalAnchor = { offset: around.left + around.width, size: 0, position: LayoutAnchorPosition.After };
|
||||||
}
|
}
|
||||||
|
|
||||||
const containerPosition = DOM.getDomNodePagePosition(this.$container);
|
const containerPosition = DOM.getDomNodePagePosition(this.container);
|
||||||
const top = layout(window.innerHeight, viewSizeHeight, verticalAnchor) - containerPosition.top;
|
const top = layout(window.innerHeight, viewSizeHeight, verticalAnchor) - containerPosition.top;
|
||||||
const left = layout(window.innerWidth, viewSizeWidth, horizontalAnchor) - containerPosition.left;
|
const left = layout(window.innerWidth, viewSizeWidth, horizontalAnchor) - containerPosition.left;
|
||||||
|
|
||||||
DOM.removeClasses(this.$view, 'top', 'bottom', 'left', 'right');
|
DOM.removeClasses(this.view, 'top', 'bottom', 'left', 'right');
|
||||||
DOM.addClass(this.$view, anchorPosition === AnchorPosition.BELOW ? 'bottom' : 'top');
|
DOM.addClass(this.view, anchorPosition === AnchorPosition.BELOW ? 'bottom' : 'top');
|
||||||
DOM.addClass(this.$view, anchorAlignment === AnchorAlignment.LEFT ? 'left' : 'right');
|
DOM.addClass(this.view, anchorAlignment === AnchorAlignment.LEFT ? 'left' : 'right');
|
||||||
|
|
||||||
this.$view.style.top = `${top}px`;
|
this.view.style.top = `${top}px`;
|
||||||
this.$view.style.left = `${left}px`;
|
this.view.style.left = `${left}px`;
|
||||||
this.$view.style.width = 'initial';
|
this.view.style.width = 'initial';
|
||||||
}
|
}
|
||||||
|
|
||||||
public hide(data?: any): void {
|
public hide(data?: any): void {
|
||||||
|
@ -260,7 +259,7 @@ export class ContextView {
|
||||||
this.toDisposeOnClean = null;
|
this.toDisposeOnClean = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
DOM.hide(this.$view);
|
DOM.hide(this.view);
|
||||||
}
|
}
|
||||||
|
|
||||||
private isVisible(): boolean {
|
private isVisible(): boolean {
|
||||||
|
@ -271,7 +270,7 @@ export class ContextView {
|
||||||
if (this.delegate) {
|
if (this.delegate) {
|
||||||
if (this.delegate.onDOMEvent) {
|
if (this.delegate.onDOMEvent) {
|
||||||
this.delegate.onDOMEvent(e, <HTMLElement>document.activeElement);
|
this.delegate.onDOMEvent(e, <HTMLElement>document.activeElement);
|
||||||
} else if (onCapture && !DOM.isAncestor(<HTMLElement>e.target, this.$container)) {
|
} else if (onCapture && !DOM.isAncestor(<HTMLElement>e.target, this.container)) {
|
||||||
this.hide();
|
this.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,6 +279,6 @@ export class ContextView {
|
||||||
public dispose(): void {
|
public dispose(): void {
|
||||||
this.hide();
|
this.hide();
|
||||||
|
|
||||||
this.toDispose = dispose(this.toDispose);
|
super.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -29,18 +29,18 @@ export interface IBaseDropdownOptions {
|
||||||
export class BaseDropdown extends ActionRunner {
|
export class BaseDropdown extends ActionRunner {
|
||||||
private _toDispose: IDisposable[] = [];
|
private _toDispose: IDisposable[] = [];
|
||||||
|
|
||||||
private $el: HTMLElement;
|
private _element: HTMLElement;
|
||||||
private $boxContainer: HTMLElement;
|
private boxContainer: HTMLElement;
|
||||||
private $label: HTMLElement;
|
private _label: HTMLElement;
|
||||||
private $contents: HTMLElement;
|
private contents: HTMLElement;
|
||||||
private visible: boolean;
|
private visible: boolean;
|
||||||
|
|
||||||
constructor(container: HTMLElement, options: IBaseDropdownOptions) {
|
constructor(container: HTMLElement, options: IBaseDropdownOptions) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.$el = append(container, $('.monaco-dropdown'));
|
this._element = append(container, $('.monaco-dropdown'));
|
||||||
|
|
||||||
this.$label = append(this.$el, $('.dropdown-label'));
|
this._label = append(this._element, $('.dropdown-label'));
|
||||||
|
|
||||||
let labelRenderer = options.labelRenderer;
|
let labelRenderer = options.labelRenderer;
|
||||||
if (!labelRenderer) {
|
if (!labelRenderer) {
|
||||||
|
@ -52,11 +52,11 @@ export class BaseDropdown extends ActionRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
[EventType.CLICK, EventType.MOUSE_DOWN, GestureEventType.Tap].forEach(event => {
|
[EventType.CLICK, EventType.MOUSE_DOWN, GestureEventType.Tap].forEach(event => {
|
||||||
this._toDispose.push(addDisposableListener(this.$label, event, e => EventHelper.stop(e, true))); // prevent default click behaviour to trigger
|
this._toDispose.push(addDisposableListener(this._label, event, e => EventHelper.stop(e, true))); // prevent default click behaviour to trigger
|
||||||
});
|
});
|
||||||
|
|
||||||
[EventType.MOUSE_DOWN, GestureEventType.Tap].forEach(event => {
|
[EventType.MOUSE_DOWN, GestureEventType.Tap].forEach(event => {
|
||||||
this._toDispose.push(addDisposableListener(this.$label, event, e => {
|
this._toDispose.push(addDisposableListener(this._label, event, e => {
|
||||||
if (e instanceof MouseEvent && e.detail > 1) {
|
if (e instanceof MouseEvent && e.detail > 1) {
|
||||||
return; // prevent multiple clicks to open multiple context menus (https://github.com/Microsoft/vscode/issues/41363)
|
return; // prevent multiple clicks to open multiple context menus (https://github.com/Microsoft/vscode/issues/41363)
|
||||||
}
|
}
|
||||||
|
@ -69,12 +69,12 @@ export class BaseDropdown extends ActionRunner {
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
const cleanupFn = labelRenderer(this.$label);
|
const cleanupFn = labelRenderer(this._label);
|
||||||
if (cleanupFn) {
|
if (cleanupFn) {
|
||||||
this._toDispose.push(cleanupFn);
|
this._toDispose.push(cleanupFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gesture.addTarget(this.$label);
|
Gesture.addTarget(this._label);
|
||||||
}
|
}
|
||||||
|
|
||||||
get toDispose(): IDisposable[] {
|
get toDispose(): IDisposable[] {
|
||||||
|
@ -82,15 +82,15 @@ export class BaseDropdown extends ActionRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
get element(): HTMLElement {
|
get element(): HTMLElement {
|
||||||
return this.$el;
|
return this._element;
|
||||||
}
|
}
|
||||||
|
|
||||||
get label(): HTMLElement {
|
get label(): HTMLElement {
|
||||||
return this.$label;
|
return this._label;
|
||||||
}
|
}
|
||||||
|
|
||||||
set tooltip(tooltip: string) {
|
set tooltip(tooltip: string) {
|
||||||
this.$label.title = tooltip;
|
this._label.title = tooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
show(): void {
|
show(): void {
|
||||||
|
@ -111,19 +111,19 @@ export class BaseDropdown extends ActionRunner {
|
||||||
|
|
||||||
this._toDispose = dispose(this.toDispose);
|
this._toDispose = dispose(this.toDispose);
|
||||||
|
|
||||||
if (this.$boxContainer) {
|
if (this.boxContainer) {
|
||||||
removeNode(this.$boxContainer);
|
removeNode(this.boxContainer);
|
||||||
this.$boxContainer = null;
|
this.boxContainer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.$contents) {
|
if (this.contents) {
|
||||||
removeNode(this.$contents);
|
removeNode(this.contents);
|
||||||
this.$contents = null;
|
this.contents = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.$label) {
|
if (this._label) {
|
||||||
removeNode(this.$label);
|
removeNode(this._label);
|
||||||
this.$label = null;
|
this._label = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,13 +283,13 @@ export class DropdownMenuActionItem extends BaseActionItem {
|
||||||
|
|
||||||
render(container: HTMLElement): void {
|
render(container: HTMLElement): void {
|
||||||
const labelRenderer: ILabelRenderer = (el: HTMLElement): IDisposable => {
|
const labelRenderer: ILabelRenderer = (el: HTMLElement): IDisposable => {
|
||||||
this.builder = append(el, $('a.action-label'));
|
this.element = append(el, $('a.action-label'));
|
||||||
addClasses(this.builder, this.clazz);
|
addClasses(this.element, this.clazz);
|
||||||
|
|
||||||
this.builder.tabIndex = 0;
|
this.element.tabIndex = 0;
|
||||||
this.builder.setAttribute('role', 'button');
|
this.element.setAttribute('role', 'button');
|
||||||
this.builder.setAttribute('aria-haspopup', 'true');
|
this.element.setAttribute('aria-haspopup', 'true');
|
||||||
this.builder.title = this._action.label || '';
|
this.element.title = this._action.label || '';
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
|
@ -245,7 +245,7 @@ class MenuActionItem extends BaseActionItem {
|
||||||
|
|
||||||
this.container = container;
|
this.container = container;
|
||||||
|
|
||||||
this.$e = $('a.action-menu-item').appendTo(this.builder);
|
this.$e = $('a.action-menu-item').appendTo(this.element);
|
||||||
if (this._action.id === Separator.ID) {
|
if (this._action.id === Separator.ID) {
|
||||||
// A separator is a presentation item
|
// A separator is a presentation item
|
||||||
this.$e.attr({ role: 'presentation' });
|
this.$e.attr({ role: 'presentation' });
|
||||||
|
@ -335,11 +335,11 @@ class MenuActionItem extends BaseActionItem {
|
||||||
|
|
||||||
_updateEnabled(): void {
|
_updateEnabled(): void {
|
||||||
if (this.getAction().enabled) {
|
if (this.getAction().enabled) {
|
||||||
removeClass(this.builder, 'disabled');
|
removeClass(this.element, 'disabled');
|
||||||
this.$e.removeClass('disabled');
|
this.$e.removeClass('disabled');
|
||||||
this.$e.attr({ tabindex: 0 });
|
this.$e.attr({ tabindex: 0 });
|
||||||
} else {
|
} else {
|
||||||
addClass(this.builder, 'disabled');
|
addClass(this.element, 'disabled');
|
||||||
this.$e.addClass('disabled');
|
this.$e.addClass('disabled');
|
||||||
removeTabIndexAndUpdateFocus(this.$e.getHTMLElement());
|
removeTabIndexAndUpdateFocus(this.$e.getHTMLElement());
|
||||||
}
|
}
|
||||||
|
@ -383,7 +383,7 @@ class SubmenuActionItem extends MenuActionItem {
|
||||||
}, 250);
|
}, 250);
|
||||||
|
|
||||||
this.hideScheduler = new RunOnceScheduler(() => {
|
this.hideScheduler = new RunOnceScheduler(() => {
|
||||||
if ((!isAncestor(document.activeElement, this.builder) && this.parentData.submenu === this.mysubmenu)) {
|
if ((!isAncestor(document.activeElement, this.element) && this.parentData.submenu === this.mysubmenu)) {
|
||||||
this.parentData.parent.focus(false);
|
this.parentData.parent.focus(false);
|
||||||
this.cleanupExistingSubmenu(true);
|
this.cleanupExistingSubmenu(true);
|
||||||
}
|
}
|
||||||
|
@ -397,7 +397,7 @@ class SubmenuActionItem extends MenuActionItem {
|
||||||
this.$e.attr('aria-haspopup', 'true');
|
this.$e.attr('aria-haspopup', 'true');
|
||||||
$('span.submenu-indicator').attr('aria-hidden', 'true').text('\u25B6').appendTo(this.$e);
|
$('span.submenu-indicator').attr('aria-hidden', 'true').text('\u25B6').appendTo(this.$e);
|
||||||
|
|
||||||
$(this.builder).on(EventType.KEY_UP, (e) => {
|
$(this.element).on(EventType.KEY_UP, (e) => {
|
||||||
let event = new StandardKeyboardEvent(e as KeyboardEvent);
|
let event = new StandardKeyboardEvent(e as KeyboardEvent);
|
||||||
if (event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Enter)) {
|
if (event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Enter)) {
|
||||||
EventHelper.stop(e, true);
|
EventHelper.stop(e, true);
|
||||||
|
@ -406,14 +406,14 @@ class SubmenuActionItem extends MenuActionItem {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$(this.builder).on(EventType.KEY_DOWN, (e) => {
|
$(this.element).on(EventType.KEY_DOWN, (e) => {
|
||||||
let event = new StandardKeyboardEvent(e as KeyboardEvent);
|
let event = new StandardKeyboardEvent(e as KeyboardEvent);
|
||||||
if (event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Enter)) {
|
if (event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Enter)) {
|
||||||
EventHelper.stop(e, true);
|
EventHelper.stop(e, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$(this.builder).on(EventType.MOUSE_OVER, (e) => {
|
$(this.element).on(EventType.MOUSE_OVER, (e) => {
|
||||||
if (!this.mouseOver) {
|
if (!this.mouseOver) {
|
||||||
this.mouseOver = true;
|
this.mouseOver = true;
|
||||||
|
|
||||||
|
@ -421,12 +421,12 @@ class SubmenuActionItem extends MenuActionItem {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$(this.builder).on(EventType.MOUSE_LEAVE, (e) => {
|
$(this.element).on(EventType.MOUSE_LEAVE, (e) => {
|
||||||
this.mouseOver = false;
|
this.mouseOver = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
$(this.builder).on(EventType.FOCUS_OUT, (e) => {
|
$(this.element).on(EventType.FOCUS_OUT, (e) => {
|
||||||
if (!isAncestor(document.activeElement, this.builder)) {
|
if (!isAncestor(document.activeElement, this.element)) {
|
||||||
this.hideScheduler.schedule();
|
this.hideScheduler.schedule();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -454,10 +454,10 @@ class SubmenuActionItem extends MenuActionItem {
|
||||||
|
|
||||||
private createSubmenu(selectFirstItem = true) {
|
private createSubmenu(selectFirstItem = true) {
|
||||||
if (!this.parentData.submenu) {
|
if (!this.parentData.submenu) {
|
||||||
this.submenuContainer = $(this.builder).div({ class: 'monaco-submenu menubar-menu-items-holder context-view' });
|
this.submenuContainer = $(this.element).div({ class: 'monaco-submenu menubar-menu-items-holder context-view' });
|
||||||
|
|
||||||
$(this.submenuContainer).style({
|
$(this.submenuContainer).style({
|
||||||
'left': `${$(this.builder).getClientArea().width}px`
|
'left': `${$(this.element).getClientArea().width}px`
|
||||||
});
|
});
|
||||||
|
|
||||||
$(this.submenuContainer).on(EventType.KEY_UP, (e) => {
|
$(this.submenuContainer).on(EventType.KEY_UP, (e) => {
|
||||||
|
|
|
@ -199,17 +199,17 @@ export class MenuItemActionItem extends ActionItem {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this._callOnDispose.push(alternativeKeyEmitter.event(value => {
|
this._register(alternativeKeyEmitter.event(value => {
|
||||||
alternativeKeyDown = value;
|
alternativeKeyDown = value;
|
||||||
updateAltState();
|
updateAltState();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._callOnDispose.push(domEvent(container, 'mouseleave')(_ => {
|
this._register(domEvent(container, 'mouseleave')(_ => {
|
||||||
mouseOver = false;
|
mouseOver = false;
|
||||||
updateAltState();
|
updateAltState();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._callOnDispose.push(domEvent(container, 'mouseenter')(e => {
|
this._register(domEvent(container, 'mouseenter')(e => {
|
||||||
mouseOver = true;
|
mouseOver = true;
|
||||||
updateAltState();
|
updateAltState();
|
||||||
}));
|
}));
|
||||||
|
@ -217,12 +217,12 @@ export class MenuItemActionItem extends ActionItem {
|
||||||
|
|
||||||
_updateLabel(): void {
|
_updateLabel(): void {
|
||||||
if (this.options.label) {
|
if (this.options.label) {
|
||||||
this.$e.textContent = this._commandAction.label;
|
this.label.textContent = this._commandAction.label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateTooltip(): void {
|
_updateTooltip(): void {
|
||||||
const element = this.$e;
|
const element = this.label;
|
||||||
const keybinding = this._keybindingService.lookupKeybinding(this._commandAction.id);
|
const keybinding = this._keybindingService.lookupKeybinding(this._commandAction.id);
|
||||||
const keybindingLabel = keybinding && keybinding.getLabel();
|
const keybindingLabel = keybinding && keybinding.getLabel();
|
||||||
|
|
||||||
|
@ -259,8 +259,8 @@ export class MenuItemActionItem extends ActionItem {
|
||||||
MenuItemActionItem.ICON_PATH_TO_CSS_RULES.set(iconPathMapKey, iconClass);
|
MenuItemActionItem.ICON_PATH_TO_CSS_RULES.set(iconPathMapKey, iconClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
addClasses(this.$e, 'icon', iconClass);
|
addClasses(this.label, 'icon', iconClass);
|
||||||
this._itemClassDispose = toDisposable(() => removeClasses(this.$e, 'icon', iconClass));
|
this._itemClassDispose = toDisposable(() => removeClasses(this.label, 'icon', iconClass));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@ export class ContextMenuHandler {
|
||||||
private notificationService: INotificationService;
|
private notificationService: INotificationService;
|
||||||
private telemetryService: ITelemetryService;
|
private telemetryService: ITelemetryService;
|
||||||
|
|
||||||
private $el: HTMLElement;
|
private element: HTMLElement;
|
||||||
private $elDisposable: IDisposable;
|
private elementDisposable: IDisposable;
|
||||||
private menuContainerElement: HTMLElement;
|
private menuContainerElement: HTMLElement;
|
||||||
private focusToReturn: HTMLElement;
|
private focusToReturn: HTMLElement;
|
||||||
|
|
||||||
|
@ -39,13 +39,13 @@ export class ContextMenuHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
public setContainer(container: HTMLElement): void {
|
public setContainer(container: HTMLElement): void {
|
||||||
if (this.$el) {
|
if (this.element) {
|
||||||
this.$elDisposable = dispose(this.$elDisposable);
|
this.elementDisposable = dispose(this.elementDisposable);
|
||||||
this.$el = null;
|
this.element = null;
|
||||||
}
|
}
|
||||||
if (container) {
|
if (container) {
|
||||||
this.$el = container;
|
this.element = container;
|
||||||
this.$elDisposable = addDisposableListener(this.$el, 'mousedown', (e) => this.onMouseDown(e as MouseEvent));
|
this.elementDisposable = addDisposableListener(this.element, 'mousedown', (e) => this.onMouseDown(e as MouseEvent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,23 +123,23 @@ export class GlobalActivityActionItem extends ActivityActionItem {
|
||||||
// Context menus are triggered on mouse down so that an item can be picked
|
// Context menus are triggered on mouse down so that an item can be picked
|
||||||
// and executed with releasing the mouse over it
|
// and executed with releasing the mouse over it
|
||||||
|
|
||||||
this.callOnDispose.push(DOM.addDisposableListener(this.$container, DOM.EventType.MOUSE_DOWN, (e: MouseEvent) => {
|
this._register(DOM.addDisposableListener(this.container, DOM.EventType.MOUSE_DOWN, (e: MouseEvent) => {
|
||||||
DOM.EventHelper.stop(e, true);
|
DOM.EventHelper.stop(e, true);
|
||||||
|
|
||||||
const event = new StandardMouseEvent(e);
|
const event = new StandardMouseEvent(e);
|
||||||
this.showContextMenu({ x: event.posx, y: event.posy });
|
this.showContextMenu({ x: event.posx, y: event.posy });
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.callOnDispose.push(DOM.addDisposableListener(this.$container, DOM.EventType.KEY_UP, (e: KeyboardEvent) => {
|
this._register(DOM.addDisposableListener(this.container, DOM.EventType.KEY_UP, (e: KeyboardEvent) => {
|
||||||
let event = new StandardKeyboardEvent(e);
|
let event = new StandardKeyboardEvent(e);
|
||||||
if (event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) {
|
if (event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) {
|
||||||
DOM.EventHelper.stop(e, true);
|
DOM.EventHelper.stop(e, true);
|
||||||
|
|
||||||
this.showContextMenu(this.$container);
|
this.showContextMenu(this.container);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.callOnDispose.push(DOM.addDisposableListener(this.$container, TouchEventType.Tap, (e: GestureEvent) => {
|
this._register(DOM.addDisposableListener(this.container, TouchEventType.Tap, (e: GestureEvent) => {
|
||||||
DOM.EventHelper.stop(e, true);
|
DOM.EventHelper.stop(e, true);
|
||||||
|
|
||||||
const event = new StandardMouseEvent(e);
|
const event = new StandardMouseEvent(e);
|
||||||
|
|
|
@ -124,12 +124,12 @@ export interface IActivityActionItemOptions extends IBaseActionItemOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ActivityActionItem extends BaseActionItem {
|
export class ActivityActionItem extends BaseActionItem {
|
||||||
protected $container: HTMLElement;
|
protected container: HTMLElement;
|
||||||
protected $label: HTMLElement;
|
protected label: HTMLElement;
|
||||||
protected $badge: HTMLElement;
|
protected badge: HTMLElement;
|
||||||
protected options: IActivityActionItemOptions;
|
protected options: IActivityActionItemOptions;
|
||||||
|
|
||||||
private $badgeContent: HTMLElement;
|
private badgeContent: HTMLElement;
|
||||||
private badgeDisposable: IDisposable = Disposable.None;
|
private badgeDisposable: IDisposable = Disposable.None;
|
||||||
private mouseUpTimeout: number;
|
private mouseUpTimeout: number;
|
||||||
|
|
||||||
|
@ -140,9 +140,9 @@ export class ActivityActionItem extends BaseActionItem {
|
||||||
) {
|
) {
|
||||||
super(null, action, options);
|
super(null, action, options);
|
||||||
|
|
||||||
this.themeService.onThemeChange(this.onThemeChange, this, this._callOnDispose);
|
this._register(this.themeService.onThemeChange(this.onThemeChange, this));
|
||||||
action.onDidChangeActivity(this.updateActivity, this, this._callOnDispose);
|
this._register(action.onDidChangeActivity(this.updateActivity, this));
|
||||||
action.onDidChangeBadge(this.updateBadge, this, this._callOnDispose);
|
this._register(action.onDidChangeBadge(this.updateBadge, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected get activity(): IActivity {
|
protected get activity(): IActivity {
|
||||||
|
@ -153,59 +153,59 @@ export class ActivityActionItem extends BaseActionItem {
|
||||||
const theme = this.themeService.getTheme();
|
const theme = this.themeService.getTheme();
|
||||||
|
|
||||||
// Label
|
// Label
|
||||||
if (this.$label && this.options.icon) {
|
if (this.label && this.options.icon) {
|
||||||
const background = theme.getColor(this.options.colors.backgroundColor);
|
const background = theme.getColor(this.options.colors.backgroundColor);
|
||||||
|
|
||||||
this.$label.style.backgroundColor = background ? background.toString() : null;
|
this.label.style.backgroundColor = background ? background.toString() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Badge
|
// Badge
|
||||||
if (this.$badgeContent) {
|
if (this.badgeContent) {
|
||||||
const badgeForeground = theme.getColor(this.options.colors.badgeForeground);
|
const badgeForeground = theme.getColor(this.options.colors.badgeForeground);
|
||||||
const badgeBackground = theme.getColor(this.options.colors.badgeBackground);
|
const badgeBackground = theme.getColor(this.options.colors.badgeBackground);
|
||||||
const contrastBorderColor = theme.getColor(contrastBorder);
|
const contrastBorderColor = theme.getColor(contrastBorder);
|
||||||
|
|
||||||
this.$badgeContent.style.color = badgeForeground ? badgeForeground.toString() : null;
|
this.badgeContent.style.color = badgeForeground ? badgeForeground.toString() : null;
|
||||||
this.$badgeContent.style.backgroundColor = badgeBackground ? badgeBackground.toString() : null;
|
this.badgeContent.style.backgroundColor = badgeBackground ? badgeBackground.toString() : null;
|
||||||
|
|
||||||
this.$badgeContent.style.borderStyle = contrastBorderColor ? 'solid' : null;
|
this.badgeContent.style.borderStyle = contrastBorderColor ? 'solid' : null;
|
||||||
this.$badgeContent.style.borderWidth = contrastBorderColor ? '1px' : null;
|
this.badgeContent.style.borderWidth = contrastBorderColor ? '1px' : null;
|
||||||
this.$badgeContent.style.borderColor = contrastBorderColor ? contrastBorderColor.toString() : null;
|
this.badgeContent.style.borderColor = contrastBorderColor ? contrastBorderColor.toString() : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render(container: HTMLElement): void {
|
render(container: HTMLElement): void {
|
||||||
super.render(container);
|
super.render(container);
|
||||||
|
|
||||||
this.$container = container;
|
this.container = container;
|
||||||
|
|
||||||
// Make the container tab-able for keyboard navigation
|
// Make the container tab-able for keyboard navigation
|
||||||
this.$container.tabIndex = 0;
|
this.container.tabIndex = 0;
|
||||||
this.$container.setAttribute('role', 'button');
|
this.container.setAttribute('role', 'button');
|
||||||
|
|
||||||
// Try hard to prevent keyboard only focus feedback when using mouse
|
// Try hard to prevent keyboard only focus feedback when using mouse
|
||||||
this.callOnDispose.push(dom.addDisposableListener(this.$container, dom.EventType.MOUSE_DOWN, () => {
|
this._register(dom.addDisposableListener(this.container, dom.EventType.MOUSE_DOWN, () => {
|
||||||
dom.addClass(this.$container, 'clicked');
|
dom.addClass(this.container, 'clicked');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.callOnDispose.push(dom.addDisposableListener(this.$container, dom.EventType.MOUSE_UP, () => {
|
this._register(dom.addDisposableListener(this.container, dom.EventType.MOUSE_UP, () => {
|
||||||
if (this.mouseUpTimeout) {
|
if (this.mouseUpTimeout) {
|
||||||
clearTimeout(this.mouseUpTimeout);
|
clearTimeout(this.mouseUpTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.mouseUpTimeout = setTimeout(() => {
|
this.mouseUpTimeout = setTimeout(() => {
|
||||||
dom.removeClass(this.$container, 'clicked');
|
dom.removeClass(this.container, 'clicked');
|
||||||
}, 800); // delayed to prevent focus feedback from showing on mouse up
|
}, 800); // delayed to prevent focus feedback from showing on mouse up
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Label
|
// Label
|
||||||
this.$label = dom.append(this.builder, dom.$('a.action-label'));
|
this.label = dom.append(this.element, dom.$('a.action-label'));
|
||||||
|
|
||||||
// Badge
|
// Badge
|
||||||
this.$badge = dom.append(this.builder, dom.$('.badge'));
|
this.badge = dom.append(this.element, dom.$('.badge'));
|
||||||
this.$badgeContent = dom.append(this.$badge, dom.$('.badge-content'));
|
this.badgeContent = dom.append(this.badge, dom.$('.badge-content'));
|
||||||
|
|
||||||
dom.hide(this.$badge);
|
dom.hide(this.badge);
|
||||||
|
|
||||||
this.updateActivity();
|
this.updateActivity();
|
||||||
this.updateStyles();
|
this.updateStyles();
|
||||||
|
@ -223,7 +223,7 @@ export class ActivityActionItem extends BaseActionItem {
|
||||||
|
|
||||||
protected updateBadge(): void {
|
protected updateBadge(): void {
|
||||||
const action = this.getAction();
|
const action = this.getAction();
|
||||||
if (!this.$badge || !this.$badgeContent || !(action instanceof ActivityAction)) {
|
if (!this.badge || !this.badgeContent || !(action instanceof ActivityAction)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,8 +233,8 @@ export class ActivityActionItem extends BaseActionItem {
|
||||||
this.badgeDisposable.dispose();
|
this.badgeDisposable.dispose();
|
||||||
this.badgeDisposable = Disposable.None;
|
this.badgeDisposable = Disposable.None;
|
||||||
|
|
||||||
dom.clearNode(this.$badgeContent);
|
dom.clearNode(this.badgeContent);
|
||||||
dom.hide(this.$badge);
|
dom.hide(this.badge);
|
||||||
|
|
||||||
if (badge) {
|
if (badge) {
|
||||||
|
|
||||||
|
@ -247,30 +247,30 @@ export class ActivityActionItem extends BaseActionItem {
|
||||||
} else if (badge.number > 999) {
|
} else if (badge.number > 999) {
|
||||||
number = number.charAt(0) + 'k';
|
number = number.charAt(0) + 'k';
|
||||||
}
|
}
|
||||||
this.$badgeContent.textContent = number;
|
this.badgeContent.textContent = number;
|
||||||
dom.show(this.$badge);
|
dom.show(this.badge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
else if (badge instanceof TextBadge) {
|
else if (badge instanceof TextBadge) {
|
||||||
this.$badgeContent.textContent = badge.text;
|
this.badgeContent.textContent = badge.text;
|
||||||
dom.show(this.$badge);
|
dom.show(this.badge);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
else if (badge instanceof IconBadge) {
|
else if (badge instanceof IconBadge) {
|
||||||
dom.show(this.$badge);
|
dom.show(this.badge);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Progress
|
// Progress
|
||||||
else if (badge instanceof ProgressBadge) {
|
else if (badge instanceof ProgressBadge) {
|
||||||
dom.show(this.$badge);
|
dom.show(this.badge);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clazz) {
|
if (clazz) {
|
||||||
dom.addClasses(this.$badge, clazz);
|
dom.addClasses(this.badge, clazz);
|
||||||
this.badgeDisposable = toDisposable(() => dom.removeClasses(this.$badge, clazz));
|
this.badgeDisposable = toDisposable(() => dom.removeClasses(this.badge, clazz));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,15 +290,15 @@ export class ActivityActionItem extends BaseActionItem {
|
||||||
|
|
||||||
private updateLabel(): void {
|
private updateLabel(): void {
|
||||||
if (this.activity.cssClass) {
|
if (this.activity.cssClass) {
|
||||||
dom.addClasses(this.$label, this.activity.cssClass);
|
dom.addClasses(this.label, this.activity.cssClass);
|
||||||
}
|
}
|
||||||
if (!this.options.icon) {
|
if (!this.options.icon) {
|
||||||
this.$label.textContent = this.getAction().label;
|
this.label.textContent = this.getAction().label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateTitle(title: string): void {
|
private updateTitle(title: string): void {
|
||||||
[this.$label, this.$badge, this.$container].forEach(element => {
|
[this.label, this.badge, this.container].forEach(element => {
|
||||||
if (element) {
|
if (element) {
|
||||||
element.setAttribute('aria-label', title);
|
element.setAttribute('aria-label', title);
|
||||||
element.title = title;
|
element.title = title;
|
||||||
|
@ -313,7 +313,7 @@ export class ActivityActionItem extends BaseActionItem {
|
||||||
clearTimeout(this.mouseUpTimeout);
|
clearTimeout(this.mouseUpTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
dom.removeNode(this.$badge);
|
dom.removeNode(this.badge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ export class CompositeOverflowActivityActionItem extends ActivityActionItem {
|
||||||
this.actions = this.getActions();
|
this.actions = this.getActions();
|
||||||
|
|
||||||
this.contextMenuService.showContextMenu({
|
this.contextMenuService.showContextMenu({
|
||||||
getAnchor: () => this.builder,
|
getAnchor: () => this.element,
|
||||||
getActions: () => TPromise.as(this.actions),
|
getActions: () => TPromise.as(this.actions),
|
||||||
onHide: () => dispose(this.actions)
|
onHide: () => dispose(this.actions)
|
||||||
});
|
});
|
||||||
|
@ -445,7 +445,7 @@ export class CompositeActionItem extends ActivityActionItem {
|
||||||
CompositeActionItem.manageExtensionAction = instantiationService.createInstance(ManageExtensionAction);
|
CompositeActionItem.manageExtensionAction = instantiationService.createInstance(ManageExtensionAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
compositeActivityAction.onDidChangeActivity(() => { this.compositeActivity = null; this.updateActivity(); }, this, this._callOnDispose);
|
this._register(compositeActivityAction.onDidChangeActivity(() => { this.compositeActivity = null; this.updateActivity(); }, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected get activity(): IActivity {
|
protected get activity(): IActivity {
|
||||||
|
@ -483,14 +483,14 @@ export class CompositeActionItem extends ActivityActionItem {
|
||||||
this._updateChecked();
|
this._updateChecked();
|
||||||
this._updateEnabled();
|
this._updateEnabled();
|
||||||
|
|
||||||
this.callOnDispose.push(dom.addDisposableListener(this.$container, dom.EventType.CONTEXT_MENU, e => {
|
this._register(dom.addDisposableListener(this.container, dom.EventType.CONTEXT_MENU, e => {
|
||||||
dom.EventHelper.stop(e, true);
|
dom.EventHelper.stop(e, true);
|
||||||
|
|
||||||
this.showContextMenu(container);
|
this.showContextMenu(container);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Allow to drag
|
// Allow to drag
|
||||||
this.callOnDispose.push(dom.addDisposableListener(this.$container, dom.EventType.DRAG_START, (e: DragEvent) => {
|
this._register(dom.addDisposableListener(this.container, dom.EventType.DRAG_START, (e: DragEvent) => {
|
||||||
e.dataTransfer.effectAllowed = 'move';
|
e.dataTransfer.effectAllowed = 'move';
|
||||||
|
|
||||||
// Registe as dragged to local transfer
|
// Registe as dragged to local transfer
|
||||||
|
@ -502,7 +502,7 @@ export class CompositeActionItem extends ActivityActionItem {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.callOnDispose.push(new DragAndDropObserver(this.$container, {
|
this._register(new DragAndDropObserver(this.container, {
|
||||||
onDragEnter: e => {
|
onDragEnter: e => {
|
||||||
if (this.compositeTransfer.hasData(DraggedCompositeIdentifier.prototype) && this.compositeTransfer.getData(DraggedCompositeIdentifier.prototype)[0].id !== this.activity.id) {
|
if (this.compositeTransfer.hasData(DraggedCompositeIdentifier.prototype) && this.compositeTransfer.getData(DraggedCompositeIdentifier.prototype)[0].id !== this.activity.id) {
|
||||||
this.updateFromDragging(container, true);
|
this.updateFromDragging(container, true);
|
||||||
|
@ -539,7 +539,7 @@ export class CompositeActionItem extends ActivityActionItem {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Activate on drag over to reveal targets
|
// Activate on drag over to reveal targets
|
||||||
[this.$badge, this.$label].forEach(b => new DelayedDragHandler(b, () => {
|
[this.badge, this.label].forEach(b => new DelayedDragHandler(b, () => {
|
||||||
if (!this.compositeTransfer.hasData(DraggedCompositeIdentifier.prototype) && !this.getAction().checked) {
|
if (!this.compositeTransfer.hasData(DraggedCompositeIdentifier.prototype) && !this.getAction().checked) {
|
||||||
this.getAction().run();
|
this.getAction().run();
|
||||||
}
|
}
|
||||||
|
@ -578,35 +578,35 @@ export class CompositeActionItem extends ActivityActionItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
focus(): void {
|
focus(): void {
|
||||||
this.$container.focus();
|
this.container.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _updateClass(): void {
|
protected _updateClass(): void {
|
||||||
if (this.cssClass) {
|
if (this.cssClass) {
|
||||||
dom.removeClasses(this.$label, this.cssClass);
|
dom.removeClasses(this.label, this.cssClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cssClass = this.getAction().class;
|
this.cssClass = this.getAction().class;
|
||||||
if (this.cssClass) {
|
if (this.cssClass) {
|
||||||
dom.addClasses(this.$label, this.cssClass);
|
dom.addClasses(this.label, this.cssClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _updateChecked(): void {
|
protected _updateChecked(): void {
|
||||||
if (this.getAction().checked) {
|
if (this.getAction().checked) {
|
||||||
dom.addClass(this.$container, 'checked');
|
dom.addClass(this.container, 'checked');
|
||||||
this.$container.setAttribute('aria-label', nls.localize('compositeActive', "{0} active", this.$container.title));
|
this.container.setAttribute('aria-label', nls.localize('compositeActive', "{0} active", this.container.title));
|
||||||
} else {
|
} else {
|
||||||
dom.removeClass(this.$container, 'checked');
|
dom.removeClass(this.container, 'checked');
|
||||||
this.$container.setAttribute('aria-label', this.$container.title);
|
this.container.setAttribute('aria-label', this.container.title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _updateEnabled(): void {
|
protected _updateEnabled(): void {
|
||||||
if (this.getAction().enabled) {
|
if (this.getAction().enabled) {
|
||||||
dom.removeClass(this.builder, 'disabled');
|
dom.removeClass(this.element, 'disabled');
|
||||||
} else {
|
} else {
|
||||||
dom.addClass(this.builder, 'disabled');
|
dom.addClass(this.element, 'disabled');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,7 +615,7 @@ export class CompositeActionItem extends ActivityActionItem {
|
||||||
|
|
||||||
this.compositeTransfer.clearData(DraggedCompositeIdentifier.prototype);
|
this.compositeTransfer.clearData(DraggedCompositeIdentifier.prototype);
|
||||||
|
|
||||||
dom.removeNode(this.$label);
|
dom.removeNode(this.label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,9 +106,9 @@ export class NotificationsCenter extends Themable {
|
||||||
|
|
||||||
private updateTitle(): void {
|
private updateTitle(): void {
|
||||||
if (this.model.notifications.length === 0) {
|
if (this.model.notifications.length === 0) {
|
||||||
this.notificationsCenterTitle.innerText = localize('notificationsEmpty', "No new notifications");
|
this.notificationsCenterTitle.textContent = localize('notificationsEmpty', "No new notifications");
|
||||||
} else {
|
} else {
|
||||||
this.notificationsCenterTitle.innerText = localize('notifications', "Notifications");
|
this.notificationsCenterTitle.textContent = localize('notifications', "Notifications");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -426,10 +426,10 @@ export class NotificationTemplateRenderer {
|
||||||
|
|
||||||
private renderSource(notification): void {
|
private renderSource(notification): void {
|
||||||
if (notification.expanded && notification.source) {
|
if (notification.expanded && notification.source) {
|
||||||
this.template.source.innerText = localize('notificationSource', "Source: {0}", notification.source);
|
this.template.source.textContent = localize('notificationSource', "Source: {0}", notification.source);
|
||||||
this.template.source.title = notification.source;
|
this.template.source.title = notification.source;
|
||||||
} else {
|
} else {
|
||||||
this.template.source.innerText = '';
|
this.template.source.textContent = '';
|
||||||
this.template.source.removeAttribute('title');
|
this.template.source.removeAttribute('title');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,10 @@ import * as paths from 'vs/base/common/paths';
|
||||||
import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||||
import { IFileService } from 'vs/platform/files/common/files';
|
import { IFileService } from 'vs/platform/files/common/files';
|
||||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
import { Schemas } from 'vs/base/common/network';
|
import { Schemas } from 'vs/base/common/network';
|
||||||
|
|
||||||
export class ResourceContextKey implements IContextKey<URI>, IDisposable {
|
export class ResourceContextKey extends Disposable implements IContextKey<URI> {
|
||||||
|
|
||||||
static Scheme = new RawContextKey<string>('resourceScheme', undefined);
|
static Scheme = new RawContextKey<string>('resourceScheme', undefined);
|
||||||
static Filename = new RawContextKey<string>('resourceFilename', undefined);
|
static Filename = new RawContextKey<string>('resourceFilename', undefined);
|
||||||
|
@ -32,13 +32,14 @@ export class ResourceContextKey implements IContextKey<URI>, IDisposable {
|
||||||
private _hasResource: IContextKey<boolean>;
|
private _hasResource: IContextKey<boolean>;
|
||||||
private _isfileSystemResource: IContextKey<boolean>;
|
private _isfileSystemResource: IContextKey<boolean>;
|
||||||
private _isFileSystemResourceOrUntitled: IContextKey<boolean>;
|
private _isFileSystemResourceOrUntitled: IContextKey<boolean>;
|
||||||
private toDispose: IDisposable[] = [];
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@IContextKeyService contextKeyService: IContextKeyService,
|
@IContextKeyService contextKeyService: IContextKeyService,
|
||||||
@IFileService private readonly _fileService: IFileService,
|
@IFileService private readonly _fileService: IFileService,
|
||||||
@IModeService private readonly _modeService: IModeService
|
@IModeService private readonly _modeService: IModeService
|
||||||
) {
|
) {
|
||||||
|
super();
|
||||||
|
|
||||||
this._schemeKey = ResourceContextKey.Scheme.bindTo(contextKeyService);
|
this._schemeKey = ResourceContextKey.Scheme.bindTo(contextKeyService);
|
||||||
this._filenameKey = ResourceContextKey.Filename.bindTo(contextKeyService);
|
this._filenameKey = ResourceContextKey.Filename.bindTo(contextKeyService);
|
||||||
this._langIdKey = ResourceContextKey.LangId.bindTo(contextKeyService);
|
this._langIdKey = ResourceContextKey.LangId.bindTo(contextKeyService);
|
||||||
|
@ -47,7 +48,8 @@ export class ResourceContextKey implements IContextKey<URI>, IDisposable {
|
||||||
this._hasResource = ResourceContextKey.HasResource.bindTo(contextKeyService);
|
this._hasResource = ResourceContextKey.HasResource.bindTo(contextKeyService);
|
||||||
this._isfileSystemResource = ResourceContextKey.IsFileSystemResource.bindTo(contextKeyService);
|
this._isfileSystemResource = ResourceContextKey.IsFileSystemResource.bindTo(contextKeyService);
|
||||||
this._isFileSystemResourceOrUntitled = ResourceContextKey.IsFileSystemResourceOrUntitled.bindTo(contextKeyService);
|
this._isFileSystemResourceOrUntitled = ResourceContextKey.IsFileSystemResourceOrUntitled.bindTo(contextKeyService);
|
||||||
this.toDispose.push(_fileService.onDidChangeFileSystemProviderRegistrations(() => {
|
|
||||||
|
this._register(_fileService.onDidChangeFileSystemProviderRegistrations(() => {
|
||||||
const resource = this._resourceKey.get();
|
const resource = this._resourceKey.get();
|
||||||
this._isfileSystemResource.set(resource && _fileService.canHandleResource(resource));
|
this._isfileSystemResource.set(resource && _fileService.canHandleResource(resource));
|
||||||
this._isFileSystemResourceOrUntitled.set(this._isfileSystemResource.get() || this._schemeKey.get() === Schemas.untitled);
|
this._isFileSystemResourceOrUntitled.set(this._isfileSystemResource.get() || this._schemeKey.get() === Schemas.untitled);
|
||||||
|
@ -77,10 +79,6 @@ export class ResourceContextKey implements IContextKey<URI>, IDisposable {
|
||||||
get(): URI {
|
get(): URI {
|
||||||
return this._resourceKey.get();
|
return this._resourceKey.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
dispose(): void {
|
|
||||||
this.toDispose = dispose(this.toDispose);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -377,7 +377,7 @@ export class DropDownMenuActionItem extends ActionItem {
|
||||||
|
|
||||||
public showMenu(): void {
|
public showMenu(): void {
|
||||||
const actions = this.getActions();
|
const actions = this.getActions();
|
||||||
let elementPosition = DOM.getDomNodePagePosition(this.builder);
|
let elementPosition = DOM.getDomNodePagePosition(this.element);
|
||||||
const anchor = { x: elementPosition.left, y: elementPosition.top + elementPosition.height + 10 };
|
const anchor = { x: elementPosition.left, y: elementPosition.top + elementPosition.height + 10 };
|
||||||
this.contextMenuService.showContextMenu({
|
this.contextMenuService.showContextMenu({
|
||||||
getAnchor: () => anchor,
|
getAnchor: () => anchor,
|
||||||
|
|
|
@ -93,14 +93,12 @@ export interface IMarkersFilterActionItemOptions {
|
||||||
|
|
||||||
export class MarkersFilterActionItem extends BaseActionItem {
|
export class MarkersFilterActionItem extends BaseActionItem {
|
||||||
|
|
||||||
private _toDispose: IDisposable[] = [];
|
|
||||||
|
|
||||||
private readonly _onDidChange: Emitter<void> = this._register(new Emitter<void>());
|
private readonly _onDidChange: Emitter<void> = this._register(new Emitter<void>());
|
||||||
readonly onDidChange: Event<void> = this._onDidChange.event;
|
readonly onDidChange: Event<void> = this._onDidChange.event;
|
||||||
|
|
||||||
private delayedFilterUpdate: Delayer<void>;
|
private delayedFilterUpdate: Delayer<void>;
|
||||||
private container: HTMLElement;
|
private container: HTMLElement;
|
||||||
private element: HTMLElement;
|
private filterContainer: HTMLElement;
|
||||||
private filterInputBox: HistoryInputBox;
|
private filterInputBox: HistoryInputBox;
|
||||||
private controlsContainer: HTMLInputElement;
|
private controlsContainer: HTMLInputElement;
|
||||||
private filterBadge: HTMLInputElement;
|
private filterBadge: HTMLInputElement;
|
||||||
|
@ -123,7 +121,7 @@ export class MarkersFilterActionItem extends BaseActionItem {
|
||||||
render(container: HTMLElement): void {
|
render(container: HTMLElement): void {
|
||||||
this.container = container;
|
this.container = container;
|
||||||
DOM.addClass(this.container, 'markers-panel-action-filter-container');
|
DOM.addClass(this.container, 'markers-panel-action-filter-container');
|
||||||
DOM.append(this.container, this.element);
|
DOM.append(this.container, this.filterContainer);
|
||||||
this.adjustInputBox();
|
this.adjustInputBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,9 +155,9 @@ export class MarkersFilterActionItem extends BaseActionItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
private create(itemOptions: IMarkersFilterActionItemOptions): void {
|
private create(itemOptions: IMarkersFilterActionItemOptions): void {
|
||||||
this.element = DOM.$('.markers-panel-action-filter');
|
this.filterContainer = DOM.$('.markers-panel-action-filter');
|
||||||
this.createInput(this.element, itemOptions);
|
this.createInput(this.filterContainer, itemOptions);
|
||||||
this.createControls(this.element, itemOptions);
|
this.createControls(this.filterContainer, itemOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private createInput(container: HTMLElement, itemOptions: IMarkersFilterActionItemOptions): void {
|
private createInput(container: HTMLElement, itemOptions: IMarkersFilterActionItemOptions): void {
|
||||||
|
@ -271,11 +269,6 @@ export class MarkersFilterActionItem extends BaseActionItem {
|
||||||
*/
|
*/
|
||||||
this.telemetryService.publicLog('problems.filter', data);
|
this.telemetryService.publicLog('problems.filter', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _register<T extends IDisposable>(t: T): T {
|
|
||||||
this._toDispose.push(t);
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class QuickFixAction extends Action {
|
export class QuickFixAction extends Action {
|
||||||
|
@ -354,7 +347,7 @@ export class QuickFixActionItem extends ActionItem {
|
||||||
|
|
||||||
public onClick(event: DOM.EventLike): void {
|
public onClick(event: DOM.EventLike): void {
|
||||||
DOM.EventHelper.stop(event, true);
|
DOM.EventHelper.stop(event, true);
|
||||||
const elementPosition = DOM.getDomNodePagePosition(this.builder);
|
const elementPosition = DOM.getDomNodePagePosition(this.element);
|
||||||
this.contextMenuService.showContextMenu({
|
this.contextMenuService.showContextMenu({
|
||||||
getAnchor: () => ({ x: elementPosition.left + 10, y: elementPosition.top + elementPosition.height }),
|
getAnchor: () => ({ x: elementPosition.left + 10, y: elementPosition.top + elementPosition.height }),
|
||||||
getActions: () => TPromise.wrap((<QuickFixAction>this.getAction()).getQuickFixActions()),
|
getActions: () => TPromise.wrap((<QuickFixAction>this.getAction()).getQuickFixActions()),
|
||||||
|
|
|
@ -317,7 +317,7 @@ export class FolderSettingsActionItem extends BaseActionItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(container: HTMLElement): void {
|
public render(container: HTMLElement): void {
|
||||||
this.builder = container;
|
this.element = container;
|
||||||
|
|
||||||
this.container = container;
|
this.container = container;
|
||||||
this.labelElement = DOM.$('.action-title');
|
this.labelElement = DOM.$('.action-title');
|
||||||
|
|
|
@ -109,7 +109,7 @@ class StatusBarActionItem extends ActionItem {
|
||||||
|
|
||||||
_updateLabel(): void {
|
_updateLabel(): void {
|
||||||
if (this.options.label) {
|
if (this.options.label) {
|
||||||
this.$e.innerHTML = renderOcticons(this.getAction().label);
|
this.label.innerHTML = renderOcticons(this.getAction().label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue