Merge from master

This commit is contained in:
Raj Musuku
2019-02-21 17:56:04 -08:00
parent 5a146e34fa
commit 666ae11639
11482 changed files with 119352 additions and 255574 deletions

View File

@@ -28,10 +28,6 @@
.monaco-action-bar .action-item {
cursor: pointer;
display: inline-block;
-ms-transition: -ms-transform 50ms ease;
-webkit-transition: -webkit-transform 50ms ease;
-moz-transition: -moz-transform 50ms ease;
-o-transition: -o-transform 50ms ease;
transition: transform 50ms ease;
position: relative; /* DO NOT REMOVE - this is the key to preventing the ghosting icon bug in Chrome 42 */
}
@@ -41,11 +37,7 @@
}
.monaco-action-bar.animated .action-item.active {
-ms-transform: scale(1.272019649, 1.272019649); /* 1.272019649 = √φ */
-webkit-transform: scale(1.272019649, 1.272019649);
-moz-transform: scale(1.272019649, 1.272019649);
-o-transform: scale(1.272019649, 1.272019649);
transform: scale(1.272019649, 1.272019649);
transform: scale(1.272019649, 1.272019649); /* 1.272019649 = √φ */
}
.monaco-action-bar .action-item .icon {
@@ -87,10 +79,6 @@
}
.monaco-action-bar.animated.vertical .action-item.active {
-ms-transform: translate(5px, 0);
-webkit-transform: translate(5px, 0);
-moz-transform: translate(5px, 0);
-o-transform: translate(5px, 0);
transform: translate(5px, 0);
}

View File

