提交 ce4d9f4e 编写于 作者: A Alex Dima

Fixes Microsoft/monaco-editor#167: introduce StandaloneCommandService

上级 04819366
......@@ -12,8 +12,8 @@ import {TPromise} from 'vs/base/common/winjs.base';
import {IConfigurationService, IConfigurationServiceEvent, IConfigurationValue, getConfigurationValue} from 'vs/platform/configuration/common/configuration';
import {IEditor, IEditorInput, IEditorOptions, IEditorService, IResourceInput, ITextEditorModel, Position} from 'vs/platform/editor/common/editor';
import {AbstractExtensionService, ActivatedExtension} from 'vs/platform/extensions/common/abstractExtensionService';
import {IExtensionDescription} from 'vs/platform/extensions/common/extensions';
import {ICommandService, ICommandHandler} from 'vs/platform/commands/common/commands';
import {IExtensionDescription, IExtensionService} from 'vs/platform/extensions/common/extensions';
import {ICommandService, ICommand, ICommandHandler} from 'vs/platform/commands/common/commands';
import {KeybindingService} from 'vs/platform/keybinding/browser/keybindingServiceImpl';
import {IOSupport} from 'vs/platform/keybinding/common/keybindingResolver';
import {IKeybindingItem} from 'vs/platform/keybinding/common/keybinding';
......@@ -24,6 +24,8 @@ import {ICodeEditor, IDiffEditor} from 'vs/editor/browser/editorBrowser';
import {Selection} from 'vs/editor/common/core/selection';
import Event, {Emitter} from 'vs/base/common/event';
import {getDefaultValues as getDefaultConfiguration} from 'vs/platform/configuration/common/model';
import {CommandService} from 'vs/platform/commands/common/commandService';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
export class SimpleEditor implements IEditor {
......@@ -198,11 +200,32 @@ export class SimpleMessageService implements IMessageService {
}
}
export class StandaloneCommandService extends CommandService {
private _dynamicCommands: { [id: string]: ICommand; };
constructor(
instantiationService: IInstantiationService,
extensionService: IExtensionService
) {
super(instantiationService, extensionService);
this._dynamicCommands = Object.create(null);
}
public addCommand(id:string, command:ICommand): void {
this._dynamicCommands[id] = command;
}
protected _getCommand(id:string): ICommand {
return super._getCommand(id) || this._dynamicCommands[id];
}
}
export class StandaloneKeybindingService extends KeybindingService {
private static LAST_GENERATED_ID = 0;
private _dynamicKeybindings: IKeybindingItem[];
private _dynamicCommands: { [id: string]: ICommandHandler };
constructor(
contextKeyService: IContextKeyService,
......@@ -213,7 +236,6 @@ export class StandaloneKeybindingService extends KeybindingService {
super(contextKeyService, commandService, messageService);
this._dynamicKeybindings = [];
this._dynamicCommands = Object.create(null);
this._beginListening(domNode);
}
......@@ -230,7 +252,15 @@ export class StandaloneKeybindingService extends KeybindingService {
weight1: 1000,
weight2: 0
});
this._dynamicCommands[commandId] = handler;
let commandService = this._commandService;
if (commandService instanceof StandaloneCommandService) {
commandService.addCommand(commandId, {
handler: handler
});
} else {
throw new Error('Unknown command service!');
}
this.updateResolver();
return commandId;
}
......@@ -238,10 +268,6 @@ export class StandaloneKeybindingService extends KeybindingService {
protected _getExtraKeybindings(isFirstTime:boolean): IKeybindingItem[] {
return this._dynamicKeybindings;
}
protected _getCommandHandler(commandId:string): ICommandHandler {
return super._getCommandHandler(commandId) || this._dynamicCommands[commandId];
}
}
export class SimpleExtensionService extends AbstractExtensionService<ActivatedExtension> {
......
......@@ -65,7 +65,7 @@ export class StandaloneEditor extends CodeEditor implements IStandaloneCodeEdito
constructor(
domElement:HTMLElement,
options:IEditorConstructionOptions,
toDispose: IDisposable[],
toDispose: IDisposable,
@IInstantiationService instantiationService: IInstantiationService,
@ICodeEditorService codeEditorService: ICodeEditorService,
@ICommandService commandService: ICommandService,
......@@ -81,7 +81,7 @@ export class StandaloneEditor extends CodeEditor implements IStandaloneCodeEdito
}
this._contextViewService = <IEditorContextViewService>contextViewService;
this._toDispose2 = toDispose;
this._toDispose2 = [toDispose];
let model: IModel = null;
if (typeof options.model === 'undefined') {
......@@ -169,7 +169,7 @@ export class StandaloneDiffEditor extends DiffEditorWidget implements IStandalon
constructor(
domElement:HTMLElement,
options:IDiffEditorConstructionOptions,
toDispose: IDisposable[],
toDispose: IDisposable,
@IInstantiationService instantiationService: IInstantiationService,
@IContextKeyService contextKeyService: IContextKeyService,
@IKeybindingService keybindingService: IKeybindingService,
......@@ -184,7 +184,7 @@ export class StandaloneDiffEditor extends DiffEditorWidget implements IStandalon
this._contextViewService = <IEditorContextViewService>contextViewService;
this._toDispose2 = toDispose;
this._toDispose2 = [toDispose];
this._contextViewService.setContainer(this._containerDomElement);
}
......
......@@ -10,13 +10,10 @@ import {ContentWidgetPositionPreference, OverlayWidgetPositionPreference} from '
import {ShallowCancelThenPromise} from 'vs/base/common/async';
import {StandaloneEditor, IStandaloneCodeEditor, StandaloneDiffEditor, IStandaloneDiffEditor, startup, IEditorConstructionOptions, IDiffEditorConstructionOptions} from 'vs/editor/browser/standalone/standaloneCodeEditor';
import {ScrollbarVisibility} from 'vs/base/common/scrollable';
import {IEditorOverrideServices, ensureDynamicPlatformServices, ensureStaticPlatformServices} from 'vs/editor/browser/standalone/standaloneServices';
import {IEditorOverrideServices, DynamicStandaloneServices, ensureStaticPlatformServices} from 'vs/editor/browser/standalone/standaloneServices';
import {IDisposable} from 'vs/base/common/lifecycle';
import URI from 'vs/base/common/uri';
import {TPromise} from 'vs/base/common/winjs.base';
import {createDecorator} from 'vs/platform/instantiation/common/instantiation';
import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection';
import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService';
import {OpenerService} from 'vs/platform/opener/browser/openerService';
import {IModel} from 'vs/editor/common/editorCommon';
import {IModelService} from 'vs/editor/common/services/modelService';
......@@ -66,7 +63,7 @@ export function create(domElement:HTMLElement, options?:IEditorConstructionOptio
}
var t = prepareServices(domElement, services);
var result = t.ctx.instantiationService.createInstance(StandaloneEditor, domElement, options, t.toDispose);
var result = t.services.instantiationService.createInstance(StandaloneEditor, domElement, options, t);
if (editorService) {
editorService.setEditor(result);
......@@ -91,7 +88,7 @@ export function createDiffEditor(domElement:HTMLElement, options?:IDiffEditorCon
}
var t = prepareServices(domElement, services);
var result = t.ctx.instantiationService.createInstance(StandaloneDiffEditor, domElement, options, t.toDispose);
var result = t.services.instantiationService.createInstance(StandaloneDiffEditor, domElement, options, t);
if (editorService) {
editorService.setEditor(result);
......@@ -117,24 +114,8 @@ export function createDiffNavigator(diffEditor:IStandaloneDiffEditor, opts?:IDif
return new DiffNavigator(diffEditor, opts);
}
function prepareServices(domElement: HTMLElement, services: IEditorOverrideServices): { ctx: IEditorOverrideServices; toDispose: IDisposable[]; } {
services = ensureStaticPlatformServices(services);
var toDispose = ensureDynamicPlatformServices(domElement, services);
var collection = new ServiceCollection();
for (var legacyServiceId in services) {
if (services.hasOwnProperty(legacyServiceId)) {
let id = createDecorator(legacyServiceId);
let service = services[legacyServiceId];
collection.set(id, service);
}
}
services.instantiationService = new InstantiationService(collection);
return {
ctx: services,
toDispose: toDispose
};
function prepareServices(domElement: HTMLElement, services: IEditorOverrideServices): DynamicStandaloneServices {
return new DynamicStandaloneServices(domElement, ensureStaticPlatformServices(services));
}
function doCreateModel(value:string, mode:TPromise<modes.IMode>, uri?:URI): IModel {
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import {IDisposable} from 'vs/base/common/lifecycle';
import {Disposable} from 'vs/base/common/lifecycle';
import URI from 'vs/base/common/uri';
import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
import {ContextMenuService} from 'vs/platform/contextview/browser/contextMenuService';
......@@ -14,11 +14,10 @@ import {IEditorService} from 'vs/platform/editor/common/editor';
import {IEventService} from 'vs/platform/event/common/event';
import {EventService} from 'vs/platform/event/common/eventService';
import {IExtensionService} from 'vs/platform/extensions/common/extensions';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {createDecorator, IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService';
import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection';
import {ICommandService} from 'vs/platform/commands/common/commands';
import {CommandService} from 'vs/platform/commands/common/commandService';
import {IOpenerService} from 'vs/platform/opener/common/opener';
import {IKeybindingService} from 'vs/platform/keybinding/common/keybinding';
import {IContextKeyService} from 'vs/platform/contextkey/common/contextkey';
......@@ -37,7 +36,7 @@ import {MainThreadModeServiceImpl} from 'vs/editor/common/services/modeServiceIm
import {IModelService} from 'vs/editor/common/services/modelService';
import {ModelServiceImpl} from 'vs/editor/common/services/modelServiceImpl';
import {CodeEditorServiceImpl} from 'vs/editor/browser/services/codeEditorServiceImpl';
import {SimpleConfigurationService, SimpleMessageService, SimpleExtensionService, StandaloneKeybindingService} from 'vs/editor/browser/standalone/simpleServices';
import {SimpleConfigurationService, SimpleMessageService, SimpleExtensionService, StandaloneKeybindingService, StandaloneCommandService} from 'vs/editor/browser/standalone/simpleServices';
import {ContextKeyService} from 'vs/platform/contextkey/browser/contextKeyService';
import {IMenuService} from 'vs/platform/actions/common/actions';
import {MenuService} from 'vs/platform/actions/common/menuService';
......@@ -150,7 +149,6 @@ export interface IStaticServices {
modeService: IModeService;
extensionService: IExtensionService;
markerService: IMarkerService;
menuService: IMenuService;
contextService: IWorkspaceContextService;
messageService: IMessageService;
telemetryService: ITelemetryService;
......@@ -159,7 +157,6 @@ export interface IStaticServices {
editorWorkerService: IEditorWorkerService;
eventService: IEventService;
storageService: IStorageService;
commandService: ICommandService;
instantiationService: IInstantiationService;
}
......@@ -191,39 +188,54 @@ export function ensureStaticPlatformServices(services: IEditorOverrideServices):
return services;
}
export function ensureDynamicPlatformServices(domElement:HTMLElement, services: IEditorOverrideServices): IDisposable[] {
let r:IDisposable[] = [];
export class DynamicStandaloneServices extends Disposable {
let contextKeyService:IContextKeyService;
if (typeof services.contextKeyService === 'undefined') {
contextKeyService = new ContextKeyService(services.configurationService);
r.push(contextKeyService);
services.contextKeyService = contextKeyService;
} else {
contextKeyService = services.contextKeyService;
}
if (typeof services.keybindingService === 'undefined') {
let keybindingService = new StandaloneKeybindingService(contextKeyService, services.commandService, services.messageService, domElement);
r.push(keybindingService);
services.keybindingService = keybindingService;
}
public services: IEditorOverrideServices;
let contextViewService:IEditorContextViewService;
if (typeof services.contextViewService === 'undefined') {
contextViewService = new ContextViewService(domElement, services.telemetryService, services.messageService);
r.push(contextViewService);
services.contextViewService = contextViewService;
} else {
contextViewService = services.contextViewService;
}
constructor(domElement:HTMLElement, _services: IEditorOverrideServices) {
super();
if (typeof services.contextMenuService === 'undefined') {
let contextMenuService = new ContextMenuService(domElement, services.telemetryService, services.messageService, contextViewService);
r.push(contextMenuService);
services.contextMenuService = contextMenuService;
}
let services: IEditorOverrideServices = {};
for (var serviceId in _services) {
services[serviceId] = _services[serviceId];
}
return r;
const serviceCollection = new ServiceCollection();
services.instantiationService = new InstantiationService(serviceCollection);
if (typeof services.contextKeyService === 'undefined') {
services.contextKeyService = this._register(new ContextKeyService(services.configurationService));
}
if (typeof services.commandService === 'undefined') {
services.commandService = new StandaloneCommandService(services.instantiationService, services.extensionService);
}
if (typeof services.keybindingService === 'undefined') {
services.keybindingService = this._register(new StandaloneKeybindingService(services.contextKeyService, services.commandService, services.messageService, domElement));
}
if (typeof services.contextViewService === 'undefined') {
services.contextViewService = this._register(new ContextViewService(domElement, services.telemetryService, services.messageService));
}
if (typeof services.contextMenuService === 'undefined') {
services.contextMenuService = this._register(new ContextMenuService(domElement, services.telemetryService, services.messageService, services.contextViewService));
}
if (typeof services.menuService === 'undefined') {
services.menuService = new MenuService(services.extensionService, services.commandService);
}
for (let serviceId in services) {
if (services.hasOwnProperty(serviceId)) {
let service = services[serviceId];
serviceCollection.set(createDecorator(serviceId), service);
}
}
this.services = services;
}
}
// The static services represents a map of services that once 1 editor has been created must be used for all subsequent editors
......@@ -257,9 +269,6 @@ export function getOrCreateStaticServices(services?: IEditorOverrideServices): I
let extensionService = services.extensionService || new SimpleExtensionService();
serviceCollection.set(IExtensionService, extensionService);
let commandService = services.commandService || new CommandService(instantiationService, extensionService);
serviceCollection.set(ICommandService, commandService);
let markerService = services.markerService || new MarkerService();
serviceCollection.set(IMarkerService, markerService);
......@@ -278,17 +287,12 @@ export function getOrCreateStaticServices(services?: IEditorOverrideServices): I
let codeEditorService = services.codeEditorService || new CodeEditorServiceImpl();
serviceCollection.set(ICodeEditorService, codeEditorService);
let menuService = services.menuService || new MenuService(extensionService, commandService);
serviceCollection.set(IMenuService, menuService);
staticServices = {
configurationService: configurationService,
extensionService: extensionService,
commandService: commandService,
compatWorkerService: compatWorkerService,
modeService: modeService,
markerService: markerService,
menuService: menuService,
contextService: contextService,
telemetryService: telemetryService,
messageService: messageService,
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import {ContextKeyService} from 'vs/platform/contextkey/browser/contextKeyService';
import {SimpleConfigurationService, SimpleMessageService, SimpleExtensionService, StandaloneKeybindingService, StandaloneCommandService} from 'vs/editor/browser/standalone/simpleServices';
import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService';
import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection';
import {KeyCode} from 'vs/base/common/keyCodes';
import {IKeyboardEvent} from 'vs/base/browser/keyboardEvent';
suite('StandaloneKeybindingService', () => {
class TestStandaloneKeybindingService extends StandaloneKeybindingService {
public dispatch(e: IKeyboardEvent): void {
super._dispatch(e);
}
}
test('issue Microsoft/monaco-editor#167', () => {
let serviceCollection = new ServiceCollection();
const instantiationService = new InstantiationService(serviceCollection, true);
let configurationService = new SimpleConfigurationService();
let contextKeyService = new ContextKeyService(configurationService);
let extensionService = new SimpleExtensionService();
let commandService = new StandaloneCommandService(instantiationService, extensionService);
let messageService = new SimpleMessageService();
let domElement = document.createElement('div');
let keybindingService = new TestStandaloneKeybindingService(contextKeyService, commandService, messageService, domElement);
let commandInvoked = false;
keybindingService.addDynamicKeybinding(KeyCode.F9, () => {
commandInvoked = true;
}, null);
keybindingService.dispatch(<any>{
asKeybinding: () => KeyCode.F9,
preventDefault: () => {}
});
assert.ok(commandInvoked, 'command invoked');
});
});
......@@ -6,7 +6,7 @@
import {TPromise} from 'vs/base/common/winjs.base';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {ICommandService, CommandsRegistry} from 'vs/platform/commands/common/commands';
import {ICommandService, ICommand, CommandsRegistry} from 'vs/platform/commands/common/commands';
import {IExtensionService} from 'vs/platform/extensions/common/extensions';
export class CommandService implements ICommandService {
......@@ -24,7 +24,7 @@ export class CommandService implements ICommandService {
return this._extensionService.activateByEvent(`onCommand:${id}`).then(_ => {
const command = CommandsRegistry.getCommand(id);
const command = this._getCommand(id);
if (!command) {
return TPromise.wrapError(new Error(`command '${id}' not found`));
}
......@@ -37,4 +37,8 @@ export class CommandService implements ICommandService {
}
});
}
protected _getCommand(id:string): ICommand {
return CommandsRegistry.getCommand(id);
}
}
......@@ -13,7 +13,7 @@ import Severity from 'vs/base/common/severity';
import {isFalsyOrEmpty} from 'vs/base/common/arrays';
import * as dom from 'vs/base/browser/dom';
import {IKeyboardEvent, StandardKeyboardEvent} from 'vs/base/browser/keyboardEvent';
import {ICommandService, CommandsRegistry, ICommandHandler, ICommandHandlerDescription} from 'vs/platform/commands/common/commands';
import {ICommandService, CommandsRegistry, ICommandHandlerDescription} from 'vs/platform/commands/common/commands';
import {KeybindingResolver} from 'vs/platform/keybinding/common/keybindingResolver';
import {IKeybindingItem, IKeybindingService} from 'vs/platform/keybinding/common/keybinding';
import {IContextKeyService} from 'vs/platform/contextkey/common/contextkey';
......@@ -32,7 +32,7 @@ export abstract class KeybindingService implements IKeybindingService {
private _currentChordStatusMessage: IDisposable;
private _contextKeyService: IContextKeyService;
private _commandService: ICommandService;
protected _commandService: ICommandService;
private _statusService: IStatusbarService;
private _messageService: IMessageService;
......@@ -132,11 +132,7 @@ export abstract class KeybindingService implements IKeybindingService {
return '// ' + nls.localize('unboundCommands', "Here are other available commands: ") + '\n// - ' + pretty;
}
protected _getCommandHandler(commandId: string): ICommandHandler {
return CommandsRegistry.getCommand(commandId).handler;
}
private _dispatch(e: IKeyboardEvent): void {
protected _dispatch(e: IKeyboardEvent): void {
let isModifierKey = (e.keyCode === KeyCode.Ctrl || e.keyCode === KeyCode.Shift || e.keyCode === KeyCode.Alt || e.keyCode === KeyCode.Meta);
if (isModifierKey) {
return;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册