提交 241f624b 编写于 作者: I isidor

ActionBar: drop event emitter

#38417
上级 778152c8
......@@ -11,16 +11,15 @@ import lifecycle = require('vs/base/common/lifecycle');
import { TPromise } from 'vs/base/common/winjs.base';
import { Builder, $ } from 'vs/base/browser/builder';
import { SelectBox } from 'vs/base/browser/ui/selectBox/selectBox';
import { IAction, IActionRunner, Action, IActionChangeEvent, ActionRunner } from 'vs/base/common/actions';
import { IAction, IActionRunner, Action, IActionChangeEvent, ActionRunner, IRunEvent } from 'vs/base/common/actions';
import DOM = require('vs/base/browser/dom');
import { EventType as CommonEventType } from 'vs/base/common/events';
import types = require('vs/base/common/types');
import { IEventEmitter, EventEmitter } from 'vs/base/common/eventEmitter';
import { Gesture, EventType } from 'vs/base/browser/touch';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import Event, { Emitter } from 'vs/base/common/event';
export interface IActionItem extends IEventEmitter {
export interface IActionItem {
actionRunner: IActionRunner;
setActionContext(context: any): void;
render(element: HTMLElement): void;
......@@ -35,7 +34,7 @@ export interface IBaseActionItemOptions {
isMenu?: boolean;
}
export class BaseActionItem extends EventEmitter implements IActionItem {
export class BaseActionItem implements IActionItem {
public builder: Builder;
public _callOnDispose: lifecycle.IDisposable[];
......@@ -46,8 +45,6 @@ export class BaseActionItem extends EventEmitter implements IActionItem {
private _actionRunner: IActionRunner;
constructor(context: any, action: IAction, protected options?: IBaseActionItemOptions) {
super();
this._callOnDispose = [];
this._context = context || this;
this._action = action;
......@@ -152,7 +149,7 @@ export class BaseActionItem extends EventEmitter implements IActionItem {
});
}
public onClick(event: Event): void {
public onClick(event: DOM.EventLike): void {
DOM.EventHelper.stop(event, true);
let context: any;
......@@ -199,8 +196,6 @@ export class BaseActionItem extends EventEmitter implements IActionItem {
}
public dispose(): void {
super.dispose();
if (this.builder) {
this.builder.destroy();
this.builder = null;
......@@ -380,7 +375,7 @@ export interface IActionOptions extends IActionItemOptions {
index?: number;
}
export class ActionBar extends EventEmitter implements IActionRunner {
export class ActionBar implements IActionRunner {
public options: IActionBarOptions;
......@@ -399,8 +394,12 @@ export class ActionBar extends EventEmitter implements IActionRunner {
private toDispose: lifecycle.IDisposable[];
private _onDidBlur = new Emitter<void>();
private _onDidCancel = new Emitter<void>();
private _onDidRun = new Emitter<IRunEvent>();
private _onDidBeforeRun = new Emitter<IRunEvent>();
constructor(container: HTMLElement | Builder, options: IActionBarOptions = defaultOptions) {
super();
this.options = options;
this._context = options.context;
this.toDispose = [];
......@@ -411,7 +410,8 @@ export class ActionBar extends EventEmitter implements IActionRunner {
this.toDispose.push(this._actionRunner);
}
this.toDispose.push(this.addEmitter(this._actionRunner));
this.toDispose.push(this._actionRunner.onDidRun(e => this._onDidRun.fire(e)));
this.toDispose.push(this._actionRunner.onDidBeforeRun(e => this._onDidBeforeRun.fire(e)));
this.items = [];
this.focusedItem = undefined;
......@@ -489,7 +489,7 @@ export class ActionBar extends EventEmitter implements IActionRunner {
this.focusTracker = DOM.trackFocus(this.domNode);
this.focusTracker.addBlurListener(() => {
if (document.activeElement === this.domNode || !DOM.isAncestor(document.activeElement, this.domNode)) {
this.emit(DOM.EventType.BLUR, {});
this._onDidBlur.fire();
this.focusedItem = undefined;
}
});
......@@ -512,6 +512,22 @@ export class ActionBar extends EventEmitter implements IActionRunner {
((container instanceof Builder) ? container.getHTMLElement() : 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 {
if (label) {
this.actionsList.setAttribute('aria-label', label);
......@@ -566,7 +582,7 @@ export class ActionBar extends EventEmitter implements IActionRunner {
actionItemElement.setAttribute('role', 'presentation');
// Prevent native context menu on actions
$(actionItemElement).on(DOM.EventType.CONTEXT_MENU, (e: Event) => {
$(actionItemElement).on(DOM.EventType.CONTEXT_MENU, (e: DOM.EventLike) => {
e.preventDefault();
e.stopPropagation();
});
......@@ -583,7 +599,6 @@ export class ActionBar extends EventEmitter implements IActionRunner {
item.actionRunner = this._actionRunner;
item.setActionContext(this.context);
this.addEmitter(item);
item.render(actionItemElement);
if (index === null || index < 0 || index >= this.actionsList.children.length) {
......@@ -726,7 +741,7 @@ export class ActionBar extends EventEmitter implements IActionRunner {
(<HTMLElement>document.activeElement).blur(); // remove focus from focused action
}
this.emit(CommonEventType.CANCEL);
this._onDidCancel.fire();
}
public run(action: IAction, context?: any): TPromise<void> {
......@@ -747,8 +762,6 @@ export class ActionBar extends EventEmitter implements IActionRunner {
this.toDispose = lifecycle.dispose(this.toDispose);
this.getContainer().destroy();
super.dispose();
}
}
......
......@@ -10,8 +10,8 @@ import { IDisposable } from 'vs/base/common/lifecycle';
import { $ } from 'vs/base/browser/builder';
import { IActionRunner, IAction } from 'vs/base/common/actions';
import { ActionBar, IActionItemProvider, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
import { EventEmitter } from 'vs/base/common/eventEmitter';
import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
import Event from 'vs/base/common/event';
export interface IMenuOptions {
context?: any;
......@@ -20,14 +20,12 @@ export interface IMenuOptions {
getKeyBinding?: (action: IAction) => ResolvedKeybinding;
}
export class Menu extends EventEmitter {
export class Menu {
private actionBar: ActionBar;
private listener: IDisposable;
constructor(container: HTMLElement, actions: IAction[], options: IMenuOptions = {}) {
super();
$(container).addClass('monaco-menu-container');
let $menu = $('.monaco-menu').appendTo(container);
......@@ -40,18 +38,22 @@ export class Menu extends EventEmitter {
isMenu: true
});
this.listener = this.addEmitter(this.actionBar);
this.actionBar.push(actions, { icon: true, label: true });
}
public get onDidCancel(): Event<void> {
return this.actionBar.onDidCancel;
}
public get onDidBlur(): Event<void> {
return this.actionBar.onDidBlur;
}
public focus() {
this.actionBar.focus(true);
}
public dispose() {
super.dispose();
if (this.actionBar) {
this.actionBar.dispose();
this.actionBar = null;
......
......@@ -186,7 +186,6 @@ class ToggleMenuAction extends Action {
export class DropdownMenuActionItem extends BaseActionItem {
private menuActionsOrProvider: any;
private dropdownMenu: DropdownMenu;
private toUnbind: IDisposable;
private contextMenuProvider: IContextMenuProvider;
private actionItemProvider: IActionItemProvider;
private keybindings: (action: IAction) => ResolvedKeybinding;
......@@ -240,9 +239,6 @@ export class DropdownMenuActionItem extends BaseActionItem {
getKeyBinding: this.keybindings,
context: this._context
};
// Reemit events for running actions
this.toUnbind = this.addEmitter(this.dropdownMenu);
}
public setActionContext(newContext: any): void {
......@@ -260,7 +256,6 @@ export class DropdownMenuActionItem extends BaseActionItem {
}
public dispose(): void {
this.toUnbind.dispose();
this.dropdownMenu.dispose();
super.dispose();
......
......@@ -5,9 +5,7 @@
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { IEventEmitter, EventEmitter } from 'vs/base/common/eventEmitter';
import { IDisposable } from 'vs/base/common/lifecycle';
import * as Events from 'vs/base/common/events';
import Event, { Emitter } from 'vs/base/common/event';
export interface ITelemetryData {
......@@ -27,11 +25,13 @@ export interface IAction extends IDisposable {
run(event?: any): TPromise<any>;
}
export interface IActionRunner extends IEventEmitter {
export interface IActionRunner extends IDisposable {
run(action: IAction, context?: any): TPromise<any>;
onDidRun: Event<IRunEvent>;
onDidBeforeRun: Event<IRunEvent>;
}
export interface IActionItem extends IEventEmitter {
export interface IActionItem {
actionRunner: IActionRunner;
setActionContext(context: any): void;
render(element: any /* HTMLElement */): void;
......@@ -222,19 +222,30 @@ export interface IRunEvent {
error?: any;
}
export class ActionRunner extends EventEmitter implements IActionRunner {
export class ActionRunner implements IActionRunner {
private _onDidBeforeRun = new Emitter<IRunEvent>();
private _onDidRun = new Emitter<IRunEvent>();
public get onDidRun(): Event<IRunEvent> {
return this._onDidRun.event;
}
public get onDidBeforeRun(): Event<IRunEvent> {
return this._onDidBeforeRun.event;
}
public run(action: IAction, context?: any): TPromise<any> {
if (!action.enabled) {
return TPromise.as(null);
}
this.emit(Events.EventType.BEFORE_RUN, { action: action });
this._onDidBeforeRun.fire({ action: action });
return this.runAction(action, context).then((result: any) => {
this.emit(Events.EventType.RUN, <IRunEvent>{ action: action, result: result });
this._onDidRun.fire({ action: action, result: result });
}, (error: any) => {
this.emit(Events.EventType.RUN, <IRunEvent>{ action: action, error: error });
this._onDidRun.fire({ action: action, error: error });
});
}
......@@ -247,4 +258,8 @@ export class ActionRunner extends EventEmitter implements IActionRunner {
return TPromise.wrap(res);
}
public dispose(): void {
// noop
}
}
......@@ -9,9 +9,8 @@ import 'vs/css!./contextMenuHandler';
import { $, Builder } from 'vs/base/browser/builder';
import { combinedDisposable, IDisposable } from 'vs/base/common/lifecycle';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { IActionRunner, ActionRunner, IAction } from 'vs/base/common/actions';
import { IActionRunner, ActionRunner, IAction, IRunEvent } from 'vs/base/common/actions';
import { Menu } from 'vs/base/browser/ui/menu/menu';
import { EventType } from 'vs/base/common/events';
import Severity from 'vs/base/common/severity';
import { IContextViewService, IContextMenuDelegate } from 'vs/platform/contextview/browser/contextView';
......@@ -42,7 +41,7 @@ export class ContextMenuHandler {
let hideViewOnRun = false;
this.toDispose.push(this.actionRunner.addListener(EventType.BEFORE_RUN, (e: any) => {
this.toDispose.push(this.actionRunner.onDidBeforeRun((e: IRunEvent) => {
if (this.telemetryService) {
/* __GDPR__
"workbenchActionExecuted" : {
......@@ -53,14 +52,14 @@ export class ContextMenuHandler {
this.telemetryService.publicLog('workbenchActionExecuted', { id: e.action.id, from: 'contextMenu' });
}
hideViewOnRun = !!e.retainActionItem;
hideViewOnRun = !!(<any>e).retainActionItem;
if (!hideViewOnRun) {
this.contextViewService.hideContextView(false);
}
}));
this.toDispose.push(this.actionRunner.addListener(EventType.RUN, (e: any) => {
this.toDispose.push(this.actionRunner.onDidRun((e: IRunEvent) => {
if (hideViewOnRun) {
this.contextViewService.hideContextView(false);
}
......@@ -105,11 +104,11 @@ export class ContextMenuHandler {
actionRunner: this.actionRunner
});
let listener1 = menu.addListener(EventType.CANCEL, (e: any) => {
let listener1 = menu.onDidCancel(() => {
this.contextViewService.hideContextView(true);
});
let listener2 = menu.addListener(EventType.BLUR, (e: any) => {
let listener2 = menu.onDidBlur(() => {
this.contextViewService.hideContextView(true);
});
......
......@@ -12,7 +12,6 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { Registry } from 'vs/platform/registry/common/platform';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Dimension, Builder, $ } from 'vs/base/browser/builder';
import events = require('vs/base/common/events');
import strings = require('vs/base/common/strings');
import { Emitter } from 'vs/base/common/event';
import types = require('vs/base/common/types');
......@@ -23,7 +22,7 @@ import { CONTEXT as ToolBarContext, ToolBar } from 'vs/base/browser/ui/toolbar/t
import { IActionItem, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
import { IActionBarRegistry, Extensions, prepareActions } from 'vs/workbench/browser/actions';
import { Action, IAction } from 'vs/base/common/actions';
import { Action, IAction, IRunEvent } from 'vs/base/common/actions';
import { Part, IPartOptions } from 'vs/workbench/browser/part';
import { Composite, CompositeRegistry } from 'vs/workbench/browser/composite';
import { IComposite } from 'vs/workbench/common/composite';
......@@ -282,7 +281,7 @@ export abstract class CompositePart<T extends Composite> extends Part {
}
// Action Run Handling
this.telemetryActionsListener = this.toolBar.actionRunner.addListener(events.EventType.RUN, (e: any) => {
this.telemetryActionsListener = this.toolBar.actionRunner.onDidRun((e: IRunEvent) => {
// Check for Error
if (e.error && !errors.isPromiseCanceledError(e.error)) {
......
......@@ -9,7 +9,7 @@ import 'vs/css!./media/titlecontrol';
import nls = require('vs/nls');
import { Registry } from 'vs/platform/registry/common/platform';
import { Scope, IActionBarRegistry, Extensions, prepareActions } from 'vs/workbench/browser/actions';
import { IAction, Action } from 'vs/base/common/actions';
import { IAction, Action, IRunEvent } from 'vs/base/common/actions';
import errors = require('vs/base/common/errors');
import DOM = require('vs/base/browser/dom');
import { TPromise } from 'vs/base/common/winjs.base';
......@@ -17,7 +17,6 @@ import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
import { RunOnceScheduler } from 'vs/base/common/async';
import arrays = require('vs/base/common/arrays');
import { IEditorStacksModel, IEditorGroup, IEditorIdentifier, EditorInput, IStacksModelChangeEvent, toResource } from 'vs/workbench/common/editor';
import { EventType as BaseEventType } from 'vs/base/common/events';
import { IActionItem, ActionsOrientation, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
......@@ -252,7 +251,7 @@ export abstract class TitleControl extends Themable implements ITitleAreaControl
});
// Action Run Handling
this.toUnbind.push(this.editorActionsToolbar.actionRunner.addListener(BaseEventType.RUN, (e: any) => {
this.toUnbind.push(this.editorActionsToolbar.actionRunner.onDidRun((e: IRunEvent) => {
// Check for Error
if (e.error && !errors.isPromiseCanceledError(e.error)) {
......
......@@ -12,7 +12,6 @@ import * as dom from 'vs/base/browser/dom';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { SelectBox } from 'vs/base/browser/ui/selectBox/selectBox';
import { SelectActionItem, IActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { EventEmitter } from 'vs/base/common/eventEmitter';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IDebugService } from 'vs/workbench/parts/debug/common/debug';
......@@ -23,7 +22,7 @@ import { selectBorder } from 'vs/platform/theme/common/colorRegistry';
const $ = dom.$;
export class StartDebugActionItem extends EventEmitter implements IActionItem {
export class StartDebugActionItem implements IActionItem {
private static SEPARATOR = '─────────';
......@@ -43,7 +42,6 @@ export class StartDebugActionItem extends EventEmitter implements IActionItem {
@IConfigurationService private configurationService: IConfigurationService,
@ICommandService private commandService: ICommandService
) {
super();
this.toDispose = [];
this.selectBox = new SelectBox([], -1);
this.toDispose.push(attachSelectBoxStyler(this.selectBox, themeService, {
......
......@@ -12,8 +12,7 @@ import * as builder from 'vs/base/browser/builder';
import * as dom from 'vs/base/browser/dom';
import * as arrays from 'vs/base/common/arrays';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { IAction } from 'vs/base/common/actions';
import { EventType } from 'vs/base/common/events';
import { IAction, IRunEvent } from 'vs/base/common/actions';
import { ActionBar, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
import { IPartService } from 'vs/workbench/services/part/common/partService';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
......@@ -94,7 +93,7 @@ export class DebugActionsWidget extends Themable implements IWorkbenchContributi
private registerListeners(): void {
this.toUnbind.push(this.debugService.onDidChangeState(state => this.update(state)));
this.toUnbind.push(this.configurationService.onDidChangeConfiguration(e => this.onDidConfigurationChange(e)));
this.toUnbind.push(this.actionBar.actionRunner.addListener(EventType.RUN, (e: any) => {
this.toUnbind.push(this.actionBar.actionRunner.onDidRun((e: IRunEvent) => {
// check for error
if (e.error && !errors.isPromiseCanceledError(e.error)) {
this.messageService.show(severity.Error, e.error);
......
......@@ -12,7 +12,7 @@ import { marked } from 'vs/base/common/marked/marked';
import { always } from 'vs/base/common/async';
import * as arrays from 'vs/base/common/arrays';
import { OS } from 'vs/base/common/platform';
import Event, { Emitter, once, fromEventEmitter, chain } from 'vs/base/common/event';
import Event, { Emitter, once, chain } from 'vs/base/common/event';
import Cache from 'vs/base/common/cache';
import { Action } from 'vs/base/common/actions';
import { isPromiseCanceledError } from 'vs/base/common/errors';
......@@ -252,7 +252,7 @@ export class ExtensionEditor extends BaseEditor {
this.recommendation = append(details, $('.recommendation'));
chain(fromEventEmitter<{ error?: any; }>(this.extensionActionBar, 'run'))
chain(this.extensionActionBar.onDidRun)
.map(({ error }) => error)
.filter(error => !!error)
.on(this.onError, this, this.disposables);
......
......@@ -19,7 +19,6 @@ import { IExtension, IExtensionsWorkbenchService } from 'vs/workbench/parts/exte
import { InstallAction, UpdateAction, BuiltinStatusLabelAction, ManageExtensionAction, ReloadAction, extensionButtonProminentBackground } from 'vs/workbench/parts/extensions/browser/extensionsActions';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { Label, RatingsWidget, InstallWidget } from 'vs/workbench/parts/extensions/browser/extensionsWidgets';
import { EventType } from 'vs/base/common/events';
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
import { IExtensionTipsService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IThemeService } from 'vs/platform/theme/common/themeService';
......@@ -89,7 +88,7 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
return null;
}
});
actionbar.addListener(EventType.RUN, ({ error }) => error && this.messageService.show(Severity.Error, error));
actionbar.onDidRun(({ error }) => error && this.messageService.show(Severity.Error, error));
const versionWidget = this.instantiationService.createInstance(Label, version, (e: IExtension) => e.version);
const installCountWidget = this.instantiationService.createInstance(InstallWidget, installCount, { small: true });
......
......@@ -36,7 +36,6 @@ import { IModeService } from 'vs/editor/common/services/modeService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { EventType } from 'vs/base/common/events';
import { InstallWorkspaceRecommendedExtensionsAction, ConfigureWorkspaceFolderRecommendedExtensionsAction } from 'vs/workbench/parts/extensions/browser/extensionsActions';
export class ExtensionsListView extends ViewsViewletPanel {
......@@ -553,7 +552,7 @@ export class WorkspaceRecommendedExtensionsView extends ExtensionsListView {
const actionbar = new ActionBar(listActionBar, {
animated: false
});
actionbar.addListener(EventType.RUN, ({ error }) => error && this.messageService.show(Severity.Error, error));
actionbar.onDidRun(({ error }) => error && this.messageService.show(Severity.Error, error));
const installAllAction = this.instantiationService.createInstance(InstallWorkspaceRecommendedExtensionsAction, InstallWorkspaceRecommendedExtensionsAction.ID, InstallWorkspaceRecommendedExtensionsAction.LABEL);
const configureWorkspaceFolderAction = this.instantiationService.createInstance(ConfigureWorkspaceFolderRecommendedExtensionsAction, ConfigureWorkspaceFolderRecommendedExtensionsAction.ID, ConfigureWorkspaceFolderRecommendedExtensionsAction.LABEL);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册