@@ -3,14 +3,10 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import 'vs/css!./actionbar';
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 { Disposable, dispose } from 'vs/base/common/lifecycle';
import { SelectBox, ISelectBoxOptions } from 'vs/base/browser/ui/selectBox/selectBox';
import { IAction, IActionRunner, Action, IActionChangeEvent, ActionRunner, IRunEvent } from 'vs/base/common/actions';
import * as DOM from 'vs/base/browser/dom';
@@ -36,77 +32,78 @@ export interface IBaseActionItemOptions {
isMenu?: boolean;
}
export class BaseActionItem implements IActionItem {
export class BaseActionItem extends Disposable implements IActionItem {
public builder: Builder;
public _callOnDispose: lifecycle.IDisposable[];
public _context: any;
public _action: IAction;
element?: HTMLElement;
_context: any;
_action: IAction;
private _actionRunner: IActionRunner;
constructor(context: any, action: IAction, protected options?: IBaseActionItemOptions) {
this._callOnDispose = [];
super();
this._context = context || this;
this._action = action;
if (action instanceof Action) {
this._callOnDispose.push(action.onDidChange(event => {
if (!this.builder) {
this._register(action.onDidChange(event => {
if (!this.element) {
// we have not been rendered yet, so there
// is no point in updating the UI
return;
}
this._handleActionChangeEvent(event);
this.handleActionChangeEvent(event);
}));
}
}
protected _handleActionChangeEvent(event: IActionChangeEvent): void {
private handleActionChangeEvent(event: IActionChangeEvent): void {
if (event.enabled !== void 0) {
this._updateEnabled();
this.updateEnabled();
}
if (event.checked !== void 0) {
this._updateChecked();
this.updateChecked();
}
if (event.class !== void 0) {
this._updateClass();
this.updateClass();
}
if (event.label !== void 0) {
this._updateLabel();
this._updateTooltip();
this.updateLabel();
this.updateTooltip();
}
if (event.tooltip !== void 0) {
this._updateTooltip();
this.updateTooltip();
}
}
public get callOnDispose() {
return this._callOnDispose;
}
public set actionRunner(actionRunner: IActionRunner) {
set actionRunner(actionRunner: IActionRunner) {
this._actionRunner = actionRunner;
}
public get actionRunner(): IActionRunner {
get actionRunner(): IActionRunner {
return this._actionRunner;
}
public getAction(): IAction {
getAction(): IAction {
return this._action;
}
public isEnabled(): boolean {
isEnabled(): boolean {
return this._action.enabled;
}
public setActionContext(newContext: any): void {
setActionContext(newContext: any): void {
this._context = newContext;
}
public render(container: HTMLElement): void {
this.builder = $(container);
render(container: HTMLElement): void {
this.element = container;
Gesture.addTarget(container);
const enableDragging = this.options && this.options.draggable;
@@ -114,20 +111,19 @@ export class BaseActionItem implements IActionItem {
container.draggable = true;
}
this.builder.on(EventType.Tap, e => this.onClick(e));
this._register(DOM.addDisposableListener(this.element, EventType.Tap, e => this.onClick(e)));
this.builder.on(DOM.EventType.MOUSE_DOWN, (e) => {
this._register(DOM.addDisposableListener(this.element, DOM.EventType.MOUSE_DOWN, e => {
if (!enableDragging) {
DOM.EventHelper.stop(e, true); // do not run when dragging is on because that would disable it
}
const mouseEvent = e as MouseEvent;
if (this._action.enabled && mouseEvent.button === 0) {
this.builder.addClass('active');
if (this._action.enabled && e.button === 0 && this.element) {
DOM.addClass(this.element, 'active');
}
});
}));
this.builder.on(DOM.EventType.CLICK, (e) => {
this._register(DOM.addDisposableListener(this.element, DOM.EventType.CLICK, e => {
DOM.EventHelper.stop(e, true);
// See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Interact_with_the_clipboard
// > Writing to the clipboard
@@ -142,82 +138,90 @@ export class BaseActionItem implements IActionItem {
} else {
platform.setImmediate(() => this.onClick(e));
}
});
}));
this.builder.on([DOM.EventType.MOUSE_UP, DOM.EventType.MOUSE_OUT], (e) => {
DOM.EventHelper.stop(e);
this.builder.removeClass('active');
this._register(DOM.addDisposableListener(this.element, DOM.EventType.DBLCLICK, e => {
DOM.EventHelper.stop(e, true);
}));
[DOM.EventType.MOUSE_UP, DOM.EventType.MOUSE_OUT].forEach(event => {
this._register(DOM.addDisposableListener(this.element!, event, e => {
DOM.EventHelper.stop(e);
DOM.removeClass(this.element!, 'active');
}));
});
}
public onClick(event: DOM.EventLike): void {
onClick(event: DOM.EventLike): void {
DOM.EventHelper.stop(event, true);
let context: any;
if (types.isUndefinedOrNull(this._context) || !types.isObject(this._context)) {
if (types.isUndefinedOrNull(this._context)) {
context = event;
} else {
context = this._context;
context.event = event;
if (types.isObject(context)) {
context.event = event;
}
}
this._actionRunner.run(this._action, context);
}
public focus(): void {
if (this.builder) {
this.builder.domFocus();
this.builder.addClass('focused');
focus(): void {
if (this.element) {
this.element.focus();
DOM.addClass(this.element, 'focused');
}
}
public blur(): void {
if (this.builder) {
this.builder.domBlur();
this.builder.removeClass('focused');
blur(): void {
if (this.element) {
this.element.blur();
DOM.removeClass(this.element, 'focused');
}
}
protected _updateEnabled(): void {
protected updateEnabled(): void {
// implement in subclass
}
protected _updateLabel(): void {
protected updateLabel(): void {
// implement in subclass
}
protected _updateTooltip(): void {
protected updateTooltip(): void {
// implement in subclass
}
protected _updateClass(): void {
protected updateClass(): void {
// implement in subclass
}
protected _updateChecked(): void {
protected updateChecked(): void {
// implement in subclass
}
public dispose(): void {
if (this.builder) {
this.builder.destroy();
this.builder = null;
dispose(): void {
if (this.element) {
DOM.removeNode(this.element);
this.element = undefined;
}
this._callOnDispose = lifecycle.dispose(this._callOnDispose);
super.dispose();
}
}
export class Separator extends Action {
public static readonly ID = 'vs.actions.separator';
static readonly ID = 'vs.actions.separator';
constructor(label?: string, order?: number) {
constructor(label?: string) {
super(Separator.ID, label, label ? 'separator text' : 'separator');
this.checked = false;
this.radio = false;
this.enabled = false;
this.order = order;
}
}
@@ -229,9 +233,10 @@ export interface IActionItemOptions extends IBaseActionItemOptions {
export class ActionItem extends BaseActionItem {
protected $e: Builder;
protected label: HTMLElement;
protected options: IActionItemOptions;
private cssClass: string;
private cssClass?: string;
constructor(context: any, action: IAction, options: IActionItemOptions = {}) {
super(context, action, options);
@@ -242,45 +247,47 @@ export class ActionItem extends BaseActionItem {
this.cssClass = '';
}
public render(container: HTMLElement): void {
render(container: HTMLElement): void {
super.render(container);
this.$e = $('a.action-label').appendTo(this.builder);
if (this.element) {
this.label = DOM.append(this.element, DOM.$('a.action-label'));
}
if (this._action.id === Separator.ID) {
// A separator is a presentation item
this.$e.attr({ role: 'presentation' });
this.label.setAttribute('role', 'presentation'); // A separator is a presentation item
} else {
if (this.options.isMenu) {
this.$e.attr({ role: 'menuitem' });
this.label.setAttribute('role', 'menuitem');
} else {
this.$e.attr({ role: 'button' });
this.label.setAttribute('role', 'button');
}
}
if (this.options.label && this.options.keybinding) {
$('span.keybinding').text(this.options.keybinding).appendTo(this.builder);
if (this.options.label && this.options.keybinding && this.element) {
DOM.append(this.element, DOM.$('span.keybinding')).textContent = this.options.keybinding;
}
this._updateClass();
this._updateLabel();
this._updateTooltip();
this._updateEnabled();
this._updateChecked();
this.updateClass();
this.updateLabel();
this.updateTooltip();
this.updateEnabled();
this.updateChecked();
}
public focus(): void {
focus(): void {
super.focus();
this.$e.domFocus();
this.label.focus();
}
public _updateLabel(): void {
updateLabel(): void {
if (this.options.label) {
this.$e.text(this.getAction().label);
this.label.textContent = this.getAction().label;
}
}
public _updateTooltip(): void {
let title: string = null;
updateTooltip(): void {
let title: string | null = null;
if (this.getAction().tooltip) {
title = this.getAction().tooltip;
@@ -294,54 +301,67 @@ export class ActionItem extends BaseActionItem {
}
if (title) {
this.$e.attr({ title: title });
this.label.title = title;
}
}
public _updateClass(): void {
updateClass(): void {
if (this.cssClass) {
this.$e.removeClass(this.cssClass);
DOM.removeClasses(this.label, this.cssClass);
}
if (this.options.icon) {
this.cssClass = this.getAction().class;
this.$e.addClass('icon');
DOM.addClass(this.label, 'icon');
if (this.cssClass) {
this.$e.addClass(this.cssClass);
DOM.addClasses(this.label, this.cssClass);
}
this._updateEnabled();
this.updateEnabled();
} else {
this.$e.removeClass('icon');
DOM.removeClass(this.label, 'icon');
}
}
public _updateEnabled(): void {
updateEnabled(): void {
if (this.getAction().enabled) {
this.builder.removeClass('disabled');
this.$e.removeClass('disabled');
this.$e.attr({ tabindex: 0 });
this.label.removeAttribute('aria-disabled');
if (this.element) {
DOM.removeClass(this.element, 'disabled');
}
DOM.removeClass(this.label, 'disabled');
this.label.tabIndex = 0;
} else {
this.builder.addClass('disabled');
this.$e.addClass('disabled');
DOM.removeTabIndexAndUpdateFocus(this.$e.getHTMLElement());
this.label.setAttribute('aria-disabled', 'true');
if (this.element) {
DOM.addClass(this.element, 'disabled');
}
DOM.addClass(this.label, 'disabled');
DOM.removeTabIndexAndUpdateFocus(this.label);
}
}
public _updateChecked(): void {
updateChecked(): void {
if (this.getAction().checked) {
this.$e.addClass('checked');
DOM.addClass(this.label, 'checked');
} else {
this.$e.removeClass('checked');
DOM.removeClass(this.label, 'checked');
}
}
}
export enum ActionsOrientation {
export const enum ActionsOrientation {
HORIZONTAL,
HORIZONTAL_REVERSE,
VERTICAL,
VERTICAL_REVERSE,
}
export interface ActionTrigger {
keys: KeyCode[];
keyDown: boolean;
}
export interface IActionItemProvider {
(action: IAction): IActionItem;
}
@@ -353,54 +373,69 @@ export interface IActionBarOptions {
actionRunner?: IActionRunner;
ariaLabel?: string;
animated?: boolean;
isMenu?: boolean;
triggerKeys?: ActionTrigger;
}
let defaultOptions: IActionBarOptions = {
orientation: ActionsOrientation.HORIZONTAL,
context: null
context: null,
triggerKeys: {
keys: [KeyCode.Enter, KeyCode.Space],
keyDown: false
}
};
export interface IActionOptions extends IActionItemOptions {
index?: number;
}
export class ActionBar implements IActionRunner {
export class ActionBar extends Disposable implements IActionRunner {
public options: IActionBarOptions;
options: IActionBarOptions;
private _actionRunner: IActionRunner;
private _context: any;
// Items
public items: IActionItem[];
private focusedItem: number;
items: IActionItem[];
protected focusedItem?: number;
private focusTracker: DOM.IFocusTracker;
// Elements
public domNode: HTMLElement;
private actionsList: HTMLElement;
domNode: HTMLElement;
protected actionsList: HTMLElement;
private toDispose: lifecycle.IDisposable[];
private _onDidBlur = this._register(new Emitter<void>());
get onDidBlur(): Event<void> { return this._onDidBlur.event; }
private _onDidBlur = new Emitter<void>();
private _onDidCancel = new Emitter<void>();
private _onDidRun = new Emitter<IRunEvent>();
private _onDidBeforeRun = new Emitter<IRunEvent>();
private _onDidCancel = this._register(new Emitter<void>());
get onDidCancel(): Event<void> { return this._onDidCancel.event; }
private _onDidRun = this._register(new Emitter<IRunEvent>());
get onDidRun(): Event<IRunEvent> { return this._onDidRun.event; }
private _onDidBeforeRun = this._register(new Emitter<IRunEvent>());
get onDidBeforeRun(): Event<IRunEvent> { return this._onDidBeforeRun.event; }
constructor(container: HTMLElement, options: IActionBarOptions = defaultOptions) {
super();
this.options = options;
this._context = options.context;
this.toDispose = [];
this._actionRunner = this.options.actionRunner;
if (!this._actionRunner) {
this._actionRunner = new ActionRunner();
this.toDispose.push(this._actionRunner);
if (!this.options.triggerKeys) {
this.options.triggerKeys = defaultOptions.triggerKeys;
}
this.toDispose.push(this._actionRunner.onDidRun(e => this._onDidRun.fire(e)));
this.toDispose.push(this._actionRunner.onDidBeforeRun(e => this._onDidBeforeRun.fire(e)));
if (this.options.actionRunner) {
this._actionRunner = this.options.actionRunner;
} else {
this._actionRunner = new ActionRunner();
this._register(this._actionRunner);
}
this._register(this._actionRunner.onDidRun(e => this._onDidRun.fire(e)));
this._register(this._actionRunner.onDidBeforeRun(e => this._onDidBeforeRun.fire(e)));
this.items = [];
this.focusedItem = undefined;
@@ -437,8 +472,8 @@ export class ActionBar implements IActionRunner {
break;
}
$(this.domNode).on(DOM.EventType.KEY_DOWN, (e) => {
let event = new StandardKeyboardEvent(e as KeyboardEvent);
this._register(DOM.addDisposableListener(this.domNode, DOM.EventType.KEY_DOWN, e => {
let event = new StandardKeyboardEvent(e);
let eventHandled = true;
if (event.equals(previousKey)) {
@@ -447,8 +482,11 @@ export class ActionBar implements IActionRunner {
this.focusNext();
} else if (event.equals(KeyCode.Escape)) {
this.cancel();
} else if (event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) {
// Nothing, just staying out of the else branch
} else if (this.isTriggerKeyEvent(event)) {
// Staying out of the else branch even if not triggered
if (this.options.triggerKeys && this.options.triggerKeys.keyDown) {
this.doTrigger(event);
}
} else {
eventHandled = false;
}
@@ -457,14 +495,17 @@ export class ActionBar implements IActionRunner {
event.preventDefault();
event.stopPropagation();
}
});
}));
$(this.domNode).on(DOM.EventType.KEY_UP, (e) => {
let event = new StandardKeyboardEvent(e as KeyboardEvent);
this._register(DOM.addDisposableListener(this.domNode, DOM.EventType.KEY_UP, e => {
let event = new StandardKeyboardEvent(e);
// Run action on Enter/Space
if (event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) {
this.doTrigger(event);
if (this.isTriggerKeyEvent(event)) {
if (this.options.triggerKeys && !this.options.triggerKeys.keyDown) {
this.doTrigger(event);
}
event.preventDefault();
event.stopPropagation();
}
@@ -473,84 +514,32 @@ export class ActionBar implements IActionRunner {
else if (event.equals(KeyCode.Tab) || event.equals(KeyMod.Shift | KeyCode.Tab)) {
this.updateFocusedItem();
}
});
}));
this.focusTracker = DOM.trackFocus(this.domNode);
this.toDispose.push(this.focusTracker.onDidBlur(() => {
this.focusTracker = this._register(DOM.trackFocus(this.domNode));
this._register(this.focusTracker.onDidBlur(() => {
if (document.activeElement === this.domNode || !DOM.isAncestor(document.activeElement, this.domNode)) {
this._onDidBlur.fire();
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.className = 'actions-container';
if (this.options.isMenu) {
this.actionsList.setAttribute('role', 'menu');
} else {
this.actionsList.setAttribute('role', 'toolbar');
}
this.actionsList.setAttribute('role', 'toolbar');
if (this.options.ariaLabel) {
this.actionsList.setAttribute('aria-label', this.options.ariaLabel);
}
if (this.options.isMenu) {
this.domNode.tabIndex = 0;
$(this.domNode).on(DOM.EventType.MOUSE_OUT, (e) => {
let relatedTarget = (e as MouseEvent).relatedTarget as HTMLElement;
if (!DOM.isAncestor(relatedTarget, this.domNode)) {
this.focusedItem = undefined;
this.updateFocus();
e.stopPropagation();
}
});
$(this.actionsList).on(DOM.EventType.MOUSE_OVER, (e) => {
let target = e.target as HTMLElement;
if (!target || !DOM.isAncestor(target, this.actionsList) || target === this.actionsList) {
return;
}
while (target.parentElement !== this.actionsList) {
target = target.parentElement;
}
if (DOM.hasClass(target, 'action-item')) {
const lastFocusedItem = this.focusedItem;
this.setFocusedItem(target);
if (lastFocusedItem !== this.focusedItem) {
this.updateFocus();
}
}
});
}
this.domNode.appendChild(this.actionsList);
container.appendChild(this.domNode);
}
public get onDidBlur(): Event<void> {
return this._onDidBlur.event;
}
public get onDidCancel(): Event<void> {
return this._onDidCancel.event;
}
public get onDidRun(): Event<IRunEvent> {
return this._onDidRun.event;
}
public get onDidBeforeRun(): Event<IRunEvent> {
return this._onDidBeforeRun.event;
}
public setAriaLabel(label: string): void {
setAriaLabel(label: string): void {
if (label) {
this.actionsList.setAttribute('aria-label', label);
} else {
@@ -558,14 +547,15 @@ export class ActionBar implements IActionRunner {
}
}
private setFocusedItem(element: HTMLElement): void {
for (let i = 0; i < this.actionsList.children.length; i++) {
let elem = this.actionsList.children[i];
if (element === elem) {
this.focusedItem = i;
break;
}
private isTriggerKeyEvent(event: StandardKeyboardEvent): boolean {
let ret = false;
if (this.options.triggerKeys) {
this.options.triggerKeys.keys.forEach(keyCode => {
ret = ret || event.equals(keyCode);
});
}
return ret;
}
private updateFocusedItem(): void {
@@ -578,32 +568,31 @@ export class ActionBar implements IActionRunner {
}
}
public get context(): any {
get context(): any {
return this._context;
}
public set context(context: any) {
set context(context: any) {
this._context = context;
this.items.forEach(i => i.setActionContext(context));
}
public get actionRunner(): IActionRunner {
get actionRunner(): IActionRunner | undefined {
return this._actionRunner;
}
public set actionRunner(actionRunner: IActionRunner) {
set actionRunner(actionRunner: IActionRunner | undefined) {
if (actionRunner) {
this._actionRunner = actionRunner;
this.items.forEach(item => item.actionRunner = actionRunner);
}
}
public getContainer(): HTMLElement {
getContainer(): HTMLElement {
return this.domNode;
}
public push(arg: IAction | IAction[], options: IActionOptions = {}): void {
push(arg: IAction | IAction[], options: IActionOptions = {}): void {
const actions: IAction[] = !Array.isArray(arg) ? [arg] : arg;
let index = types.isNumber(options.index) ? options.index : null;
@@ -614,12 +603,12 @@ export class ActionBar implements IActionRunner {
actionItemElement.setAttribute('role', 'presentation');
// Prevent native context menu on actions
$(actionItemElement).on(DOM.EventType.CONTEXT_MENU, (e: DOM.EventLike) => {
this._register(DOM.addDisposableListener(actionItemElement, DOM.EventType.CONTEXT_MENU, (e: DOM.EventLike) => {
e.preventDefault();
e.stopPropagation();
});
}));
let item: IActionItem = null;
let item: IActionItem | null = null;
if (this.options.actionItemProvider) {
item = this.options.actionItemProvider(action);
@@ -641,52 +630,73 @@ export class ActionBar implements IActionRunner {
this.items.splice(index, 0, item);
index++;
}
});
}
public getWidth(index: number): number {
getWidth(index: number): number {
if (index >= 0 && index < this.actionsList.children.length) {
return this.actionsList.children.item(index).clientWidth;
const item = this.actionsList.children.item(index);
if (item) {
return item.clientWidth;
}
}
return 0;
}
public getHeight(index: number): number {
getHeight(index: number): number {
if (index >= 0 && index < this.actionsList.children.length) {
return this.actionsList.children.item(index).clientHeight;
const item = this.actionsList.children.item(index);
if (item) {
return item.clientHeight;
}
}
return 0;
}
public pull(index: number): void {
pull(index: number): void {
if (index >= 0 && index < this.items.length) {
this.items.splice(index, 1);
this.actionsList.removeChild(this.actionsList.childNodes[index]);
}
}
public clear(): void {
this.items = lifecycle.dispose(this.items);
$(this.actionsList).empty();
clear(): void {
this.items = dispose(this.items);
DOM.clearNode(this.actionsList);
}
public length(): number {
length(): number {
return this.items.length;
}
public isEmpty(): boolean {
isEmpty(): boolean {
return this.items.length === 0;
}
public focus(selectFirst?: boolean): void {
focus(index?: number): void;
focus(selectFirst?: boolean): void;
focus(arg?: any): void {
let selectFirst: boolean = false;
let index: number | undefined = void 0;
if (arg === undefined) {
selectFirst = true;
} else if (typeof arg === 'number') {
index = arg;
} else if (typeof arg === 'boolean') {
selectFirst = arg;
}
if (selectFirst && typeof this.focusedItem === 'undefined') {
// Focus the first enabled item
this.focusedItem = this.items.length - 1;
this.focusNext();
} else {
if (index !== undefined) {
this.focusedItem = index;
}
this.updateFocus();
}
}
@@ -736,22 +746,22 @@ export class ActionBar implements IActionRunner {
this.updateFocus(true);
}
private updateFocus(fromRight?: boolean): void {
protected updateFocus(fromRight?: boolean): void {
if (typeof this.focusedItem === 'undefined') {
this.domNode.focus();
this.actionsList.focus();
}
for (let i = 0; i < this.items.length; i++) {
let item = this.items[i];
let actionItem = <any>item;
let actionItem = item;
if (i === this.focusedItem) {
if (types.isFunction(actionItem.isEnabled)) {
if (actionItem.isEnabled() && types.isFunction(actionItem.focus)) {
actionItem.focus(fromRight);
} else {
this.domNode.focus();
this.actionsList.focus();
}
}
} else {
@@ -771,7 +781,7 @@ export class ActionBar implements IActionRunner {
let actionItem = this.items[this.focusedItem];
if (actionItem instanceof BaseActionItem) {
const context = (actionItem._context === null || actionItem._context === undefined) ? event : actionItem._context;
this.run(actionItem._action, context).done();
this.run(actionItem._action, context);
}
}
@@ -783,78 +793,63 @@ export class ActionBar implements IActionRunner {
this._onDidCancel.fire();
}
public run(action: IAction, context?: any): TPromise<void> {
run(action: IAction, context?: any): Thenable<void> {
return this._actionRunner.run(action, context);
}
public dispose(): void {
if (this.items !== null) {
lifecycle.dispose(this.items);
}
this.items = null;
dispose(): void {
dispose(this.items);
this.items = [];
if (this.focusTracker) {
this.focusTracker.dispose();
this.focusTracker = null;
}
DOM.removeNode(this.getContainer());
this.toDispose = lifecycle.dispose(this.toDispose);
$(this.getContainer()).destroy();
super.dispose();
}
}
export class SelectActionItem extends BaseActionItem {
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);
this.selectBox = new SelectBox(options, selected, contextViewProvider, null, selectBoxOptions);
this.toDispose = [];
this.toDispose.push(this.selectBox);
this.selectBox = new SelectBox(options, selected, contextViewProvider, undefined, selectBoxOptions);
this._register(this.selectBox);
this.registerListeners();
}
public setOptions(options: string[], selected?: number, disabled?: number): void {
setOptions(options: string[], selected?: number, disabled?: number): void {
this.selectBox.setOptions(options, selected, disabled);
}
public select(index: number): void {
select(index: number): void {
this.selectBox.select(index);
}
private registerListeners(): void {
this.toDispose.push(this.selectBox.onDidSelect(e => {
this.actionRunner.run(this._action, this.getActionContext(e.selected)).done();
this._register(this.selectBox.onDidSelect(e => {
this.actionRunner.run(this._action, this.getActionContext(e.selected, e.index));
}));
}
protected getActionContext(option: string) {
protected getActionContext(option: string, index: number) {
return option;
}
public focus(): void {
focus(): void {
if (this.selectBox) {
this.selectBox.focus();
}
}
public blur(): void {
blur(): void {
if (this.selectBox) {
this.selectBox.blur();
}
}
public render(container: HTMLElement): void {
render(container: HTMLElement): void {
this.selectBox.render(container);
}
public dispose(): void {
this.toDispose = lifecycle.dispose(this.toDispose);
super.dispose();
}
}
}