提交 487e7dd1 编写于 作者: A Alex Dima

Do not patch in "context" when invoking command through keybinding service

上级 c63fbe6f
......@@ -202,7 +202,7 @@ class TextAreaWrapper extends Disposable implements ITextAreaWrapper {
export class KeyboardHandler extends ViewEventHandler implements IDisposable {
private context:ViewContext;
private _context:ViewContext;
private viewController:IViewController;
private viewHelper:IKeyboardHandlerHelper;
private textArea:TextAreaWrapper;
......@@ -216,17 +216,17 @@ export class KeyboardHandler extends ViewEventHandler implements IDisposable {
constructor(context:ViewContext, viewController:IViewController, viewHelper:IKeyboardHandlerHelper) {
super();
this.context = context;
this._context = context;
this.viewController = viewController;
this.textArea = new TextAreaWrapper(viewHelper.textArea);
Configuration.applyFontInfoSlow(this.textArea.actual, this.context.configuration.editor.fontInfo);
Configuration.applyFontInfoSlow(this.textArea.actual, this._context.configuration.editor.fontInfo);
this.viewHelper = viewHelper;
this.contentLeft = 0;
this.contentWidth = 0;
this.scrollLeft = 0;
this.textAreaHandler = new TextAreaHandler(browser, this._getStrategy(), this.textArea, this.context.model, () => this.viewHelper.flushAnyAccumulatedEvents());
this.textAreaHandler = new TextAreaHandler(browser, this._getStrategy(), this.textArea, this._context.model, () => this.viewHelper.flushAnyAccumulatedEvents());
this._toDispose = [];
this._toDispose.push(this.textAreaHandler.onKeyDown((e) => this.viewController.emitKeyDown(<IKeyboardEvent>e._actual)));
......@@ -249,7 +249,7 @@ export class KeyboardHandler extends ViewEventHandler implements IDisposable {
verticalType: editorCommon.VerticalRevealType.Simple,
revealHorizontal: true
};
this.context.privateViewEventBus.emit(editorCommon.ViewEventNames.RevealRangeEvent, revealPositionEvent);
this._context.privateViewEventBus.emit(editorCommon.ViewEventNames.RevealRangeEvent, revealPositionEvent);
// Find range pixel position
let visibleRange = this.viewHelper.visibleRangeForPositionRelativeToEditor(lineNumber, column);
......@@ -264,7 +264,7 @@ export class KeyboardHandler extends ViewEventHandler implements IDisposable {
}
// Show the textarea
StyleMutator.setHeight(this.textArea.actual, this.context.configuration.editor.lineHeight);
StyleMutator.setHeight(this.textArea.actual, this._context.configuration.editor.lineHeight);
dom.addClass(this.viewHelper.viewDomNode, 'ime-input');
}));
this._toDispose.push(this.textAreaHandler.onCompositionEnd((e) => {
......@@ -279,11 +279,11 @@ export class KeyboardHandler extends ViewEventHandler implements IDisposable {
}));
this.context.addEventHandler(this);
this._context.addEventHandler(this);
}
public dispose(): void {
this.context.removeEventHandler(this);
this._context.removeEventHandler(this);
this.textAreaHandler.dispose();
this.textArea.dispose();
this._toDispose = dispose(this._toDispose);
......@@ -293,7 +293,7 @@ export class KeyboardHandler extends ViewEventHandler implements IDisposable {
if (GlobalScreenReaderNVDA.getValue()) {
return TextAreaStrategy.NVDA;
}
if (this.context.configuration.editor.experimentalScreenReader) {
if (this._context.configuration.editor.experimentalScreenReader) {
return TextAreaStrategy.NVDA;
}
return TextAreaStrategy.IENarrator;
......@@ -306,7 +306,7 @@ export class KeyboardHandler extends ViewEventHandler implements IDisposable {
public onConfigurationChanged(e: editorCommon.IConfigurationChangedEvent): boolean {
// Give textarea same font size & line height as editor, for the IME case (when the textarea is visible)
if (e.fontInfo) {
Configuration.applyFontInfoSlow(this.textArea.actual, this.context.configuration.editor.fontInfo);
Configuration.applyFontInfoSlow(this.textArea.actual, this._context.configuration.editor.fontInfo);
}
if (e.experimentalScreenReader) {
this.textAreaHandler.setStrategy(this._getStrategy());
......
......@@ -117,11 +117,11 @@ export class MouseHandler extends ViewEventHandler implements IDisposable {
static MOUSE_MOVE_MINIMUM_TIME = 100; // ms
public context:ViewContext;
public viewController:editorBrowser.IViewController;
public viewHelper:IPointerHandlerHelper;
public mouseTargetFactory: MouseTargetFactory;
public listenersToRemove:IDisposable[];
protected _context:ViewContext;
protected viewController:editorBrowser.IViewController;
protected viewHelper:IPointerHandlerHelper;
protected mouseTargetFactory: MouseTargetFactory;
protected listenersToRemove:IDisposable[];
private toDispose:IDisposable[];
private _mouseDownOperation: MouseDownOperation;
......@@ -132,14 +132,14 @@ export class MouseHandler extends ViewEventHandler implements IDisposable {
constructor(context:ViewContext, viewController:editorBrowser.IViewController, viewHelper:IPointerHandlerHelper) {
super();
this.context = context;
this._context = context;
this.viewController = viewController;
this.viewHelper = viewHelper;
this.mouseTargetFactory = new MouseTargetFactory(this.context, viewHelper);
this.mouseTargetFactory = new MouseTargetFactory(this._context, viewHelper);
this.listenersToRemove = [];
this._mouseDownOperation = new MouseDownOperation(
this.context,
this._context,
this.viewController,
this.viewHelper,
(e, testEventTarget) => this._createMouseTarget(e, testEventTarget),
......@@ -168,11 +168,11 @@ export class MouseHandler extends ViewEventHandler implements IDisposable {
this.listenersToRemove.push(dom.addDisposableListener(this.viewHelper.viewDomNode, 'mousedown',
(e: MouseEvent) => this._onMouseDown(e)));
this.context.addEventHandler(this);
this._context.addEventHandler(this);
}
public dispose(): void {
this.context.removeEventHandler(this);
this._context.removeEventHandler(this);
this.listenersToRemove = dispose(this.listenersToRemove);
this.toDispose = dispose(this.toDispose);
this._mouseDownOperation.dispose();
......@@ -260,7 +260,7 @@ export class MouseHandler extends ViewEventHandler implements IDisposable {
let targetIsContent = (t.type === editorCommon.MouseTargetType.CONTENT_TEXT || t.type === editorCommon.MouseTargetType.CONTENT_EMPTY);
let targetIsGutter = (t.type === editorCommon.MouseTargetType.GUTTER_GLYPH_MARGIN || t.type === editorCommon.MouseTargetType.GUTTER_LINE_NUMBERS || t.type === editorCommon.MouseTargetType.GUTTER_LINE_DECORATIONS);
let targetIsLineNumbers = (t.type === editorCommon.MouseTargetType.GUTTER_LINE_NUMBERS);
let selectOnLineNumbers = this.context.configuration.editor.selectOnLineNumbers;
let selectOnLineNumbers = this._context.configuration.editor.selectOnLineNumbers;
let targetIsViewZone = (t.type === editorCommon.MouseTargetType.CONTENT_VIEW_ZONE || t.type === editorCommon.MouseTargetType.GUTTER_VIEW_ZONE);
let shouldHandle = e.leftButton;
......
......@@ -132,12 +132,12 @@ var REGEX = (function() {
export class MouseTargetFactory {
private context: ViewContext;
private viewHelper: IPointerHandlerHelper;
private _context: ViewContext;
private _viewHelper: IPointerHandlerHelper;
constructor(context:ViewContext, viewHelper:IPointerHandlerHelper) {
this.context = context;
this.viewHelper = viewHelper;
this._context = context;
this._viewHelper = viewHelper;
}
private getClassNamePathTo(child:Node, stopAt:Node): string {
......@@ -162,7 +162,7 @@ export class MouseTargetFactory {
public mouseTargetIsWidget(e:ISimplifiedMouseEvent): boolean {
var t = <Element>e.target;
var path = this.getClassNamePathTo(t, this.viewHelper.viewDomNode);
var path = this.getClassNamePathTo(t, this._viewHelper.viewDomNode);
// Is it a content widget?
if (REGEX.IS_CHILD_OF_CONTENT_WIDGETS.test(path) || REGEX.IS_CHILD_OF_OVERFLOWING_CONTENT_WIDGETS.test(path)) {
......@@ -187,12 +187,12 @@ export class MouseTargetFactory {
}
private _unsafeCreateMouseTarget(layoutInfo:IEditorLayoutInfo, editorContent:IDomNodePosition, e:ISimplifiedMouseEvent, testEventTarget:boolean): IMouseTarget {
var mouseVerticalOffset = Math.max(0, this.viewHelper.getScrollTop() + (e.posy - editorContent.top));
var mouseContentHorizontalOffset = this.viewHelper.getScrollLeft() + (e.posx - editorContent.left) - layoutInfo.contentLeft;
var mouseVerticalOffset = Math.max(0, this._viewHelper.getScrollTop() + (e.posy - editorContent.top));
var mouseContentHorizontalOffset = this._viewHelper.getScrollLeft() + (e.posx - editorContent.left) - layoutInfo.contentLeft;
let mouseColumn = this._getMouseColumn(mouseContentHorizontalOffset);
var t = <Element>e.target;
var path = this.getClassNamePathTo(t, this.viewHelper.viewDomNode);
var path = this.getClassNamePathTo(t, this._viewHelper.viewDomNode);
// Is it a cursor ?
var lineNumberAttribute = t.hasAttribute && t.hasAttribute('lineNumber') ? t.getAttribute('lineNumber') : null;
......@@ -213,9 +213,9 @@ export class MouseTargetFactory {
// Is it the textarea cover?
if (REGEX.IS_TEXTAREA_COVER.test(path)) {
if (this.context.configuration.editor.glyphMargin) {
if (this._context.configuration.editor.glyphMargin) {
return this.createMouseTargetFromGlyphMargin(t, mouseVerticalOffset, mouseColumn);
} else if (this.context.configuration.editor.lineNumbers) {
} else if (this._context.configuration.editor.lineNumbers) {
return this.createMouseTargetFromLineNumbers(t, mouseVerticalOffset, mouseColumn);
} else {
return this.createMouseTargetFromLinesDecorationsChild(t, mouseVerticalOffset, mouseColumn);
......@@ -243,7 +243,7 @@ export class MouseTargetFactory {
// -> See Bug #12990: [F12] Context menu shows incorrect position while doing a resize
// Check if it is below any lines and any view zones
if (this.viewHelper.isAfterLines(mouseVerticalOffset)) {
if (this._viewHelper.isAfterLines(mouseVerticalOffset)) {
return this.createMouseTargetFromViewLines(t, mouseVerticalOffset, mouseColumn);
}
......@@ -270,7 +270,7 @@ export class MouseTargetFactory {
return this.createMouseTargetFromHitTestPosition(t, hitTestResult.position.lineNumber, hitTestResult.position.column, mouseContentHorizontalOffset, mouseColumn);
} else if (hitTestResult.hitTarget) {
t = hitTestResult.hitTarget;
path = this.getClassNamePathTo(t, this.viewHelper.viewDomNode);
path = this.getClassNamePathTo(t, this._viewHelper.viewDomNode);
// TODO@Alex: try again with this different target, but guard against recursion.
// Is it a cursor ?
......@@ -351,16 +351,16 @@ export class MouseTargetFactory {
// In Chrome, especially on Linux it is possible to click between lines,
// so try to adjust the `hity` below so that it lands in the center of a line
var lineNumber = this.viewHelper.getLineNumberAtVerticalOffset(mouseVerticalOffset);
var lineVerticalOffset = this.viewHelper.getVerticalOffsetForLineNumber(lineNumber);
var centeredVerticalOffset = lineVerticalOffset + Math.floor(this.context.configuration.editor.lineHeight / 2);
var lineNumber = this._viewHelper.getLineNumberAtVerticalOffset(mouseVerticalOffset);
var lineVerticalOffset = this._viewHelper.getVerticalOffsetForLineNumber(lineNumber);
var centeredVerticalOffset = lineVerticalOffset + Math.floor(this._context.configuration.editor.lineHeight / 2);
var adjustedPosy = e.posy + (centeredVerticalOffset - mouseVerticalOffset);
if (adjustedPosy <= editorContent.top) {
adjustedPosy = editorContent.top + 1;
}
if (adjustedPosy >= editorContent.top + this.context.configuration.editor.observedOuterHeight) {
adjustedPosy = editorContent.top + this.context.configuration.editor.observedOuterHeight - 1;
if (adjustedPosy >= editorContent.top + this._context.configuration.editor.observedOuterHeight) {
adjustedPosy = editorContent.top + this._context.configuration.editor.observedOuterHeight - 1;
}
var hitx = e.posx - document.body.scrollLeft;
......@@ -397,7 +397,7 @@ export class MouseTargetFactory {
if (parent3ClassName === ClassNames.VIEW_LINE) {
return {
position: this.viewHelper.getPositionFromDOMInfo(<HTMLElement>parent1, range.startOffset),
position: this._viewHelper.getPositionFromDOMInfo(<HTMLElement>parent1, range.startOffset),
hitTarget: null
};
} else {
......@@ -411,7 +411,7 @@ export class MouseTargetFactory {
if (parent2ClassName === ClassNames.VIEW_LINE) {
return {
position: this.viewHelper.getPositionFromDOMInfo(<HTMLElement>startContainer, (<HTMLElement>startContainer).textContent.length),
position: this._viewHelper.getPositionFromDOMInfo(<HTMLElement>startContainer, (<HTMLElement>startContainer).textContent.length),
hitTarget: null
};
} else {
......@@ -440,7 +440,7 @@ export class MouseTargetFactory {
var range = document.createRange();
range.setStart(hitResult.offsetNode, hitResult.offset);
range.collapse(true);
resultPosition = this.viewHelper.getPositionFromDOMInfo(<HTMLElement>range.startContainer.parentNode, range.startOffset);
resultPosition = this._viewHelper.getPositionFromDOMInfo(<HTMLElement>range.startContainer.parentNode, range.startOffset);
range.detach();
return {
......@@ -482,10 +482,10 @@ export class MouseTargetFactory {
rangeToContainEntireSpan.moveToElementText(parentElement);
rangeToContainEntireSpan.setEndPoint('EndToStart', textRange);
resultPosition = this.viewHelper.getPositionFromDOMInfo(<HTMLElement>parentElement, rangeToContainEntireSpan.text.length);
resultPosition = this._viewHelper.getPositionFromDOMInfo(<HTMLElement>parentElement, rangeToContainEntireSpan.text.length);
// Move range out of the span node, IE doesn't like having many ranges in
// the same spot and will act badly for lines containing dashes ('-')
rangeToContainEntireSpan.moveToElementText(this.viewHelper.viewDomNode);
rangeToContainEntireSpan.moveToElementText(this._viewHelper.viewDomNode);
} else {
// Looks like we've hit the hover or something foreign
resultHitTarget = parentElement;
......@@ -493,7 +493,7 @@ export class MouseTargetFactory {
// Move range out of the span node, IE doesn't like having many ranges in
// the same spot and will act badly for lines containing dashes ('-')
textRange.moveToElementText(this.viewHelper.viewDomNode);
textRange.moveToElementText(this._viewHelper.viewDomNode);
return {
position: resultPosition,
......@@ -536,11 +536,11 @@ export class MouseTargetFactory {
private _getZoneAtCoord(mouseVerticalOffset: number): IViewZoneData {
// The target is either a view zone or the empty space after the last view-line
var viewZoneWhitespace = this.viewHelper.getWhitespaceAtVerticalOffset(mouseVerticalOffset);
var viewZoneWhitespace = this._viewHelper.getWhitespaceAtVerticalOffset(mouseVerticalOffset);
if (viewZoneWhitespace) {
var viewZoneMiddle = viewZoneWhitespace.verticalOffset + viewZoneWhitespace.height / 2,
lineCount = this.context.model.getLineCount(),
lineCount = this._context.model.getLineCount(),
positionBefore: IEditorPosition = null,
position: IEditorPosition,
positionAfter: IEditorPosition = null;
......@@ -551,7 +551,7 @@ export class MouseTargetFactory {
}
if (viewZoneWhitespace.afterLineNumber > 0) {
// There are more lines above this view zone
positionBefore = new Position(viewZoneWhitespace.afterLineNumber, this.context.model.getLineMaxColumn(viewZoneWhitespace.afterLineNumber));
positionBefore = new Position(viewZoneWhitespace.afterLineNumber, this._context.model.getLineMaxColumn(viewZoneWhitespace.afterLineNumber));
}
if (positionAfter === null) {
......@@ -576,18 +576,18 @@ export class MouseTargetFactory {
}
private _getFullLineRangeAtCoord(mouseVerticalOffset: number): { range: IEditorRange; isAfterLines: boolean; } {
if (this.viewHelper.isAfterLines(mouseVerticalOffset)) {
if (this._viewHelper.isAfterLines(mouseVerticalOffset)) {
// Below the last line
var lineNumber = this.context.model.getLineCount();
var maxLineColumn = this.context.model.getLineMaxColumn(lineNumber);
var lineNumber = this._context.model.getLineCount();
var maxLineColumn = this._context.model.getLineMaxColumn(lineNumber);
return {
range: new EditorRange(lineNumber, maxLineColumn, lineNumber, maxLineColumn),
isAfterLines: true
};
}
var lineNumber = this.viewHelper.getLineNumberAtVerticalOffset(mouseVerticalOffset);
var maxLineColumn = this.context.model.getLineMaxColumn(lineNumber);
var lineNumber = this._viewHelper.getLineNumberAtVerticalOffset(mouseVerticalOffset);
var maxLineColumn = this._context.model.getLineMaxColumn(lineNumber);
return {
range: new EditorRange(lineNumber, 1, lineNumber, maxLineColumn),
isAfterLines: false
......@@ -595,7 +595,7 @@ export class MouseTargetFactory {
}
public getMouseColumn(layoutInfo:IEditorLayoutInfo, editorContent:IDomNodePosition, e:ISimplifiedMouseEvent): number {
let mouseContentHorizontalOffset = this.viewHelper.getScrollLeft() + (e.posx - editorContent.left) - layoutInfo.contentLeft;
let mouseContentHorizontalOffset = this._viewHelper.getScrollLeft() + (e.posx - editorContent.left) - layoutInfo.contentLeft;
return this._getMouseColumn(mouseContentHorizontalOffset);
}
......@@ -603,7 +603,7 @@ export class MouseTargetFactory {
if (mouseContentHorizontalOffset < 0) {
return 1;
}
let charWidth = this.context.configuration.editor.fontInfo.typicalHalfwidthCharacterWidth;
let charWidth = this._context.configuration.editor.fontInfo.typicalHalfwidthCharacterWidth;
let chars = Math.round(mouseContentHorizontalOffset / charWidth);
return (chars + 1);
}
......@@ -614,21 +614,21 @@ export class MouseTargetFactory {
private createMouseTargetFromViewLines(target:Element, mouseVerticalOffset: number, mouseColumn:number): MouseTarget {
// This most likely indicates it happened after the last view-line
var lineCount = this.context.model.getLineCount();
var maxLineColumn = this.context.model.getLineMaxColumn(lineCount);
var lineCount = this._context.model.getLineCount();
var maxLineColumn = this._context.model.getLineMaxColumn(lineCount);
return new MouseTarget(target, MouseTargetType.CONTENT_EMPTY, mouseColumn, new Position(lineCount, maxLineColumn));
}
private createMouseTargetFromHitTestPosition(target:Element, lineNumber: number, column: number, mouseHorizontalOffset: number, mouseColumn:number): MouseTarget {
var pos = new Position(lineNumber, column);
var lineWidth = this.viewHelper.getLineWidth(lineNumber);
var lineWidth = this._viewHelper.getLineWidth(lineNumber);
if (mouseHorizontalOffset > lineWidth) {
return new MouseTarget(target, MouseTargetType.CONTENT_EMPTY, mouseColumn, pos);
}
var visibleRange = this.viewHelper.visibleRangeForPosition2(lineNumber, column);
var visibleRange = this._viewHelper.visibleRangeForPosition2(lineNumber, column);
if (!visibleRange) {
return new MouseTarget(target, MouseTargetType.UNKNOWN, mouseColumn, pos);
......@@ -652,9 +652,9 @@ export class MouseTargetFactory {
}
}
var lineMaxColumn = this.context.model.getLineMaxColumn(lineNumber);
var lineMaxColumn = this._context.model.getLineMaxColumn(lineNumber);
if (column < lineMaxColumn) {
var nextColumnVisibleRange = this.viewHelper.visibleRangeForPosition2(lineNumber, column + 1);
var nextColumnVisibleRange = this._viewHelper.visibleRangeForPosition2(lineNumber, column + 1);
if (nextColumnVisibleRange) {
var nextColumnHorizontalOffset = nextColumnVisibleRange.left;
mouseIsBetween = false;
......@@ -671,7 +671,7 @@ export class MouseTargetFactory {
}
private createMouseTargetFromContentWidgetsChild(target: Element, mouseColumn:number): MouseTarget {
var widgetId = this._findAttribute(target, 'widgetId', this.viewHelper.viewDomNode);
var widgetId = this._findAttribute(target, 'widgetId', this._viewHelper.viewDomNode);
if (widgetId) {
return new MouseTarget(target, MouseTargetType.CONTENT_WIDGET, mouseColumn, null, null, widgetId);
......@@ -681,7 +681,7 @@ export class MouseTargetFactory {
}
private createMouseTargetFromOverlayWidgetsChild(target: Element, mouseColumn:number): MouseTarget {
var widgetId = this._findAttribute(target, 'widgetId', this.viewHelper.viewDomNode);
var widgetId = this._findAttribute(target, 'widgetId', this._viewHelper.viewDomNode);
if (widgetId) {
return new MouseTarget(target, MouseTargetType.OVERLAY_WIDGET, mouseColumn, null, null, widgetId);
......@@ -721,16 +721,16 @@ export class MouseTargetFactory {
}
private createMouseTargetFromScrollbar(target: Element, mouseVerticalOffset: number, mouseColumn:number): MouseTarget {
var possibleLineNumber = this.viewHelper.getLineNumberAtVerticalOffset(mouseVerticalOffset);
var maxColumn = this.context.model.getLineMaxColumn(possibleLineNumber);
var possibleLineNumber = this._viewHelper.getLineNumberAtVerticalOffset(mouseVerticalOffset);
var maxColumn = this._context.model.getLineMaxColumn(possibleLineNumber);
return new MouseTarget(target, MouseTargetType.SCROLLBAR, mouseColumn, new Position(possibleLineNumber, maxColumn));
}
private createMouseTargetFromUnknownTarget(target: Element): MouseTarget {
var isInView = this._isChild(target, this.viewHelper.viewDomNode, this.viewHelper.viewDomNode);
var isInView = this._isChild(target, this._viewHelper.viewDomNode, this._viewHelper.viewDomNode);
var widgetId = null;
if (isInView) {
widgetId = this._findAttribute(target, 'widgetId', this.viewHelper.viewDomNode);
widgetId = this._findAttribute(target, 'widgetId', this._viewHelper.viewDomNode);
}
if (widgetId) {
......
......@@ -220,15 +220,15 @@ export class StandaloneKeybindingService extends KeybindingService {
this._beginListening(domNode);
}
public addDynamicKeybinding(keybinding: number, handler:ICommandHandler, context:string, commandId:string = null): string {
public addDynamicKeybinding(keybinding: number, handler:ICommandHandler, when:string, commandId:string = null): string {
if (commandId === null) {
commandId = 'DYNAMIC_' + (++StandaloneKeybindingService.LAST_GENERATED_ID);
}
var parsedContext = IOSupport.readKeybindingContexts(context);
var parsedContext = IOSupport.readKeybindingWhen(when);
this._dynamicKeybindings.push({
keybinding: keybinding,
command: commandId,
context: parsedContext,
when: parsedContext,
weight1: 1000,
weight2: 0
});
......
......@@ -53,7 +53,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
private listenersToDispose:IDisposable[];
private layoutProvider: LayoutProvider;
public context: ViewContext;
public _context: ViewContext;
// The view lines
private viewLines: ViewLines;
......@@ -85,14 +85,12 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
private accumulatedModelEvents: IEmitterEvent[];
private _renderAnimationFrame: IDisposable;
private _editorId: number;
private _keybindingService: IKeybindingService;
private _editorTextFocusContextKey: IKeybindingContextKey<boolean>;
constructor(editorId:number, configuration:Configuration, model:IViewModel, keybindingService: IKeybindingService) {
constructor(configuration:Configuration, model:IViewModel, keybindingService: IKeybindingService) {
super();
this._isDisposed = false;
this._editorId = editorId;
this._renderAnimationFrame = null;
this.outgoingEventBus = new EventEmitter();
......@@ -121,8 +119,8 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
this.eventDispatcher.addEventHandler(this.layoutProvider);
// The view context is passed on to most classes (basically to reduce param. counts in ctors)
this.context = new ViewContext(
editorId, configuration, model, this.eventDispatcher,
this._context = new ViewContext(
configuration, model, this.eventDispatcher,
(eventHandler:IViewEventHandler) => this.eventDispatcher.addEventHandler(eventHandler),
(eventHandler:IViewEventHandler) => this.eventDispatcher.removeEventHandler(eventHandler)
);
......@@ -131,10 +129,10 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
this.createViewParts();
// Keyboard handler
this.keyboardHandler = new KeyboardHandler(this.context, viewController, this.createKeyboardHandlerHelper());
this.keyboardHandler = new KeyboardHandler(this._context, viewController, this.createKeyboardHandlerHelper());
// Pointer handler
this.pointerHandler = new PointerHandler(this.context, viewController, this.createPointerHandlerHelper());
this.pointerHandler = new PointerHandler(this._context, viewController, this.createPointerHandlerHelper());
this.hasFocus = false;
this.codeEditorHelper = null;
......@@ -174,7 +172,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
this.textArea.setAttribute('autocorrect', 'off');
this.textArea.setAttribute('autocapitalize', 'off');
this.textArea.setAttribute('spellcheck', 'false');
this.textArea.setAttribute('aria-label', this.context.configuration.editor.ariaLabel);
this.textArea.setAttribute('aria-label', this._context.configuration.editor.ariaLabel);
this.textArea.setAttribute('role', 'textbox');
this.textArea.setAttribute('aria-multiline', 'true');
this.textArea.setAttribute('aria-haspopup', 'false');
......@@ -190,10 +188,10 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
// (there have been reports of tiny blinking cursors)
// (in WebKit the textarea is 1px by 1px because it cannot handle input to a 0x0 textarea)
this.textAreaCover = document.createElement('div');
if (this.context.configuration.editor.glyphMargin) {
if (this._context.configuration.editor.glyphMargin) {
this.textAreaCover.className = 'monaco-editor-background ' + editorBrowser.ClassNames.GLYPH_MARGIN + ' ' + editorBrowser.ClassNames.TEXTAREA_COVER;
} else {
if (this.context.configuration.editor.lineNumbers) {
if (this._context.configuration.editor.lineNumbers) {
this.textAreaCover.className = 'monaco-editor-background ' + editorBrowser.ClassNames.LINE_NUMBERS + ' ' + editorBrowser.ClassNames.TEXTAREA_COVER;
} else {
this.textAreaCover.className = 'monaco-editor-background ' + editorBrowser.ClassNames.TEXTAREA_COVER;
......@@ -210,48 +208,48 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
this.viewParts = [];
// View Lines
this.viewLines = new ViewLines(this.context, this.layoutProvider);
this.viewLines = new ViewLines(this._context, this.layoutProvider);
// View Zones
this.viewZones = new ViewZones(this.context, this.layoutProvider);
this.viewZones = new ViewZones(this._context, this.layoutProvider);
this.viewParts.push(this.viewZones);
// Decorations overview ruler
var decorationsOverviewRuler = new DecorationsOverviewRuler(
this.context, this.layoutProvider.getScrollHeight(),
this._context, this.layoutProvider.getScrollHeight(),
(lineNumber:number) => this.layoutProvider.getVerticalOffsetForLineNumber(lineNumber)
);
this.viewParts.push(decorationsOverviewRuler);
var scrollDecoration = new ScrollDecorationViewPart(this.context);
var scrollDecoration = new ScrollDecorationViewPart(this._context);
this.viewParts.push(scrollDecoration);
var contentViewOverlays = new ContentViewOverlays(this.context, this.layoutProvider);
var contentViewOverlays = new ContentViewOverlays(this._context, this.layoutProvider);
this.viewParts.push(contentViewOverlays);
contentViewOverlays.addDynamicOverlay(new CurrentLineHighlightOverlay(this.context, this.layoutProvider));
contentViewOverlays.addDynamicOverlay(new SelectionsOverlay(this.context));
contentViewOverlays.addDynamicOverlay(new DecorationsOverlay(this.context));
contentViewOverlays.addDynamicOverlay(new CurrentLineHighlightOverlay(this._context, this.layoutProvider));
contentViewOverlays.addDynamicOverlay(new SelectionsOverlay(this._context));
contentViewOverlays.addDynamicOverlay(new DecorationsOverlay(this._context));
var marginViewOverlays = new MarginViewOverlays(this.context, this.layoutProvider);
var marginViewOverlays = new MarginViewOverlays(this._context, this.layoutProvider);
this.viewParts.push(marginViewOverlays);
marginViewOverlays.addDynamicOverlay(new GlyphMarginOverlay(this.context));
marginViewOverlays.addDynamicOverlay(new LinesDecorationsOverlay(this.context));
marginViewOverlays.addDynamicOverlay(new LineNumbersOverlay(this.context));
marginViewOverlays.addDynamicOverlay(new GlyphMarginOverlay(this._context));
marginViewOverlays.addDynamicOverlay(new LinesDecorationsOverlay(this._context));
marginViewOverlays.addDynamicOverlay(new LineNumbersOverlay(this._context));
// Content widgets
this.contentWidgets = new ViewContentWidgets(this.context, this.domNode);
this.contentWidgets = new ViewContentWidgets(this._context, this.domNode);
this.viewParts.push(this.contentWidgets);
var viewCursors = new ViewCursors(this.context);
var viewCursors = new ViewCursors(this._context);
this.viewParts.push(viewCursors);
// Overlay widgets
this.overlayWidgets = new ViewOverlayWidgets(this.context);
this.overlayWidgets = new ViewOverlayWidgets(this._context);
this.viewParts.push(this.overlayWidgets);
var rulers = new Rulers(this.context, this.layoutProvider);
var rulers = new Rulers(this._context, this.layoutProvider);
this.viewParts.push(rulers);
// -------------- Wire dom nodes up
......@@ -446,10 +444,10 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
}
public onConfigurationChanged(e: editorCommon.IConfigurationChangedEvent): boolean {
if (e.editorClassName) {
this.domNode.className = this.context.configuration.editor.editorClassName;
this.domNode.className = this._context.configuration.editor.editorClassName;
}
if (e.ariaLabel) {
this.textArea.setAttribute('aria-label', this.context.configuration.editor.ariaLabel);
this.textArea.setAttribute('aria-label', this._context.configuration.editor.ariaLabel);
}
return false;
}
......@@ -556,11 +554,11 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
if (this._isDisposed) {
throw new Error('ViewImpl.codeEditorHelper.getVerticalOffsetForPosition: View is disposed');
}
var modelPosition = this.context.model.validateModelPosition({
var modelPosition = this._context.model.validateModelPosition({
lineNumber: modelLineNumber,
column: modelColumn
});
var viewPosition = this.context.model.convertModelPositionToViewPosition(modelPosition.lineNumber, modelPosition.column);
var viewPosition = this._context.model.convertModelPositionToViewPosition(modelPosition.lineNumber, modelPosition.column);
return this.layoutProvider.getVerticalOffsetForLineNumber(viewPosition.lineNumber);
},
delegateVerticalScrollbarMouseDown: (browserEvent: MouseEvent) => {
......@@ -573,11 +571,11 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
if (this._isDisposed) {
throw new Error('ViewImpl.codeEditorHelper.getOffsetForColumn: View is disposed');
}
var modelPosition = this.context.model.validateModelPosition({
var modelPosition = this._context.model.validateModelPosition({
lineNumber: modelLineNumber,
column: modelColumn
});
var viewPosition = this.context.model.convertModelPositionToViewPosition(modelPosition.lineNumber, modelPosition.column);
var viewPosition = this._context.model.convertModelPositionToViewPosition(modelPosition.lineNumber, modelPosition.column);
this._flushAccumulatedAndRenderNow();
var visibleRanges = this.viewLines.visibleRangesForRange2(new Range(viewPosition.lineNumber, viewPosition.column, viewPosition.lineNumber, viewPosition.column), 0);
if (!visibleRanges) {
......@@ -595,7 +593,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
throw new Error('ViewImpl.getCenteredRangeInViewport: View is disposed');
}
var viewLineNumber = this.layoutProvider.getCenteredViewLineNumberInViewport();
var viewModel = this.context.model;
var viewModel = this._context.model;
var currentCenteredViewRange = new Range(viewLineNumber, 1, viewLineNumber, viewModel.getLineMaxColumn(viewLineNumber));
return viewModel.convertViewRangeToModelRange(currentCenteredViewRange);
}
......@@ -648,7 +646,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
throw new Error('ViewImpl.createOverviewRuler: View is disposed');
}
return new OverviewRuler(
this.context, cssClassName, this.layoutProvider.getScrollHeight(), minimumHeight, maximumHeight,
this._context, cssClassName, this.layoutProvider.getScrollHeight(), minimumHeight, maximumHeight,
(lineNumber:number) => this.layoutProvider.getVerticalOffsetForLineNumber(lineNumber)
);
}
......@@ -681,7 +679,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
changeAccessor.removeZone = null;
if (zonesHaveChanged) {
this.context.privateViewEventBus.emit(editorCommon.EventType.ViewZonesChanged, null);
this._context.privateViewEventBus.emit(editorCommon.EventType.ViewZonesChanged, null);
}
return r;
......@@ -922,7 +920,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
private _setHasFocus(newHasFocus:boolean): void {
if (this.hasFocus !== newHasFocus) {
this.hasFocus = newHasFocus;
this.context.privateViewEventBus.emit(editorCommon.EventType.ViewFocusChanged, this.hasFocus);
this._context.privateViewEventBus.emit(editorCommon.EventType.ViewFocusChanged, this.hasFocus);
}
}
}
......
......@@ -30,6 +30,7 @@ export class CodeEditorWidget extends CommonCodeEditor implements editorBrowser.
protected domElement:HTMLElement;
private focusTracker:dom.IFocusTracker;
private _hasWidgetFocus: boolean;
_configuration:Configuration;
......@@ -48,17 +49,21 @@ export class CodeEditorWidget extends CommonCodeEditor implements editorBrowser.
) {
super(domElement, options, instantiationService, codeEditorService, keybindingService, telemetryService);
this._hasWidgetFocus = false;
// track focus of the domElement and all its anchestors
this.focusTracker = dom.trackFocus(this.domElement);
this.focusTracker.addFocusListener(() => {
if (this.forcedWidgetFocusCount === 0) {
this._editorFocusContextKey.set(true);
this._hasWidgetFocus = true;
this.emit(editorCommon.EventType.EditorFocus, {});
}
});
this.focusTracker.addBlurListener(() => {
if (this.forcedWidgetFocusCount === 0) {
this._editorFocusContextKey.reset();
this._hasWidgetFocus = false;
this.emit(editorCommon.EventType.EditorBlur, {});
}
});
......@@ -253,6 +258,10 @@ export class CodeEditorWidget extends CommonCodeEditor implements editorBrowser.
return this.hasView && this._view.isFocused();
}
public hasWidgetFocus(): boolean {
return this._hasWidgetFocus;
}
public addContentWidget(widget: editorBrowser.IContentWidget): void {
var widgetData: editorBrowser.IContentWidgetData = {
widget: widget,
......@@ -447,7 +456,6 @@ export class CodeEditorWidget extends CommonCodeEditor implements editorBrowser.
protected _createView(): void {
this._view = new View(
this.id,
this._configuration,
this.viewModel,
this._keybindingService
......
......@@ -38,6 +38,10 @@ export class EmbeddedCodeEditorWidget extends CodeEditorWidget {
this._lifetimeDispose.push(parentEditor.addListener2(EventType.ConfigurationChanged, (e:IConfigurationChangedEvent) => this._onParentConfigurationChanged(e)));
}
public getParentEditor(): ICodeEditor {
return this._parentEditor;
}
private _onParentConfigurationChanged(e:IConfigurationChangedEvent): void {
super.updateOptions(this._parentEditor.getRawConfiguration());
super.updateOptions(this._overwriteOptions);
......
......@@ -510,6 +510,8 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr
public abstract isFocused(): boolean;
public abstract hasWidgetFocus(): boolean;
public getContribution(id: string): editorCommon.IEditorContribution {
return this.contributions[id] || null;
}
......
......@@ -14,27 +14,19 @@ import {ICodeEditorService} from 'vs/editor/common/services/codeEditorService';
const H = editorCommon.Handler;
export function findFocusedEditor(commandId: string, accessor: ServicesAccessor, args: any, complain: boolean): editorCommon.ICommonCodeEditor {
let codeEditorService = accessor.get(ICodeEditorService);
let editorId = args.context.editorId;
if (!editorId) {
if (complain) {
console.warn('Cannot execute ' + commandId + ' because no editor is focused.');
}
return null;
}
let editor = codeEditorService.getCodeEditor(editorId);
export function findFocusedEditor(commandId: string, accessor: ServicesAccessor, complain: boolean): editorCommon.ICommonCodeEditor {
let editor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
if (!editor) {
if (complain) {
console.warn('Cannot execute ' + commandId + ' because editor `' + editorId + '` could not be found.');
console.warn('Cannot execute ' + commandId + ' because no code editor is focused.');
}
return null;
}
return editor;
}
export function withCodeEditorFromCommandHandler(commandId: string, accessor: ServicesAccessor, args: any, callback: (editor:editorCommon.ICommonCodeEditor) => void): void {
let editor = findFocusedEditor(commandId, accessor, args, true);
export function withCodeEditorFromCommandHandler(commandId: string, accessor: ServicesAccessor, callback: (editor:editorCommon.ICommonCodeEditor) => void): void {
let editor = findFocusedEditor(commandId, accessor, true);
if (editor) {
callback(editor);
}
......@@ -57,17 +49,17 @@ export function getActiveEditor(accessor: ServicesAccessor): editorCommon.ICommo
}
function triggerEditorHandler(handlerId: string, accessor: ServicesAccessor, args: any): void {
withCodeEditorFromCommandHandler(handlerId, accessor, args, (editor) => {
withCodeEditorFromCommandHandler(handlerId, accessor, (editor) => {
editor.trigger('keyboard', handlerId, args);
});
}
function registerCoreCommand(handlerId: string, kb: IKeybindings, weight: number = KeybindingsRegistry.WEIGHT.editorCore(), context?: KbExpr): void {
function registerCoreCommand(handlerId: string, kb: IKeybindings, weight: number = KeybindingsRegistry.WEIGHT.editorCore(), when?: KbExpr): void {
let desc: ICommandDescriptor = {
id: handlerId,
handler: triggerEditorHandler.bind(null, handlerId),
weight: weight,
context: (context ? context : KbExpr.has(editorCommon.KEYBINDING_CONTEXT_EDITOR_TEXT_FOCUS)),
when: (when ? when : KbExpr.has(editorCommon.KEYBINDING_CONTEXT_EDITOR_TEXT_FOCUS)),
primary: kb.primary,
secondary: kb.secondary,
win: kb.win,
......@@ -82,7 +74,7 @@ function registerCoreDispatchCommand2(handlerId: string) {
id: handlerId,
handler: triggerEditorHandler.bind(null, handlerId),
weight: KeybindingsRegistry.WEIGHT.editorCore(),
context: null,
when: null,
primary: 0
};
KeybindingsRegistry.registerCommandDesc(desc);
......@@ -90,12 +82,12 @@ function registerCoreDispatchCommand2(handlerId: string) {
let desc2: ICommandDescriptor = {
id: 'default:' + handlerId,
handler: (accessor: ServicesAccessor, args: any) => {
withCodeEditorFromCommandHandler(handlerId, accessor, args, (editor) => {
withCodeEditorFromCommandHandler(handlerId, accessor, (editor) => {
editor.trigger('keyboard', handlerId, args[0]);
});
},
weight: KeybindingsRegistry.WEIGHT.editorCore(),
context: null,
when: null,
primary: 0
};
KeybindingsRegistry.registerCommandDesc(desc2);
......@@ -384,13 +376,11 @@ registerCoreCommand(H.Redo, {
function selectAll(accessor: ServicesAccessor, args: any): void {
let HANDLER = editorCommon.Handler.SelectAll;
// If editor text focus
if (args.context[editorCommon.KEYBINDING_CONTEXT_EDITOR_TEXT_FOCUS]) {
let focusedEditor = findFocusedEditor(HANDLER, accessor, args, false);
if (focusedEditor) {
focusedEditor.trigger('keyboard', HANDLER, args);
return;
}
let focusedEditor = findFocusedEditor(HANDLER, accessor, false);
// Only if editor text focus (i.e. not if editor has widget focus).
if (focusedEditor && focusedEditor.isFocused()) {
focusedEditor.trigger('keyboard', HANDLER, args);
return;
}
// Ignore this action when user is focussed on an element that allows for entering text
......@@ -411,6 +401,6 @@ KeybindingsRegistry.registerCommandDesc({
id: 'editor.action.selectAll',
handler: selectAll,
weight: KeybindingsRegistry.WEIGHT.editorCore(),
context: null,
when: null,
primary: KeyMod.CtrlCmd | KeyCode.KEY_A
});
......@@ -2770,7 +2770,7 @@ export interface IEditor extends IEventEmitter {
focus(): void;
/**
* Returns true if this editor has keyboard focus.
* Returns true if this editor has keyboard focus (e.g. cursor is blinking).
*/
isFocused(): boolean;
......@@ -3001,6 +3001,11 @@ export interface IRangeWithMessage {
export interface ICommonCodeEditor extends IEditor {
/**
* Returns true if this editor or one of its widgets has keyboard focus.
*/
hasWidgetFocus(): boolean;
/**
* Get a contribution of this editor.
* @id Unique identifier of the contribution.
......
......@@ -79,7 +79,7 @@ export module CommonEditorRegistry {
id: commandId,
handler: createCommandHandler(commandId, handler),
weight: weight,
context: contextRule(needsTextFocus, needsKey),
when: whenRule(needsTextFocus, needsKey),
primary: keybinding.primary,
secondary: keybinding.secondary,
win: keybinding.win,
......@@ -101,7 +101,7 @@ export module CommonEditorRegistry {
},
weight: KeybindingsRegistry.WEIGHT.editorContrib(),
primary: undefined,
context: undefined,
when: undefined,
});
}
......@@ -170,8 +170,9 @@ class EditorContributionRegistry {
}
public registerEditorAction(desc:EditorActionDescriptor): void {
var handler = desc.kbOpts.handler;
let handler = desc.kbOpts.handler;
if (!handler) {
// here
if (desc.kbOpts.context === ContextKey.EditorTextFocus || desc.kbOpts.context === ContextKey.EditorFocus) {
handler = triggerEditorAction.bind(null, desc.id);
} else {
......@@ -179,22 +180,23 @@ class EditorContributionRegistry {
}
}
var context: KbExpr = null;
let when: KbExpr = null;
if (typeof desc.kbOpts.kbExpr === 'undefined') {
// here
if (desc.kbOpts.context === ContextKey.EditorTextFocus) {
context = KbExpr.has(editorCommon.KEYBINDING_CONTEXT_EDITOR_TEXT_FOCUS);
when = KbExpr.has(editorCommon.KEYBINDING_CONTEXT_EDITOR_TEXT_FOCUS);
} else if (desc.kbOpts.context === ContextKey.EditorFocus) {
context = KbExpr.has(editorCommon.KEYBINDING_CONTEXT_EDITOR_FOCUS);
when = KbExpr.has(editorCommon.KEYBINDING_CONTEXT_EDITOR_FOCUS);
}
} else {
context = desc.kbOpts.kbExpr;
when = desc.kbOpts.kbExpr;
}
var commandDesc: ICommandDescriptor = {
let commandDesc: ICommandDescriptor = {
id: desc.id,
handler: handler,
weight: KeybindingsRegistry.WEIGHT.editorContrib(),
context: context,
when: when,
primary: desc.kbOpts.primary,
secondary: desc.kbOpts.secondary,
win: desc.kbOpts.win,
......@@ -213,14 +215,14 @@ class EditorContributionRegistry {
Registry.add(Extensions.EditorCommonContributions, new EditorContributionRegistry());
function triggerEditorAction(actionId: string, accessor: ServicesAccessor, args: any): void {
withCodeEditorFromCommandHandler(actionId, accessor, args,(editor) => {
withCodeEditorFromCommandHandler(actionId, accessor, (editor) => {
editor.trigger('keyboard', actionId, args);
});
}
function triggerEditorActionGlobal(actionId: string, accessor: ServicesAccessor, args: any): void {
// TODO: this is not necessarily keyboard
var focusedEditor = findFocusedEditor(actionId, accessor, args, false);
var focusedEditor = findFocusedEditor(actionId, accessor, false);
if (focusedEditor) {
focusedEditor.trigger('keyboard', actionId, args);
return;
......@@ -239,7 +241,7 @@ function triggerEditorActionGlobal(actionId: string, accessor: ServicesAccessor,
var defaultEditorActionKeybindingOptions:IEditorActionKeybindingOptions = { primary: null, context: ContextKey.EditorTextFocus };
function contextRule(needsTextFocus: boolean, needsKey: string): KbExpr {
function whenRule(needsTextFocus: boolean, needsKey: string): KbExpr {
let base = KbExpr.has(needsTextFocus ? editorCommon.KEYBINDING_CONTEXT_EDITOR_TEXT_FOCUS : editorCommon.KEYBINDING_CONTEXT_EDITOR_FOCUS);
......@@ -252,8 +254,8 @@ function contextRule(needsTextFocus: boolean, needsKey: string): KbExpr {
function createCommandHandler(commandId: string, handler: IEditorCommandHandler): ICommandHandler {
return (accessor, args) => {
withCodeEditorFromCommandHandler(commandId, accessor, args, (editor) => {
withCodeEditorFromCommandHandler(commandId, accessor, (editor) => {
handler(accessor, editor, args);
});
};
}
\ No newline at end of file
}
......@@ -49,6 +49,26 @@ export abstract class AbstractCodeEditorService implements ICodeEditorService {
return Object.keys(this._codeEditors).map(id => this._codeEditors[id]);
}
public getFocusedCodeEditor(): ICommonCodeEditor {
let editorWithWidgetFocus: ICommonCodeEditor = null;
let editors = this.listCodeEditors();
for (let i = 0; i < editors.length; i++) {
let editor = editors[i];
if (editor.isFocused()) {
// bingo!
return editor;
}
if (editor.hasWidgetFocus()) {
editorWithWidgetFocus = editor;
}
}
return editorWithWidgetFocus;
}
public abstract registerDecorationType(key:string, options: IDecorationRenderOptions): void;
public abstract removeDecorationType(key:string): void;
public abstract resolveDecorationType(key:string): IModelDecorationOptions;
......
......@@ -15,17 +15,20 @@ export interface ICodeEditorService {
serviceId: ServiceIdentifier<any>;
addCodeEditor(editor: ICommonCodeEditor): void;
onCodeEditorAdd: Event<ICommonCodeEditor>;
removeCodeEditor(editor: ICommonCodeEditor): void;
onCodeEditorRemove: Event<ICommonCodeEditor>;
getCodeEditor(editorId: string): ICommonCodeEditor;
listCodeEditors(): ICommonCodeEditor[];
/**
* Returns the current focused code editor (if the focus is in the editor or in an editor widget) or null.
*/
getFocusedCodeEditor(): ICommonCodeEditor;
registerDecorationType(key:string, options: IDecorationRenderOptions): void;
removeDecorationType(key:string): void;
resolveDecorationType(key:string): IModelDecorationOptions;
......
......@@ -14,7 +14,6 @@ export interface IViewEventHandler {
export class ViewContext {
public editorId:number;
public configuration:IConfiguration;
public model: IViewModel;
public privateViewEventBus:IViewEventBus;
......@@ -22,7 +21,6 @@ export class ViewContext {
public removeEventHandler:(eventHandler:IViewEventHandler)=>void;
constructor(
editorId:number,
configuration:IConfiguration,
model: IViewModel,
privateViewEventBus:IViewEventBus,
......@@ -30,7 +28,6 @@ export class ViewContext {
removeEventHandler:(eventHandler:IViewEventHandler)=>void
)
{
this.editorId = editorId;
this.configuration = configuration;
this.model = model;
this.privateViewEventBus = privateViewEventBus;
......
......@@ -237,6 +237,6 @@ KeybindingsRegistry.registerCommandDesc({
GlobalScreenReaderNVDA.setValue(!currentValue);
},
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
context: null,
when: null,
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_R
});
......@@ -166,13 +166,11 @@ registerClipboardAction({
}, 'Paste');
function execCommandToHandler(actionId: string, browserCommand: string, accessor: ServicesAccessor, args: any): void {
// If editor text focus
if (args.context[editorCommon.KEYBINDING_CONTEXT_EDITOR_TEXT_FOCUS]) {
var focusedEditor = findFocusedEditor(actionId, accessor, args, false);
if (focusedEditor) {
focusedEditor.trigger('keyboard', actionId, args);
return;
}
let focusedEditor = findFocusedEditor(actionId, accessor, false);
// Only if editor text focus (i.e. not if editor has widget focus).
if (focusedEditor && focusedEditor.isFocused()) {
focusedEditor.trigger('keyboard', actionId, args);
return;
}
document.execCommand(browserCommand);
......
......@@ -371,14 +371,14 @@ KeybindingsRegistry.registerCommandDesc({
id: 'editor.action.findReferences',
handler: findReferencesCommand,
weight: CommonEditorRegistry.commandWeight(50),
context: null,
when: null,
primary: undefined
});
KeybindingsRegistry.registerCommandDesc({
id: 'editor.action.showReferences',
handler: showReferencesCommand,
weight: CommonEditorRegistry.commandWeight(50),
context: null,
when: null,
primary: undefined,
description: {
description: 'Show references at a position in a file',
......
......@@ -228,13 +228,13 @@ CommonEditorRegistry.registerEditorCommand(ACCEPT_SELECTED_SUGGESTION_CMD, weigh
KeybindingsRegistry.registerCommandDesc({
id: 'acceptSelectedSuggestionOnEnter',
handler(accessor, args) {
withCodeEditorFromCommandHandler('acceptSelectedSuggestionOnEnter', accessor, args, (editor) => {
withCodeEditorFromCommandHandler('acceptSelectedSuggestionOnEnter', accessor, (editor) => {
const controller = SuggestController.getSuggestController(editor);
controller.acceptSelectedSuggestion();
});
},
weight,
context: KbExpr.and(KbExpr.has(CONTEXT_SUGGEST_WIDGET_VISIBLE), KbExpr.has('config.editor.acceptSuggestionOnEnter')),
when: KbExpr.and(KbExpr.has(CONTEXT_SUGGEST_WIDGET_VISIBLE), KbExpr.has('config.editor.acceptSuggestionOnEnter')),
primary: KeyCode.Enter,
});
CommonEditorRegistry.registerEditorCommand('hideSuggestWidget', weight, { primary: KeyCode.Escape, secondary: [KeyMod.Shift | KeyCode.Escape] }, true, CONTEXT_SUGGEST_WIDGET_VISIBLE, (ctx, editor, args) => {
......
......@@ -19,6 +19,7 @@ import {ICommonCodeEditor} from 'vs/editor/common/editorCommon';
import {ICodeEditorService} from 'vs/editor/common/services/codeEditorService';
import {ICodeEditor} from 'vs/editor/browser/editorBrowser';
import {IOptions, ZoneWidget} from './zoneWidget';
import {EmbeddedCodeEditorWidget} from 'vs/editor/browser/widget/embeddedCodeEditorWidget';
export var IPeekViewService = createDecorator<IPeekViewService>('peekViewService');
......@@ -29,14 +30,12 @@ export interface IPeekViewService {
getActiveWidget(): PeekViewWidget;
}
var CONTEXT_OUTER_EDITOR = 'outerEditorId';
export function getOuterEditor(accessor: ServicesAccessor, args: any): ICommonCodeEditor {
var outerEditorId = args.context[CONTEXT_OUTER_EDITOR];
if (!outerEditorId) {
return null;
let editor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
if (editor instanceof EmbeddedCodeEditorWidget) {
return editor.getParentEditor();
}
return accessor.get(ICodeEditorService).getCodeEditor(outerEditorId);
return editor;
}
export class PeekViewWidget extends ZoneWidget implements IPeekViewService {
......@@ -57,7 +56,6 @@ export class PeekViewWidget extends ZoneWidget implements IPeekViewService {
constructor(editor: ICodeEditor, keybindingService: IKeybindingService, contextKey: string, options: IOptions = {}) {
super(editor, options);
this.contextKey = contextKey;
keybindingService.createKey(CONTEXT_OUTER_EDITOR, editor.getId());
}
public dispose(): void {
......
......@@ -42,6 +42,7 @@ export class MockCodeEditor extends CommonCodeEditor {
public focus(): void { }
public isFocused(): boolean { return true; }
public hasWidgetFocus(): boolean { return true; };
protected _enableEmptySelectionClipboard(): boolean { return false; }
protected _createView(): void { }
......
......@@ -378,16 +378,9 @@ export abstract class KeybindingService extends AbstractKeybindingService implem
public executeCommand(commandId: string, args: any = {}): TPromise<any> {
// TODO@{Alex,Joh} we should spec what args should be. adding extra
// props on a string will throw errors
if ((Array.isArray(args) || typeof args === 'object')
&& !args.context) {
args.context = Object.create(null);
this.getContext(this._findContextAttr(<HTMLElement>document.activeElement)).fillInContext(args.context);
this._configurationContext.fillInContext(args.context);
}
// TODO@{Alex,Joh} we should spec what args should be.
// TODO@Alex - move this to its own command
if (commandId === SET_CONTEXT_COMMAND_ID) {
var contextKey = String(args[0]);
var contextValue = args[1];
......
......@@ -26,7 +26,7 @@ interface IChordsMap {
}
interface ICommandEntry {
context: KbExpr;
when: KbExpr;
keybinding: number;
commandId: string;
}
......@@ -68,12 +68,12 @@ export class KeybindingResolver {
if (k.keybinding === 0) {
continue;
}
if (k.context) {
k.context = k.context.normalize();
if (k.when) {
k.when = k.when.normalize();
}
let entry: ICommandEntry = {
context: k.context,
when: k.when,
keybinding: k.keybinding,
commandId: k.command
};
......@@ -119,7 +119,7 @@ export class KeybindingResolver {
continue;
}
if (KeybindingResolver.contextIsEntirelyIncluded(true, conflict.context, item.context)) {
if (KeybindingResolver.whenIsEntirelyIncluded(true, conflict.when, item.when)) {
// `item` completely overwrites `conflict`
if (this._shouldWarnOnConflict && isDefault) {
console.warn('Conflict detected, command `' + conflict.commandId + '` cannot be triggered by ' + Keybinding.toUserSettingsLabel(keypress) + ' due to ' + item.command);
......@@ -138,7 +138,7 @@ export class KeybindingResolver {
* Returns true if `b` is a more relaxed `a`.
* Return true if (`a` === true implies `b` === true).
*/
public static contextIsEntirelyIncluded(inNormalizedForm: boolean, a: KbExpr, b: KbExpr): boolean {
public static whenIsEntirelyIncluded(inNormalizedForm: boolean, a: KbExpr, b: KbExpr): boolean {
if (!inNormalizedForm) {
a = a ? a.normalize() : null;
b = b ? b.normalize() : null;
......@@ -266,7 +266,7 @@ export class KeybindingResolver {
for (let i = matches.length - 1; i >= 0; i--) {
let k = matches[i];
if (!KeybindingResolver.contextMatchesRules(context, k.context)) {
if (!KeybindingResolver.contextMatchesRules(context, k.when)) {
continue;
}
......@@ -330,12 +330,12 @@ export class IOSupport {
let quotedSerializedKeybinding = JSON.stringify(IOSupport.writeKeybinding(item.keybinding));
out.write(`{ "key": ${rightPaddedString(quotedSerializedKeybinding + ',', 25)} "command": `);
let serializedContext = item.context ? item.context.serialize() : '';
let serializedWhen = item.when ? item.when.serialize() : '';
let quotedSerializeCommand = JSON.stringify(item.command);
if (serializedContext.length > 0) {
if (serializedWhen.length > 0) {
out.write(`${quotedSerializeCommand},`);
out.writeLine();
out.write(` "when": "${serializedContext}" `);
out.write(` "when": "${serializedWhen}" `);
} else {
out.write(`${quotedSerializeCommand} `);
}
......@@ -345,11 +345,11 @@ export class IOSupport {
public static readKeybindingItem(input: IUserFriendlyKeybinding, index: number): IKeybindingItem {
let key = IOSupport.readKeybinding(input.key);
let context = IOSupport.readKeybindingContexts(input.when);
let when = IOSupport.readKeybindingWhen(input.when);
return {
keybinding: key,
command: input.command,
context: context,
when: when,
weight1: 1000,
weight2: index
};
......@@ -363,7 +363,7 @@ export class IOSupport {
return Keybinding.fromUserSettingsLabel(input, Platform);
}
public static readKeybindingContexts(input: string): KbExpr {
public static readKeybindingWhen(input: string): KbExpr {
return KbExpr.deserialize(input);
}
}
......@@ -286,7 +286,7 @@ export let KbExpr = {
export interface IKeybindingItem {
keybinding: number;
command: string;
context: KbExpr;
when: KbExpr;
weight1: number;
weight2: number;
}
......
......@@ -13,7 +13,7 @@ import {Registry} from 'vs/platform/platform';
export interface ICommandRule extends IKeybindings {
id: string;
weight: number;
context: KbExpr;
when: KbExpr;
}
export interface ICommandDescriptor extends ICommandRule {
......@@ -88,12 +88,14 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
public registerCommandRule(rule: ICommandRule): void {
let actualKb = KeybindingsRegistryImpl.bindToCurrentPlatform(rule);
// here
if (actualKb && actualKb.primary) {
this.registerDefaultKeybinding(actualKb.primary, rule.id, rule.weight, 0, rule.context);
this.registerDefaultKeybinding(actualKb.primary, rule.id, rule.weight, 0, rule.when);
}
// here
if (actualKb && Array.isArray(actualKb.secondary)) {
actualKb.secondary.forEach((k, i) => this.registerDefaultKeybinding(k, rule.id, rule.weight, -i - 1, rule.context));
actualKb.secondary.forEach((k, i) => this.registerDefaultKeybinding(k, rule.id, rule.weight, -i - 1, rule.when));
}
}
......@@ -131,7 +133,7 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
return this._commands;
}
private registerDefaultKeybinding(keybinding: number, commandId: string, weight1: number, weight2: number, context: KbExpr): void {
private registerDefaultKeybinding(keybinding: number, commandId: string, weight1: number, weight2: number, when: KbExpr): void {
if (platform.isWindows) {
if (BinaryKeybindings.hasCtrlCmd(keybinding) && !BinaryKeybindings.hasShift(keybinding) && BinaryKeybindings.hasAlt(keybinding) && !BinaryKeybindings.hasWinCtrl(keybinding)) {
if (/^[A-Z0-9\[\]\|\;\'\,\.\/\`]$/.test(KeyCode.toString(BinaryKeybindings.extractKeyCode(keybinding)))) {
......@@ -142,7 +144,7 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
this._keybindings.push({
keybinding: keybinding,
command: commandId,
context: context,
when: when,
weight1: weight1,
weight2: weight2
});
......
......@@ -16,7 +16,7 @@ suite('Keybinding Service', () => {
let contextRules = KbExpr.equals('bar', 'baz');
let keybindingItem: IKeybindingItem = {
command: 'yes',
context: contextRules,
when: contextRules,
keybinding: keybinding,
weight1: 0,
weight2: 0
......@@ -44,10 +44,10 @@ suite('Keybinding Service', () => {
test('contextIsEntirelyIncluded', function() {
let assertIsIncluded = (a: KbExpr[], b: KbExpr[]) => {
assert.equal(KeybindingResolver.contextIsEntirelyIncluded(false, new KbAndExpression(a), new KbAndExpression(b)), true);
assert.equal(KeybindingResolver.whenIsEntirelyIncluded(false, new KbAndExpression(a), new KbAndExpression(b)), true);
};
let assertIsNotIncluded = (a: KbExpr[], b: KbExpr[]) => {
assert.equal(KeybindingResolver.contextIsEntirelyIncluded(false, new KbAndExpression(a), new KbAndExpression(b)), false);
assert.equal(KeybindingResolver.whenIsEntirelyIncluded(false, new KbAndExpression(a), new KbAndExpression(b)), false);
};
let key1IsTrue = KbExpr.equals('key1', true);
let key1IsNotFalse = KbExpr.notEquals('key1', false);
......@@ -97,10 +97,10 @@ suite('Keybinding Service', () => {
test('resolve command', function() {
let items: IKeybindingItem[] = [
// This one will never match because its context is always overwritten by another one
// This one will never match because its "when" is always overwritten by another one
{
keybinding: KeyCode.KEY_X,
context: KbExpr.and(
when: KbExpr.and(
KbExpr.equals('key1', true),
KbExpr.notEquals('key2', false)
),
......@@ -111,7 +111,7 @@ suite('Keybinding Service', () => {
// This one always overwrites first
{
keybinding: KeyCode.KEY_X,
context: KbExpr.equals('key2', true),
when: KbExpr.equals('key2', true),
command: 'second',
weight1: 2,
weight2: 0
......@@ -119,7 +119,7 @@ suite('Keybinding Service', () => {
// This one is a secondary mapping for `second`
{
keybinding: KeyCode.KEY_Z,
context: null,
when: null,
command: 'second',
weight1: 2.5,
weight2: 0
......@@ -127,7 +127,7 @@ suite('Keybinding Service', () => {
// This one sometimes overwrites first
{
keybinding: KeyCode.KEY_X,
context: KbExpr.equals('key3', true),
when: KbExpr.equals('key3', true),
command: 'third',
weight1: 3,
weight2: 0
......@@ -135,7 +135,7 @@ suite('Keybinding Service', () => {
// This one is always overwritten by another one
{
keybinding: KeyMod.CtrlCmd | KeyCode.KEY_Y,
context: KbExpr.equals('key4', true),
when: KbExpr.equals('key4', true),
command: 'fourth',
weight1: 4,
weight2: 0
......@@ -143,7 +143,7 @@ suite('Keybinding Service', () => {
// This one overwrites with a chord the previous one
{
keybinding: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_Y, KeyCode.KEY_Z),
context: null,
when: null,
command: 'fifth',
weight1: 5,
weight2: 0
......@@ -151,49 +151,49 @@ suite('Keybinding Service', () => {
// This one has no keybinding
{
keybinding: 0,
context: null,
when: null,
command: 'sixth',
weight1: 6,
weight2: 0
},
{
keybinding: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_U),
context: null,
when: null,
command: 'seventh',
weight1: 6.5,
weight2: 0
},
{
keybinding: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_K),
context: null,
when: null,
command: 'seventh',
weight1: 6.5,
weight2: 0
},
{
keybinding: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_U),
context: null,
when: null,
command: 'uncomment lines',
weight1: 7,
weight2: 0
},
{
keybinding: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_C),
context: null,
when: null,
command: 'comment lines',
weight1: 8,
weight2: 0
},
{
keybinding: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_G, KeyMod.CtrlCmd | KeyCode.KEY_C),
context: null,
when: null,
command: 'unreachablechord',
weight1: 10,
weight2: 0
},
{
keybinding: KeyMod.CtrlCmd | KeyCode.KEY_G,
context: null,
when: null,
command: 'eleven',
weight1: 11,
weight2: 0
......@@ -275,7 +275,7 @@ suite('Keybinding Service', () => {
'c': '5'
};
function testExpression(expr: string, expected: boolean): void {
let rules = IOSupport.readKeybindingContexts(expr);
let rules = IOSupport.readKeybindingWhen(expr);
assert.equal(KeybindingResolver.contextMatchesRules(context, rules), expected, expr);
}
function testBatch(expr: string, value: any): void {
......
......@@ -13,7 +13,7 @@ suite('Keybinding Registry', () => {
KeybindingsRegistry.registerCommandDesc({
id: 'test',
context: undefined,
when: undefined,
primary: undefined,
weight: 0,
handler: function(accessor, args) {
......@@ -24,7 +24,7 @@ suite('Keybinding Registry', () => {
KeybindingsRegistry.registerCommandDesc({
id: 'test2',
description: 'test',
context: undefined,
when: undefined,
primary: undefined,
weight: 0,
handler: function(accessor, args) {
......@@ -34,7 +34,7 @@ suite('Keybinding Registry', () => {
KeybindingsRegistry.registerCommandDesc({
id: 'test3',
context: undefined,
when: undefined,
primary: undefined,
weight: 0,
description: {
......
......@@ -145,7 +145,7 @@ export class MainThreadCommands {
return this._proxy.$executeContributedCommand(id, ...args);
},
weight: undefined,
context: undefined,
when: undefined,
win: undefined,
mac: undefined,
linux: undefined,
......@@ -190,7 +190,7 @@ KeybindingsRegistry.registerCommandDesc({
console.log(all.join('\n'));
});
},
context: undefined,
when: undefined,
weight: KeybindingsRegistry.WEIGHT.builtinExtension(0),
primary: undefined
});
......
......@@ -157,7 +157,7 @@ actionBarRegistry.registerActionBarContributor(Scope.EDITOR, IFrameEditorActionC
KeybindingsRegistry.registerCommandDesc({
id: 'workbench.action.compareEditor.nextChange',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
context: KbExpr.has('textCompareEditorVisible'),
when: KbExpr.has('textCompareEditorVisible'),
primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.RightArrow),
handler: accessor => navigateInDiffEditor(accessor, true)
});
......@@ -165,7 +165,7 @@ KeybindingsRegistry.registerCommandDesc({
KeybindingsRegistry.registerCommandDesc({
id: 'workbench.action.compareEditor.previousChange',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
context: KbExpr.has('textCompareEditorVisible'),
when: KbExpr.has('textCompareEditorVisible'),
primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.LeftArrow),
handler: accessor => navigateInDiffEditor(accessor, false)
});
......
......@@ -125,7 +125,7 @@ class WorkbenchActionRegistry implements IWorkbenchActionRegistry {
Registry.add(Extensions.WorkbenchActions, new WorkbenchActionRegistry());
function registerWorkbenchCommandFromAction(descriptor: SyncActionDescriptor): void {
let context = descriptor.keybindingContext;
let when = descriptor.keybindingContext;
let weight = (typeof descriptor.keybindingWeight === 'undefined' ? KeybindingsRegistry.WEIGHT.workbenchContrib() : descriptor.keybindingWeight);
let keybindings = descriptor.keybindings;
......@@ -133,7 +133,7 @@ function registerWorkbenchCommandFromAction(descriptor: SyncActionDescriptor): v
id: descriptor.id,
handler: createCommandHandler(descriptor),
weight: weight,
context: context,
when: when,
primary: keybindings && keybindings.primary,
secondary: keybindings && keybindings.secondary,
win: keybindings && keybindings.win,
......
......@@ -479,6 +479,6 @@ KeybindingsRegistry.registerCommandDesc({
ipc.send(ipcMessage);
}
},
context: undefined,
when: undefined,
primary: undefined
});
\ No newline at end of file
......@@ -24,7 +24,7 @@ CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(ExpandAbbre
KeybindingsRegistry.registerCommandRule({
id: ExpandAbbreviationAction.ID,
weight: KeybindingsRegistry.WEIGHT.editorContrib(),
context: KbExpr.and(
when: KbExpr.and(
KbExpr.has(editorCommon.KEYBINDING_CONTEXT_EDITOR_TEXT_FOCUS),
KbExpr.not(editorCommon.KEYBINDING_CONTEXT_EDITOR_HAS_NON_EMPTY_SELECTION),
KbExpr.not(editorCommon.KEYBINDING_CONTEXT_EDITOR_HAS_MULTIPLE_SELECTIONS),
......
......@@ -37,6 +37,6 @@ KeybindingsRegistry.registerCommandDesc({
return accessor.get(IWorkbenchEditorService).openEditor(input, null, position)
.then(editor => true);
},
context: undefined,
when: undefined,
primary: undefined
});
......@@ -28,7 +28,7 @@ import {IOpenerService} from 'vs/platform/opener/common/opener';
KeybindingsRegistry.registerCommandDesc({
id: '_webview.openDevTools',
context: null,
when: null,
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(0),
primary: null,
handler() {
......
......@@ -33,7 +33,7 @@ export const VIEWLET_ID = 'workbench.view.search';
KeybindingsRegistry.registerCommandDesc({
id: 'workbench.action.search.toggleQueryDetails',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
context: KbExpr.has('searchViewletVisible'),
when: KbExpr.has('searchViewletVisible'),
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_J,
handler: accessor => {
let viewletService = accessor.get(IViewletService);
......
......@@ -179,7 +179,7 @@ KeybindingsRegistry.registerCommandDesc({
}
},
context: undefined,
when: undefined,
primary: undefined
});
......@@ -272,7 +272,7 @@ export class WorkbenchKeybindingService extends KeybindingService {
let desc = {
id: command,
context: IOSupport.readKeybindingContexts(when),
when: IOSupport.readKeybindingWhen(when),
weight: weight,
primary: IOSupport.readKeybinding(key),
mac: mac && { primary: IOSupport.readKeybinding(mac) },
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册