mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from master
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
|
||||
|
||||
@@ -29,17 +28,13 @@ export class CharWidthRequest {
|
||||
}
|
||||
}
|
||||
|
||||
interface ICharWidthReader {
|
||||
read(): void;
|
||||
}
|
||||
|
||||
class DomCharWidthReader implements ICharWidthReader {
|
||||
class DomCharWidthReader {
|
||||
|
||||
private readonly _bareFontInfo: BareFontInfo;
|
||||
private readonly _requests: CharWidthRequest[];
|
||||
|
||||
private _container: HTMLElement;
|
||||
private _testElements: HTMLSpanElement[];
|
||||
private _container: HTMLElement | null;
|
||||
private _testElements: HTMLSpanElement[] | null;
|
||||
|
||||
constructor(bareFontInfo: BareFontInfo, requests: CharWidthRequest[]) {
|
||||
this._bareFontInfo = bareFontInfo;
|
||||
@@ -54,13 +49,13 @@ class DomCharWidthReader implements ICharWidthReader {
|
||||
this._createDomElements();
|
||||
|
||||
// Add the container to the DOM
|
||||
document.body.appendChild(this._container);
|
||||
document.body.appendChild(this._container!);
|
||||
|
||||
// Read character widths
|
||||
this._readFromDomElements();
|
||||
|
||||
// Remove the container from the DOM
|
||||
document.body.removeChild(this._container);
|
||||
document.body.removeChild(this._container!);
|
||||
|
||||
this._container = null;
|
||||
this._testElements = null;
|
||||
@@ -73,7 +68,7 @@ class DomCharWidthReader implements ICharWidthReader {
|
||||
container.style.width = '50000px';
|
||||
|
||||
let regularDomNode = document.createElement('div');
|
||||
regularDomNode.style.fontFamily = this._bareFontInfo.fontFamily;
|
||||
regularDomNode.style.fontFamily = this._bareFontInfo.getMassagedFontFamily();
|
||||
regularDomNode.style.fontWeight = this._bareFontInfo.fontWeight;
|
||||
regularDomNode.style.fontSize = this._bareFontInfo.fontSize + 'px';
|
||||
regularDomNode.style.lineHeight = this._bareFontInfo.lineHeight + 'px';
|
||||
@@ -81,7 +76,7 @@ class DomCharWidthReader implements ICharWidthReader {
|
||||
container.appendChild(regularDomNode);
|
||||
|
||||
let boldDomNode = document.createElement('div');
|
||||
boldDomNode.style.fontFamily = this._bareFontInfo.fontFamily;
|
||||
boldDomNode.style.fontFamily = this._bareFontInfo.getMassagedFontFamily();
|
||||
boldDomNode.style.fontWeight = 'bold';
|
||||
boldDomNode.style.fontSize = this._bareFontInfo.fontSize + 'px';
|
||||
boldDomNode.style.lineHeight = this._bareFontInfo.lineHeight + 'px';
|
||||
@@ -89,7 +84,7 @@ class DomCharWidthReader implements ICharWidthReader {
|
||||
container.appendChild(boldDomNode);
|
||||
|
||||
let italicDomNode = document.createElement('div');
|
||||
italicDomNode.style.fontFamily = this._bareFontInfo.fontFamily;
|
||||
italicDomNode.style.fontFamily = this._bareFontInfo.getMassagedFontFamily();
|
||||
italicDomNode.style.fontWeight = this._bareFontInfo.fontWeight;
|
||||
italicDomNode.style.fontSize = this._bareFontInfo.fontSize + 'px';
|
||||
italicDomNode.style.lineHeight = this._bareFontInfo.lineHeight + 'px';
|
||||
@@ -112,11 +107,11 @@ class DomCharWidthReader implements ICharWidthReader {
|
||||
parent = italicDomNode;
|
||||
}
|
||||
|
||||
parent.appendChild(document.createElement('br'));
|
||||
parent!.appendChild(document.createElement('br'));
|
||||
|
||||
let testElement = document.createElement('span');
|
||||
DomCharWidthReader._render(testElement, request);
|
||||
parent.appendChild(testElement);
|
||||
parent!.appendChild(testElement);
|
||||
|
||||
testElements[i] = testElement;
|
||||
}
|
||||
@@ -146,7 +141,7 @@ class DomCharWidthReader implements ICharWidthReader {
|
||||
private _readFromDomElements(): void {
|
||||
for (let i = 0, len = this._requests.length; i < len; i++) {
|
||||
const request = this._requests[i];
|
||||
const testElement = this._testElements[i];
|
||||
const testElement = this._testElements![i];
|
||||
|
||||
request.fulfill(testElement.offsetWidth / 256);
|
||||
}
|
||||
|
||||
@@ -2,20 +2,19 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import { FastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import { CommonEditorConfiguration, IEnvConfiguration } from 'vs/editor/common/config/commonEditorConfig';
|
||||
import { IDimension } from 'vs/editor/common/editorCommon';
|
||||
import { FontInfo, BareFontInfo } from 'vs/editor/common/config/fontInfo';
|
||||
import { ElementSizeObserver } from 'vs/editor/browser/config/elementSizeObserver';
|
||||
import { FastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { CharWidthRequest, CharWidthRequestType, readCharWidths } from 'vs/editor/browser/config/charWidthReader';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { ElementSizeObserver } from 'vs/editor/browser/config/elementSizeObserver';
|
||||
import { CommonEditorConfiguration, IEnvConfiguration } from 'vs/editor/common/config/commonEditorConfig';
|
||||
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { BareFontInfo, FontInfo } from 'vs/editor/common/config/fontInfo';
|
||||
import { IDimension } from 'vs/editor/common/editorCommon';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
|
||||
class CSSBasedConfigurationCache {
|
||||
|
||||
@@ -63,7 +62,7 @@ export function restoreFontInfo(storageService: IStorageService): void {
|
||||
if (typeof strStoredFontInfo !== 'string') {
|
||||
return;
|
||||
}
|
||||
let storedFontInfo: ISerializedFontInfo[] = null;
|
||||
let storedFontInfo: ISerializedFontInfo[] | null = null;
|
||||
try {
|
||||
storedFontInfo = JSON.parse(strStoredFontInfo);
|
||||
} catch (err) {
|
||||
@@ -77,7 +76,9 @@ export function restoreFontInfo(storageService: IStorageService): void {
|
||||
|
||||
export function saveFontInfo(storageService: IStorageService): void {
|
||||
let knownFontInfo = CSSBasedConfiguration.INSTANCE.saveFontInfo();
|
||||
storageService.store('editorFontInfo', JSON.stringify(knownFontInfo), StorageScope.GLOBAL);
|
||||
if (knownFontInfo.length > 0) {
|
||||
storageService.store('editorFontInfo', JSON.stringify(knownFontInfo), StorageScope.GLOBAL);
|
||||
}
|
||||
}
|
||||
|
||||
export interface ISerializedFontInfo {
|
||||
@@ -90,6 +91,7 @@ export interface ISerializedFontInfo {
|
||||
readonly isMonospace: boolean;
|
||||
readonly typicalHalfwidthCharacterWidth: number;
|
||||
readonly typicalFullwidthCharacterWidth: number;
|
||||
readonly canUseHalfwidthRightwardsArrow: boolean;
|
||||
readonly spaceWidth: number;
|
||||
readonly maxDigitWidth: number;
|
||||
}
|
||||
@@ -99,7 +101,7 @@ class CSSBasedConfiguration extends Disposable {
|
||||
public static readonly INSTANCE = new CSSBasedConfiguration();
|
||||
|
||||
private _cache: CSSBasedConfigurationCache;
|
||||
private _evictUntrustedReadingsTimeout: number;
|
||||
private _evictUntrustedReadingsTimeout: any;
|
||||
|
||||
private _onDidChange = this._register(new Emitter<void>());
|
||||
public readonly onDidChange: Event<void> = this._onDidChange.event;
|
||||
@@ -176,6 +178,7 @@ class CSSBasedConfiguration extends Disposable {
|
||||
isMonospace: readConfig.isMonospace,
|
||||
typicalHalfwidthCharacterWidth: Math.max(readConfig.typicalHalfwidthCharacterWidth, 5),
|
||||
typicalFullwidthCharacterWidth: Math.max(readConfig.typicalFullwidthCharacterWidth, 5),
|
||||
canUseHalfwidthRightwardsArrow: readConfig.canUseHalfwidthRightwardsArrow,
|
||||
spaceWidth: Math.max(readConfig.spaceWidth, 5),
|
||||
maxDigitWidth: Math.max(readConfig.maxDigitWidth, 5),
|
||||
}, false);
|
||||
@@ -186,7 +189,7 @@ class CSSBasedConfiguration extends Disposable {
|
||||
return this._cache.get(bareFontInfo);
|
||||
}
|
||||
|
||||
private static createRequest(chr: string, type: CharWidthRequestType, all: CharWidthRequest[], monospace: CharWidthRequest[]): CharWidthRequest {
|
||||
private static createRequest(chr: string, type: CharWidthRequestType, all: CharWidthRequest[], monospace: CharWidthRequest[] | null): CharWidthRequest {
|
||||
let result = new CharWidthRequest(chr, type);
|
||||
all.push(result);
|
||||
if (monospace) {
|
||||
@@ -214,7 +217,9 @@ class CSSBasedConfiguration extends Disposable {
|
||||
const digit9 = this.createRequest('9', CharWidthRequestType.Regular, all, monospace);
|
||||
|
||||
// monospace test: used for whitespace rendering
|
||||
this.createRequest('→', CharWidthRequestType.Regular, all, monospace);
|
||||
const rightwardsArrow = this.createRequest('→', CharWidthRequestType.Regular, all, monospace);
|
||||
const halfwidthRightwardsArrow = this.createRequest('→', CharWidthRequestType.Regular, all, null);
|
||||
|
||||
this.createRequest('·', CharWidthRequestType.Regular, all, monospace);
|
||||
|
||||
// monospace test: some characters
|
||||
@@ -256,6 +261,16 @@ class CSSBasedConfiguration extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
let canUseHalfwidthRightwardsArrow = true;
|
||||
if (isMonospace && halfwidthRightwardsArrow.width !== referenceWidth) {
|
||||
// using a halfwidth rightwards arrow would break monospace...
|
||||
canUseHalfwidthRightwardsArrow = false;
|
||||
}
|
||||
if (halfwidthRightwardsArrow.width > rightwardsArrow.width) {
|
||||
// using a halfwidth rightwards arrow would paint a larger arrow than a regular rightwards arrow
|
||||
canUseHalfwidthRightwardsArrow = false;
|
||||
}
|
||||
|
||||
// let's trust the zoom level only 2s after it was changed.
|
||||
const canTrustBrowserZoomLevel = (browser.getTimeSinceLastZoomLevelChanged() > 2000);
|
||||
return new FontInfo({
|
||||
@@ -268,6 +283,7 @@ class CSSBasedConfiguration extends Disposable {
|
||||
isMonospace: isMonospace,
|
||||
typicalHalfwidthCharacterWidth: typicalHalfwidthCharacter.width,
|
||||
typicalFullwidthCharacterWidth: typicalFullwidthCharacter.width,
|
||||
canUseHalfwidthRightwardsArrow: canUseHalfwidthRightwardsArrow,
|
||||
spaceWidth: space.width,
|
||||
maxDigitWidth: maxDigitWidth
|
||||
}, canTrustBrowserZoomLevel);
|
||||
@@ -276,21 +292,8 @@ class CSSBasedConfiguration extends Disposable {
|
||||
|
||||
export class Configuration extends CommonEditorConfiguration {
|
||||
|
||||
private static _massageFontFamily(fontFamily: string): string {
|
||||
if (/[,"']/.test(fontFamily)) {
|
||||
// Looks like the font family might be already escaped
|
||||
return fontFamily;
|
||||
}
|
||||
if (/[+ ]/.test(fontFamily)) {
|
||||
// Wrap a font family using + or <space> with quotes
|
||||
return `"${fontFamily}"`;
|
||||
}
|
||||
|
||||
return fontFamily;
|
||||
}
|
||||
|
||||
public static applyFontInfoSlow(domNode: HTMLElement, fontInfo: BareFontInfo): void {
|
||||
domNode.style.fontFamily = Configuration._massageFontFamily(fontInfo.fontFamily);
|
||||
domNode.style.fontFamily = fontInfo.getMassagedFontFamily();
|
||||
domNode.style.fontWeight = fontInfo.fontWeight;
|
||||
domNode.style.fontSize = fontInfo.fontSize + 'px';
|
||||
domNode.style.lineHeight = fontInfo.lineHeight + 'px';
|
||||
@@ -298,7 +301,7 @@ export class Configuration extends CommonEditorConfiguration {
|
||||
}
|
||||
|
||||
public static applyFontInfo(domNode: FastDomNode<HTMLElement>, fontInfo: BareFontInfo): void {
|
||||
domNode.setFontFamily(Configuration._massageFontFamily(fontInfo.fontFamily));
|
||||
domNode.setFontFamily(fontInfo.getMassagedFontFamily());
|
||||
domNode.setFontWeight(fontInfo.fontWeight);
|
||||
domNode.setFontSize(fontInfo.fontSize);
|
||||
domNode.setLineHeight(fontInfo.lineHeight);
|
||||
@@ -307,7 +310,7 @@ export class Configuration extends CommonEditorConfiguration {
|
||||
|
||||
private readonly _elementSizeObserver: ElementSizeObserver;
|
||||
|
||||
constructor(options: IEditorOptions, referenceDomElement: HTMLElement = null) {
|
||||
constructor(options: IEditorOptions, referenceDomElement: HTMLElement | null = null) {
|
||||
super(options);
|
||||
|
||||
this._elementSizeObserver = this._register(new ElementSizeObserver(referenceDomElement, () => this._onReferenceDomElementSizeChanged()));
|
||||
|
||||
@@ -2,20 +2,19 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IDimension } from 'vs/editor/common/editorCommon';
|
||||
|
||||
export class ElementSizeObserver extends Disposable {
|
||||
|
||||
private referenceDomElement: HTMLElement;
|
||||
private measureReferenceDomElementToken: number;
|
||||
private referenceDomElement: HTMLElement | null;
|
||||
private measureReferenceDomElementToken: any;
|
||||
private changeCallback: () => void;
|
||||
private width: number;
|
||||
private height: number;
|
||||
|
||||
constructor(referenceDomElement: HTMLElement, changeCallback: () => void) {
|
||||
constructor(referenceDomElement: HTMLElement | null, changeCallback: () => void) {
|
||||
super();
|
||||
this.referenceDomElement = referenceDomElement;
|
||||
this.changeCallback = changeCallback;
|
||||
|
||||
@@ -3,31 +3,28 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { Command, EditorCommand, ICommandOptions, registerEditorCommand } from 'vs/editor/browser/editorExtensions';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { ColumnSelection, IColumnSelectResult } from 'vs/editor/common/controller/cursorColumnSelection';
|
||||
import { CursorContext, CursorState, EditOperationType, IColumnSelectData, ICursors, PartialCursorState, RevealTarget } from 'vs/editor/common/controller/cursorCommon';
|
||||
import { DeleteOperations } from 'vs/editor/common/controller/cursorDeleteOperations';
|
||||
import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents';
|
||||
import { CursorMove as CursorMove_, CursorMoveCommands } from 'vs/editor/common/controller/cursorMoveCommands';
|
||||
import { TypeOperations } from 'vs/editor/common/controller/cursorTypeOperations';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { CursorState, ICursors, RevealTarget, IColumnSelectData, CursorContext, EditOperationType } from 'vs/editor/common/controller/cursorCommon';
|
||||
import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents';
|
||||
import { CursorMoveCommands, CursorMove as CursorMove_ } from 'vs/editor/common/controller/cursorMoveCommands';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { registerEditorCommand, ICommandOptions, EditorCommand, Command } from 'vs/editor/browser/editorExtensions';
|
||||
import { IColumnSelectResult, ColumnSelection } from 'vs/editor/common/controller/cursorColumnSelection';
|
||||
import { Handler, ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import H = editorCommon.Handler;
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands';
|
||||
import { TypeOperations } from 'vs/editor/common/controller/cursorTypeOperations';
|
||||
import { DeleteOperations } from 'vs/editor/common/controller/cursorDeleteOperations';
|
||||
import { VerticalRevealType } from 'vs/editor/common/view/viewEvents';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
|
||||
const CORE_WEIGHT = KeybindingWeight.EditorCore;
|
||||
|
||||
@@ -123,7 +120,7 @@ export namespace EditorScroll_ {
|
||||
select?: boolean;
|
||||
}
|
||||
|
||||
export function parse(args: RawArguments): ParsedArguments {
|
||||
export function parse(args: RawArguments): ParsedArguments | null {
|
||||
let direction: Direction;
|
||||
switch (args.to) {
|
||||
case RawDirection.Up:
|
||||
@@ -263,7 +260,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorMoveCommands.moveTo(cursors.context, cursors.getPrimaryCursor(), this._inSelectionMode, args.position, args.viewPosition)
|
||||
]
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,7 +285,7 @@ export namespace CoreNavigationCommands {
|
||||
toViewLineNumber: result.toLineNumber,
|
||||
toViewVisualColumn: result.toVisualColumn
|
||||
});
|
||||
cursors.reveal(true, (result.reversed ? RevealTarget.TopMost : RevealTarget.BottomMost), editorCommon.ScrollType.Smooth);
|
||||
cursors.reveal(true, (result.reversed ? RevealTarget.TopMost : RevealTarget.BottomMost), ScrollType.Smooth);
|
||||
}
|
||||
|
||||
protected abstract _getColumnSelectResult(context: CursorContext, primary: CursorState, prevColumnSelectData: IColumnSelectData, args: any): IColumnSelectResult;
|
||||
@@ -458,7 +455,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorChangeReason.Explicit,
|
||||
CursorMoveCommands.move(cursors.context, cursors.getAll(), args)
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -705,14 +702,14 @@ export namespace CoreNavigationCommands {
|
||||
public runCoreEditorCommand(cursors: ICursors, args: any): void {
|
||||
const context = cursors.context;
|
||||
|
||||
let newState: CursorState;
|
||||
let newState: PartialCursorState;
|
||||
if (args.wholeLine) {
|
||||
newState = CursorMoveCommands.line(context, cursors.getPrimaryCursor(), false, args.position, args.viewPosition);
|
||||
} else {
|
||||
newState = CursorMoveCommands.moveTo(context, cursors.getPrimaryCursor(), false, args.position, args.viewPosition);
|
||||
}
|
||||
|
||||
const states = cursors.getAll();
|
||||
const states: PartialCursorState[] = cursors.getAll();
|
||||
|
||||
// Check if we should remove a cursor (sort of like a toggle)
|
||||
if (states.length > 1) {
|
||||
@@ -722,11 +719,11 @@ export namespace CoreNavigationCommands {
|
||||
for (let i = 0, len = states.length; i < len; i++) {
|
||||
const state = states[i];
|
||||
|
||||
if (newModelPosition && !state.modelState.selection.containsPosition(newModelPosition)) {
|
||||
if (newModelPosition && !state.modelState!.selection.containsPosition(newModelPosition)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newViewPosition && !state.viewState.selection.containsPosition(newViewPosition)) {
|
||||
if (newViewPosition && !state.viewState!.selection.containsPosition(newViewPosition)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -768,8 +765,9 @@ export namespace CoreNavigationCommands {
|
||||
|
||||
const lastAddedCursorIndex = cursors.getLastAddedCursorIndex();
|
||||
|
||||
let newStates = cursors.getAll().slice(0);
|
||||
newStates[lastAddedCursorIndex] = CursorMoveCommands.moveTo(context, newStates[lastAddedCursorIndex], true, args.position, args.viewPosition);
|
||||
const states = cursors.getAll();
|
||||
let newStates: PartialCursorState[] = states.slice(0);
|
||||
newStates[lastAddedCursorIndex] = CursorMoveCommands.moveTo(context, states[lastAddedCursorIndex], true, args.position, args.viewPosition);
|
||||
|
||||
cursors.context.model.pushStackElement();
|
||||
cursors.setStates(
|
||||
@@ -796,7 +794,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorChangeReason.Explicit,
|
||||
CursorMoveCommands.moveToBeginningOfLine(cursors.context, cursors.getAll(), this._inSelectionMode)
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -845,11 +843,11 @@ export namespace CoreNavigationCommands {
|
||||
CursorChangeReason.Explicit,
|
||||
this._exec(cursors.context, cursors.getAll())
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
|
||||
private _exec(context: CursorContext, cursors: CursorState[]): CursorState[] {
|
||||
let result: CursorState[] = [];
|
||||
private _exec(context: CursorContext, cursors: CursorState[]): PartialCursorState[] {
|
||||
let result: PartialCursorState[] = [];
|
||||
for (let i = 0, len = cursors.length; i < len; i++) {
|
||||
const cursor = cursors[i];
|
||||
const lineNumber = cursor.modelState.position.lineNumber;
|
||||
@@ -875,7 +873,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorChangeReason.Explicit,
|
||||
CursorMoveCommands.moveToEndOfLine(cursors.context, cursors.getAll(), this._inSelectionMode)
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -924,11 +922,11 @@ export namespace CoreNavigationCommands {
|
||||
CursorChangeReason.Explicit,
|
||||
this._exec(cursors.context, cursors.getAll())
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
|
||||
private _exec(context: CursorContext, cursors: CursorState[]): CursorState[] {
|
||||
let result: CursorState[] = [];
|
||||
private _exec(context: CursorContext, cursors: CursorState[]): PartialCursorState[] {
|
||||
let result: PartialCursorState[] = [];
|
||||
for (let i = 0, len = cursors.length; i < len; i++) {
|
||||
const cursor = cursors[i];
|
||||
const lineNumber = cursor.modelState.position.lineNumber;
|
||||
@@ -955,7 +953,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorChangeReason.Explicit,
|
||||
CursorMoveCommands.moveToBeginningOfBuffer(cursors.context, cursors.getAll(), this._inSelectionMode)
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -999,7 +997,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorChangeReason.Explicit,
|
||||
CursorMoveCommands.moveToEndOfBuffer(cursors.context, cursors.getAll(), this._inSelectionMode)
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1218,7 +1216,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorMoveCommands.word(cursors.context, cursors.getPrimaryCursor(), this._inSelectionMode, args.position)
|
||||
]
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1247,8 +1245,9 @@ export namespace CoreNavigationCommands {
|
||||
|
||||
const lastAddedCursorIndex = cursors.getLastAddedCursorIndex();
|
||||
|
||||
let newStates = cursors.getAll().slice(0);
|
||||
let lastAddedState = newStates[lastAddedCursorIndex];
|
||||
const states = cursors.getAll();
|
||||
let newStates: PartialCursorState[] = states.slice(0);
|
||||
let lastAddedState = states[lastAddedCursorIndex];
|
||||
newStates[lastAddedCursorIndex] = CursorMoveCommands.word(context, lastAddedState, lastAddedState.modelState.hasSelection(), args.position);
|
||||
|
||||
context.model.pushStackElement();
|
||||
@@ -1277,7 +1276,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorMoveCommands.line(cursors.context, cursors.getPrimaryCursor(), this._inSelectionMode, args.position, args.viewPosition)
|
||||
]
|
||||
);
|
||||
cursors.reveal(false, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
cursors.reveal(false, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1304,8 +1303,9 @@ export namespace CoreNavigationCommands {
|
||||
public runCoreEditorCommand(cursors: ICursors, args: any): void {
|
||||
const lastAddedCursorIndex = cursors.getLastAddedCursorIndex();
|
||||
|
||||
let newStates = cursors.getAll().slice(0);
|
||||
newStates[lastAddedCursorIndex] = CursorMoveCommands.line(cursors.context, newStates[lastAddedCursorIndex], this._inSelectionMode, args.position, args.viewPosition);
|
||||
const states = cursors.getAll();
|
||||
let newStates: PartialCursorState[] = states.slice(0);
|
||||
newStates[lastAddedCursorIndex] = CursorMoveCommands.line(cursors.context, states[lastAddedCursorIndex], this._inSelectionMode, args.position, args.viewPosition);
|
||||
|
||||
cursors.context.model.pushStackElement();
|
||||
cursors.setStates(
|
||||
@@ -1348,7 +1348,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorChangeReason.Explicit,
|
||||
CursorMoveCommands.expandLineSelection(cursors.context, cursors.getAll())
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1376,7 +1376,7 @@ export namespace CoreNavigationCommands {
|
||||
CursorMoveCommands.cancelSelection(cursors.context, cursors.getPrimaryCursor())
|
||||
]
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1403,7 +1403,7 @@ export namespace CoreNavigationCommands {
|
||||
cursors.getPrimaryCursor()
|
||||
]
|
||||
);
|
||||
cursors.reveal(true, RevealTarget.Primary, editorCommon.ScrollType.Smooth);
|
||||
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1418,7 +1418,7 @@ export namespace CoreNavigationCommands {
|
||||
|
||||
public runCoreEditorCommand(cursors: ICursors, args: any): void {
|
||||
const revealLineArg = <RevealLine_.RawArguments>args;
|
||||
let lineNumber = revealLineArg.lineNumber + 1;
|
||||
let lineNumber = (revealLineArg.lineNumber || 0) + 1;
|
||||
if (lineNumber < 1) {
|
||||
lineNumber = 1;
|
||||
}
|
||||
@@ -1451,7 +1451,7 @@ export namespace CoreNavigationCommands {
|
||||
|
||||
const viewRange = cursors.context.convertModelRangeToViewRange(range);
|
||||
|
||||
cursors.revealRange(false, viewRange, revealAt, editorCommon.ScrollType.Smooth);
|
||||
cursors.revealRange(false, viewRange, revealAt, ScrollType.Smooth);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1498,7 +1498,20 @@ export namespace CoreNavigationCommands {
|
||||
|
||||
export namespace CoreEditingCommands {
|
||||
|
||||
export const LineBreakInsert: EditorCommand = registerEditorCommand(new class extends EditorCommand {
|
||||
export abstract class CoreEditingCommand extends EditorCommand {
|
||||
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
|
||||
const cursors = editor._getCursors();
|
||||
if (!cursors) {
|
||||
// the editor has no view => has no cursors
|
||||
return;
|
||||
}
|
||||
this.runCoreEditingCommand(editor, cursors, args || {});
|
||||
}
|
||||
|
||||
public abstract runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void;
|
||||
}
|
||||
|
||||
export const LineBreakInsert: EditorCommand = registerEditorCommand(new class extends CoreEditingCommand {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'lineBreakInsert',
|
||||
@@ -1506,19 +1519,19 @@ export namespace CoreEditingCommands {
|
||||
kbOpts: {
|
||||
weight: CORE_WEIGHT,
|
||||
kbExpr: EditorContextKeys.textInputFocus,
|
||||
primary: null,
|
||||
primary: 0,
|
||||
mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_O }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
|
||||
public runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void {
|
||||
editor.pushUndoStop();
|
||||
editor.executeCommands(this.id, TypeOperations.lineBreakInsert(editor._getCursorConfiguration(), editor.getModel(), editor.getSelections()));
|
||||
editor.executeCommands(this.id, TypeOperations.lineBreakInsert(cursors.context.config, cursors.context.model, cursors.getAll().map(s => s.modelState.selection)));
|
||||
}
|
||||
});
|
||||
|
||||
export const Outdent: EditorCommand = registerEditorCommand(new class extends EditorCommand {
|
||||
export const Outdent: EditorCommand = registerEditorCommand(new class extends CoreEditingCommand {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'outdent',
|
||||
@@ -1534,14 +1547,14 @@ export namespace CoreEditingCommands {
|
||||
});
|
||||
}
|
||||
|
||||
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
|
||||
public runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void {
|
||||
editor.pushUndoStop();
|
||||
editor.executeCommands(this.id, TypeOperations.outdent(editor._getCursorConfiguration(), editor.getModel(), editor.getSelections()));
|
||||
editor.executeCommands(this.id, TypeOperations.outdent(cursors.context.config, cursors.context.model, cursors.getAll().map(s => s.modelState.selection)));
|
||||
editor.pushUndoStop();
|
||||
}
|
||||
});
|
||||
|
||||
export const Tab: EditorCommand = registerEditorCommand(new class extends EditorCommand {
|
||||
export const Tab: EditorCommand = registerEditorCommand(new class extends CoreEditingCommand {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'tab',
|
||||
@@ -1557,14 +1570,14 @@ export namespace CoreEditingCommands {
|
||||
});
|
||||
}
|
||||
|
||||
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
|
||||
public runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void {
|
||||
editor.pushUndoStop();
|
||||
editor.executeCommands(this.id, TypeOperations.tab(editor._getCursorConfiguration(), editor.getModel(), editor.getSelections()));
|
||||
editor.executeCommands(this.id, TypeOperations.tab(cursors.context.config, cursors.context.model, cursors.getAll().map(s => s.modelState.selection)));
|
||||
editor.pushUndoStop();
|
||||
}
|
||||
});
|
||||
|
||||
export const DeleteLeft: EditorCommand = registerEditorCommand(new class extends EditorCommand {
|
||||
export const DeleteLeft: EditorCommand = registerEditorCommand(new class extends CoreEditingCommand {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'deleteLeft',
|
||||
@@ -1579,9 +1592,8 @@ export namespace CoreEditingCommands {
|
||||
});
|
||||
}
|
||||
|
||||
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
|
||||
const cursors = editor._getCursors();
|
||||
const [shouldPushStackElementBefore, commands] = DeleteOperations.deleteLeft(cursors.getPrevEditOperationType(), editor._getCursorConfiguration(), editor.getModel(), editor.getSelections());
|
||||
public runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void {
|
||||
const [shouldPushStackElementBefore, commands] = DeleteOperations.deleteLeft(cursors.getPrevEditOperationType(), cursors.context.config, cursors.context.model, cursors.getAll().map(s => s.modelState.selection));
|
||||
if (shouldPushStackElementBefore) {
|
||||
editor.pushUndoStop();
|
||||
}
|
||||
@@ -1590,7 +1602,7 @@ export namespace CoreEditingCommands {
|
||||
}
|
||||
});
|
||||
|
||||
export const DeleteRight: EditorCommand = registerEditorCommand(new class extends EditorCommand {
|
||||
export const DeleteRight: EditorCommand = registerEditorCommand(new class extends CoreEditingCommand {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'deleteRight',
|
||||
@@ -1604,9 +1616,8 @@ export namespace CoreEditingCommands {
|
||||
});
|
||||
}
|
||||
|
||||
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
|
||||
const cursors = editor._getCursors();
|
||||
const [shouldPushStackElementBefore, commands] = DeleteOperations.deleteRight(cursors.getPrevEditOperationType(), editor._getCursorConfiguration(), editor.getModel(), editor.getSelections());
|
||||
public runCoreEditingCommand(editor: ICodeEditor, cursors: ICursors, args: any): void {
|
||||
const [shouldPushStackElementBefore, commands] = DeleteOperations.deleteRight(cursors.getPrevEditOperationType(), cursors.context.config, cursors.context.model, cursors.getAll().map(s => s.modelState.selection));
|
||||
if (shouldPushStackElementBefore) {
|
||||
editor.pushUndoStop();
|
||||
}
|
||||
@@ -1617,10 +1628,6 @@ export namespace CoreEditingCommands {
|
||||
|
||||
}
|
||||
|
||||
function findFocusedEditor(accessor: ServicesAccessor): ICodeEditor {
|
||||
return accessor.get(ICodeEditorService).getFocusedCodeEditor();
|
||||
}
|
||||
|
||||
function registerCommand(command: Command) {
|
||||
command.register();
|
||||
}
|
||||
@@ -1644,10 +1651,10 @@ class EditorOrNativeTextInputCommand extends Command {
|
||||
|
||||
public runCommand(accessor: ServicesAccessor, args: any): void {
|
||||
|
||||
let focusedEditor = findFocusedEditor(accessor);
|
||||
let focusedEditor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
|
||||
// Only if editor text focus (i.e. not if editor has widget focus).
|
||||
if (focusedEditor && focusedEditor.hasTextFocus()) {
|
||||
return this._runEditorHandler(focusedEditor, args);
|
||||
return this._runEditorHandler(accessor, focusedEditor, args);
|
||||
}
|
||||
|
||||
// Ignore this action when user is focused on an element that allows for entering text
|
||||
@@ -1661,18 +1668,18 @@ class EditorOrNativeTextInputCommand extends Command {
|
||||
let activeEditor = accessor.get(ICodeEditorService).getActiveCodeEditor();
|
||||
if (activeEditor) {
|
||||
activeEditor.focus();
|
||||
return this._runEditorHandler(activeEditor, args);
|
||||
return this._runEditorHandler(accessor, activeEditor, args);
|
||||
}
|
||||
}
|
||||
|
||||
private _runEditorHandler(editor: ICodeEditor, args: any): void {
|
||||
private _runEditorHandler(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
|
||||
let HANDLER = this._editorHandler;
|
||||
if (typeof HANDLER === 'string') {
|
||||
editor.trigger('keyboard', HANDLER, args);
|
||||
} else {
|
||||
args = args || {};
|
||||
args.source = 'keyboard';
|
||||
HANDLER.runEditorCommand(null, editor, args);
|
||||
HANDLER.runEditorCommand(accessor, editor, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1693,7 +1700,7 @@ class EditorHandlerCommand extends Command {
|
||||
}
|
||||
|
||||
public runCommand(accessor: ServicesAccessor, args: any): void {
|
||||
const editor = findFocusedEditor(accessor);
|
||||
const editor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
@@ -1721,9 +1728,9 @@ registerCommand(new EditorOrNativeTextInputCommand({
|
||||
}));
|
||||
|
||||
registerCommand(new EditorOrNativeTextInputCommand({
|
||||
editorHandler: H.Undo,
|
||||
editorHandler: Handler.Undo,
|
||||
inputHandler: 'undo',
|
||||
id: H.Undo,
|
||||
id: Handler.Undo,
|
||||
precondition: EditorContextKeys.writable,
|
||||
kbOpts: {
|
||||
weight: CORE_WEIGHT,
|
||||
@@ -1737,12 +1744,12 @@ registerCommand(new EditorOrNativeTextInputCommand({
|
||||
order: 1
|
||||
}
|
||||
}));
|
||||
registerCommand(new EditorHandlerCommand('default:' + H.Undo, H.Undo));
|
||||
registerCommand(new EditorHandlerCommand('default:' + Handler.Undo, Handler.Undo));
|
||||
|
||||
registerCommand(new EditorOrNativeTextInputCommand({
|
||||
editorHandler: H.Redo,
|
||||
editorHandler: Handler.Redo,
|
||||
inputHandler: 'redo',
|
||||
id: H.Redo,
|
||||
id: Handler.Redo,
|
||||
precondition: EditorContextKeys.writable,
|
||||
kbOpts: {
|
||||
weight: CORE_WEIGHT,
|
||||
@@ -1758,16 +1765,16 @@ registerCommand(new EditorOrNativeTextInputCommand({
|
||||
order: 2
|
||||
}
|
||||
}));
|
||||
registerCommand(new EditorHandlerCommand('default:' + H.Redo, H.Redo));
|
||||
registerCommand(new EditorHandlerCommand('default:' + Handler.Redo, Handler.Redo));
|
||||
|
||||
function registerOverwritableCommand(handlerId: string): void {
|
||||
registerCommand(new EditorHandlerCommand('default:' + handlerId, handlerId));
|
||||
registerCommand(new EditorHandlerCommand(handlerId, handlerId));
|
||||
}
|
||||
|
||||
registerOverwritableCommand(H.Type);
|
||||
registerOverwritableCommand(H.ReplacePreviousChar);
|
||||
registerOverwritableCommand(H.CompositionStart);
|
||||
registerOverwritableCommand(H.CompositionEnd);
|
||||
registerOverwritableCommand(H.Paste);
|
||||
registerOverwritableCommand(H.Cut);
|
||||
registerOverwritableCommand(Handler.Type);
|
||||
registerOverwritableCommand(Handler.ReplacePreviousChar);
|
||||
registerOverwritableCommand(Handler.CompositionStart);
|
||||
registerOverwritableCommand(Handler.CompositionEnd);
|
||||
registerOverwritableCommand(Handler.Paste);
|
||||
registerOverwritableCommand(Handler.Cut);
|
||||
|
||||
@@ -2,31 +2,30 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { StandardWheelEvent, IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { RunOnceScheduler, TimeoutTimer } from 'vs/base/common/async';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { HitTestContext, IViewZoneData, MouseTarget, MouseTargetFactory } from 'vs/editor/browser/controller/mouseTarget';
|
||||
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
|
||||
import { ClientCoordinates, EditorMouseEvent, EditorMouseEventFactory, GlobalEditorMouseMoveMonitor, createEditorPagePosition } from 'vs/editor/browser/editorDom';
|
||||
import { ViewController } from 'vs/editor/browser/view/viewController';
|
||||
import { IViewCursorRenderData } from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
|
||||
import { EditorZoom } from 'vs/editor/common/config/editorZoom';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
|
||||
import { MouseTarget, MouseTargetFactory, IViewZoneData, HitTestContext } from 'vs/editor/browser/controller/mouseTarget';
|
||||
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
|
||||
import { TimeoutTimer, RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { HorizontalRange } from 'vs/editor/common/view/renderingContext';
|
||||
import { EditorMouseEventFactory, GlobalEditorMouseMoveMonitor, EditorMouseEvent, createEditorPagePosition, ClientCoordinates } from 'vs/editor/browser/editorDom';
|
||||
import { StandardMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { EditorZoom } from 'vs/editor/common/config/editorZoom';
|
||||
import { IViewCursorRenderData } from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { ViewController } from 'vs/editor/browser/view/viewController';
|
||||
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
|
||||
|
||||
/**
|
||||
* Merges mouse events when mouse move events are throttled
|
||||
*/
|
||||
function createMouseMoveEventMerger(mouseTargetFactory: MouseTargetFactory) {
|
||||
function createMouseMoveEventMerger(mouseTargetFactory: MouseTargetFactory | null) {
|
||||
return function (lastEvent: EditorMouseEvent, currentEvent: EditorMouseEvent): EditorMouseEvent {
|
||||
let targetIsWidget = false;
|
||||
if (mouseTargetFactory) {
|
||||
@@ -56,9 +55,9 @@ export interface IPointerHandlerHelper {
|
||||
/**
|
||||
* Decode a position from a rendered dom node
|
||||
*/
|
||||
getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position;
|
||||
getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position | null;
|
||||
|
||||
visibleRangeForPosition2(lineNumber: number, column: number): HorizontalRange;
|
||||
visibleRangeForPosition2(lineNumber: number, column: number): HorizontalRange | null;
|
||||
getLineWidth(lineNumber: number): number;
|
||||
}
|
||||
|
||||
@@ -109,12 +108,12 @@ export class MouseHandler extends ViewEventHandler {
|
||||
|
||||
this._register(mouseEvents.onMouseDown(this.viewHelper.viewDomNode, (e) => this._onMouseDown(e)));
|
||||
|
||||
let onMouseWheel = (browserEvent: MouseWheelEvent) => {
|
||||
let onMouseWheel = (browserEvent: IMouseWheelEvent) => {
|
||||
if (!this._context.configuration.editor.viewInfo.mouseWheelZoom) {
|
||||
return;
|
||||
}
|
||||
let e = new StandardMouseWheelEvent(browserEvent);
|
||||
if (e.browserEvent.ctrlKey || e.browserEvent.metaKey) {
|
||||
let e = new StandardWheelEvent(browserEvent);
|
||||
if (e.browserEvent!.ctrlKey || e.browserEvent!.metaKey) {
|
||||
let zoomLevel: number = EditorZoom.getZoomLevel();
|
||||
let delta = e.deltaY > 0 ? 1 : -1;
|
||||
EditorZoom.setZoomLevel(zoomLevel + delta);
|
||||
@@ -123,7 +122,6 @@ export class MouseHandler extends ViewEventHandler {
|
||||
}
|
||||
};
|
||||
this._register(dom.addDisposableListener(this.viewHelper.viewDomNode, 'mousewheel', onMouseWheel, true));
|
||||
this._register(dom.addDisposableListener(this.viewHelper.viewDomNode, 'DOMMouseScroll', onMouseWheel, true));
|
||||
|
||||
this._context.addEventHandler(this);
|
||||
}
|
||||
@@ -149,7 +147,7 @@ export class MouseHandler extends ViewEventHandler {
|
||||
}
|
||||
// --- end event handlers
|
||||
|
||||
public getTargetAtClientPoint(clientX: number, clientY: number): editorBrowser.IMouseTarget {
|
||||
public getTargetAtClientPoint(clientX: number, clientY: number): editorBrowser.IMouseTarget | null {
|
||||
let clientPos = new ClientCoordinates(clientX, clientY);
|
||||
let pos = clientPos.toPageCoordinates();
|
||||
let editorPos = createEditorPagePosition(this.viewHelper.viewDomNode);
|
||||
@@ -277,7 +275,7 @@ class MouseDownOperation extends Disposable {
|
||||
|
||||
private _currentSelection: Selection;
|
||||
private _isActive: boolean;
|
||||
private _lastMouseEvent: EditorMouseEvent;
|
||||
private _lastMouseEvent: EditorMouseEvent | null;
|
||||
|
||||
constructor(
|
||||
context: ViewContext,
|
||||
@@ -337,7 +335,7 @@ class MouseDownOperation extends Disposable {
|
||||
this._mouseState.setStartButtons(e);
|
||||
this._mouseState.setModifiers(e);
|
||||
let position = this._findMousePosition(e, true);
|
||||
if (!position) {
|
||||
if (!position || !position.position) {
|
||||
// Ignoring because position is unknown
|
||||
return;
|
||||
}
|
||||
@@ -353,7 +351,8 @@ class MouseDownOperation extends Disposable {
|
||||
&& e.detail < 2 // only single click on a selection can work
|
||||
&& !this._isActive // the mouse is not down yet
|
||||
&& !this._currentSelection.isEmpty() // we don't drag single cursor
|
||||
&& this._currentSelection.containsPosition(position.position) // single click on a selection
|
||||
&& (position.type === editorBrowser.MouseTargetType.CONTENT_TEXT) // single click on text
|
||||
&& position.position && this._currentSelection.containsPosition(position.position) // single click on a selection
|
||||
) {
|
||||
this._mouseState.isDragAndDrop = true;
|
||||
this._isActive = true;
|
||||
@@ -362,11 +361,11 @@ class MouseDownOperation extends Disposable {
|
||||
createMouseMoveEventMerger(null),
|
||||
(e) => this._onMouseDownThenMove(e),
|
||||
() => {
|
||||
let position = this._findMousePosition(this._lastMouseEvent, true);
|
||||
let position = this._findMousePosition(this._lastMouseEvent!, true);
|
||||
|
||||
this._viewController.emitMouseDrop({
|
||||
event: this._lastMouseEvent,
|
||||
target: position ? this._createMouseTarget(this._lastMouseEvent, true) : null // Ignoring because position is unknown, e.g., Content View Zone
|
||||
event: this._lastMouseEvent!,
|
||||
target: (position ? this._createMouseTarget(this._lastMouseEvent!, true) : null) // Ignoring because position is unknown, e.g., Content View Zone
|
||||
});
|
||||
|
||||
this._stop();
|
||||
@@ -399,6 +398,9 @@ class MouseDownOperation extends Disposable {
|
||||
return;
|
||||
}
|
||||
this._onScrollTimeout.setIfNotSet(() => {
|
||||
if (!this._lastMouseEvent) {
|
||||
return;
|
||||
}
|
||||
let position = this._findMousePosition(this._lastMouseEvent, false);
|
||||
if (!position) {
|
||||
// Ignoring because position is unknown
|
||||
@@ -416,7 +418,7 @@ class MouseDownOperation extends Disposable {
|
||||
this._currentSelection = e.selections[0];
|
||||
}
|
||||
|
||||
private _getPositionOutsideEditor(e: EditorMouseEvent): MouseTarget {
|
||||
private _getPositionOutsideEditor(e: EditorMouseEvent): MouseTarget | null {
|
||||
const editorContent = e.editorPos;
|
||||
const model = this._context.model;
|
||||
const viewLayout = this._context.viewLayout;
|
||||
@@ -464,7 +466,7 @@ class MouseDownOperation extends Disposable {
|
||||
return null;
|
||||
}
|
||||
|
||||
private _findMousePosition(e: EditorMouseEvent, testEventTarget: boolean): MouseTarget {
|
||||
private _findMousePosition(e: EditorMouseEvent, testEventTarget: boolean): MouseTarget | null {
|
||||
let positionOutsideEditor = this._getPositionOutsideEditor(e);
|
||||
if (positionOutsideEditor) {
|
||||
return positionOutsideEditor;
|
||||
@@ -486,7 +488,7 @@ class MouseDownOperation extends Disposable {
|
||||
return t;
|
||||
}
|
||||
|
||||
private _helpPositionJumpOverViewZone(viewZoneData: IViewZoneData): Position {
|
||||
private _helpPositionJumpOverViewZone(viewZoneData: IViewZoneData): Position | null {
|
||||
// Force position on view zones to go above or below depending on where selection started from
|
||||
let selectionStart = new Position(this._currentSelection.selectionStartLineNumber, this._currentSelection.selectionStartColumn);
|
||||
let positionBefore = viewZoneData.positionBefore;
|
||||
@@ -503,6 +505,9 @@ class MouseDownOperation extends Disposable {
|
||||
}
|
||||
|
||||
private _dispatchMouse(position: MouseTarget, inSelectionMode: boolean): void {
|
||||
if (!position.position) {
|
||||
return;
|
||||
}
|
||||
this._viewController.dispatchMouse({
|
||||
position: position.position,
|
||||
mouseColumn: position.mouseColumn,
|
||||
@@ -546,7 +551,7 @@ class MouseDownState {
|
||||
private _startedOnLineNumbers: boolean;
|
||||
public get startedOnLineNumbers(): boolean { return this._startedOnLineNumbers; }
|
||||
|
||||
private _lastMouseDownPosition: Position;
|
||||
private _lastMouseDownPosition: Position | null;
|
||||
private _lastMouseDownPositionEqualCount: number;
|
||||
private _lastMouseDownCount: number;
|
||||
private _lastSetMouseDownCountTime: number;
|
||||
|
||||
@@ -2,26 +2,25 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import { IPointerHandlerHelper } from 'vs/editor/browser/controller/mouseHandler';
|
||||
import { IMouseTarget, MouseTargetType } from 'vs/editor/browser/editorBrowser';
|
||||
import { ClientCoordinates, EditorMouseEvent, EditorPagePosition, PageCoordinates } from 'vs/editor/browser/editorDom';
|
||||
import { PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
|
||||
import { ViewLine } from 'vs/editor/browser/viewParts/lines/viewLine';
|
||||
import { IViewCursorRenderData } from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
|
||||
import { EditorLayoutInfo } from 'vs/editor/common/config/editorOptions';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range as EditorRange } from 'vs/editor/common/core/range';
|
||||
import { MouseTargetType, IMouseTarget } from 'vs/editor/browser/editorBrowser';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { IPointerHandlerHelper } from 'vs/editor/browser/controller/mouseHandler';
|
||||
import { EditorMouseEvent, PageCoordinates, ClientCoordinates, EditorPagePosition } from 'vs/editor/browser/editorDom';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import { IViewCursorRenderData } from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
|
||||
import { PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
|
||||
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { EditorLayoutInfo } from 'vs/editor/common/config/editorOptions';
|
||||
import { ViewLine } from 'vs/editor/browser/viewParts/lines/viewLine';
|
||||
import { HorizontalRange } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
|
||||
|
||||
export interface IViewZoneData {
|
||||
viewZoneId: number;
|
||||
positionBefore: Position;
|
||||
positionAfter: Position;
|
||||
positionBefore: Position | null;
|
||||
positionAfter: Position | null;
|
||||
position: Position;
|
||||
afterLineNumber: number;
|
||||
}
|
||||
@@ -85,20 +84,20 @@ declare var IETextRange: {
|
||||
};
|
||||
|
||||
interface IHitTestResult {
|
||||
position: Position;
|
||||
hitTarget: Element;
|
||||
position: Position | null;
|
||||
hitTarget: Element | null;
|
||||
}
|
||||
|
||||
export class MouseTarget implements IMouseTarget {
|
||||
|
||||
public readonly element: Element;
|
||||
public readonly element: Element | null;
|
||||
public readonly type: MouseTargetType;
|
||||
public readonly mouseColumn: number;
|
||||
public readonly position: Position;
|
||||
public readonly range: EditorRange;
|
||||
public readonly position: Position | null;
|
||||
public readonly range: EditorRange | null;
|
||||
public readonly detail: any;
|
||||
|
||||
constructor(element: Element, type: MouseTargetType, mouseColumn: number = 0, position: Position = null, range: EditorRange = null, detail: any = null) {
|
||||
constructor(element: Element | null, type: MouseTargetType, mouseColumn: number = 0, position: Position | null = null, range: EditorRange | null = null, detail: any = null) {
|
||||
this.element = element;
|
||||
this.type = type;
|
||||
this.mouseColumn = mouseColumn;
|
||||
@@ -248,20 +247,20 @@ export class HitTestContext {
|
||||
this._viewHelper = viewHelper;
|
||||
}
|
||||
|
||||
public getZoneAtCoord(mouseVerticalOffset: number): IViewZoneData {
|
||||
public getZoneAtCoord(mouseVerticalOffset: number): IViewZoneData | null {
|
||||
return HitTestContext.getZoneAtCoord(this._context, mouseVerticalOffset);
|
||||
}
|
||||
|
||||
public static getZoneAtCoord(context: ViewContext, mouseVerticalOffset: number): IViewZoneData {
|
||||
public static getZoneAtCoord(context: ViewContext, mouseVerticalOffset: number): IViewZoneData | null {
|
||||
// The target is either a view zone or the empty space after the last view-line
|
||||
let viewZoneWhitespace = context.viewLayout.getWhitespaceAtVerticalOffset(mouseVerticalOffset);
|
||||
|
||||
if (viewZoneWhitespace) {
|
||||
let viewZoneMiddle = viewZoneWhitespace.verticalOffset + viewZoneWhitespace.height / 2,
|
||||
lineCount = context.model.getLineCount(),
|
||||
positionBefore: Position = null,
|
||||
position: Position,
|
||||
positionAfter: Position = null;
|
||||
positionBefore: Position | null = null,
|
||||
position: Position | null,
|
||||
positionAfter: Position | null = null;
|
||||
|
||||
if (viewZoneWhitespace.afterLineNumber !== lineCount) {
|
||||
// There are more lines after this view zone
|
||||
@@ -287,7 +286,7 @@ export class HitTestContext {
|
||||
afterLineNumber: viewZoneWhitespace.afterLineNumber,
|
||||
positionBefore: positionBefore,
|
||||
positionAfter: positionAfter,
|
||||
position: position
|
||||
position: position!
|
||||
};
|
||||
}
|
||||
return null;
|
||||
@@ -324,11 +323,11 @@ export class HitTestContext {
|
||||
return this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber);
|
||||
}
|
||||
|
||||
public findAttribute(element: Element, attr: string): string {
|
||||
public findAttribute(element: Element, attr: string): string | null {
|
||||
return HitTestContext._findAttribute(element, attr, this._viewHelper.viewDomNode);
|
||||
}
|
||||
|
||||
private static _findAttribute(element: Element, attr: string, stopAt: Element): string {
|
||||
private static _findAttribute(element: Element, attr: string, stopAt: Element): string | null {
|
||||
while (element && element !== document.body) {
|
||||
if (element.hasAttribute && element.hasAttribute(attr)) {
|
||||
return element.getAttribute(attr);
|
||||
@@ -345,11 +344,11 @@ export class HitTestContext {
|
||||
return this._viewHelper.getLineWidth(lineNumber);
|
||||
}
|
||||
|
||||
public visibleRangeForPosition2(lineNumber: number, column: number): HorizontalRange {
|
||||
public visibleRangeForPosition2(lineNumber: number, column: number): HorizontalRange | null {
|
||||
return this._viewHelper.visibleRangeForPosition2(lineNumber, column);
|
||||
}
|
||||
|
||||
public getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position {
|
||||
public getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position | null {
|
||||
return this._viewHelper.getPositionFromDOMInfo(spanNode, offset);
|
||||
}
|
||||
|
||||
@@ -387,10 +386,10 @@ abstract class BareHitTestRequest {
|
||||
|
||||
class HitTestRequest extends BareHitTestRequest {
|
||||
private readonly _ctx: HitTestContext;
|
||||
public readonly target: Element;
|
||||
public readonly target: Element | null;
|
||||
public readonly targetPath: Uint8Array;
|
||||
|
||||
constructor(ctx: HitTestContext, editorPos: EditorPagePosition, pos: PageCoordinates, target: Element) {
|
||||
constructor(ctx: HitTestContext, editorPos: EditorPagePosition, pos: PageCoordinates, target: Element | null) {
|
||||
super(ctx, editorPos, pos);
|
||||
this._ctx = ctx;
|
||||
|
||||
@@ -407,15 +406,19 @@ class HitTestRequest extends BareHitTestRequest {
|
||||
return `pos(${this.pos.x},${this.pos.y}), editorPos(${this.editorPos.x},${this.editorPos.y}), mouseVerticalOffset: ${this.mouseVerticalOffset}, mouseContentHorizontalOffset: ${this.mouseContentHorizontalOffset}\n\ttarget: ${this.target ? (<HTMLElement>this.target).outerHTML : null}`;
|
||||
}
|
||||
|
||||
public fulfill(type: MouseTargetType, position: Position = null, range: EditorRange = null, detail: any = null): MouseTarget {
|
||||
public fulfill(type: MouseTargetType, position: Position | null = null, range: EditorRange | null = null, detail: any = null): MouseTarget {
|
||||
return new MouseTarget(this.target, type, this.mouseColumn, position, range, detail);
|
||||
}
|
||||
|
||||
public withTarget(target: Element): HitTestRequest {
|
||||
public withTarget(target: Element | null): HitTestRequest {
|
||||
return new HitTestRequest(this._ctx, this.editorPos, this.pos, target);
|
||||
}
|
||||
}
|
||||
|
||||
interface ResolvedHitTestRequest extends HitTestRequest {
|
||||
readonly target: Element;
|
||||
}
|
||||
|
||||
const EMPTY_CONTENT_AFTER_LINES: IEmptyContentData = { isAfterLines: true };
|
||||
|
||||
function createEmptyContentDataInLines(horizontalDistanceToText: number): IEmptyContentData {
|
||||
@@ -452,7 +455,7 @@ export class MouseTargetFactory {
|
||||
return false;
|
||||
}
|
||||
|
||||
public createMouseTarget(lastViewCursorsRenderData: IViewCursorRenderData[], editorPos: EditorPagePosition, pos: PageCoordinates, target: HTMLElement): IMouseTarget {
|
||||
public createMouseTarget(lastViewCursorsRenderData: IViewCursorRenderData[], editorPos: EditorPagePosition, pos: PageCoordinates, target: HTMLElement | null): IMouseTarget {
|
||||
const ctx = new HitTestContext(this._context, this._viewHelper, lastViewCursorsRenderData);
|
||||
const request = new HitTestRequest(ctx, editorPos, pos, target);
|
||||
try {
|
||||
@@ -485,23 +488,26 @@ export class MouseTargetFactory {
|
||||
return this._createMouseTarget(ctx, request.withTarget(hitTestResult.hitTarget), true);
|
||||
}
|
||||
|
||||
let result: MouseTarget = null;
|
||||
// we know for a fact that request.target is not null
|
||||
const resolvedRequest = <ResolvedHitTestRequest>request;
|
||||
|
||||
result = result || MouseTargetFactory._hitTestContentWidget(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestOverlayWidget(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestMinimap(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestScrollbarSlider(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestViewZone(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestMargin(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestViewCursor(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestTextArea(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestViewLines(ctx, request, domHitTestExecuted);
|
||||
result = result || MouseTargetFactory._hitTestScrollbar(ctx, request);
|
||||
let result: MouseTarget | null = null;
|
||||
|
||||
result = result || MouseTargetFactory._hitTestContentWidget(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestOverlayWidget(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestMinimap(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestScrollbarSlider(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestViewZone(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestMargin(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestViewCursor(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestTextArea(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestViewLines(ctx, resolvedRequest, domHitTestExecuted);
|
||||
result = result || MouseTargetFactory._hitTestScrollbar(ctx, resolvedRequest);
|
||||
|
||||
return (result || request.fulfill(MouseTargetType.UNKNOWN));
|
||||
}
|
||||
|
||||
private static _hitTestContentWidget(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestContentWidget(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
// Is it a content widget?
|
||||
if (ElementPath.isChildOfContentWidgets(request.targetPath) || ElementPath.isChildOfOverflowingContentWidgets(request.targetPath)) {
|
||||
let widgetId = ctx.findAttribute(request.target, 'widgetId');
|
||||
@@ -514,7 +520,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestOverlayWidget(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestOverlayWidget(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
// Is it an overlay widget?
|
||||
if (ElementPath.isChildOfOverlayWidgets(request.targetPath)) {
|
||||
let widgetId = ctx.findAttribute(request.target, 'widgetId');
|
||||
@@ -527,7 +533,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestViewCursor(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestViewCursor(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
|
||||
if (request.target) {
|
||||
// Check if we've hit a painted cursor
|
||||
@@ -578,7 +584,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestViewZone(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestViewZone(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
let viewZoneData = ctx.getZoneAtCoord(request.mouseVerticalOffset);
|
||||
if (viewZoneData) {
|
||||
let mouseTargetType = (request.isInContentArea ? MouseTargetType.CONTENT_VIEW_ZONE : MouseTargetType.GUTTER_VIEW_ZONE);
|
||||
@@ -588,7 +594,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestTextArea(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestTextArea(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
// Is it the textarea?
|
||||
if (ElementPath.isTextArea(request.targetPath)) {
|
||||
return request.fulfill(MouseTargetType.TEXTAREA);
|
||||
@@ -596,7 +602,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestMargin(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestMargin(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
if (request.isInMarginArea) {
|
||||
let res = ctx.getFullLineRangeAtCoord(request.mouseVerticalOffset);
|
||||
let pos = res.range.getStartPosition();
|
||||
@@ -629,7 +635,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestViewLines(ctx: HitTestContext, request: HitTestRequest, domHitTestExecuted: boolean): MouseTarget {
|
||||
private static _hitTestViewLines(ctx: HitTestContext, request: ResolvedHitTestRequest, domHitTestExecuted: boolean): MouseTarget | null {
|
||||
if (!ElementPath.isChildOfViewLines(request.targetPath)) {
|
||||
return null;
|
||||
}
|
||||
@@ -667,7 +673,7 @@ export class MouseTargetFactory {
|
||||
return this._createMouseTarget(ctx, request.withTarget(hitTestResult.hitTarget), true);
|
||||
}
|
||||
|
||||
private static _hitTestMinimap(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestMinimap(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
if (ElementPath.isChildOfMinimap(request.targetPath)) {
|
||||
const possibleLineNumber = ctx.getLineNumberAtVerticalOffset(request.mouseVerticalOffset);
|
||||
const maxColumn = ctx.model.getLineMaxColumn(possibleLineNumber);
|
||||
@@ -676,7 +682,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestScrollbarSlider(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestScrollbarSlider(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
if (ElementPath.isChildOfScrollableElement(request.targetPath)) {
|
||||
if (request.target && request.target.nodeType === 1) {
|
||||
let className = request.target.className;
|
||||
@@ -690,7 +696,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestScrollbar(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestScrollbar(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
// Is it the overview ruler?
|
||||
// Is it a child of the scrollable element?
|
||||
if (ElementPath.isChildOfScrollableElement(request.targetPath)) {
|
||||
@@ -818,7 +824,7 @@ export class MouseTargetFactory {
|
||||
|
||||
// Chrome always hits a TEXT_NODE, while Edge sometimes hits a token span
|
||||
let startContainer = range.startContainer;
|
||||
let hitTarget: HTMLElement;
|
||||
let hitTarget: HTMLElement | null = null;
|
||||
|
||||
if (startContainer.nodeType === startContainer.TEXT_NODE) {
|
||||
// startContainer is expected to be the token text
|
||||
@@ -843,7 +849,7 @@ export class MouseTargetFactory {
|
||||
let parent2ClassName = parent2 && parent2.nodeType === parent2.ELEMENT_NODE ? (<HTMLElement>parent2).className : null;
|
||||
|
||||
if (parent2ClassName === ViewLine.CLASS_NAME) {
|
||||
let p = ctx.getPositionFromDOMInfo(<HTMLElement>startContainer, (<HTMLElement>startContainer).textContent.length);
|
||||
let p = ctx.getPositionFromDOMInfo(<HTMLElement>startContainer, (<HTMLElement>startContainer).textContent!.length);
|
||||
return {
|
||||
position: p,
|
||||
hitTarget: null
|
||||
@@ -896,8 +902,8 @@ export class MouseTargetFactory {
|
||||
* Most probably IE
|
||||
*/
|
||||
private static _doHitTestWithMoveToPoint(ctx: HitTestContext, coords: ClientCoordinates): IHitTestResult {
|
||||
let resultPosition: Position = null;
|
||||
let resultHitTarget: Element = null;
|
||||
let resultPosition: Position | null = null;
|
||||
let resultHitTarget: Element | null = null;
|
||||
|
||||
let textRange: IETextRange = (<any>document.body).createTextRange();
|
||||
try {
|
||||
@@ -920,7 +926,7 @@ export class MouseTargetFactory {
|
||||
|
||||
if (parent2ClassName === ViewLine.CLASS_NAME) {
|
||||
let rangeToContainEntireSpan = textRange.duplicate();
|
||||
rangeToContainEntireSpan.moveToElementText(parentElement);
|
||||
rangeToContainEntireSpan.moveToElementText(parentElement!);
|
||||
rangeToContainEntireSpan.setEndPoint('EndToStart', textRange);
|
||||
|
||||
resultPosition = ctx.getPositionFromDOMInfo(<HTMLElement>parentElement, rangeToContainEntireSpan.text.length);
|
||||
|
||||
@@ -2,16 +2,15 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { EventType, Gesture, GestureEvent } from 'vs/base/browser/touch';
|
||||
import { MouseHandler, IPointerHandlerHelper } from 'vs/editor/browser/controller/mouseHandler';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IPointerHandlerHelper, MouseHandler } from 'vs/editor/browser/controller/mouseHandler';
|
||||
import { IMouseTarget } from 'vs/editor/browser/editorBrowser';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { EditorMouseEvent } from 'vs/editor/browser/editorDom';
|
||||
import { ViewController } from 'vs/editor/browser/view/viewController';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
|
||||
interface IThrottledGestureEvent {
|
||||
translationX: number;
|
||||
@@ -235,7 +234,7 @@ export class PointerHandler implements IDisposable {
|
||||
}
|
||||
}
|
||||
|
||||
public getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget {
|
||||
public getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget | null {
|
||||
return this.handler.getTargetAtClientPoint(clientX, clientY);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,35 +2,34 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./textAreaHandler';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { TextAreaInput, ITextAreaInputHost, IPasteData, ICompositionData } from 'vs/editor/browser/controller/textAreaInput';
|
||||
import { ISimpleModel, ITypeData, TextAreaState, PagedScreenReaderStrategy } from 'vs/editor/browser/controller/textAreaState';
|
||||
import { Configuration } from 'vs/editor/browser/config/configuration';
|
||||
import { CopyOptions, ICompositionData, IPasteData, ITextAreaInputHost, TextAreaInput } from 'vs/editor/browser/controller/textAreaInput';
|
||||
import { ISimpleModel, ITypeData, PagedScreenReaderStrategy, TextAreaState } from 'vs/editor/browser/controller/textAreaState';
|
||||
import { ViewController } from 'vs/editor/browser/view/viewController';
|
||||
import { PartFingerprint, PartFingerprints, ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { LineNumbersOverlay } from 'vs/editor/browser/viewParts/lineNumbers/lineNumbers';
|
||||
import { Margin } from 'vs/editor/browser/viewParts/margin/margin';
|
||||
import { RenderLineNumbersType } from 'vs/editor/common/config/editorOptions';
|
||||
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
|
||||
import { WordCharacterClass, getMapForWordSeparators } from 'vs/editor/common/controller/wordCharacterClassifier';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Configuration } from 'vs/editor/browser/config/configuration';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { HorizontalRange, RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { ViewController } from 'vs/editor/browser/view/viewController';
|
||||
import { ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { PartFingerprints, PartFingerprint, ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { Margin } from 'vs/editor/browser/viewParts/margin/margin';
|
||||
import { LineNumbersOverlay } from 'vs/editor/browser/viewParts/lineNumbers/lineNumbers';
|
||||
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
|
||||
import { RenderLineNumbersType } from 'vs/editor/common/config/editorOptions';
|
||||
import { EndOfLinePreference } from 'vs/editor/common/model';
|
||||
import { getMapForWordSeparators, WordCharacterClass } from 'vs/editor/common/controller/wordCharacterClassifier';
|
||||
import { HorizontalRange, RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
|
||||
export interface ITextAreaHandlerHelper {
|
||||
visibleRangeForPositionRelativeToEditor(lineNumber: number, column: number): HorizontalRange;
|
||||
visibleRangeForPositionRelativeToEditor(lineNumber: number, column: number): HorizontalRange | null;
|
||||
}
|
||||
|
||||
class VisibleTextAreaData {
|
||||
@@ -56,7 +55,7 @@ const canUseZeroSizeTextarea = (browser.isEdgeOrIE || browser.isFirefox);
|
||||
interface LocalClipboardMetadata {
|
||||
lastCopiedValue: string;
|
||||
isFromEmptySelection: boolean;
|
||||
multicursorText: string[];
|
||||
multicursorText: string[] | null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,17 +66,17 @@ interface LocalClipboardMetadata {
|
||||
class LocalClipboardMetadataManager {
|
||||
public static INSTANCE = new LocalClipboardMetadataManager();
|
||||
|
||||
private _lastState: LocalClipboardMetadata;
|
||||
private _lastState: LocalClipboardMetadata | null;
|
||||
|
||||
constructor() {
|
||||
this._lastState = null;
|
||||
}
|
||||
|
||||
public set(state: LocalClipboardMetadata): void {
|
||||
public set(state: LocalClipboardMetadata | null): void {
|
||||
this._lastState = state;
|
||||
}
|
||||
|
||||
public get(pastedText: string): LocalClipboardMetadata {
|
||||
public get(pastedText: string): LocalClipboardMetadata | null {
|
||||
if (this._lastState && this._lastState.lastCopiedValue === pastedText) {
|
||||
// match!
|
||||
return this._lastState;
|
||||
@@ -100,11 +99,12 @@ export class TextAreaHandler extends ViewPart {
|
||||
private _fontInfo: BareFontInfo;
|
||||
private _lineHeight: number;
|
||||
private _emptySelectionClipboard: boolean;
|
||||
private _copyWithSyntaxHighlighting: boolean;
|
||||
|
||||
/**
|
||||
* Defined only when the text area is visible (composition case).
|
||||
*/
|
||||
private _visibleTextArea: VisibleTextAreaData;
|
||||
private _visibleTextArea: VisibleTextAreaData | null;
|
||||
private _selections: Selection[];
|
||||
|
||||
public readonly textArea: FastDomNode<HTMLTextAreaElement>;
|
||||
@@ -128,6 +128,7 @@ export class TextAreaHandler extends ViewPart {
|
||||
this._fontInfo = conf.fontInfo;
|
||||
this._lineHeight = conf.lineHeight;
|
||||
this._emptySelectionClipboard = conf.emptySelectionClipboard;
|
||||
this._copyWithSyntaxHighlighting = conf.copyWithSyntaxHighlighting;
|
||||
|
||||
this._visibleTextArea = null;
|
||||
this._selections = [new Selection(1, 1, 1, 1)];
|
||||
@@ -171,7 +172,7 @@ export class TextAreaHandler extends ViewPart {
|
||||
const multicursorText = (Array.isArray(rawWhatToCopy) ? rawWhatToCopy : null);
|
||||
const whatToCopy = (Array.isArray(rawWhatToCopy) ? rawWhatToCopy.join(newLineCharacter) : rawWhatToCopy);
|
||||
|
||||
let metadata: LocalClipboardMetadata = null;
|
||||
let metadata: LocalClipboardMetadata | null = null;
|
||||
if (isFromEmptySelection || multicursorText) {
|
||||
// Only store the non-default metadata
|
||||
|
||||
@@ -190,7 +191,11 @@ export class TextAreaHandler extends ViewPart {
|
||||
return whatToCopy;
|
||||
},
|
||||
|
||||
getHTMLToCopy: (): string => {
|
||||
getHTMLToCopy: (): string | null => {
|
||||
if (!this._copyWithSyntaxHighlighting && !CopyOptions.forceCopyWithSyntaxHighlighting) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this._context.model.getHTMLToCopy(this._selections, this._emptySelectionClipboard);
|
||||
},
|
||||
|
||||
@@ -245,7 +250,7 @@ export class TextAreaHandler extends ViewPart {
|
||||
const metadata = LocalClipboardMetadataManager.INSTANCE.get(e.text);
|
||||
|
||||
let pasteOnNewLine = false;
|
||||
let multicursorText: string[] = null;
|
||||
let multicursorText: string[] | null = null;
|
||||
if (metadata) {
|
||||
pasteOnNewLine = (this._emptySelectionClipboard && metadata.isFromEmptySelection);
|
||||
multicursorText = metadata.multicursorText;
|
||||
@@ -302,10 +307,10 @@ export class TextAreaHandler extends ViewPart {
|
||||
if (browser.isEdgeOrIE) {
|
||||
// Due to isEdgeOrIE (where the textarea was not cleared initially)
|
||||
// we cannot assume the text consists only of the composited text
|
||||
this._visibleTextArea = this._visibleTextArea.setWidth(0);
|
||||
this._visibleTextArea = this._visibleTextArea!.setWidth(0);
|
||||
} else {
|
||||
// adjust width by its size
|
||||
this._visibleTextArea = this._visibleTextArea.setWidth(measureText(e.data, this._fontInfo));
|
||||
this._visibleTextArea = this._visibleTextArea!.setWidth(measureText(e.data, this._fontInfo));
|
||||
}
|
||||
this._render();
|
||||
}));
|
||||
@@ -387,6 +392,9 @@ export class TextAreaHandler extends ViewPart {
|
||||
if (e.emptySelectionClipboard) {
|
||||
this._emptySelectionClipboard = conf.emptySelectionClipboard;
|
||||
}
|
||||
if (e.copyWithSyntaxHighlighting) {
|
||||
this._copyWithSyntaxHighlighting = conf.copyWithSyntaxHighlighting;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -434,7 +442,7 @@ export class TextAreaHandler extends ViewPart {
|
||||
|
||||
// --- end view API
|
||||
|
||||
private _primaryCursorVisibleRange: HorizontalRange = null;
|
||||
private _primaryCursorVisibleRange: HorizontalRange | null = null;
|
||||
|
||||
public prepareRender(ctx: RenderingContext): void {
|
||||
if (this._accessibilitySupport === platform.AccessibilitySupport.Enabled) {
|
||||
@@ -556,7 +564,7 @@ export class TextAreaHandler extends ViewPart {
|
||||
function measureText(text: string, fontInfo: BareFontInfo): number {
|
||||
// adjust width by its size
|
||||
const canvasElem = <HTMLCanvasElement>document.createElement('canvas');
|
||||
const context = canvasElem.getContext('2d');
|
||||
const context = canvasElem.getContext('2d')!;
|
||||
context.font = createFontString(fontInfo);
|
||||
const metrics = context.measureText(text);
|
||||
|
||||
|
||||
@@ -2,21 +2,20 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { FastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { ITypeData, TextAreaState, ITextAreaWrapper } from 'vs/editor/browser/controller/textAreaState';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { FastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { ITextAreaWrapper, ITypeData, TextAreaState } from 'vs/editor/browser/controller/textAreaState';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
|
||||
export interface ICompositionData {
|
||||
data: string;
|
||||
@@ -37,7 +36,7 @@ export interface IPasteData {
|
||||
|
||||
export interface ITextAreaInputHost {
|
||||
getPlainTextToCopy(): string;
|
||||
getHTMLToCopy(): string;
|
||||
getHTMLToCopy(): string | null;
|
||||
getScreenReaderContent(currentState: TextAreaState): TextAreaState;
|
||||
deduceModelPosition(viewAnchorPosition: Position, deltaOffset: number, lineFeedCnt: number): Position;
|
||||
}
|
||||
@@ -401,10 +400,10 @@ export class TextAreaInput extends Disposable {
|
||||
}
|
||||
|
||||
const _newSelectionStartPosition = this._textAreaState.deduceEditorPosition(newSelectionStart);
|
||||
const newSelectionStartPosition = this._host.deduceModelPosition(_newSelectionStartPosition[0], _newSelectionStartPosition[1], _newSelectionStartPosition[2]);
|
||||
const newSelectionStartPosition = this._host.deduceModelPosition(_newSelectionStartPosition[0]!, _newSelectionStartPosition[1], _newSelectionStartPosition[2]);
|
||||
|
||||
const _newSelectionEndPosition = this._textAreaState.deduceEditorPosition(newSelectionEnd);
|
||||
const newSelectionEndPosition = this._host.deduceModelPosition(_newSelectionEndPosition[0], _newSelectionEndPosition[1], _newSelectionEndPosition[2]);
|
||||
const newSelectionEndPosition = this._host.deduceModelPosition(_newSelectionEndPosition[0]!, _newSelectionEndPosition[1], _newSelectionEndPosition[2]);
|
||||
|
||||
const newSelection = new Selection(
|
||||
newSelectionStartPosition.lineNumber, newSelectionStartPosition.column,
|
||||
@@ -480,7 +479,7 @@ export class TextAreaInput extends Disposable {
|
||||
return;
|
||||
}
|
||||
|
||||
let copyHTML: string = null;
|
||||
let copyHTML: string | null = null;
|
||||
if (browser.hasClipboardSupport() && (copyPlainText.length < 65536 || CopyOptions.forceCopyWithSyntaxHighlighting)) {
|
||||
copyHTML = this._host.getHTMLToCopy();
|
||||
}
|
||||
@@ -514,7 +513,7 @@ class ClipboardEventUtils {
|
||||
throw new Error('ClipboardEventUtils.getTextData: Cannot use text data!');
|
||||
}
|
||||
|
||||
public static setTextData(e: ClipboardEvent, text: string, richText: string): void {
|
||||
public static setTextData(e: ClipboardEvent, text: string, richText: string | null): void {
|
||||
if (e.clipboardData) {
|
||||
e.clipboardData.setData('text/plain', text);
|
||||
if (richText !== null) {
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { EndOfLinePreference } from 'vs/editor/common/model';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { EndOfLinePreference } from 'vs/editor/common/model';
|
||||
|
||||
export interface ITextAreaWrapper {
|
||||
getValue(): string;
|
||||
@@ -36,10 +35,10 @@ export class TextAreaState {
|
||||
public readonly value: string;
|
||||
public readonly selectionStart: number;
|
||||
public readonly selectionEnd: number;
|
||||
public readonly selectionStartPosition: Position;
|
||||
public readonly selectionEndPosition: Position;
|
||||
public readonly selectionStartPosition: Position | null;
|
||||
public readonly selectionEndPosition: Position | null;
|
||||
|
||||
constructor(value: string, selectionStart: number, selectionEnd: number, selectionStartPosition: Position, selectionEndPosition: Position) {
|
||||
constructor(value: string, selectionStart: number, selectionEnd: number, selectionStartPosition: Position | null, selectionEndPosition: Position | null) {
|
||||
this.value = value;
|
||||
this.selectionStart = selectionStart;
|
||||
this.selectionEnd = selectionEnd;
|
||||
@@ -67,7 +66,7 @@ export class TextAreaState {
|
||||
}
|
||||
}
|
||||
|
||||
public deduceEditorPosition(offset: number): [Position, number, number] {
|
||||
public deduceEditorPosition(offset: number): [Position | null, number, number] {
|
||||
if (offset <= this.selectionStart) {
|
||||
const str = this.value.substring(offset, this.selectionStart);
|
||||
return this._finishDeduceEditorPosition(this.selectionStartPosition, str, -1);
|
||||
@@ -84,7 +83,7 @@ export class TextAreaState {
|
||||
return this._finishDeduceEditorPosition(this.selectionEndPosition, str2, -1);
|
||||
}
|
||||
|
||||
private _finishDeduceEditorPosition(anchor: Position, deltaText: string, signum: number): [Position, number, number] {
|
||||
private _finishDeduceEditorPosition(anchor: Position | null, deltaText: string, signum: number): [Position | null, number, number] {
|
||||
let lineFeedCnt = 0;
|
||||
let lastLineFeedIndex = -1;
|
||||
while ((lastLineFeedIndex = deltaText.indexOf('\n', lastLineFeedIndex + 1)) !== -1) {
|
||||
@@ -154,7 +153,7 @@ export class TextAreaState {
|
||||
// the only hints we can use is that the selection is immediately after the inserted emoji
|
||||
// and that none of the old text has been deleted
|
||||
|
||||
let potentialEmojiInput: string = null;
|
||||
let potentialEmojiInput: string | null = null;
|
||||
|
||||
if (currentSelectionStart === currentValue.length) {
|
||||
// emoji potentially inserted "somewhere" after the previous selection => it should appear at the end of `currentValue`
|
||||
@@ -248,21 +247,22 @@ export class PagedScreenReaderStrategy {
|
||||
let selectionEndPage = PagedScreenReaderStrategy._getPageOfLine(selection.endLineNumber);
|
||||
let selectionEndPageRange = PagedScreenReaderStrategy._getRangeForPage(selectionEndPage);
|
||||
|
||||
let pretextRange = selectionStartPageRange.intersectRanges(new Range(1, 1, selection.startLineNumber, selection.startColumn));
|
||||
let pretextRange = selectionStartPageRange.intersectRanges(new Range(1, 1, selection.startLineNumber, selection.startColumn))!;
|
||||
let pretext = model.getValueInRange(pretextRange, EndOfLinePreference.LF);
|
||||
|
||||
let lastLine = model.getLineCount();
|
||||
let lastLineMaxColumn = model.getLineMaxColumn(lastLine);
|
||||
let posttextRange = selectionEndPageRange.intersectRanges(new Range(selection.endLineNumber, selection.endColumn, lastLine, lastLineMaxColumn));
|
||||
let posttextRange = selectionEndPageRange.intersectRanges(new Range(selection.endLineNumber, selection.endColumn, lastLine, lastLineMaxColumn))!;
|
||||
let posttext = model.getValueInRange(posttextRange, EndOfLinePreference.LF);
|
||||
|
||||
let text: string = null;
|
||||
|
||||
let text: string;
|
||||
if (selectionStartPage === selectionEndPage || selectionStartPage + 1 === selectionEndPage) {
|
||||
// take full selection
|
||||
text = model.getValueInRange(selection, EndOfLinePreference.LF);
|
||||
} else {
|
||||
let selectionRange1 = selectionStartPageRange.intersectRanges(selection);
|
||||
let selectionRange2 = selectionEndPageRange.intersectRanges(selection);
|
||||
let selectionRange1 = selectionStartPageRange.intersectRanges(selection)!;
|
||||
let selectionRange2 = selectionEndPageRange.intersectRanges(selection)!;
|
||||
text = (
|
||||
model.getValueInRange(selectionRange1, EndOfLinePreference.LF)
|
||||
+ String.fromCharCode(8230)
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
|
||||
export const enum CodeEditorStateFlag {
|
||||
Value = 1,
|
||||
@@ -20,9 +19,9 @@ export class EditorState {
|
||||
|
||||
private readonly flags: number;
|
||||
|
||||
private readonly position: Position;
|
||||
private readonly selection: Range;
|
||||
private readonly modelVersionId: string;
|
||||
private readonly position: Position | null;
|
||||
private readonly selection: Range | null;
|
||||
private readonly modelVersionId: string | null;
|
||||
private readonly scrollLeft: number;
|
||||
private readonly scrollTop: number;
|
||||
|
||||
@@ -75,7 +74,7 @@ export class EditorState {
|
||||
export class StableEditorScrollState {
|
||||
|
||||
public static capture(editor: ICodeEditor): StableEditorScrollState {
|
||||
let visiblePosition: Position = null;
|
||||
let visiblePosition: Position | null = null;
|
||||
let visiblePositionScrollDelta = 0;
|
||||
if (editor.getScrollTop() !== 0) {
|
||||
const visibleRanges = editor.getVisibleRanges();
|
||||
@@ -89,7 +88,7 @@ export class StableEditorScrollState {
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly _visiblePosition: Position,
|
||||
private readonly _visiblePosition: Position | null,
|
||||
private readonly _visiblePositionScrollDelta: number
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -2,23 +2,22 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { Position, IPosition } from 'vs/editor/common/core/position';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { Range, IRange } from 'vs/editor/common/core/range';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import * as editorOptions from 'vs/editor/common/config/editorOptions';
|
||||
import { OverviewRulerZone } from 'vs/editor/common/view/overviewZoneManager';
|
||||
import { IModelContentChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelOptionsChangedEvent, IModelDecorationsChangedEvent } from 'vs/editor/common/model/textModelEvents';
|
||||
import { ICursors } from 'vs/editor/common/controller/cursorCommon';
|
||||
import { ICursorPositionChangedEvent, ICursorSelectionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ICursors, CursorConfiguration } from 'vs/editor/common/controller/cursorCommon';
|
||||
import { IPosition, Position } from 'vs/editor/common/core/position';
|
||||
import { IRange, Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IIdentifiedSingleEditOperation, IModelDecoration, IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model';
|
||||
import { IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelOptionsChangedEvent } from 'vs/editor/common/model/textModelEvents';
|
||||
import { OverviewRulerZone } from 'vs/editor/common/view/overviewZoneManager';
|
||||
import { IEditorWhitespace } from 'vs/editor/common/viewLayout/whitespaceComputer';
|
||||
import { ITextModel, IIdentifiedSingleEditOperation, IModelDecoration, IModelDeltaDecoration } from 'vs/editor/common/model';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
/**
|
||||
* A view zone is a full horizontal rectangle that 'pushes' text down.
|
||||
@@ -65,7 +64,7 @@ export interface IViewZone {
|
||||
/**
|
||||
* An optional dom node for the view zone that will be placed in the margin area.
|
||||
*/
|
||||
marginDomNode?: HTMLElement;
|
||||
marginDomNode?: HTMLElement | null;
|
||||
/**
|
||||
* Callback which gives the relative top of the view zone as it appears (taking scrolling into account).
|
||||
*/
|
||||
@@ -100,7 +99,7 @@ export interface IViewZoneChangeAccessor {
|
||||
/**
|
||||
* A positioning preference for rendering content widgets.
|
||||
*/
|
||||
export enum ContentWidgetPositionPreference {
|
||||
export const enum ContentWidgetPositionPreference {
|
||||
/**
|
||||
* Place the content widget exactly at a position
|
||||
*/
|
||||
@@ -122,7 +121,12 @@ export interface IContentWidgetPosition {
|
||||
* Desired position for the content widget.
|
||||
* `preference` will also affect the placement.
|
||||
*/
|
||||
position: IPosition;
|
||||
position: IPosition | null;
|
||||
/**
|
||||
* Optionally, a range can be provided to further
|
||||
* define the position of the content widget.
|
||||
*/
|
||||
range?: IRange | null;
|
||||
/**
|
||||
* Placement preference for position, in order of preference.
|
||||
*/
|
||||
@@ -150,13 +154,13 @@ export interface IContentWidget {
|
||||
* Get the placement of the content widget.
|
||||
* If null is returned, the content widget will be placed off screen.
|
||||
*/
|
||||
getPosition(): IContentWidgetPosition;
|
||||
getPosition(): IContentWidgetPosition | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A positioning preference for rendering overlay widgets.
|
||||
*/
|
||||
export enum OverlayWidgetPositionPreference {
|
||||
export const enum OverlayWidgetPositionPreference {
|
||||
/**
|
||||
* Position the overlay widget in the top right corner
|
||||
*/
|
||||
@@ -179,7 +183,7 @@ export interface IOverlayWidgetPosition {
|
||||
/**
|
||||
* The position preference for the overlay widget.
|
||||
*/
|
||||
preference: OverlayWidgetPositionPreference;
|
||||
preference: OverlayWidgetPositionPreference | null;
|
||||
}
|
||||
/**
|
||||
* An overlay widgets renders on top of the text.
|
||||
@@ -197,13 +201,13 @@ export interface IOverlayWidget {
|
||||
* Get the placement of the overlay widget.
|
||||
* If null is returned, the overlay widget is responsible to place itself.
|
||||
*/
|
||||
getPosition(): IOverlayWidgetPosition;
|
||||
getPosition(): IOverlayWidgetPosition | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of hit element with the mouse in the editor.
|
||||
*/
|
||||
export enum MouseTargetType {
|
||||
export const enum MouseTargetType {
|
||||
/**
|
||||
* Mouse is on top of an unknown element.
|
||||
*/
|
||||
@@ -269,7 +273,7 @@ export interface IMouseTarget {
|
||||
/**
|
||||
* The target element
|
||||
*/
|
||||
readonly element: Element;
|
||||
readonly element: Element | null;
|
||||
/**
|
||||
* The target type
|
||||
*/
|
||||
@@ -277,7 +281,7 @@ export interface IMouseTarget {
|
||||
/**
|
||||
* The 'approximate' editor position
|
||||
*/
|
||||
readonly position: Position;
|
||||
readonly position: Position | null;
|
||||
/**
|
||||
* Desired mouse column (e.g. when position.column gets clamped to text length -- clicking after text on a line).
|
||||
*/
|
||||
@@ -285,7 +289,7 @@ export interface IMouseTarget {
|
||||
/**
|
||||
* The 'approximate' editor range
|
||||
*/
|
||||
readonly range: Range;
|
||||
readonly range: Range | null;
|
||||
/**
|
||||
* Some extra detail.
|
||||
*/
|
||||
@@ -298,6 +302,10 @@ export interface IEditorMouseEvent {
|
||||
readonly event: IMouseEvent;
|
||||
readonly target: IMouseTarget;
|
||||
}
|
||||
export interface IPartialEditorMouseEvent {
|
||||
readonly event: IMouseEvent;
|
||||
readonly target: IMouseTarget | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* An overview ruler
|
||||
@@ -396,6 +404,14 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
* @internal
|
||||
*/
|
||||
onDidType(listener: (text: string) => void): IDisposable;
|
||||
/**
|
||||
* An event emitted after composition has started.
|
||||
*/
|
||||
onCompositionStart(listener: () => void): IDisposable;
|
||||
/**
|
||||
* An event emitted after composition has ended.
|
||||
*/
|
||||
onCompositionEnd(listener: () => void): IDisposable;
|
||||
/**
|
||||
* An event emitted when editing failed because the editor is read-only.
|
||||
* @event
|
||||
@@ -429,7 +445,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
* @internal
|
||||
* @event
|
||||
*/
|
||||
onMouseDrop(listener: (e: IEditorMouseEvent) => void): IDisposable;
|
||||
onMouseDrop(listener: (e: IPartialEditorMouseEvent) => void): IDisposable;
|
||||
/**
|
||||
* An event emitted on a "contextmenu".
|
||||
* @event
|
||||
@@ -444,7 +460,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
* An event emitted on a "mouseleave".
|
||||
* @event
|
||||
*/
|
||||
onMouseLeave(listener: (e: IEditorMouseEvent) => void): IDisposable;
|
||||
onMouseLeave(listener: (e: IPartialEditorMouseEvent) => void): IDisposable;
|
||||
/**
|
||||
* An event emitted on a "keyup".
|
||||
* @event
|
||||
@@ -469,7 +485,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
/**
|
||||
* Saves current view state of the editor in a serializable object.
|
||||
*/
|
||||
saveViewState(): editorCommon.ICodeEditorViewState;
|
||||
saveViewState(): editorCommon.ICodeEditorViewState | null;
|
||||
|
||||
/**
|
||||
* Restores the view state of the editor from a serializable object generated by `saveViewState`.
|
||||
@@ -497,7 +513,17 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
/**
|
||||
* Type the getModel() of IEditor.
|
||||
*/
|
||||
getModel(): ITextModel;
|
||||
getModel(): ITextModel | null;
|
||||
|
||||
/**
|
||||
* Sets the current model attached to this editor.
|
||||
* If the previous model was created by the editor via the value key in the options
|
||||
* literal object, it will be destroyed. Otherwise, if the previous model was set
|
||||
* via setModel, or the model key in the options literal object, the previous model
|
||||
* will not be destroyed.
|
||||
* It is safe to call setModel(null) to simply detach the current model from the editor.
|
||||
*/
|
||||
setModel(model: ITextModel | null): void;
|
||||
|
||||
/**
|
||||
* Returns the current editor's configuration
|
||||
@@ -583,26 +609,21 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
executeEdits(source: string, edits: IIdentifiedSingleEditOperation[], endCursorState?: Selection[]): boolean;
|
||||
|
||||
/**
|
||||
* Execute multiple (concommitent) commands on the editor.
|
||||
* Execute multiple (concomitant) commands on the editor.
|
||||
* @param source The source of the call.
|
||||
* @param command The commands to execute
|
||||
*/
|
||||
executeCommands(source: string, commands: editorCommon.ICommand[]): void;
|
||||
executeCommands(source: string, commands: (editorCommon.ICommand | null)[]): void;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_getCursors(): ICursors;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_getCursorConfiguration(): CursorConfiguration;
|
||||
_getCursors(): ICursors | null;
|
||||
|
||||
/**
|
||||
* Get all the decorations on a line (filtering out decorations from other editors).
|
||||
*/
|
||||
getLineDecorations(lineNumber: number): IModelDecoration[];
|
||||
getLineDecorations(lineNumber: number): IModelDecoration[] | null;
|
||||
|
||||
/**
|
||||
* All decorations added through this call will get the ownerId of this editor.
|
||||
@@ -661,12 +682,12 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getTelemetryData(): { [key: string]: any; };
|
||||
getTelemetryData(): { [key: string]: any; } | null;
|
||||
|
||||
/**
|
||||
* Returns the editor's dom node
|
||||
*/
|
||||
getDomNode(): HTMLElement;
|
||||
getDomNode(): HTMLElement | null;
|
||||
|
||||
/**
|
||||
* Add a content widget. Widgets must have unique ids, otherwise they will be overwritten.
|
||||
@@ -674,7 +695,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
addContentWidget(widget: IContentWidget): void;
|
||||
/**
|
||||
* Layout/Reposition a content widget. This is a ping to the editor to call widget.getPosition()
|
||||
* and update appropiately.
|
||||
* and update appropriately.
|
||||
*/
|
||||
layoutContentWidget(widget: IContentWidget): void;
|
||||
/**
|
||||
@@ -688,7 +709,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
addOverlayWidget(widget: IOverlayWidget): void;
|
||||
/**
|
||||
* Layout/Reposition an overlay widget. This is a ping to the editor to call widget.getPosition()
|
||||
* and update appropiately.
|
||||
* and update appropriately.
|
||||
*/
|
||||
layoutOverlayWidget(widget: IOverlayWidget): void;
|
||||
/**
|
||||
@@ -719,21 +740,81 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
*
|
||||
* @returns Hit test target or null if the coordinates fall outside the editor or the editor has no model.
|
||||
*/
|
||||
getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget;
|
||||
getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget | null;
|
||||
|
||||
/**
|
||||
* Get the visible position for `position`.
|
||||
* The result position takes scrolling into account and is relative to the top left corner of the editor.
|
||||
* Explanation 1: the results of this method will change for the same `position` if the user scrolls the editor.
|
||||
* Explanation 2: the results of this method will not change if the container of the editor gets repositioned.
|
||||
* Warning: the results of this method are innacurate for positions that are outside the current editor viewport.
|
||||
* Warning: the results of this method are inaccurate for positions that are outside the current editor viewport.
|
||||
*/
|
||||
getScrolledVisiblePosition(position: IPosition): { top: number; left: number; height: number; };
|
||||
getScrolledVisiblePosition(position: IPosition): { top: number; left: number; height: number; } | null;
|
||||
|
||||
/**
|
||||
* Apply the same font settings as the editor to `target`.
|
||||
*/
|
||||
applyFontInfo(target: HTMLElement): void;
|
||||
|
||||
/**
|
||||
* Check if the current instance has a model attached.
|
||||
* @internal
|
||||
*/
|
||||
hasModel(): this is IActiveCodeEditor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface IActiveCodeEditor extends ICodeEditor {
|
||||
/**
|
||||
* Returns the primary position of the cursor.
|
||||
*/
|
||||
getPosition(): Position;
|
||||
|
||||
/**
|
||||
* Returns the primary selection of the editor.
|
||||
*/
|
||||
getSelection(): Selection;
|
||||
|
||||
/**
|
||||
* Returns all the selections of the editor.
|
||||
*/
|
||||
getSelections(): Selection[];
|
||||
|
||||
/**
|
||||
* Saves current view state of the editor in a serializable object.
|
||||
*/
|
||||
saveViewState(): editorCommon.ICodeEditorViewState;
|
||||
|
||||
/**
|
||||
* Type the getModel() of IEditor.
|
||||
*/
|
||||
getModel(): ITextModel;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_getCursors(): ICursors;
|
||||
|
||||
/**
|
||||
* Get all the decorations on a line (filtering out decorations from other editors).
|
||||
*/
|
||||
getLineDecorations(lineNumber: number): IModelDecoration[];
|
||||
|
||||
/**
|
||||
* Returns the editor's dom node
|
||||
*/
|
||||
getDomNode(): HTMLElement;
|
||||
|
||||
/**
|
||||
* Get the visible position for `position`.
|
||||
* The result position takes scrolling into account and is relative to the top left corner of the editor.
|
||||
* Explanation 1: the results of this method will change for the same `position` if the user scrolls the editor.
|
||||
* Explanation 2: the results of this method will not change if the container of the editor gets repositioned.
|
||||
* Warning: the results of this method are inaccurate for positions that are outside the current editor viewport.
|
||||
*/
|
||||
getScrolledVisiblePosition(position: IPosition): { top: number; left: number; height: number; };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -778,7 +859,7 @@ export interface IDiffEditor extends editorCommon.IEditor {
|
||||
/**
|
||||
* Saves current view state of the editor in a serializable object.
|
||||
*/
|
||||
saveViewState(): editorCommon.IDiffEditorViewState;
|
||||
saveViewState(): editorCommon.IDiffEditorViewState | null;
|
||||
|
||||
/**
|
||||
* Restores the view state of the editor from a serializable object generated by `saveViewState`.
|
||||
@@ -788,7 +869,17 @@ export interface IDiffEditor extends editorCommon.IEditor {
|
||||
/**
|
||||
* Type the getModel() of IEditor.
|
||||
*/
|
||||
getModel(): editorCommon.IDiffEditorModel;
|
||||
getModel(): editorCommon.IDiffEditorModel | null;
|
||||
|
||||
/**
|
||||
* Sets the current model attached to this editor.
|
||||
* If the previous model was created by the editor via the value key in the options
|
||||
* literal object, it will be destroyed. Otherwise, if the previous model was set
|
||||
* via setModel, or the model key in the options literal object, the previous model
|
||||
* will not be destroyed.
|
||||
* It is safe to call setModel(null) to simply detach the current model from the editor.
|
||||
*/
|
||||
setModel(model: editorCommon.IDiffEditorModel | null): void;
|
||||
|
||||
/**
|
||||
* Get the `original` editor.
|
||||
@@ -803,19 +894,19 @@ export interface IDiffEditor extends editorCommon.IEditor {
|
||||
/**
|
||||
* Get the computed diff information.
|
||||
*/
|
||||
getLineChanges(): editorCommon.ILineChange[];
|
||||
getLineChanges(): editorCommon.ILineChange[] | null;
|
||||
|
||||
/**
|
||||
* Get information based on computed diff about a line number from the original model.
|
||||
* If the diff computation is not finished or the model is missing, will return null.
|
||||
*/
|
||||
getDiffLineInformationForOriginal(lineNumber: number): IDiffLineInformation;
|
||||
getDiffLineInformationForOriginal(lineNumber: number): IDiffLineInformation | null;
|
||||
|
||||
/**
|
||||
* Get information based on computed diff about a line number from the modified model.
|
||||
* If the diff computation is not finished or the model is missing, will return null.
|
||||
*/
|
||||
getDiffLineInformationForModified(lineNumber: number): IDiffLineInformation;
|
||||
getDiffLineInformationForModified(lineNumber: number): IDiffLineInformation | null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -843,7 +934,7 @@ export function isDiffEditor(thing: any): thing is IDiffEditor {
|
||||
/**
|
||||
*@internal
|
||||
*/
|
||||
export function getCodeEditor(thing: any): ICodeEditor {
|
||||
export function getCodeEditor(thing: any): ICodeEditor | null {
|
||||
if (isCodeEditor(thing)) {
|
||||
return thing;
|
||||
}
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { GlobalMouseMoveMonitor } from 'vs/base/browser/globalMouseMoveMonitor';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
/**
|
||||
* Coordinates relative to the whole document (e.g. mouse event's pageX and pageY)
|
||||
@@ -136,7 +135,7 @@ export class GlobalEditorMouseMoveMonitor extends Disposable {
|
||||
|
||||
private _editorViewDomNode: HTMLElement;
|
||||
private _globalMouseMoveMonitor: GlobalMouseMoveMonitor<EditorMouseEvent>;
|
||||
private _keydownListener: IDisposable;
|
||||
private _keydownListener: IDisposable | null;
|
||||
|
||||
constructor(editorViewDomNode: HTMLElement) {
|
||||
super();
|
||||
@@ -163,7 +162,7 @@ export class GlobalEditorMouseMoveMonitor extends Disposable {
|
||||
};
|
||||
|
||||
this._globalMouseMoveMonitor.startMonitoring(myMerger, mouseMoveCallback, () => {
|
||||
this._keydownListener.dispose();
|
||||
this._keydownListener!.dispose();
|
||||
onStopCallback();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,33 +2,33 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { IPosition } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { always } from 'vs/base/common/async';
|
||||
import { illegalArgument } from 'vs/base/common/errors';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ServicesAccessor, IConstructorSignature1 } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions';
|
||||
import { CommandsRegistry, ICommandHandlerDescription } from 'vs/platform/commands/common/commands';
|
||||
import { KeybindingsRegistry, IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IConstructorSignature1, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IKeybindings, KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions';
|
||||
import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { IPosition } from 'vs/base/browser/ui/contextview/contextview';
|
||||
|
||||
export type ServicesAccessor = ServicesAccessor;
|
||||
export type IEditorContributionCtor = IConstructorSignature1<ICodeEditor, editorCommon.IEditorContribution>;
|
||||
export type IEditorContributionCtor = IConstructorSignature1<ICodeEditor, IEditorContribution>;
|
||||
|
||||
//#region Command
|
||||
|
||||
export interface ICommandKeybindingsOptions extends IKeybindings {
|
||||
kbExpr?: ContextKeyExpr;
|
||||
kbExpr?: ContextKeyExpr | null;
|
||||
weight: number;
|
||||
}
|
||||
export interface ICommandMenubarOptions {
|
||||
@@ -40,17 +40,17 @@ export interface ICommandMenubarOptions {
|
||||
}
|
||||
export interface ICommandOptions {
|
||||
id: string;
|
||||
precondition: ContextKeyExpr;
|
||||
kbOpts?: ICommandKeybindingsOptions;
|
||||
precondition: ContextKeyExpr | null;
|
||||
kbOpts?: ICommandKeybindingsOptions | null;
|
||||
description?: ICommandHandlerDescription;
|
||||
menubarOpts?: ICommandMenubarOptions;
|
||||
}
|
||||
export abstract class Command {
|
||||
public readonly id: string;
|
||||
public readonly precondition: ContextKeyExpr;
|
||||
private readonly _kbOpts: ICommandKeybindingsOptions;
|
||||
private readonly _menubarOpts: ICommandMenubarOptions;
|
||||
private readonly _description: ICommandHandlerDescription;
|
||||
public readonly precondition: ContextKeyExpr | null;
|
||||
private readonly _kbOpts: ICommandKeybindingsOptions | null | undefined;
|
||||
private readonly _menubarOpts: ICommandMenubarOptions | null | undefined;
|
||||
private readonly _description: ICommandHandlerDescription | null | undefined;
|
||||
|
||||
constructor(opts: ICommandOptions) {
|
||||
this.id = opts.id;
|
||||
@@ -89,7 +89,7 @@ export abstract class Command {
|
||||
id: this.id,
|
||||
handler: (accessor, args) => this.runCommand(accessor, args),
|
||||
weight: this._kbOpts.weight,
|
||||
when: kbWhen,
|
||||
when: kbWhen || null,
|
||||
primary: this._kbOpts.primary,
|
||||
secondary: this._kbOpts.secondary,
|
||||
win: this._kbOpts.win,
|
||||
@@ -108,7 +108,7 @@ export abstract class Command {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract runCommand(accessor: ServicesAccessor, args: any): void | TPromise<void>;
|
||||
public abstract runCommand(accessor: ServicesAccessor, args: any): void | Thenable<void>;
|
||||
}
|
||||
|
||||
//#endregion Command
|
||||
@@ -118,7 +118,7 @@ export abstract class Command {
|
||||
export interface IContributionCommandOptions<T> extends ICommandOptions {
|
||||
handler: (controller: T) => void;
|
||||
}
|
||||
export interface EditorControllerCommand<T extends editorCommon.IEditorContribution> {
|
||||
export interface EditorControllerCommand<T extends IEditorContribution> {
|
||||
new(opts: IContributionCommandOptions<T>): EditorCommand;
|
||||
}
|
||||
export abstract class EditorCommand extends Command {
|
||||
@@ -126,7 +126,7 @@ export abstract class EditorCommand extends Command {
|
||||
/**
|
||||
* Create a command class that is bound to a certain editor contribution.
|
||||
*/
|
||||
public static bindToContribution<T extends editorCommon.IEditorContribution>(controllerGetter: (editor: ICodeEditor) => T): EditorControllerCommand<T> {
|
||||
public static bindToContribution<T extends IEditorContribution>(controllerGetter: (editor: ICodeEditor) => T): EditorControllerCommand<T> {
|
||||
return class EditorControllerCommandImpl extends EditorCommand {
|
||||
private _callback: (controller: T) => void;
|
||||
|
||||
@@ -145,7 +145,7 @@ export abstract class EditorCommand extends Command {
|
||||
};
|
||||
}
|
||||
|
||||
public runCommand(accessor: ServicesAccessor, args: any): void | TPromise<void> {
|
||||
public runCommand(accessor: ServicesAccessor, args: any): void | Thenable<void> {
|
||||
const codeEditorService = accessor.get(ICodeEditorService);
|
||||
|
||||
// Find the editor with text focus or active
|
||||
@@ -162,11 +162,11 @@ export abstract class EditorCommand extends Command {
|
||||
return;
|
||||
}
|
||||
|
||||
return this.runEditorCommand(editorAccessor, editor, args);
|
||||
return this.runEditorCommand(editorAccessor, editor!, args);
|
||||
});
|
||||
}
|
||||
|
||||
public abstract runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void | TPromise<void>;
|
||||
public abstract runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void | Thenable<void>;
|
||||
}
|
||||
|
||||
//#endregion EditorCommand
|
||||
@@ -187,7 +187,7 @@ export abstract class EditorAction extends EditorCommand {
|
||||
|
||||
public label: string;
|
||||
public alias: string;
|
||||
private menuOpts: IEditorCommandMenuOptions;
|
||||
private menuOpts: IEditorCommandMenuOptions | undefined;
|
||||
|
||||
constructor(opts: IActionOptions) {
|
||||
super(opts);
|
||||
@@ -213,7 +213,7 @@ export abstract class EditorAction extends EditorCommand {
|
||||
super.register();
|
||||
}
|
||||
|
||||
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void | TPromise<void> {
|
||||
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void | Thenable<void> {
|
||||
this.reportTelemetry(accessor, editor);
|
||||
return this.run(accessor, editor, args || {});
|
||||
}
|
||||
@@ -231,7 +231,7 @@ export abstract class EditorAction extends EditorCommand {
|
||||
accessor.get(ITelemetryService).publicLog('editorActionInvoked', { name: this.label, id: this.id, ...editor.getTelemetryData() });
|
||||
}
|
||||
|
||||
public abstract run(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void | TPromise<void>;
|
||||
public abstract run(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void | Thenable<void>;
|
||||
}
|
||||
|
||||
//#endregion EditorAction
|
||||
@@ -260,13 +260,23 @@ export function registerDefaultLanguageCommand(id: string, handler: (model: ITex
|
||||
}
|
||||
|
||||
const model = accessor.get(IModelService).getModel(resource);
|
||||
if (!model) {
|
||||
throw illegalArgument('Can not find open model for ' + resource);
|
||||
if (model) {
|
||||
const editorPosition = Position.lift(position);
|
||||
return handler(model, editorPosition, args);
|
||||
}
|
||||
|
||||
const editorPosition = Position.lift(position);
|
||||
|
||||
return handler(model, editorPosition, args);
|
||||
return accessor.get(ITextModelService).createModelReference(resource).then(reference => {
|
||||
return always(new Promise((resolve, reject) => {
|
||||
try {
|
||||
let result = handler(reference.object.textEditorModel, Position.lift(position), args);
|
||||
resolve(result);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
}), () => {
|
||||
reference.dispose();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -2,35 +2,42 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { IDecorationRenderOptions } from 'vs/editor/common/editorCommon';
|
||||
import { IModelDecorationOptions, ITextModel } from 'vs/editor/common/model';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IResourceInput } from 'vs/platform/editor/common/editor';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
|
||||
export abstract class AbstractCodeEditorService implements ICodeEditorService {
|
||||
export abstract class AbstractCodeEditorService extends Disposable implements ICodeEditorService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
private readonly _onCodeEditorAdd: Emitter<ICodeEditor>;
|
||||
private readonly _onCodeEditorRemove: Emitter<ICodeEditor>;
|
||||
private _codeEditors: { [editorId: string]: ICodeEditor; };
|
||||
private readonly _onCodeEditorAdd: Emitter<ICodeEditor> = this._register(new Emitter<ICodeEditor>());
|
||||
public readonly onCodeEditorAdd: Event<ICodeEditor> = this._onCodeEditorAdd.event;
|
||||
|
||||
private readonly _onDiffEditorAdd: Emitter<IDiffEditor>;
|
||||
private readonly _onDiffEditorRemove: Emitter<IDiffEditor>;
|
||||
private readonly _onCodeEditorRemove: Emitter<ICodeEditor> = this._register(new Emitter<ICodeEditor>());
|
||||
public readonly onCodeEditorRemove: Event<ICodeEditor> = this._onCodeEditorRemove.event;
|
||||
|
||||
private readonly _onDiffEditorAdd: Emitter<IDiffEditor> = this._register(new Emitter<IDiffEditor>());
|
||||
public readonly onDiffEditorAdd: Event<IDiffEditor> = this._onDiffEditorAdd.event;
|
||||
|
||||
private readonly _onDiffEditorRemove: Emitter<IDiffEditor> = this._register(new Emitter<IDiffEditor>());
|
||||
public readonly onDiffEditorRemove: Event<IDiffEditor> = this._onDiffEditorRemove.event;
|
||||
|
||||
private readonly _onDidChangeTransientModelProperty: Emitter<ITextModel> = this._register(new Emitter<ITextModel>());
|
||||
public readonly onDidChangeTransientModelProperty: Event<ITextModel> = this._onDidChangeTransientModelProperty.event;
|
||||
|
||||
|
||||
private _codeEditors: { [editorId: string]: ICodeEditor; };
|
||||
private _diffEditors: { [editorId: string]: IDiffEditor; };
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._codeEditors = Object.create(null);
|
||||
this._diffEditors = Object.create(null);
|
||||
this._onCodeEditorAdd = new Emitter<ICodeEditor>();
|
||||
this._onCodeEditorRemove = new Emitter<ICodeEditor>();
|
||||
this._onDiffEditorAdd = new Emitter<IDiffEditor>();
|
||||
this._onDiffEditorRemove = new Emitter<IDiffEditor>();
|
||||
}
|
||||
|
||||
addCodeEditor(editor: ICodeEditor): void {
|
||||
@@ -38,20 +45,12 @@ export abstract class AbstractCodeEditorService implements ICodeEditorService {
|
||||
this._onCodeEditorAdd.fire(editor);
|
||||
}
|
||||
|
||||
get onCodeEditorAdd(): Event<ICodeEditor> {
|
||||
return this._onCodeEditorAdd.event;
|
||||
}
|
||||
|
||||
removeCodeEditor(editor: ICodeEditor): void {
|
||||
if (delete this._codeEditors[editor.getId()]) {
|
||||
this._onCodeEditorRemove.fire(editor);
|
||||
}
|
||||
}
|
||||
|
||||
get onCodeEditorRemove(): Event<ICodeEditor> {
|
||||
return this._onCodeEditorRemove.event;
|
||||
}
|
||||
|
||||
listCodeEditors(): ICodeEditor[] {
|
||||
return Object.keys(this._codeEditors).map(id => this._codeEditors[id]);
|
||||
}
|
||||
@@ -61,26 +60,18 @@ export abstract class AbstractCodeEditorService implements ICodeEditorService {
|
||||
this._onDiffEditorAdd.fire(editor);
|
||||
}
|
||||
|
||||
get onDiffEditorAdd(): Event<IDiffEditor> {
|
||||
return this._onDiffEditorAdd.event;
|
||||
}
|
||||
|
||||
removeDiffEditor(editor: IDiffEditor): void {
|
||||
if (delete this._diffEditors[editor.getId()]) {
|
||||
this._onDiffEditorRemove.fire(editor);
|
||||
}
|
||||
}
|
||||
|
||||
get onDiffEditorRemove(): Event<IDiffEditor> {
|
||||
return this._onDiffEditorRemove.event;
|
||||
}
|
||||
|
||||
listDiffEditors(): IDiffEditor[] {
|
||||
return Object.keys(this._diffEditors).map(id => this._diffEditors[id]);
|
||||
}
|
||||
|
||||
getFocusedCodeEditor(): ICodeEditor {
|
||||
let editorWithWidgetFocus: ICodeEditor = null;
|
||||
getFocusedCodeEditor(): ICodeEditor | null {
|
||||
let editorWithWidgetFocus: ICodeEditor | null = null;
|
||||
|
||||
let editors = this.listCodeEditors();
|
||||
for (let i = 0; i < editors.length; i++) {
|
||||
@@ -101,7 +92,7 @@ export abstract class AbstractCodeEditorService implements ICodeEditorService {
|
||||
|
||||
abstract registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string): void;
|
||||
abstract removeDecorationType(key: string): void;
|
||||
abstract resolveDecorationOptions(decorationTypeKey: string, writable: boolean): IModelDecorationOptions;
|
||||
abstract resolveDecorationOptions(decorationTypeKey: string | undefined, writable: boolean): IModelDecorationOptions;
|
||||
|
||||
private _transientWatchers: { [uri: string]: ModelTransientSettingWatcher; } = {};
|
||||
|
||||
@@ -117,6 +108,7 @@ export abstract class AbstractCodeEditorService implements ICodeEditorService {
|
||||
}
|
||||
|
||||
w.set(key, value);
|
||||
this._onDidChangeTransientModelProperty.fire(model);
|
||||
}
|
||||
|
||||
public getTransientModelProperty(model: ITextModel, key: string): any {
|
||||
@@ -133,8 +125,8 @@ export abstract class AbstractCodeEditorService implements ICodeEditorService {
|
||||
delete this._transientWatchers[w.uri];
|
||||
}
|
||||
|
||||
abstract getActiveCodeEditor(): ICodeEditor;
|
||||
abstract openCodeEditor(input: IResourceInput, source: ICodeEditor, sideBySide?: boolean): TPromise<ICodeEditor>;
|
||||
abstract getActiveCodeEditor(): ICodeEditor | null;
|
||||
abstract openCodeEditor(input: IResourceInput, source: ICodeEditor | null, sideBySide?: boolean): Thenable<ICodeEditor | null>;
|
||||
}
|
||||
|
||||
export class ModelTransientSettingWatcher {
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { WorkspaceEdit } from 'vs/editor/common/modes';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ICodeEditor } from '../editorBrowser';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IProgressRunner } from 'vs/platform/progress/common/progress';
|
||||
|
||||
export const IBulkEditService = createDecorator<IBulkEditService>('IWorkspaceEditService');
|
||||
@@ -25,6 +23,6 @@ export interface IBulkEditResult {
|
||||
export interface IBulkEditService {
|
||||
_serviceBrand: any;
|
||||
|
||||
apply(edit: WorkspaceEdit, options: IBulkEditOptions): TPromise<IBulkEditResult>;
|
||||
apply(edit: WorkspaceEdit, options: IBulkEditOptions): Promise<IBulkEditResult>;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,26 +2,27 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IDecorationRenderOptions } from 'vs/editor/common/editorCommon';
|
||||
import { IModelDecorationOptions, ITextModel } from 'vs/editor/common/model';
|
||||
import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IResourceInput } from 'vs/platform/editor/common/editor';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
export const ICodeEditorService = createDecorator<ICodeEditorService>('codeEditorService');
|
||||
|
||||
export interface ICodeEditorService {
|
||||
_serviceBrand: any;
|
||||
|
||||
onCodeEditorAdd: Event<ICodeEditor>;
|
||||
onCodeEditorRemove: Event<ICodeEditor>;
|
||||
readonly onCodeEditorAdd: Event<ICodeEditor>;
|
||||
readonly onCodeEditorRemove: Event<ICodeEditor>;
|
||||
|
||||
readonly onDiffEditorAdd: Event<IDiffEditor>;
|
||||
readonly onDiffEditorRemove: Event<IDiffEditor>;
|
||||
|
||||
readonly onDidChangeTransientModelProperty: Event<ITextModel>;
|
||||
|
||||
onDiffEditorAdd: Event<IDiffEditor>;
|
||||
onDiffEditorRemove: Event<IDiffEditor>;
|
||||
|
||||
addCodeEditor(editor: ICodeEditor): void;
|
||||
removeCodeEditor(editor: ICodeEditor): void;
|
||||
@@ -34,7 +35,7 @@ export interface ICodeEditorService {
|
||||
/**
|
||||
* Returns the current focused code editor (if the focus is in the editor or in an editor widget) or null.
|
||||
*/
|
||||
getFocusedCodeEditor(): ICodeEditor;
|
||||
getFocusedCodeEditor(): ICodeEditor | null;
|
||||
|
||||
registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string): void;
|
||||
removeDecorationType(key: string): void;
|
||||
@@ -43,6 +44,6 @@ export interface ICodeEditorService {
|
||||
setTransientModelProperty(model: ITextModel, key: string, value: any): void;
|
||||
getTransientModelProperty(model: ITextModel, key: string): any;
|
||||
|
||||
getActiveCodeEditor(): ICodeEditor;
|
||||
openCodeEditor(input: IResourceInput, source: ICodeEditor, sideBySide?: boolean): TPromise<ICodeEditor>;
|
||||
getActiveCodeEditor(): ICodeEditor | null;
|
||||
openCodeEditor(input: IResourceInput, source: ICodeEditor | null, sideBySide?: boolean): Thenable<ICodeEditor | null>;
|
||||
}
|
||||
|
||||
@@ -2,19 +2,17 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { IDecorationRenderOptions, IThemeDecorationRenderOptions, IContentDecorationRenderOptions, isThemeColor } from 'vs/editor/common/editorCommon';
|
||||
import { IModelDecorationOptions, IModelDecorationOverviewRulerOptions, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model';
|
||||
import { AbstractCodeEditorService } from 'vs/editor/browser/services/abstractCodeEditorService';
|
||||
import { IDisposable, dispose as disposeAll } from 'vs/base/common/lifecycle';
|
||||
import { IThemeService, ITheme, ThemeColor } from 'vs/platform/theme/common/themeService';
|
||||
import { IResourceInput } from 'vs/platform/editor/common/editor';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { AbstractCodeEditorService } from 'vs/editor/browser/services/abstractCodeEditorService';
|
||||
import { IContentDecorationRenderOptions, IDecorationRenderOptions, IThemeDecorationRenderOptions, isThemeColor } from 'vs/editor/common/editorCommon';
|
||||
import { IModelDecorationOptions, IModelDecorationOverviewRulerOptions, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model';
|
||||
import { IResourceInput } from 'vs/platform/editor/common/editor';
|
||||
import { ITheme, IThemeService, ThemeColor } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
export abstract class CodeEditorServiceImpl extends AbstractCodeEditorService {
|
||||
|
||||
@@ -68,8 +66,8 @@ export abstract class CodeEditorServiceImpl extends AbstractCodeEditorService {
|
||||
return provider.getOptions(this, writable);
|
||||
}
|
||||
|
||||
abstract getActiveCodeEditor(): ICodeEditor;
|
||||
abstract openCodeEditor(input: IResourceInput, source: ICodeEditor, sideBySide?: boolean): TPromise<ICodeEditor>;
|
||||
abstract getActiveCodeEditor(): ICodeEditor | null;
|
||||
abstract openCodeEditor(input: IResourceInput, source: ICodeEditor | null, sideBySide?: boolean): Thenable<ICodeEditor | null>;
|
||||
}
|
||||
|
||||
interface IModelDecorationOptionsProvider extends IDisposable {
|
||||
@@ -81,9 +79,9 @@ class DecorationSubTypeOptionsProvider implements IModelDecorationOptionsProvide
|
||||
|
||||
public refCount: number;
|
||||
|
||||
private _parentTypeKey: string;
|
||||
private _beforeContentRules: DecorationCSSRules;
|
||||
private _afterContentRules: DecorationCSSRules;
|
||||
private _parentTypeKey: string | undefined;
|
||||
private _beforeContentRules: DecorationCSSRules | null;
|
||||
private _afterContentRules: DecorationCSSRules | null;
|
||||
|
||||
constructor(themeService: IThemeService, providerArgs: ProviderArguments) {
|
||||
this._parentTypeKey = providerArgs.parentTypeKey;
|
||||
@@ -129,32 +127,32 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
|
||||
private _disposables: IDisposable[];
|
||||
public refCount: number;
|
||||
|
||||
public className: string;
|
||||
public className: string | undefined;
|
||||
public inlineClassName: string;
|
||||
public inlineClassNameAffectsLetterSpacing: boolean;
|
||||
public beforeContentClassName: string;
|
||||
public afterContentClassName: string;
|
||||
public glyphMarginClassName: string;
|
||||
public beforeContentClassName: string | undefined;
|
||||
public afterContentClassName: string | undefined;
|
||||
public glyphMarginClassName: string | undefined;
|
||||
public isWholeLine: boolean;
|
||||
public overviewRuler: IModelDecorationOverviewRulerOptions;
|
||||
public stickiness: TrackedRangeStickiness;
|
||||
public stickiness: TrackedRangeStickiness | undefined;
|
||||
|
||||
constructor(themeService: IThemeService, providerArgs: ProviderArguments) {
|
||||
this.refCount = 0;
|
||||
this._disposables = [];
|
||||
|
||||
let createCSSRules = (type: ModelDecorationCSSRuleType) => {
|
||||
let rules = new DecorationCSSRules(type, providerArgs, themeService);
|
||||
const createCSSRules = (type: ModelDecorationCSSRuleType) => {
|
||||
const rules = new DecorationCSSRules(type, providerArgs, themeService);
|
||||
this._disposables.push(rules);
|
||||
if (rules.hasContent) {
|
||||
this._disposables.push(rules);
|
||||
return rules.className;
|
||||
}
|
||||
return void 0;
|
||||
};
|
||||
let createInlineCSSRules = (type: ModelDecorationCSSRuleType) => {
|
||||
let rules = new DecorationCSSRules(type, providerArgs, themeService);
|
||||
const createInlineCSSRules = (type: ModelDecorationCSSRuleType) => {
|
||||
const rules = new DecorationCSSRules(type, providerArgs, themeService);
|
||||
this._disposables.push(rules);
|
||||
if (rules.hasContent) {
|
||||
this._disposables.push(rules);
|
||||
return { className: rules.className, hasLetterSpacing: rules.hasLetterSpacing };
|
||||
}
|
||||
return null;
|
||||
@@ -252,7 +250,7 @@ class DecorationCSSRules {
|
||||
private _hasContent: boolean;
|
||||
private _hasLetterSpacing: boolean;
|
||||
private _ruleType: ModelDecorationCSSRuleType;
|
||||
private _themeListener: IDisposable;
|
||||
private _themeListener: IDisposable | null;
|
||||
private _providerArgs: ProviderArguments;
|
||||
private _usesThemeColors: boolean;
|
||||
|
||||
@@ -280,6 +278,8 @@ class DecorationCSSRules {
|
||||
this._removeCSS();
|
||||
this._buildCSS();
|
||||
});
|
||||
} else {
|
||||
this._themeListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,7 +363,7 @@ class DecorationCSSRules {
|
||||
/**
|
||||
* Build the CSS for decorations styled via `className`.
|
||||
*/
|
||||
private getCSSTextForModelDecorationClassName(opts: IThemeDecorationRenderOptions): string {
|
||||
private getCSSTextForModelDecorationClassName(opts: IThemeDecorationRenderOptions | undefined): string {
|
||||
if (!opts) {
|
||||
return '';
|
||||
}
|
||||
@@ -377,7 +377,7 @@ class DecorationCSSRules {
|
||||
/**
|
||||
* Build the CSS for decorations styled via `inlineClassName`.
|
||||
*/
|
||||
private getCSSTextForModelDecorationInlineClassName(opts: IThemeDecorationRenderOptions): string {
|
||||
private getCSSTextForModelDecorationInlineClassName(opts: IThemeDecorationRenderOptions | undefined): string {
|
||||
if (!opts) {
|
||||
return '';
|
||||
}
|
||||
@@ -392,7 +392,7 @@ class DecorationCSSRules {
|
||||
/**
|
||||
* Build the CSS for decorations styled before or after content.
|
||||
*/
|
||||
private getCSSTextForModelDecorationContentClassName(opts: IContentDecorationRenderOptions): string {
|
||||
private getCSSTextForModelDecorationContentClassName(opts: IContentDecorationRenderOptions | undefined): string {
|
||||
if (!opts) {
|
||||
return '';
|
||||
}
|
||||
@@ -401,14 +401,10 @@ class DecorationCSSRules {
|
||||
if (typeof opts !== 'undefined') {
|
||||
this.collectBorderSettingsCSSText(opts, cssTextArr);
|
||||
if (typeof opts.contentIconPath !== 'undefined') {
|
||||
if (typeof opts.contentIconPath === 'string') {
|
||||
cssTextArr.push(strings.format(_CSS_MAP.contentIconPath, URI.file(opts.contentIconPath).toString().replace(/'/g, '%27')));
|
||||
} else {
|
||||
cssTextArr.push(strings.format(_CSS_MAP.contentIconPath, URI.revive(opts.contentIconPath).toString(true).replace(/'/g, '%27')));
|
||||
}
|
||||
cssTextArr.push(strings.format(_CSS_MAP.contentIconPath, URI.revive(opts.contentIconPath).toString(true).replace(/'/g, '%27')));
|
||||
}
|
||||
if (typeof opts.contentText === 'string') {
|
||||
const truncated = opts.contentText.match(/^.*$/m)[0]; // only take first line
|
||||
const truncated = opts.contentText.match(/^.*$/m)![0]; // only take first line
|
||||
const escaped = truncated.replace(/['\\]/g, '\\$&');
|
||||
|
||||
cssTextArr.push(strings.format(_CSS_MAP.contentText, escaped));
|
||||
@@ -425,18 +421,14 @@ class DecorationCSSRules {
|
||||
/**
|
||||
* Build the CSS for decorations styled via `glpyhMarginClassName`.
|
||||
*/
|
||||
private getCSSTextForModelDecorationGlyphMarginClassName(opts: IThemeDecorationRenderOptions): string {
|
||||
private getCSSTextForModelDecorationGlyphMarginClassName(opts: IThemeDecorationRenderOptions | undefined): string {
|
||||
if (!opts) {
|
||||
return '';
|
||||
}
|
||||
let cssTextArr = [];
|
||||
let cssTextArr: string[] = [];
|
||||
|
||||
if (typeof opts.gutterIconPath !== 'undefined') {
|
||||
if (typeof opts.gutterIconPath === 'string') {
|
||||
cssTextArr.push(strings.format(_CSS_MAP.gutterIconPath, URI.file(opts.gutterIconPath).toString()));
|
||||
} else {
|
||||
cssTextArr.push(strings.format(_CSS_MAP.gutterIconPath, URI.revive(opts.gutterIconPath).toString(true).replace(/'/g, '%27')));
|
||||
}
|
||||
cssTextArr.push(strings.format(_CSS_MAP.gutterIconPath, URI.revive(opts.gutterIconPath).toString(true).replace(/'/g, '%27')));
|
||||
if (typeof opts.gutterIconSize !== 'undefined') {
|
||||
cssTextArr.push(strings.format(_CSS_MAP.gutterIconSize, opts.gutterIconSize));
|
||||
}
|
||||
@@ -491,7 +483,7 @@ class CSSNameHelper {
|
||||
return 'ced-' + key + '-' + type;
|
||||
}
|
||||
|
||||
public static getSelector(key: string, parentKey: string, ruleType: ModelDecorationCSSRuleType): string {
|
||||
public static getSelector(key: string, parentKey: string | undefined, ruleType: ModelDecorationCSSRuleType): string {
|
||||
let selector = '.monaco-editor .' + this.getClassName(key, ruleType);
|
||||
if (parentKey) {
|
||||
selector = selector + '.' + this.getClassName(parentKey, ruleType);
|
||||
|
||||
@@ -2,19 +2,17 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import URI from 'vs/base/common/uri';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { parse } from 'vs/base/common/marshalling';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { normalize } from 'vs/base/common/paths';
|
||||
import { ICommandService, CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { optional } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { optional } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
|
||||
export class OpenerService implements IOpenerService {
|
||||
@@ -24,22 +22,24 @@ export class OpenerService implements IOpenerService {
|
||||
constructor(
|
||||
@ICodeEditorService private readonly _editorService: ICodeEditorService,
|
||||
@ICommandService private readonly _commandService: ICommandService,
|
||||
@optional(ITelemetryService) private _telemetryService: ITelemetryService = NullTelemetryService
|
||||
@optional(ITelemetryService) private _telemetryService: ITelemetryService | null = NullTelemetryService
|
||||
) {
|
||||
//
|
||||
}
|
||||
|
||||
open(resource: URI, options?: { openToSide?: boolean }): TPromise<any> {
|
||||
open(resource: URI, options?: { openToSide?: boolean }): Promise<any> {
|
||||
|
||||
/* __GDPR__
|
||||
"openerService" : {
|
||||
"scheme" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
this._telemetryService.publicLog('openerService', { scheme: resource.scheme });
|
||||
if (this._telemetryService) {
|
||||
/* __GDPR__
|
||||
"openerService" : {
|
||||
"scheme" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
this._telemetryService.publicLog('openerService', { scheme: resource.scheme });
|
||||
}
|
||||
|
||||
const { scheme, path, query, fragment } = resource;
|
||||
let promise: TPromise<any> = TPromise.wrap(void 0);
|
||||
let promise: Thenable<any> | undefined = undefined;
|
||||
|
||||
if (scheme === Schemas.http || scheme === Schemas.https || scheme === Schemas.mailto) {
|
||||
// open http or default mail application
|
||||
@@ -61,7 +61,7 @@ export class OpenerService implements IOpenerService {
|
||||
let selection: {
|
||||
startLineNumber: number;
|
||||
startColumn: number;
|
||||
};
|
||||
} | undefined = undefined;
|
||||
const match = /^L?(\d+)(?:,(\d+))?/.exec(fragment);
|
||||
if (match) {
|
||||
// support file:///some/file.js#73,84
|
||||
@@ -76,14 +76,14 @@ export class OpenerService implements IOpenerService {
|
||||
|
||||
if (!resource.scheme) {
|
||||
// we cannot handle those
|
||||
return TPromise.as(undefined);
|
||||
return Promise.resolve(undefined);
|
||||
|
||||
} else if (resource.scheme === Schemas.file) {
|
||||
resource = resource.with({ path: normalize(resource.path) }); // workaround for non-normalized paths (https://github.com/Microsoft/vscode/issues/12954)
|
||||
resource = resources.normalizePath(resource); // workaround for non-normalized paths (https://github.com/Microsoft/vscode/issues/12954)
|
||||
}
|
||||
promise = this._editorService.openCodeEditor({ resource, options: { selection, } }, this._editorService.getFocusedCodeEditor(), options && options.openToSide);
|
||||
}
|
||||
|
||||
return promise;
|
||||
return Promise.resolve(promise);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
|
||||
import { RenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
|
||||
|
||||
export abstract class DynamicViewOverlay extends ViewEventHandler {
|
||||
|
||||
|
||||
@@ -2,20 +2,15 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { CoreEditorCommand, CoreNavigationCommands } from 'vs/editor/browser/controller/coreCommands';
|
||||
import { IEditorMouseEvent, IPartialEditorMouseEvent } from 'vs/editor/browser/editorBrowser';
|
||||
import { ViewOutgoingEvents } from 'vs/editor/browser/view/viewOutgoingEvents';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { IEditorMouseEvent } from 'vs/editor/browser/editorBrowser';
|
||||
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { ViewOutgoingEvents } from 'vs/editor/browser/view/viewOutgoingEvents';
|
||||
import { CoreNavigationCommands, CoreEditorCommand } from 'vs/editor/browser/controller/coreCommands';
|
||||
import { IConfiguration } from 'vs/editor/common/editorCommon';
|
||||
|
||||
export interface ExecCoreEditorCommandFunc {
|
||||
(editorCommand: CoreEditorCommand, args: any): void;
|
||||
}
|
||||
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
|
||||
|
||||
export interface IMouseDispatchData {
|
||||
position: Position;
|
||||
@@ -37,7 +32,9 @@ export interface IMouseDispatchData {
|
||||
}
|
||||
|
||||
export interface ICommandDelegate {
|
||||
paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[]): void;
|
||||
executeEditorCommand(editorCommand: CoreEditorCommand, args: any): void;
|
||||
|
||||
paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[] | null): void;
|
||||
type(source: string, text: string): void;
|
||||
replacePreviousChar(source: string, text: string, replaceCharCnt: number): void;
|
||||
compositionStart(source: string): void;
|
||||
@@ -49,30 +46,27 @@ export class ViewController {
|
||||
|
||||
private readonly configuration: IConfiguration;
|
||||
private readonly viewModel: IViewModel;
|
||||
private readonly _execCoreEditorCommandFunc: ExecCoreEditorCommandFunc;
|
||||
private readonly outgoingEvents: ViewOutgoingEvents;
|
||||
private readonly commandDelegate: ICommandDelegate;
|
||||
|
||||
constructor(
|
||||
configuration: IConfiguration,
|
||||
viewModel: IViewModel,
|
||||
execCommandFunc: ExecCoreEditorCommandFunc,
|
||||
outgoingEvents: ViewOutgoingEvents,
|
||||
commandDelegate: ICommandDelegate
|
||||
) {
|
||||
this.configuration = configuration;
|
||||
this.viewModel = viewModel;
|
||||
this._execCoreEditorCommandFunc = execCommandFunc;
|
||||
this.outgoingEvents = outgoingEvents;
|
||||
this.commandDelegate = commandDelegate;
|
||||
}
|
||||
|
||||
private _execMouseCommand(editorCommand: CoreEditorCommand, args: any): void {
|
||||
args.source = 'mouse';
|
||||
this._execCoreEditorCommandFunc(editorCommand, args);
|
||||
this.commandDelegate.executeEditorCommand(editorCommand, args);
|
||||
}
|
||||
|
||||
public paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[]): void {
|
||||
public paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[] | null): void {
|
||||
this.commandDelegate.paste(source, text, pasteOnNewLine, multicursorText);
|
||||
}
|
||||
|
||||
@@ -97,7 +91,7 @@ export class ViewController {
|
||||
}
|
||||
|
||||
public setSelection(source: string, modelSelection: Selection): void {
|
||||
this._execCoreEditorCommandFunc(CoreNavigationCommands.SetSelection, {
|
||||
this.commandDelegate.executeEditorCommand(CoreNavigationCommands.SetSelection, {
|
||||
source: source,
|
||||
selection: modelSelection
|
||||
});
|
||||
@@ -299,7 +293,7 @@ export class ViewController {
|
||||
this.outgoingEvents.emitMouseMove(e);
|
||||
}
|
||||
|
||||
public emitMouseLeave(e: IEditorMouseEvent): void {
|
||||
public emitMouseLeave(e: IPartialEditorMouseEvent): void {
|
||||
this.outgoingEvents.emitMouseLeave(e);
|
||||
}
|
||||
|
||||
@@ -315,7 +309,7 @@ export class ViewController {
|
||||
this.outgoingEvents.emitMouseDrag(e);
|
||||
}
|
||||
|
||||
public emitMouseDrop(e: IEditorMouseEvent): void {
|
||||
public emitMouseDrop(e: IPartialEditorMouseEvent): void {
|
||||
this.outgoingEvents.emitMouseDrop(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,32 +2,33 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
|
||||
import { IConfiguration } from 'vs/editor/common/editorCommon';
|
||||
import { TextAreaHandler, ITextAreaHandlerHelper } from 'vs/editor/browser/controller/textAreaHandler';
|
||||
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IPointerHandlerHelper } from 'vs/editor/browser/controller/mouseHandler';
|
||||
import { PointerHandler } from 'vs/editor/browser/controller/pointerHandler';
|
||||
import { ITextAreaHandlerHelper, TextAreaHandler } from 'vs/editor/browser/controller/textAreaHandler';
|
||||
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
|
||||
import { ViewController, ExecCoreEditorCommandFunc, ICommandDelegate } from 'vs/editor/browser/view/viewController';
|
||||
import { ViewEventDispatcher } from 'vs/editor/common/view/viewEventDispatcher';
|
||||
import { ICommandDelegate, ViewController } from 'vs/editor/browser/view/viewController';
|
||||
import { ViewOutgoingEvents } from 'vs/editor/browser/view/viewOutgoingEvents';
|
||||
import { ContentViewOverlays, MarginViewOverlays } from 'vs/editor/browser/view/viewOverlays';
|
||||
import { PartFingerprint, PartFingerprints, ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { ViewContentWidgets } from 'vs/editor/browser/viewParts/contentWidgets/contentWidgets';
|
||||
import { CurrentLineHighlightOverlay } from 'vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight';
|
||||
import { CurrentLineMarginHighlightOverlay } from 'vs/editor/browser/viewParts/currentLineMarginHighlight/currentLineMarginHighlight';
|
||||
import { DecorationsOverlay } from 'vs/editor/browser/viewParts/decorations/decorations';
|
||||
import { EditorScrollbar } from 'vs/editor/browser/viewParts/editorScrollbar/editorScrollbar';
|
||||
import { GlyphMarginOverlay } from 'vs/editor/browser/viewParts/glyphMargin/glyphMargin';
|
||||
import { LineNumbersOverlay } from 'vs/editor/browser/viewParts/lineNumbers/lineNumbers';
|
||||
import { IndentGuidesOverlay } from 'vs/editor/browser/viewParts/indentGuides/indentGuides';
|
||||
import { LineNumbersOverlay } from 'vs/editor/browser/viewParts/lineNumbers/lineNumbers';
|
||||
import { ViewLines } from 'vs/editor/browser/viewParts/lines/viewLines';
|
||||
import { Margin } from 'vs/editor/browser/viewParts/margin/margin';
|
||||
import { LinesDecorationsOverlay } from 'vs/editor/browser/viewParts/linesDecorations/linesDecorations';
|
||||
import { Margin } from 'vs/editor/browser/viewParts/margin/margin';
|
||||
import { MarginViewLineDecorationsOverlay } from 'vs/editor/browser/viewParts/marginDecorations/marginDecorations';
|
||||
import { Minimap } from 'vs/editor/browser/viewParts/minimap/minimap';
|
||||
import { ViewOverlayWidgets } from 'vs/editor/browser/viewParts/overlayWidgets/overlayWidgets';
|
||||
import { DecorationsOverviewRuler } from 'vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler';
|
||||
import { OverviewRuler } from 'vs/editor/browser/viewParts/overviewRuler/overviewRuler';
|
||||
@@ -36,30 +37,30 @@ import { ScrollDecorationViewPart } from 'vs/editor/browser/viewParts/scrollDeco
|
||||
import { SelectionsOverlay } from 'vs/editor/browser/viewParts/selections/selections';
|
||||
import { ViewCursors } from 'vs/editor/browser/viewParts/viewCursors/viewCursors';
|
||||
import { ViewZones } from 'vs/editor/browser/viewParts/viewZones/viewZones';
|
||||
import { ViewPart, PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { RenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { IPointerHandlerHelper } from 'vs/editor/browser/controller/mouseHandler';
|
||||
import { ViewOutgoingEvents } from 'vs/editor/browser/view/viewOutgoingEvents';
|
||||
import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
|
||||
import { EditorScrollbar } from 'vs/editor/browser/viewParts/editorScrollbar/editorScrollbar';
|
||||
import { Minimap } from 'vs/editor/browser/viewParts/minimap/minimap';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { IThemeService, getThemeTypeSelector } from 'vs/platform/theme/common/themeService';
|
||||
import { Cursor } from 'vs/editor/common/controller/cursor';
|
||||
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { IConfiguration } from 'vs/editor/common/editorCommon';
|
||||
import { RenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { ViewEventDispatcher } from 'vs/editor/common/view/viewEventDispatcher';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
|
||||
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
|
||||
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { IThemeService, getThemeTypeSelector } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
export interface IContentWidgetData {
|
||||
widget: editorBrowser.IContentWidget;
|
||||
position: editorBrowser.IContentWidgetPosition;
|
||||
position: editorBrowser.IContentWidgetPosition | null;
|
||||
}
|
||||
|
||||
export interface IOverlayWidgetData {
|
||||
widget: editorBrowser.IOverlayWidget;
|
||||
position: editorBrowser.IOverlayWidgetPosition;
|
||||
position: editorBrowser.IOverlayWidgetPosition | null;
|
||||
}
|
||||
|
||||
const invalidFunc = () => { throw new Error(`Invalid change accessor`); };
|
||||
|
||||
export class View extends ViewEventHandler {
|
||||
|
||||
private eventDispatcher: ViewEventDispatcher;
|
||||
@@ -89,7 +90,7 @@ export class View extends ViewEventHandler {
|
||||
private overflowGuardContainer: FastDomNode<HTMLElement>;
|
||||
|
||||
// Actual mutable state
|
||||
private _renderAnimationFrame: IDisposable;
|
||||
private _renderAnimationFrame: IDisposable | null;
|
||||
|
||||
constructor(
|
||||
commandDelegate: ICommandDelegate,
|
||||
@@ -97,14 +98,14 @@ export class View extends ViewEventHandler {
|
||||
themeService: IThemeService,
|
||||
model: IViewModel,
|
||||
cursor: Cursor,
|
||||
execCoreEditorCommandFunc: ExecCoreEditorCommandFunc
|
||||
outgoingEvents: ViewOutgoingEvents
|
||||
) {
|
||||
super();
|
||||
this._cursor = cursor;
|
||||
this._renderAnimationFrame = null;
|
||||
this.outgoingEvents = new ViewOutgoingEvents(model);
|
||||
this.outgoingEvents = outgoingEvents;
|
||||
|
||||
let viewController = new ViewController(configuration, model, execCoreEditorCommandFunc, this.outgoingEvents, commandDelegate);
|
||||
let viewController = new ViewController(configuration, model, this.outgoingEvents, commandDelegate);
|
||||
|
||||
// The event dispatcher will always go through _renderOnce before dispatching any events
|
||||
this.eventDispatcher = new ViewEventDispatcher((callback: () => void) => this._renderOnce(callback));
|
||||
@@ -263,11 +264,7 @@ export class View extends ViewEventHandler {
|
||||
|
||||
visibleRangeForPosition2: (lineNumber: number, column: number) => {
|
||||
this._flushAccumulatedAndRenderNow();
|
||||
let visibleRanges = this.viewLines.visibleRangesForRange2(new Range(lineNumber, column, lineNumber, column));
|
||||
if (!visibleRanges) {
|
||||
return null;
|
||||
}
|
||||
return visibleRanges[0];
|
||||
return this.viewLines.visibleRangeForPosition(new Position(lineNumber, column));
|
||||
},
|
||||
|
||||
getLineWidth: (lineNumber: number) => {
|
||||
@@ -281,11 +278,7 @@ export class View extends ViewEventHandler {
|
||||
return {
|
||||
visibleRangeForPositionRelativeToEditor: (lineNumber: number, column: number) => {
|
||||
this._flushAccumulatedAndRenderNow();
|
||||
let visibleRanges = this.viewLines.visibleRangesForRange2(new Range(lineNumber, column, lineNumber, column));
|
||||
if (!visibleRanges) {
|
||||
return null;
|
||||
}
|
||||
return visibleRanges[0];
|
||||
return this.viewLines.visibleRangeForPosition(new Position(lineNumber, column));
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -464,21 +457,17 @@ export class View extends ViewEventHandler {
|
||||
});
|
||||
let viewPosition = this._context.model.coordinatesConverter.convertModelPositionToViewPosition(modelPosition);
|
||||
this._flushAccumulatedAndRenderNow();
|
||||
let visibleRanges = this.viewLines.visibleRangesForRange2(new Range(viewPosition.lineNumber, viewPosition.column, viewPosition.lineNumber, viewPosition.column));
|
||||
if (!visibleRanges) {
|
||||
const visibleRange = this.viewLines.visibleRangeForPosition(new Position(viewPosition.lineNumber, viewPosition.column));
|
||||
if (!visibleRange) {
|
||||
return -1;
|
||||
}
|
||||
return visibleRanges[0].left;
|
||||
return visibleRange.left;
|
||||
}
|
||||
|
||||
public getTargetAtClientPoint(clientX: number, clientY: number): editorBrowser.IMouseTarget {
|
||||
public getTargetAtClientPoint(clientX: number, clientY: number): editorBrowser.IMouseTarget | null {
|
||||
return this.pointerHandler.getTargetAtClientPoint(clientX, clientY);
|
||||
}
|
||||
|
||||
public getInternalEventBus(): ViewOutgoingEvents {
|
||||
return this.outgoingEvents;
|
||||
}
|
||||
|
||||
public createOverviewRuler(cssClassName: string): OverviewRuler {
|
||||
return new OverviewRuler(this._context, cssClassName);
|
||||
}
|
||||
@@ -509,8 +498,9 @@ export class View extends ViewEventHandler {
|
||||
safeInvoke1Arg(callback, changeAccessor);
|
||||
|
||||
// Invalidate changeAccessor
|
||||
changeAccessor.addZone = null;
|
||||
changeAccessor.removeZone = null;
|
||||
changeAccessor.addZone = invalidFunc;
|
||||
changeAccessor.removeZone = invalidFunc;
|
||||
changeAccessor.layoutZone = invalidFunc;
|
||||
|
||||
if (zonesHaveChanged) {
|
||||
this._context.viewLayout.onHeightMaybeChanged();
|
||||
@@ -552,8 +542,9 @@ export class View extends ViewEventHandler {
|
||||
|
||||
public layoutContentWidget(widgetData: IContentWidgetData): void {
|
||||
let newPosition = widgetData.position ? widgetData.position.position : null;
|
||||
let newRange = widgetData.position ? widgetData.position.range : null;
|
||||
let newPreference = widgetData.position ? widgetData.position.preference : null;
|
||||
this.contentWidgets.setWidgetPosition(widgetData.widget, newPosition, newPreference);
|
||||
this.contentWidgets.setWidgetPosition(widgetData.widget, newPosition, newRange, newPreference);
|
||||
this._scheduleRender();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,18 +2,17 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
|
||||
import { IStringBuilder, createStringBuilder } from 'vs/editor/common/core/stringBuilder';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { createStringBuilder, IStringBuilder } from 'vs/editor/common/core/stringBuilder';
|
||||
import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
|
||||
|
||||
/**
|
||||
* Represents a visible line
|
||||
*/
|
||||
export interface IVisibleLine extends ILine {
|
||||
getDomNode(): HTMLElement;
|
||||
getDomNode(): HTMLElement | null;
|
||||
setDomNode(domNode: HTMLElement): void;
|
||||
|
||||
/**
|
||||
@@ -88,7 +87,7 @@ export class RenderedLinesCollection<T extends ILine> {
|
||||
/**
|
||||
* @returns Lines that were removed from this collection
|
||||
*/
|
||||
public onLinesDeleted(deleteFromLineNumber: number, deleteToLineNumber: number): T[] {
|
||||
public onLinesDeleted(deleteFromLineNumber: number, deleteToLineNumber: number): T[] | null {
|
||||
if (this.getCount() === 0) {
|
||||
// no lines
|
||||
return null;
|
||||
@@ -168,7 +167,7 @@ export class RenderedLinesCollection<T extends ILine> {
|
||||
return someoneNotified;
|
||||
}
|
||||
|
||||
public onLinesInserted(insertFromLineNumber: number, insertToLineNumber: number): T[] {
|
||||
public onLinesInserted(insertFromLineNumber: number, insertToLineNumber: number): T[] | null {
|
||||
if (this.getCount() === 0) {
|
||||
// no lines
|
||||
return null;
|
||||
@@ -528,8 +527,8 @@ class ViewLayerRenderer<T extends IVisibleLine> {
|
||||
let line = ctx.lines[i];
|
||||
if (wasInvalid[i]) {
|
||||
let source = <HTMLElement>hugeDomNode.firstChild;
|
||||
let lineDomNode = line.getDomNode();
|
||||
lineDomNode.parentNode.replaceChild(source, lineDomNode);
|
||||
let lineDomNode = line.getDomNode()!;
|
||||
lineDomNode.parentNode!.replaceChild(source, lineDomNode);
|
||||
line.setDomNode(source);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,16 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { MouseTarget } from 'vs/editor/browser/controller/mouseTarget';
|
||||
import { IEditorMouseEvent, IMouseTarget, IPartialEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { IScrollEvent } from 'vs/editor/common/editorCommon';
|
||||
import { IEditorMouseEvent, IMouseTarget, MouseTargetType } from 'vs/editor/browser/editorBrowser';
|
||||
import { MouseTarget } from 'vs/editor/browser/controller/mouseTarget';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
|
||||
|
||||
export interface EventCallback<T> {
|
||||
(event: T): void;
|
||||
@@ -20,18 +19,18 @@ export interface EventCallback<T> {
|
||||
|
||||
export class ViewOutgoingEvents extends Disposable {
|
||||
|
||||
public onDidScroll: EventCallback<IScrollEvent> = null;
|
||||
public onDidGainFocus: EventCallback<void> = null;
|
||||
public onDidLoseFocus: EventCallback<void> = null;
|
||||
public onKeyDown: EventCallback<IKeyboardEvent> = null;
|
||||
public onKeyUp: EventCallback<IKeyboardEvent> = null;
|
||||
public onContextMenu: EventCallback<IEditorMouseEvent> = null;
|
||||
public onMouseMove: EventCallback<IEditorMouseEvent> = null;
|
||||
public onMouseLeave: EventCallback<IEditorMouseEvent> = null;
|
||||
public onMouseUp: EventCallback<IEditorMouseEvent> = null;
|
||||
public onMouseDown: EventCallback<IEditorMouseEvent> = null;
|
||||
public onMouseDrag: EventCallback<IEditorMouseEvent> = null;
|
||||
public onMouseDrop: EventCallback<IEditorMouseEvent> = null;
|
||||
public onDidScroll: EventCallback<IScrollEvent> | null = null;
|
||||
public onDidGainFocus: EventCallback<void> | null = null;
|
||||
public onDidLoseFocus: EventCallback<void> | null = null;
|
||||
public onKeyDown: EventCallback<IKeyboardEvent> | null = null;
|
||||
public onKeyUp: EventCallback<IKeyboardEvent> | null = null;
|
||||
public onContextMenu: EventCallback<IEditorMouseEvent> | null = null;
|
||||
public onMouseMove: EventCallback<IEditorMouseEvent> | null = null;
|
||||
public onMouseLeave: EventCallback<IPartialEditorMouseEvent> | null = null;
|
||||
public onMouseUp: EventCallback<IEditorMouseEvent> | null = null;
|
||||
public onMouseDown: EventCallback<IEditorMouseEvent> | null = null;
|
||||
public onMouseDrag: EventCallback<IEditorMouseEvent> | null = null;
|
||||
public onMouseDrop: EventCallback<IPartialEditorMouseEvent> | null = null;
|
||||
|
||||
private _viewModel: IViewModel;
|
||||
|
||||
@@ -82,7 +81,7 @@ export class ViewOutgoingEvents extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
public emitMouseLeave(e: IEditorMouseEvent): void {
|
||||
public emitMouseLeave(e: IPartialEditorMouseEvent): void {
|
||||
if (this.onMouseLeave) {
|
||||
this.onMouseLeave(this._convertViewToModelMouseEvent(e));
|
||||
}
|
||||
@@ -106,13 +105,15 @@ export class ViewOutgoingEvents extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
public emitMouseDrop(e: IEditorMouseEvent): void {
|
||||
public emitMouseDrop(e: IPartialEditorMouseEvent): void {
|
||||
if (this.onMouseDrop) {
|
||||
this.onMouseDrop(this._convertViewToModelMouseEvent(e));
|
||||
}
|
||||
}
|
||||
|
||||
private _convertViewToModelMouseEvent(e: IEditorMouseEvent): IEditorMouseEvent {
|
||||
private _convertViewToModelMouseEvent(e: IEditorMouseEvent): IEditorMouseEvent;
|
||||
private _convertViewToModelMouseEvent(e: IPartialEditorMouseEvent): IPartialEditorMouseEvent;
|
||||
private _convertViewToModelMouseEvent(e: IEditorMouseEvent | IPartialEditorMouseEvent): IEditorMouseEvent | IPartialEditorMouseEvent {
|
||||
if (e.target) {
|
||||
return {
|
||||
event: e.event,
|
||||
@@ -144,14 +145,14 @@ export class ViewOutgoingEvents extends Disposable {
|
||||
|
||||
class ExternalMouseTarget implements IMouseTarget {
|
||||
|
||||
public readonly element: Element;
|
||||
public readonly element: Element | null;
|
||||
public readonly type: MouseTargetType;
|
||||
public readonly mouseColumn: number;
|
||||
public readonly position: Position;
|
||||
public readonly range: Range;
|
||||
public readonly position: Position | null;
|
||||
public readonly range: Range | null;
|
||||
public readonly detail: any;
|
||||
|
||||
constructor(element: Element, type: MouseTargetType, mouseColumn: number, position: Position, range: Range, detail: any) {
|
||||
constructor(element: Element | null, type: MouseTargetType, mouseColumn: number, position: Position | null, range: Range | null, detail: any) {
|
||||
this.element = element;
|
||||
this.type = type;
|
||||
this.mouseColumn = mouseColumn;
|
||||
|
||||
@@ -2,19 +2,18 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { IConfiguration } from 'vs/editor/common/editorCommon';
|
||||
import { IVisibleLine, VisibleLinesCollection, IVisibleLinesHost } from 'vs/editor/browser/view/viewLayer';
|
||||
import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay';
|
||||
import { Configuration } from 'vs/editor/browser/config/configuration';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay';
|
||||
import { IVisibleLine, IVisibleLinesHost, VisibleLinesCollection } from 'vs/editor/browser/view/viewLayer';
|
||||
import { ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { IStringBuilder } from 'vs/editor/common/core/stringBuilder';
|
||||
import { IConfiguration } from 'vs/editor/common/editorCommon';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
|
||||
|
||||
export class ViewOverlays extends ViewPart implements IVisibleLinesHost<ViewOverlayLine> {
|
||||
|
||||
@@ -57,7 +56,7 @@ export class ViewOverlays extends ViewPart implements IVisibleLinesHost<ViewOver
|
||||
let dynamicOverlay = this._dynamicOverlays[i];
|
||||
dynamicOverlay.dispose();
|
||||
}
|
||||
this._dynamicOverlays = null;
|
||||
this._dynamicOverlays = [];
|
||||
}
|
||||
|
||||
public getDomNode(): FastDomNode<HTMLElement> {
|
||||
@@ -124,8 +123,6 @@ export class ViewOverlays extends ViewPart implements IVisibleLinesHost<ViewOver
|
||||
dynamicOverlay.prepareRender(ctx);
|
||||
dynamicOverlay.onDidRender();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public render(ctx: RestrictedRenderingContext): void {
|
||||
@@ -144,8 +141,8 @@ export class ViewOverlayLine implements IVisibleLine {
|
||||
|
||||
private _configuration: IConfiguration;
|
||||
private _dynamicOverlays: DynamicViewOverlay[];
|
||||
private _domNode: FastDomNode<HTMLElement>;
|
||||
private _renderedContent: string;
|
||||
private _domNode: FastDomNode<HTMLElement> | null;
|
||||
private _renderedContent: string | null;
|
||||
private _lineHeight: number;
|
||||
|
||||
constructor(configuration: IConfiguration, dynamicOverlays: DynamicViewOverlay[]) {
|
||||
@@ -157,7 +154,7 @@ export class ViewOverlayLine implements IVisibleLine {
|
||||
this._renderedContent = null;
|
||||
}
|
||||
|
||||
public getDomNode(): HTMLElement {
|
||||
public getDomNode(): HTMLElement | null {
|
||||
if (!this._domNode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { FastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
|
||||
|
||||
export abstract class ViewPart extends ViewEventHandler {
|
||||
|
||||
@@ -21,7 +20,6 @@ export abstract class ViewPart extends ViewEventHandler {
|
||||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -59,7 +57,7 @@ export class PartFingerprints {
|
||||
return parseInt(r, 10);
|
||||
}
|
||||
|
||||
public static collect(child: Element, stopAt: Element): Uint8Array {
|
||||
public static collect(child: Element | null, stopAt: Element): Uint8Array {
|
||||
let result: PartFingerprint[] = [], resultLen = 0;
|
||||
|
||||
while (child && child !== document.body) {
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { ContentWidgetPositionPreference, IContentWidget } from 'vs/editor/browser/editorBrowser';
|
||||
import { ViewPart, PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { PartFingerprint, PartFingerprints, ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { IPosition, Position } from 'vs/editor/common/core/position';
|
||||
import { IRange, Range } from 'vs/editor/common/core/range';
|
||||
import { Constants } from 'vs/editor/common/core/uint';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { Position, IPosition } from 'vs/editor/common/core/position';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
|
||||
|
||||
@@ -53,8 +53,7 @@ export class ViewContentWidgets extends ViewPart {
|
||||
|
||||
public dispose(): void {
|
||||
super.dispose();
|
||||
this._widgets = null;
|
||||
this.domNode = null;
|
||||
this._widgets = {};
|
||||
}
|
||||
|
||||
// --- begin event handlers
|
||||
@@ -113,9 +112,9 @@ export class ViewContentWidgets extends ViewPart {
|
||||
this.setShouldRender();
|
||||
}
|
||||
|
||||
public setWidgetPosition(widget: IContentWidget, position: IPosition, preference: ContentWidgetPositionPreference[]): void {
|
||||
public setWidgetPosition(widget: IContentWidget, position: IPosition | null | undefined, range: IRange | null | undefined, preference: ContentWidgetPositionPreference[] | null | undefined): void {
|
||||
const myWidget = this._widgets[widget.getId()];
|
||||
myWidget.setPosition(position, preference);
|
||||
myWidget.setPosition(position, range, preference);
|
||||
|
||||
this.setShouldRender();
|
||||
}
|
||||
@@ -127,7 +126,7 @@ export class ViewContentWidgets extends ViewPart {
|
||||
delete this._widgets[widgetId];
|
||||
|
||||
const domNode = myWidget.domNode.domNode;
|
||||
domNode.parentNode.removeChild(domNode);
|
||||
domNode.parentNode!.removeChild(domNode);
|
||||
domNode.removeAttribute('monaco-visible-content-widget');
|
||||
|
||||
this.setShouldRender();
|
||||
@@ -167,11 +166,13 @@ export class ViewContentWidgets extends ViewPart {
|
||||
}
|
||||
|
||||
interface IBoxLayoutResult {
|
||||
aboveTop: number;
|
||||
fitsAbove: boolean;
|
||||
belowTop: number;
|
||||
aboveTop: number;
|
||||
aboveLeft: number;
|
||||
|
||||
fitsBelow: boolean;
|
||||
left: number;
|
||||
belowTop: number;
|
||||
belowLeft: number;
|
||||
}
|
||||
|
||||
class Widget {
|
||||
@@ -189,15 +190,17 @@ class Widget {
|
||||
private _contentLeft: number;
|
||||
private _lineHeight: number;
|
||||
|
||||
private _position: IPosition;
|
||||
private _viewPosition: Position;
|
||||
private _preference: ContentWidgetPositionPreference[];
|
||||
private _position: IPosition | null;
|
||||
private _viewPosition: Position | null;
|
||||
private _range: IRange | null;
|
||||
private _viewRange: Range | null;
|
||||
private _preference: ContentWidgetPositionPreference[] | null;
|
||||
private _cachedDomNodeClientWidth: number;
|
||||
private _cachedDomNodeClientHeight: number;
|
||||
private _maxWidth: number;
|
||||
private _isVisible: boolean;
|
||||
|
||||
private _renderData: Coordinate;
|
||||
private _renderData: Coordinate | null;
|
||||
|
||||
constructor(context: ViewContext, viewDomNode: FastDomNode<HTMLElement>, actual: IContentWidget) {
|
||||
this._context = context;
|
||||
@@ -214,8 +217,8 @@ class Widget {
|
||||
this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft;
|
||||
this._lineHeight = this._context.configuration.editor.lineHeight;
|
||||
|
||||
this._setPosition(null);
|
||||
this._preference = null;
|
||||
this._setPosition(null, null);
|
||||
this._preference = [];
|
||||
this._cachedDomNodeClientWidth = -1;
|
||||
this._cachedDomNodeClientHeight = -1;
|
||||
this._maxWidth = this._getMaxWidth();
|
||||
@@ -240,12 +243,14 @@ class Widget {
|
||||
}
|
||||
|
||||
public onLineMappingChanged(e: viewEvents.ViewLineMappingChangedEvent): void {
|
||||
this._setPosition(this._position);
|
||||
this._setPosition(this._position, this._range);
|
||||
}
|
||||
|
||||
private _setPosition(position: IPosition): void {
|
||||
this._position = position;
|
||||
private _setPosition(position: IPosition | null | undefined, range: IRange | null | undefined): void {
|
||||
this._position = position || null;
|
||||
this._range = range || null;
|
||||
this._viewPosition = null;
|
||||
this._viewRange = null;
|
||||
|
||||
if (this._position) {
|
||||
// Do not trust that widgets give a valid position
|
||||
@@ -254,24 +259,29 @@ class Widget {
|
||||
this._viewPosition = this._context.model.coordinatesConverter.convertModelPositionToViewPosition(validModelPosition);
|
||||
}
|
||||
}
|
||||
if (this._range) {
|
||||
// Do not trust that widgets give a valid position
|
||||
const validModelRange = this._context.model.validateModelRange(this._range);
|
||||
this._viewRange = this._context.model.coordinatesConverter.convertModelRangeToViewRange(validModelRange);
|
||||
}
|
||||
}
|
||||
|
||||
private _getMaxWidth(): number {
|
||||
return (
|
||||
this.allowEditorOverflow
|
||||
? window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
|
||||
? window.innerWidth || document.documentElement!.clientWidth || document.body.clientWidth
|
||||
: this._contentWidth
|
||||
);
|
||||
}
|
||||
|
||||
public setPosition(position: IPosition, preference: ContentWidgetPositionPreference[]): void {
|
||||
this._setPosition(position);
|
||||
this._preference = preference;
|
||||
public setPosition(position: IPosition | null | undefined, range: IRange | null | undefined, preference: ContentWidgetPositionPreference[] | null | undefined): void {
|
||||
this._setPosition(position, range);
|
||||
this._preference = preference || null;
|
||||
this._cachedDomNodeClientWidth = -1;
|
||||
this._cachedDomNodeClientHeight = -1;
|
||||
}
|
||||
|
||||
private _layoutBoxInViewport(topLeft: Coordinate, width: number, height: number, ctx: RenderingContext): IBoxLayoutResult {
|
||||
private _layoutBoxInViewport(topLeft: Coordinate, bottomLeft: Coordinate, width: number, height: number, ctx: RenderingContext): IBoxLayoutResult {
|
||||
// Our visible box is split horizontally by the current line => 2 boxes
|
||||
|
||||
// a) the box above the line
|
||||
@@ -279,7 +289,7 @@ class Widget {
|
||||
let heightAboveLine = aboveLineTop;
|
||||
|
||||
// b) the box under the line
|
||||
let underLineTop = topLeft.top + this._lineHeight;
|
||||
let underLineTop = bottomLeft.top + this._lineHeight;
|
||||
let heightUnderLine = ctx.viewportHeight - underLineTop;
|
||||
|
||||
let aboveTop = aboveLineTop - height;
|
||||
@@ -288,42 +298,54 @@ class Widget {
|
||||
let fitsBelow = (heightUnderLine >= height);
|
||||
|
||||
// And its left
|
||||
let actualLeft = topLeft.left;
|
||||
if (actualLeft + width > ctx.scrollLeft + ctx.viewportWidth) {
|
||||
actualLeft = ctx.scrollLeft + ctx.viewportWidth - width;
|
||||
let actualAboveLeft = topLeft.left;
|
||||
let actualBelowLeft = bottomLeft.left;
|
||||
if (actualAboveLeft + width > ctx.scrollLeft + ctx.viewportWidth) {
|
||||
actualAboveLeft = ctx.scrollLeft + ctx.viewportWidth - width;
|
||||
}
|
||||
if (actualLeft < ctx.scrollLeft) {
|
||||
actualLeft = ctx.scrollLeft;
|
||||
if (actualBelowLeft + width > ctx.scrollLeft + ctx.viewportWidth) {
|
||||
actualBelowLeft = ctx.scrollLeft + ctx.viewportWidth - width;
|
||||
}
|
||||
if (actualAboveLeft < ctx.scrollLeft) {
|
||||
actualAboveLeft = ctx.scrollLeft;
|
||||
}
|
||||
if (actualBelowLeft < ctx.scrollLeft) {
|
||||
actualBelowLeft = ctx.scrollLeft;
|
||||
}
|
||||
|
||||
return {
|
||||
aboveTop: aboveTop,
|
||||
fitsAbove: fitsAbove,
|
||||
belowTop: belowTop,
|
||||
aboveTop: aboveTop,
|
||||
aboveLeft: actualAboveLeft,
|
||||
|
||||
fitsBelow: fitsBelow,
|
||||
left: actualLeft
|
||||
belowTop: belowTop,
|
||||
belowLeft: actualBelowLeft,
|
||||
};
|
||||
}
|
||||
|
||||
private _layoutBoxInPage(topLeft: Coordinate, width: number, height: number, ctx: RenderingContext): IBoxLayoutResult {
|
||||
let left0 = topLeft.left - ctx.scrollLeft;
|
||||
private _layoutBoxInPage(topLeft: Coordinate, bottomLeft: Coordinate, width: number, height: number, ctx: RenderingContext): IBoxLayoutResult | null {
|
||||
let aboveLeft0 = topLeft.left - ctx.scrollLeft;
|
||||
let belowLeft0 = bottomLeft.left - ctx.scrollLeft;
|
||||
|
||||
if (left0 < 0 || left0 > this._contentWidth) {
|
||||
if (aboveLeft0 < 0 || aboveLeft0 > this._contentWidth) {
|
||||
// Don't render if position is scrolled outside viewport
|
||||
return null;
|
||||
}
|
||||
|
||||
let aboveTop = topLeft.top - height;
|
||||
let belowTop = topLeft.top + this._lineHeight;
|
||||
let left = left0 + this._contentLeft;
|
||||
let belowTop = bottomLeft.top + this._lineHeight;
|
||||
let aboveLeft = aboveLeft0 + this._contentLeft;
|
||||
let belowLeft = belowLeft0 + this._contentLeft;
|
||||
|
||||
let domNodePosition = dom.getDomNodePagePosition(this._viewDomNode.domNode);
|
||||
let absoluteAboveTop = domNodePosition.top + aboveTop - dom.StandardWindow.scrollY;
|
||||
let absoluteBelowTop = domNodePosition.top + belowTop - dom.StandardWindow.scrollY;
|
||||
let absoluteLeft = domNodePosition.left + left - dom.StandardWindow.scrollX;
|
||||
let absoluteAboveLeft = domNodePosition.left + aboveLeft - dom.StandardWindow.scrollX;
|
||||
let absoluteBelowLeft = domNodePosition.left + belowLeft - dom.StandardWindow.scrollX;
|
||||
|
||||
let INNER_WIDTH = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
|
||||
let INNER_HEIGHT = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
|
||||
let INNER_WIDTH = window.innerWidth || document.documentElement!.clientWidth || document.body.clientWidth;
|
||||
let INNER_HEIGHT = window.innerHeight || document.documentElement!.clientHeight || document.body.clientHeight;
|
||||
|
||||
// Leave some clearance to the bottom
|
||||
let TOP_PADDING = 22;
|
||||
@@ -332,24 +354,35 @@ class Widget {
|
||||
let fitsAbove = (absoluteAboveTop >= TOP_PADDING),
|
||||
fitsBelow = (absoluteBelowTop + height <= INNER_HEIGHT - BOTTOM_PADDING);
|
||||
|
||||
if (absoluteLeft + width + 20 > INNER_WIDTH) {
|
||||
let delta = absoluteLeft - (INNER_WIDTH - width - 20);
|
||||
absoluteLeft -= delta;
|
||||
left -= delta;
|
||||
if (absoluteAboveLeft + width + 20 > INNER_WIDTH) {
|
||||
let delta = absoluteAboveLeft - (INNER_WIDTH - width - 20);
|
||||
absoluteAboveLeft -= delta;
|
||||
aboveLeft -= delta;
|
||||
}
|
||||
if (absoluteLeft < 0) {
|
||||
let delta = absoluteLeft;
|
||||
absoluteLeft -= delta;
|
||||
left -= delta;
|
||||
if (absoluteBelowLeft + width + 20 > INNER_WIDTH) {
|
||||
let delta = absoluteBelowLeft - (INNER_WIDTH - width - 20);
|
||||
absoluteBelowLeft -= delta;
|
||||
belowLeft -= delta;
|
||||
}
|
||||
if (absoluteAboveLeft < 0) {
|
||||
let delta = absoluteAboveLeft;
|
||||
absoluteAboveLeft -= delta;
|
||||
aboveLeft -= delta;
|
||||
}
|
||||
if (absoluteBelowLeft < 0) {
|
||||
let delta = absoluteBelowLeft;
|
||||
absoluteBelowLeft -= delta;
|
||||
belowLeft -= delta;
|
||||
}
|
||||
|
||||
if (this._fixedOverflowWidgets) {
|
||||
aboveTop = absoluteAboveTop;
|
||||
belowTop = absoluteBelowTop;
|
||||
left = absoluteLeft;
|
||||
aboveLeft = absoluteAboveLeft;
|
||||
belowLeft = absoluteBelowLeft;
|
||||
}
|
||||
|
||||
return { aboveTop, fitsAbove, belowTop, fitsBelow, left };
|
||||
return { fitsAbove, aboveTop, aboveLeft, fitsBelow, belowTop, belowLeft };
|
||||
}
|
||||
|
||||
private _prepareRenderWidgetAtExactPositionOverflowing(topLeft: Coordinate): Coordinate {
|
||||
@@ -359,71 +392,97 @@ class Widget {
|
||||
/**
|
||||
* Compute `this._topLeft`
|
||||
*/
|
||||
private _getTopLeft(ctx: RenderingContext): Coordinate {
|
||||
private _getTopAndBottomLeft(ctx: RenderingContext): [Coordinate, Coordinate] | [null, null] {
|
||||
if (!this._viewPosition) {
|
||||
return null;
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
const visibleRange = ctx.visibleRangeForPosition(this._viewPosition);
|
||||
if (!visibleRange) {
|
||||
return null;
|
||||
const visibleRangeForPosition = ctx.visibleRangeForPosition(this._viewPosition);
|
||||
if (!visibleRangeForPosition) {
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
const top = ctx.getVerticalOffsetForLineNumber(this._viewPosition.lineNumber) - ctx.scrollTop;
|
||||
return new Coordinate(top, visibleRange.left);
|
||||
const topForPosition = ctx.getVerticalOffsetForLineNumber(this._viewPosition.lineNumber) - ctx.scrollTop;
|
||||
const topLeft = new Coordinate(topForPosition, visibleRangeForPosition.left);
|
||||
|
||||
let largestLineNumber = this._viewPosition.lineNumber;
|
||||
let smallestLeft = visibleRangeForPosition.left;
|
||||
|
||||
if (this._viewRange) {
|
||||
const visibleRangesForRange = ctx.linesVisibleRangesForRange(this._viewRange, false);
|
||||
if (visibleRangesForRange && visibleRangesForRange.length > 0) {
|
||||
for (let i = visibleRangesForRange.length - 1; i >= 0; i--) {
|
||||
const visibleRangesForLine = visibleRangesForRange[i];
|
||||
if (visibleRangesForLine.lineNumber >= largestLineNumber) {
|
||||
if (visibleRangesForLine.lineNumber > largestLineNumber) {
|
||||
largestLineNumber = visibleRangesForLine.lineNumber;
|
||||
smallestLeft = Constants.MAX_SAFE_SMALL_INTEGER;
|
||||
}
|
||||
for (let j = 0, lenJ = visibleRangesForLine.ranges.length; j < lenJ; j++) {
|
||||
const visibleRange = visibleRangesForLine.ranges[j];
|
||||
|
||||
if (visibleRange.left < smallestLeft) {
|
||||
smallestLeft = visibleRange.left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const topForBottomLine = ctx.getVerticalOffsetForLineNumber(largestLineNumber) - ctx.scrollTop;
|
||||
const bottomLeft = new Coordinate(topForBottomLine, smallestLeft);
|
||||
|
||||
return [topLeft, bottomLeft];
|
||||
}
|
||||
|
||||
private _prepareRenderWidget(topLeft: Coordinate, ctx: RenderingContext): Coordinate {
|
||||
if (!topLeft) {
|
||||
private _prepareRenderWidget(ctx: RenderingContext): Coordinate | null {
|
||||
const [topLeft, bottomLeft] = this._getTopAndBottomLeft(ctx);
|
||||
if (!topLeft || !bottomLeft) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let placement: IBoxLayoutResult = null;
|
||||
let fetchPlacement = (): void => {
|
||||
if (placement) {
|
||||
return;
|
||||
}
|
||||
if (this._cachedDomNodeClientWidth === -1 || this._cachedDomNodeClientHeight === -1) {
|
||||
const domNode = this.domNode.domNode;
|
||||
this._cachedDomNodeClientWidth = domNode.clientWidth;
|
||||
this._cachedDomNodeClientHeight = domNode.clientHeight;
|
||||
}
|
||||
|
||||
if (this._cachedDomNodeClientWidth === -1 || this._cachedDomNodeClientHeight === -1) {
|
||||
const domNode = this.domNode.domNode;
|
||||
this._cachedDomNodeClientWidth = domNode.clientWidth;
|
||||
this._cachedDomNodeClientHeight = domNode.clientHeight;
|
||||
}
|
||||
|
||||
if (this.allowEditorOverflow) {
|
||||
placement = this._layoutBoxInPage(topLeft, this._cachedDomNodeClientWidth, this._cachedDomNodeClientHeight, ctx);
|
||||
} else {
|
||||
placement = this._layoutBoxInViewport(topLeft, this._cachedDomNodeClientWidth, this._cachedDomNodeClientHeight, ctx);
|
||||
}
|
||||
};
|
||||
let placement: IBoxLayoutResult | null;
|
||||
if (this.allowEditorOverflow) {
|
||||
placement = this._layoutBoxInPage(topLeft, bottomLeft, this._cachedDomNodeClientWidth, this._cachedDomNodeClientHeight, ctx);
|
||||
} else {
|
||||
placement = this._layoutBoxInViewport(topLeft, bottomLeft, this._cachedDomNodeClientWidth, this._cachedDomNodeClientHeight, ctx);
|
||||
}
|
||||
|
||||
// Do two passes, first for perfect fit, second picks first option
|
||||
for (let pass = 1; pass <= 2; pass++) {
|
||||
for (let i = 0; i < this._preference.length; i++) {
|
||||
let pref = this._preference[i];
|
||||
if (pref === ContentWidgetPositionPreference.ABOVE) {
|
||||
fetchPlacement();
|
||||
if (!placement) {
|
||||
// Widget outside of viewport
|
||||
return null;
|
||||
}
|
||||
if (pass === 2 || placement.fitsAbove) {
|
||||
return new Coordinate(placement.aboveTop, placement.left);
|
||||
}
|
||||
} else if (pref === ContentWidgetPositionPreference.BELOW) {
|
||||
fetchPlacement();
|
||||
if (!placement) {
|
||||
// Widget outside of viewport
|
||||
return null;
|
||||
}
|
||||
if (pass === 2 || placement.fitsBelow) {
|
||||
return new Coordinate(placement.belowTop, placement.left);
|
||||
}
|
||||
} else {
|
||||
if (this.allowEditorOverflow) {
|
||||
return this._prepareRenderWidgetAtExactPositionOverflowing(topLeft);
|
||||
if (this._preference) {
|
||||
for (let pass = 1; pass <= 2; pass++) {
|
||||
for (let i = 0; i < this._preference.length; i++) {
|
||||
// placement
|
||||
let pref = this._preference[i];
|
||||
if (pref === ContentWidgetPositionPreference.ABOVE) {
|
||||
if (!placement) {
|
||||
// Widget outside of viewport
|
||||
return null;
|
||||
}
|
||||
if (pass === 2 || placement.fitsAbove) {
|
||||
return new Coordinate(placement.aboveTop, placement.aboveLeft);
|
||||
}
|
||||
} else if (pref === ContentWidgetPositionPreference.BELOW) {
|
||||
if (!placement) {
|
||||
// Widget outside of viewport
|
||||
return null;
|
||||
}
|
||||
if (pass === 2 || placement.fitsBelow) {
|
||||
return new Coordinate(placement.belowTop, placement.belowLeft);
|
||||
}
|
||||
} else {
|
||||
return topLeft;
|
||||
if (this.allowEditorOverflow) {
|
||||
return this._prepareRenderWidgetAtExactPositionOverflowing(topLeft);
|
||||
} else {
|
||||
return topLeft;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -448,8 +507,7 @@ class Widget {
|
||||
}
|
||||
|
||||
public prepareRender(ctx: RenderingContext): void {
|
||||
const topLeft = this._getTopLeft(ctx);
|
||||
this._renderData = this._prepareRenderWidget(topLeft, ctx);
|
||||
this._renderData = this._prepareRenderWidget(ctx);
|
||||
}
|
||||
|
||||
public render(ctx: RestrictedRenderingContext): void {
|
||||
|
||||
@@ -3,15 +3,13 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./currentLineHighlight';
|
||||
import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { editorLineHighlight, editorLineHighlightBorder } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { RenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { editorLineHighlight, editorLineHighlightBorder } from 'vs/editor/common/view/editorColorRegistry';
|
||||
|
||||
export class CurrentLineHighlightOverlay extends DynamicViewOverlay {
|
||||
private _context: ViewContext;
|
||||
@@ -38,7 +36,6 @@ export class CurrentLineHighlightOverlay extends DynamicViewOverlay {
|
||||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -131,12 +128,12 @@ export class CurrentLineHighlightOverlay extends DynamicViewOverlay {
|
||||
}
|
||||
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
let lineHighlight = theme.getColor(editorLineHighlight);
|
||||
const lineHighlight = theme.getColor(editorLineHighlight);
|
||||
if (lineHighlight) {
|
||||
collector.addRule(`.monaco-editor .view-overlays .current-line { background-color: ${lineHighlight}; }`);
|
||||
}
|
||||
if (!lineHighlight || lineHighlight.isTransparent() || theme.defines(editorLineHighlightBorder)) {
|
||||
let lineHighlightBorder = theme.getColor(editorLineHighlightBorder);
|
||||
const lineHighlightBorder = theme.getColor(editorLineHighlightBorder);
|
||||
if (lineHighlightBorder) {
|
||||
collector.addRule(`.monaco-editor .view-overlays .current-line { border: 2px solid ${lineHighlightBorder}; }`);
|
||||
if (theme.type === 'hc') {
|
||||
|
||||
@@ -3,15 +3,13 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./currentLineMarginHighlight';
|
||||
import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { editorLineHighlight, editorLineHighlightBorder } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { RenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { editorLineHighlight, editorLineHighlightBorder } from 'vs/editor/common/view/editorColorRegistry';
|
||||
|
||||
export class CurrentLineMarginHighlightOverlay extends DynamicViewOverlay {
|
||||
private _context: ViewContext;
|
||||
@@ -36,7 +34,6 @@ export class CurrentLineMarginHighlightOverlay extends DynamicViewOverlay {
|
||||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -125,11 +122,11 @@ export class CurrentLineMarginHighlightOverlay extends DynamicViewOverlay {
|
||||
}
|
||||
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
let lineHighlight = theme.getColor(editorLineHighlight);
|
||||
const lineHighlight = theme.getColor(editorLineHighlight);
|
||||
if (lineHighlight) {
|
||||
collector.addRule(`.monaco-editor .margin-view-overlays .current-line-margin { background-color: ${lineHighlight}; border: none; }`);
|
||||
} else {
|
||||
let lineHighlightBorder = theme.getColor(editorLineHighlightBorder);
|
||||
const lineHighlightBorder = theme.getColor(editorLineHighlightBorder);
|
||||
if (lineHighlightBorder) {
|
||||
collector.addRule(`.monaco-editor .margin-view-overlays .current-line-margin { border: 2px solid ${lineHighlightBorder}; }`);
|
||||
}
|
||||
|
||||
@@ -3,22 +3,20 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./decorations';
|
||||
import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { HorizontalRange, RenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { RenderingContext, HorizontalRange } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewModelDecoration } from 'vs/editor/common/viewModel/viewModel';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { ViewModelDecoration } from 'vs/editor/common/viewModel/viewModel';
|
||||
|
||||
export class DecorationsOverlay extends DynamicViewOverlay {
|
||||
|
||||
private _context: ViewContext;
|
||||
private _lineHeight: number;
|
||||
private _typicalHalfwidthCharacterWidth: number;
|
||||
private _renderResult: string[];
|
||||
private _renderResult: string[] | null;
|
||||
|
||||
constructor(context: ViewContext) {
|
||||
super();
|
||||
@@ -32,7 +30,6 @@ export class DecorationsOverlay extends DynamicViewOverlay {
|
||||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
this._renderResult = null;
|
||||
super.dispose();
|
||||
}
|
||||
@@ -85,14 +82,14 @@ export class DecorationsOverlay extends DynamicViewOverlay {
|
||||
|
||||
// Sort decorations for consistent render output
|
||||
decorations = decorations.sort((a, b) => {
|
||||
if (a.options.zIndex < b.options.zIndex) {
|
||||
if (a.options.zIndex! < b.options.zIndex!) {
|
||||
return -1;
|
||||
}
|
||||
if (a.options.zIndex > b.options.zIndex) {
|
||||
if (a.options.zIndex! > b.options.zIndex!) {
|
||||
return 1;
|
||||
}
|
||||
const aClassName = a.options.className;
|
||||
const bClassName = b.options.className;
|
||||
const aClassName = a.options.className!;
|
||||
const bClassName = b.options.className!;
|
||||
|
||||
if (aClassName < bClassName) {
|
||||
return -1;
|
||||
@@ -151,9 +148,9 @@ export class DecorationsOverlay extends DynamicViewOverlay {
|
||||
const lineHeight = String(this._lineHeight);
|
||||
const visibleStartLineNumber = ctx.visibleRange.startLineNumber;
|
||||
|
||||
let prevClassName: string = null;
|
||||
let prevClassName: string | null = null;
|
||||
let prevShowIfCollapsed: boolean = false;
|
||||
let prevRange: Range = null;
|
||||
let prevRange: Range | null = null;
|
||||
|
||||
for (let i = 0, lenI = decorations.length; i < lenI; i++) {
|
||||
const d = decorations[i];
|
||||
@@ -162,23 +159,23 @@ export class DecorationsOverlay extends DynamicViewOverlay {
|
||||
continue;
|
||||
}
|
||||
|
||||
const className = d.options.className;
|
||||
const showIfCollapsed = d.options.showIfCollapsed;
|
||||
const className = d.options.className!;
|
||||
const showIfCollapsed = Boolean(d.options.showIfCollapsed);
|
||||
|
||||
let range = d.range;
|
||||
if (showIfCollapsed && range.endColumn === 1 && range.endLineNumber !== range.startLineNumber) {
|
||||
range = new Range(range.startLineNumber, range.startColumn, range.endLineNumber - 1, this._context.model.getLineMaxColumn(range.endLineNumber - 1));
|
||||
}
|
||||
|
||||
if (prevClassName === className && prevShowIfCollapsed === showIfCollapsed && Range.areIntersectingOrTouching(prevRange, range)) {
|
||||
if (prevClassName === className && prevShowIfCollapsed === showIfCollapsed && Range.areIntersectingOrTouching(prevRange!, range)) {
|
||||
// merge into previous decoration
|
||||
prevRange = Range.plusRange(prevRange, range);
|
||||
prevRange = Range.plusRange(prevRange!, range);
|
||||
continue;
|
||||
}
|
||||
|
||||
// flush previous decoration
|
||||
if (prevClassName !== null) {
|
||||
this._renderNormalDecoration(ctx, prevRange, prevClassName, prevShowIfCollapsed, lineHeight, visibleStartLineNumber, output);
|
||||
this._renderNormalDecoration(ctx, prevRange!, prevClassName, prevShowIfCollapsed, lineHeight, visibleStartLineNumber, output);
|
||||
}
|
||||
|
||||
prevClassName = className;
|
||||
@@ -187,7 +184,7 @@ export class DecorationsOverlay extends DynamicViewOverlay {
|
||||
}
|
||||
|
||||
if (prevClassName !== null) {
|
||||
this._renderNormalDecoration(ctx, prevRange, prevClassName, prevShowIfCollapsed, lineHeight, visibleStartLineNumber, output);
|
||||
this._renderNormalDecoration(ctx, prevRange!, prevClassName, prevShowIfCollapsed, lineHeight, visibleStartLineNumber, output);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,19 +2,18 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { ScrollableElementCreationOptions, ScrollableElementChangeOptions } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { IOverviewRulerLayoutInfo, SmoothScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
import { ScrollableElementChangeOptions, ScrollableElementCreationOptions } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
|
||||
import { PartFingerprint, PartFingerprints, ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { INewScrollPosition } from 'vs/editor/common/editorCommon';
|
||||
import { ViewPart, PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { getThemeTypeSelector } from 'vs/platform/theme/common/themeService';
|
||||
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
|
||||
export class EditorScrollbar extends ViewPart {
|
||||
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./glyphMargin';
|
||||
import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { RenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
|
||||
export class DecorationToRender {
|
||||
@@ -49,7 +47,7 @@ export abstract class DedupOverlay extends DynamicViewOverlay {
|
||||
return (a.className < b.className ? -1 : 1);
|
||||
});
|
||||
|
||||
let prevClassName: string = null;
|
||||
let prevClassName: string | null = null;
|
||||
let prevEndLineIndex = 0;
|
||||
for (let i = 0, len = decorations.length; i < len; i++) {
|
||||
let d = decorations[i];
|
||||
@@ -81,7 +79,7 @@ export class GlyphMarginOverlay extends DedupOverlay {
|
||||
private _glyphMargin: boolean;
|
||||
private _glyphMarginLeft: number;
|
||||
private _glyphMarginWidth: number;
|
||||
private _renderResult: string[];
|
||||
private _renderResult: string[] | null;
|
||||
|
||||
constructor(context: ViewContext) {
|
||||
super();
|
||||
@@ -96,7 +94,6 @@ export class GlyphMarginOverlay extends DedupOverlay {
|
||||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
this._renderResult = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -3,16 +3,14 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./indentGuides';
|
||||
import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { editorActiveIndentGuides, editorIndentGuides } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { RenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { editorIndentGuides, editorActiveIndentGuides } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
|
||||
export class IndentGuidesOverlay extends DynamicViewOverlay {
|
||||
|
||||
@@ -20,7 +18,7 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
|
||||
private _primaryLineNumber: number;
|
||||
private _lineHeight: number;
|
||||
private _spaceWidth: number;
|
||||
private _renderResult: string[];
|
||||
private _renderResult: string[] | null;
|
||||
private _enabled: boolean;
|
||||
private _activeIndentEnabled: boolean;
|
||||
|
||||
@@ -39,7 +37,6 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
|
||||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
this._renderResult = null;
|
||||
super.dispose();
|
||||
}
|
||||
@@ -160,11 +157,11 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
|
||||
}
|
||||
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
let editorIndentGuidesColor = theme.getColor(editorIndentGuides);
|
||||
const editorIndentGuidesColor = theme.getColor(editorIndentGuides);
|
||||
if (editorIndentGuidesColor) {
|
||||
collector.addRule(`.monaco-editor .lines-content .cigr { box-shadow: 1px 0 0 0 ${editorIndentGuidesColor} inset; }`);
|
||||
}
|
||||
let editorActiveIndentGuidesColor = theme.getColor(editorActiveIndentGuides) || editorIndentGuidesColor;
|
||||
const editorActiveIndentGuidesColor = theme.getColor(editorActiveIndentGuides) || editorIndentGuidesColor;
|
||||
if (editorActiveIndentGuidesColor) {
|
||||
collector.addRule(`.monaco-editor .lines-content .cigra { box-shadow: 1px 0 0 0 ${editorActiveIndentGuidesColor} inset; }`);
|
||||
}
|
||||
|
||||
@@ -3,18 +3,16 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./lineNumbers';
|
||||
import { editorLineNumbers, editorActiveLineNumber } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { RenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { RenderLineNumbersType } from 'vs/editor/common/config/editorOptions';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { editorActiveLineNumber, editorLineNumbers } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { RenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
export class LineNumbersOverlay extends DynamicViewOverlay {
|
||||
|
||||
@@ -24,11 +22,11 @@ export class LineNumbersOverlay extends DynamicViewOverlay {
|
||||
|
||||
private _lineHeight: number;
|
||||
private _renderLineNumbers: RenderLineNumbersType;
|
||||
private _renderCustomLineNumbers: (lineNumber: number) => string;
|
||||
private _renderCustomLineNumbers: ((lineNumber: number) => string) | null;
|
||||
private _lineNumbersLeft: number;
|
||||
private _lineNumbersWidth: number;
|
||||
private _lastCursorModelPosition: Position;
|
||||
private _renderResult: string[];
|
||||
private _renderResult: string[] | null;
|
||||
|
||||
constructor(context: ViewContext) {
|
||||
super();
|
||||
@@ -52,7 +50,6 @@ export class LineNumbersOverlay extends DynamicViewOverlay {
|
||||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
this._renderResult = null;
|
||||
super.dispose();
|
||||
}
|
||||
@@ -171,7 +168,7 @@ export class LineNumbersOverlay extends DynamicViewOverlay {
|
||||
// theming
|
||||
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
let lineNumbers = theme.getColor(editorLineNumbers);
|
||||
const lineNumbers = theme.getColor(editorLineNumbers);
|
||||
if (lineNumbers) {
|
||||
collector.addRule(`.monaco-editor .line-numbers { color: ${lineNumbers}; }`);
|
||||
}
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { HorizontalRange } from 'vs/editor/common/view/renderingContext';
|
||||
import { Constants } from 'vs/editor/common/core/uint';
|
||||
import { HorizontalRange } from 'vs/editor/common/view/renderingContext';
|
||||
|
||||
class FloatHorizontalRange {
|
||||
_floatHorizontalRangeBrand: void;
|
||||
@@ -49,7 +48,7 @@ export class RangeUtil {
|
||||
range.selectNodeContents(endNode);
|
||||
}
|
||||
|
||||
private static _readClientRects(startElement: Node, startOffset: number, endElement: Node, endOffset: number, endNode: HTMLElement): ClientRectList {
|
||||
private static _readClientRects(startElement: Node, startOffset: number, endElement: Node, endOffset: number, endNode: HTMLElement): ClientRectList | DOMRectList | null {
|
||||
let range = this._createRange();
|
||||
try {
|
||||
range.setStart(startElement, startOffset);
|
||||
@@ -95,7 +94,7 @@ export class RangeUtil {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static _createHorizontalRangesFromClientRects(clientRects: ClientRectList, clientRectDeltaLeft: number): HorizontalRange[] {
|
||||
private static _createHorizontalRangesFromClientRects(clientRects: ClientRectList | DOMRectList | null, clientRectDeltaLeft: number): HorizontalRange[] | null {
|
||||
if (!clientRects || clientRects.length === 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -112,7 +111,7 @@ export class RangeUtil {
|
||||
return this._mergeAdjacentRanges(result);
|
||||
}
|
||||
|
||||
public static readHorizontalRanges(domNode: HTMLElement, startChildIndex: number, startOffset: number, endChildIndex: number, endOffset: number, clientRectDeltaLeft: number, endNode: HTMLElement): HorizontalRange[] {
|
||||
public static readHorizontalRanges(domNode: HTMLElement, startChildIndex: number, startOffset: number, endChildIndex: number, endOffset: number, clientRectDeltaLeft: number, endNode: HTMLElement): HorizontalRange[] | null {
|
||||
// Panic check
|
||||
let min = 0;
|
||||
let max = domNode.children.length - 1;
|
||||
@@ -150,8 +149,8 @@ export class RangeUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
startOffset = Math.min(startElement.textContent.length, Math.max(0, startOffset));
|
||||
endOffset = Math.min(endElement.textContent.length, Math.max(0, endOffset));
|
||||
startOffset = Math.min(startElement.textContent!.length, Math.max(0, startOffset));
|
||||
endOffset = Math.min(endElement.textContent!.length, Math.max(0, endOffset));
|
||||
|
||||
let clientRects = this._readClientRects(startElement, startOffset, endElement, endOffset, endNode);
|
||||
return this._createHorizontalRangesFromClientRects(clientRects, clientRectDeltaLeft);
|
||||
|
||||
@@ -2,21 +2,20 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { IConfiguration } from 'vs/editor/common/editorCommon';
|
||||
import { LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations';
|
||||
import { renderViewLine, RenderLineInput, CharacterMapping, ForeignElementType } from 'vs/editor/common/viewLayout/viewLineRenderer';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { IVisibleLine } from 'vs/editor/browser/view/viewLayer';
|
||||
import { RangeUtil } from 'vs/editor/browser/viewParts/lines/rangeUtil';
|
||||
import { HorizontalRange } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
|
||||
import { ThemeType, HIGH_CONTRAST } from 'vs/platform/theme/common/themeService';
|
||||
import { IStringBuilder } from 'vs/editor/common/core/stringBuilder';
|
||||
import { IConfiguration } from 'vs/editor/common/editorCommon';
|
||||
import { HorizontalRange } from 'vs/editor/common/view/renderingContext';
|
||||
import { LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations';
|
||||
import { CharacterMapping, ForeignElementType, RenderLineInput, renderViewLine } from 'vs/editor/common/viewLayout/viewLineRenderer';
|
||||
import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
|
||||
import { InlineDecorationType } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { HIGH_CONTRAST, ThemeType } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
const canUseFastRenderedViewLine = (function () {
|
||||
if (platform.isNative) {
|
||||
@@ -74,6 +73,7 @@ export class ViewLineOptions {
|
||||
public readonly renderControlCharacters: boolean;
|
||||
public readonly spaceWidth: number;
|
||||
public readonly useMonospaceOptimizations: boolean;
|
||||
public readonly canUseHalfwidthRightwardsArrow: boolean;
|
||||
public readonly lineHeight: number;
|
||||
public readonly stopRenderingLineAfter: number;
|
||||
public readonly fontLigatures: boolean;
|
||||
@@ -87,6 +87,7 @@ export class ViewLineOptions {
|
||||
config.editor.fontInfo.isMonospace
|
||||
&& !config.editor.viewInfo.disableMonospaceOptimizations
|
||||
);
|
||||
this.canUseHalfwidthRightwardsArrow = config.editor.fontInfo.canUseHalfwidthRightwardsArrow;
|
||||
this.lineHeight = config.editor.lineHeight;
|
||||
this.stopRenderingLineAfter = config.editor.viewInfo.stopRenderingLineAfter;
|
||||
this.fontLigatures = config.editor.viewInfo.fontLigatures;
|
||||
@@ -99,6 +100,7 @@ export class ViewLineOptions {
|
||||
&& this.renderControlCharacters === other.renderControlCharacters
|
||||
&& this.spaceWidth === other.spaceWidth
|
||||
&& this.useMonospaceOptimizations === other.useMonospaceOptimizations
|
||||
&& this.canUseHalfwidthRightwardsArrow === other.canUseHalfwidthRightwardsArrow
|
||||
&& this.lineHeight === other.lineHeight
|
||||
&& this.stopRenderingLineAfter === other.stopRenderingLineAfter
|
||||
&& this.fontLigatures === other.fontLigatures
|
||||
@@ -112,7 +114,7 @@ export class ViewLine implements IVisibleLine {
|
||||
|
||||
private _options: ViewLineOptions;
|
||||
private _isMaybeInvalid: boolean;
|
||||
private _renderedViewLine: IRenderedViewLine;
|
||||
private _renderedViewLine: IRenderedViewLine | null;
|
||||
|
||||
constructor(options: ViewLineOptions) {
|
||||
this._options = options;
|
||||
@@ -122,7 +124,7 @@ export class ViewLine implements IVisibleLine {
|
||||
|
||||
// --- begin IVisibleLineData
|
||||
|
||||
public getDomNode(): HTMLElement {
|
||||
public getDomNode(): HTMLElement | null {
|
||||
if (this._renderedViewLine && this._renderedViewLine.domNode) {
|
||||
return this._renderedViewLine.domNode.domNode;
|
||||
}
|
||||
@@ -190,6 +192,7 @@ export class ViewLine implements IVisibleLine {
|
||||
|
||||
let renderLineInput = new RenderLineInput(
|
||||
options.useMonospaceOptimizations,
|
||||
options.canUseHalfwidthRightwardsArrow,
|
||||
lineData.content,
|
||||
lineData.continuesWithWrappedLine,
|
||||
lineData.isBasicASCII,
|
||||
@@ -222,7 +225,7 @@ export class ViewLine implements IVisibleLine {
|
||||
|
||||
sb.appendASCIIString('</div>');
|
||||
|
||||
let renderedViewLine: IRenderedViewLine = null;
|
||||
let renderedViewLine: IRenderedViewLine | null = null;
|
||||
if (canUseFastRenderedViewLine && lineData.isBasicASCII && options.useMonospaceOptimizations && output.containsForeignElements === ForeignElementType.None) {
|
||||
if (lineData.content.length < 300 && renderLineInput.lineTokens.getCount() < 100) {
|
||||
// Browser rounding errors have been observed in Chrome and IE, so using the fast
|
||||
@@ -279,7 +282,10 @@ export class ViewLine implements IVisibleLine {
|
||||
return this._renderedViewLine.getWidthIsFast();
|
||||
}
|
||||
|
||||
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
|
||||
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
|
||||
if (!this._renderedViewLine) {
|
||||
return null;
|
||||
}
|
||||
startColumn = startColumn | 0; // @perf
|
||||
endColumn = endColumn | 0; // @perf
|
||||
|
||||
@@ -305,16 +311,19 @@ export class ViewLine implements IVisibleLine {
|
||||
}
|
||||
|
||||
public getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number {
|
||||
if (!this._renderedViewLine) {
|
||||
return 1;
|
||||
}
|
||||
return this._renderedViewLine.getColumnOfNodeOffset(lineNumber, spanNode, offset);
|
||||
}
|
||||
}
|
||||
|
||||
interface IRenderedViewLine {
|
||||
domNode: FastDomNode<HTMLElement>;
|
||||
domNode: FastDomNode<HTMLElement> | null;
|
||||
readonly input: RenderLineInput;
|
||||
getWidth(): number;
|
||||
getWidthIsFast(): boolean;
|
||||
getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[];
|
||||
getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null;
|
||||
getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number;
|
||||
}
|
||||
|
||||
@@ -323,13 +332,13 @@ interface IRenderedViewLine {
|
||||
*/
|
||||
class FastRenderedViewLine implements IRenderedViewLine {
|
||||
|
||||
public domNode: FastDomNode<HTMLElement>;
|
||||
public domNode: FastDomNode<HTMLElement> | null;
|
||||
public readonly input: RenderLineInput;
|
||||
|
||||
private readonly _characterMapping: CharacterMapping;
|
||||
private readonly _charWidth: number;
|
||||
|
||||
constructor(domNode: FastDomNode<HTMLElement>, renderLineInput: RenderLineInput, characterMapping: CharacterMapping) {
|
||||
constructor(domNode: FastDomNode<HTMLElement> | null, renderLineInput: RenderLineInput, characterMapping: CharacterMapping) {
|
||||
this.domNode = domNode;
|
||||
this.input = renderLineInput;
|
||||
|
||||
@@ -345,7 +354,7 @@ class FastRenderedViewLine implements IRenderedViewLine {
|
||||
return true;
|
||||
}
|
||||
|
||||
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
|
||||
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
|
||||
const startPosition = this._getCharPosition(startColumn);
|
||||
const endPosition = this._getCharPosition(endColumn);
|
||||
return [new HorizontalRange(startPosition, endPosition - startPosition)];
|
||||
@@ -361,7 +370,7 @@ class FastRenderedViewLine implements IRenderedViewLine {
|
||||
}
|
||||
|
||||
public getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number {
|
||||
let spanNodeTextContentLength = spanNode.textContent.length;
|
||||
let spanNodeTextContentLength = spanNode.textContent!.length;
|
||||
|
||||
let spanIndex = -1;
|
||||
while (spanNode) {
|
||||
@@ -390,7 +399,7 @@ class RenderedViewLine implements IRenderedViewLine {
|
||||
/**
|
||||
* This is a map that is used only when the line is guaranteed to have no RTL text.
|
||||
*/
|
||||
private _pixelOffsetCache: Int32Array;
|
||||
private _pixelOffsetCache: Int32Array | null;
|
||||
|
||||
constructor(domNode: FastDomNode<HTMLElement>, renderLineInput: RenderLineInput, characterMapping: CharacterMapping, containsRTL: boolean, containsForeignElements: ForeignElementType) {
|
||||
this.domNode = domNode;
|
||||
@@ -435,7 +444,7 @@ class RenderedViewLine implements IRenderedViewLine {
|
||||
/**
|
||||
* Visible ranges for a model range
|
||||
*/
|
||||
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
|
||||
public getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
|
||||
if (this._pixelOffsetCache !== null) {
|
||||
// the text is LTR
|
||||
let startOffset = this._readPixelOffset(startColumn, context);
|
||||
@@ -454,7 +463,7 @@ class RenderedViewLine implements IRenderedViewLine {
|
||||
return this._readVisibleRangesForRange(startColumn, endColumn, context);
|
||||
}
|
||||
|
||||
protected _readVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
|
||||
protected _readVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
|
||||
if (startColumn === endColumn) {
|
||||
let pixelOffset = this._readPixelOffset(startColumn, context);
|
||||
if (pixelOffset === -1) {
|
||||
@@ -526,7 +535,7 @@ class RenderedViewLine implements IRenderedViewLine {
|
||||
return r[0].left;
|
||||
}
|
||||
|
||||
private _readRawVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
|
||||
private _readRawVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
|
||||
|
||||
if (startColumn === 1 && endColumn === this._characterMapping.length) {
|
||||
// This branch helps IE with bidi text & gives a performance boost to other browsers when reading visible ranges for an entire line
|
||||
@@ -549,7 +558,7 @@ class RenderedViewLine implements IRenderedViewLine {
|
||||
* Returns the column for the text found at a specific offset inside a rendered dom node
|
||||
*/
|
||||
public getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number {
|
||||
let spanNodeTextContentLength = spanNode.textContent.length;
|
||||
let spanNodeTextContentLength = spanNode.textContent!.length;
|
||||
|
||||
let spanIndex = -1;
|
||||
while (spanNode) {
|
||||
@@ -563,7 +572,7 @@ class RenderedViewLine implements IRenderedViewLine {
|
||||
}
|
||||
|
||||
class WebKitRenderedViewLine extends RenderedViewLine {
|
||||
protected _readVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] {
|
||||
protected _readVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[] | null {
|
||||
let output = super._readVisibleRangesForRange(startColumn, endColumn, context);
|
||||
|
||||
if (!output || output.length === 0 || startColumn === endColumn || (startColumn === 1 && endColumn === this._characterMapping.length)) {
|
||||
@@ -572,20 +581,16 @@ class WebKitRenderedViewLine extends RenderedViewLine {
|
||||
|
||||
// WebKit is buggy and returns an expanded range (to contain words in some cases)
|
||||
// The last client rect is enlarged (I think)
|
||||
|
||||
// This is an attempt to patch things up
|
||||
// Find position of previous column
|
||||
let beforeEndPixelOffset = this._readPixelOffset(endColumn - 1, context);
|
||||
// Find position of last column
|
||||
let endPixelOffset = this._readPixelOffset(endColumn, context);
|
||||
|
||||
if (beforeEndPixelOffset !== -1 && endPixelOffset !== -1) {
|
||||
let isLTR = (beforeEndPixelOffset <= endPixelOffset);
|
||||
let lastRange = output[output.length - 1];
|
||||
|
||||
if (isLTR && lastRange.left < endPixelOffset) {
|
||||
// Trim down the width of the last visible range to not go after the last column's position
|
||||
lastRange.width = endPixelOffset - lastRange.left;
|
||||
if (!this.input.containsRTL) {
|
||||
// This is an attempt to patch things up
|
||||
// Find position of last column
|
||||
let endPixelOffset = this._readPixelOffset(endColumn, context);
|
||||
if (endPixelOffset !== -1) {
|
||||
let lastRange = output[output.length - 1];
|
||||
if (lastRange.left < endPixelOffset) {
|
||||
// Trim down the width of the last visible range to not go after the last column's position
|
||||
lastRange.width = endPixelOffset - lastRange.left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,7 +598,7 @@ class WebKitRenderedViewLine extends RenderedViewLine {
|
||||
}
|
||||
}
|
||||
|
||||
const createRenderedLine: (domNode: FastDomNode<HTMLElement>, renderLineInput: RenderLineInput, characterMapping: CharacterMapping, containsRTL: boolean, containsForeignElements: ForeignElementType) => RenderedViewLine = (function () {
|
||||
const createRenderedLine: (domNode: FastDomNode<HTMLElement> | null, renderLineInput: RenderLineInput, characterMapping: CharacterMapping, containsRTL: boolean, containsForeignElements: ForeignElementType) => RenderedViewLine = (function () {
|
||||
if (browser.isWebKit) {
|
||||
return createWebKitRenderedLine;
|
||||
}
|
||||
|
||||
@@ -2,23 +2,22 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./viewLines';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { FastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { VisibleLinesCollection, IVisibleLinesHost } from 'vs/editor/browser/view/viewLayer';
|
||||
import { ViewLineOptions, DomReadingContext, ViewLine } from 'vs/editor/browser/viewParts/lines/viewLine';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { Configuration } from 'vs/editor/browser/config/configuration';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
|
||||
import { IViewLines, HorizontalRange, LineVisibleRanges } from 'vs/editor/common/view/renderingContext';
|
||||
import { Viewport } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { ViewPart, PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { IVisibleLinesHost, VisibleLinesCollection } from 'vs/editor/browser/view/viewLayer';
|
||||
import { PartFingerprint, PartFingerprints, ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { DomReadingContext, ViewLine, ViewLineOptions } from 'vs/editor/browser/viewParts/lines/viewLine';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { HorizontalRange, IViewLines, LineVisibleRanges } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
|
||||
import { Viewport } from 'vs/editor/common/viewModel/viewModel';
|
||||
|
||||
class LastRenderedData {
|
||||
|
||||
@@ -58,7 +57,7 @@ class HorizontalRevealRequest {
|
||||
|
||||
export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>, IViewLines {
|
||||
/**
|
||||
* Adds this ammount of pixels to the right of lines (no-one wants to type near the edge of the viewport)
|
||||
* Adds this amount of pixels to the right of lines (no-one wants to type near the edge of the viewport)
|
||||
*/
|
||||
private static readonly HORIZONTAL_EXTRA_PX = 30;
|
||||
|
||||
@@ -79,7 +78,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
||||
private _maxLineWidth: number;
|
||||
private _asyncUpdateLineWidths: RunOnceScheduler;
|
||||
|
||||
private _horizontalRevealRequest: HorizontalRevealRequest;
|
||||
private _horizontalRevealRequest: HorizontalRevealRequest | null;
|
||||
private _lastRenderedData: LastRenderedData;
|
||||
|
||||
constructor(context: ViewContext, linesContent: FastDomNode<HTMLElement>) {
|
||||
@@ -282,7 +281,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
||||
|
||||
// ----------- HELPERS FOR OTHERS
|
||||
|
||||
public getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position {
|
||||
public getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position | null {
|
||||
let viewLineDomNode = this._getViewLineDomNode(spanNode);
|
||||
if (viewLineDomNode === null) {
|
||||
// Couldn't find view line node
|
||||
@@ -320,7 +319,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
||||
return new Position(lineNumber, column);
|
||||
}
|
||||
|
||||
private _getViewLineDomNode(node: HTMLElement): HTMLElement {
|
||||
private _getViewLineDomNode(node: HTMLElement | null): HTMLElement | null {
|
||||
while (node && node.nodeType === 1) {
|
||||
if (node.className === ViewLine.CLASS_NAME) {
|
||||
return node;
|
||||
@@ -356,15 +355,15 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
||||
return this._visibleLines.getVisibleLine(lineNumber).getWidth();
|
||||
}
|
||||
|
||||
public linesVisibleRangesForRange(range: Range, includeNewLines: boolean): LineVisibleRanges[] {
|
||||
public linesVisibleRangesForRange(_range: Range, includeNewLines: boolean): LineVisibleRanges[] | null {
|
||||
if (this.shouldRender()) {
|
||||
// Cannot read from the DOM because it is dirty
|
||||
// i.e. the model & the dom are out of sync, so I'd be reading something stale
|
||||
return null;
|
||||
}
|
||||
|
||||
let originalEndLineNumber = range.endLineNumber;
|
||||
range = Range.intersectRanges(range, this._lastRenderedData.getCurrentVisibleRange());
|
||||
let originalEndLineNumber = _range.endLineNumber;
|
||||
const range = Range.intersectRanges(_range, this._lastRenderedData.getCurrentVisibleRange());
|
||||
if (!range) {
|
||||
return null;
|
||||
}
|
||||
@@ -372,7 +371,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
||||
let visibleRanges: LineVisibleRanges[] = [], visibleRangesLen = 0;
|
||||
let domReadingContext = new DomReadingContext(this.domNode.domNode, this._textRangeRestingSpot);
|
||||
|
||||
let nextLineModelLineNumber: number;
|
||||
let nextLineModelLineNumber: number = 0;
|
||||
if (includeNewLines) {
|
||||
nextLineModelLineNumber = this._context.model.coordinatesConverter.convertViewPositionToModelPosition(new Position(range.startLineNumber, 1)).lineNumber;
|
||||
}
|
||||
@@ -412,7 +411,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
||||
return visibleRanges;
|
||||
}
|
||||
|
||||
public visibleRangesForRange2(range: Range): HorizontalRange[] {
|
||||
private visibleRangesForRange2(_range: Range): HorizontalRange[] | null {
|
||||
|
||||
if (this.shouldRender()) {
|
||||
// Cannot read from the DOM because it is dirty
|
||||
@@ -420,7 +419,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
||||
return null;
|
||||
}
|
||||
|
||||
range = Range.intersectRanges(range, this._lastRenderedData.getCurrentVisibleRange());
|
||||
const range = Range.intersectRanges(_range, this._lastRenderedData.getCurrentVisibleRange());
|
||||
if (!range) {
|
||||
return null;
|
||||
}
|
||||
@@ -454,6 +453,14 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
||||
return result;
|
||||
}
|
||||
|
||||
public visibleRangeForPosition(position: Position): HorizontalRange | null {
|
||||
const visibleRanges = this.visibleRangesForRange2(new Range(position.lineNumber, position.column, position.lineNumber, position.column));
|
||||
if (!visibleRanges) {
|
||||
return null;
|
||||
}
|
||||
return visibleRanges[0];
|
||||
}
|
||||
|
||||
// --- implementation
|
||||
|
||||
public updateLineWidths(): void {
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./linesDecorations';
|
||||
import { DecorationToRender, DedupOverlay } from 'vs/editor/browser/viewParts/glyphMargin/glyphMargin';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { RenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
|
||||
export class LinesDecorationsOverlay extends DedupOverlay {
|
||||
@@ -17,7 +15,7 @@ export class LinesDecorationsOverlay extends DedupOverlay {
|
||||
|
||||
private _decorationsLeft: number;
|
||||
private _decorationsWidth: number;
|
||||
private _renderResult: string[];
|
||||
private _renderResult: string[] | null;
|
||||
|
||||
constructor(context: ViewContext) {
|
||||
super();
|
||||
@@ -30,7 +28,6 @@ export class LinesDecorationsOverlay extends DedupOverlay {
|
||||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
this._renderResult = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
|
||||
export class Margin extends ViewPart {
|
||||
|
||||
@@ -3,17 +3,15 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./marginDecorations';
|
||||
import { DecorationToRender, DedupOverlay } from 'vs/editor/browser/viewParts/glyphMargin/glyphMargin';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { RenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
|
||||
export class MarginViewLineDecorationsOverlay extends DedupOverlay {
|
||||
private _context: ViewContext;
|
||||
private _renderResult: string[];
|
||||
private _renderResult: string[] | null;
|
||||
|
||||
constructor(context: ViewContext) {
|
||||
super();
|
||||
@@ -24,7 +22,6 @@ export class MarginViewLineDecorationsOverlay extends DedupOverlay {
|
||||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
this._renderResult = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -3,38 +3,29 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./minimap';
|
||||
import { ViewPart, PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { getOrCreateMinimapCharRenderer } from 'vs/editor/common/view/runtimeMinimapCharRenderer';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { MinimapCharRenderer, MinimapTokensColorTracker, Constants } from 'vs/editor/common/view/minimapCharRenderer';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
import { ViewLineData } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { ColorId } from 'vs/editor/common/modes';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { GlobalMouseMoveMonitor, IStandardMouseMoveEventData, standardMouseMoveMerger } from 'vs/base/browser/globalMouseMoveMonitor';
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { RenderedLinesCollection, ILine } from 'vs/editor/browser/view/viewLayer';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { ILine, RenderedLinesCollection } from 'vs/editor/browser/view/viewLayer';
|
||||
import { PartFingerprint, PartFingerprints, ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { RenderMinimap } from 'vs/editor/common/config/editorOptions';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { RGBA8 } from 'vs/editor/common/core/rgba';
|
||||
import { IConfiguration, ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { ColorId } from 'vs/editor/common/modes';
|
||||
import { Constants, MinimapCharRenderer, MinimapTokensColorTracker } from 'vs/editor/common/view/minimapCharRenderer';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { getOrCreateMinimapCharRenderer } from 'vs/editor/common/view/runtimeMinimapCharRenderer';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { GlobalMouseMoveMonitor, IStandardMouseMoveEventData, standardMouseMoveMerger } from 'vs/base/browser/globalMouseMoveMonitor';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { ViewLineData } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { scrollbarShadow, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { scrollbarSliderBackground, scrollbarSliderHoverBackground, scrollbarSliderActiveBackground, scrollbarShadow } from 'vs/platform/theme/common/colorRegistry';
|
||||
|
||||
const enum RenderMinimap {
|
||||
None = 0,
|
||||
Small = 1,
|
||||
Large = 2,
|
||||
SmallBlocks = 3,
|
||||
LargeBlocks = 4,
|
||||
}
|
||||
|
||||
function getMinimapLineHeight(renderMinimap: RenderMinimap): number {
|
||||
if (renderMinimap === RenderMinimap.Large) {
|
||||
@@ -114,7 +105,7 @@ class MinimapOptions {
|
||||
*/
|
||||
public readonly canvasOuterHeight: number;
|
||||
|
||||
constructor(configuration: editorCommon.IConfiguration) {
|
||||
constructor(configuration: IConfiguration) {
|
||||
const pixelRatio = configuration.editor.pixelRatio;
|
||||
const layoutInfo = configuration.editor.layoutInfo;
|
||||
const viewInfo = configuration.editor.viewInfo;
|
||||
@@ -222,7 +213,7 @@ class MinimapLayout {
|
||||
lineCount: number,
|
||||
scrollTop: number,
|
||||
scrollHeight: number,
|
||||
previousLayout: MinimapLayout
|
||||
previousLayout: MinimapLayout | null
|
||||
): MinimapLayout {
|
||||
const pixelRatio = options.pixelRatio;
|
||||
const minimapLineHeight = getMinimapLineHeight(options.renderMinimap);
|
||||
@@ -447,8 +438,8 @@ export class Minimap extends ViewPart {
|
||||
private readonly _sliderMouseDownListener: IDisposable;
|
||||
|
||||
private _options: MinimapOptions;
|
||||
private _lastRenderData: RenderData;
|
||||
private _buffers: MinimapBuffers;
|
||||
private _lastRenderData: RenderData | null;
|
||||
private _buffers: MinimapBuffers | null;
|
||||
|
||||
constructor(context: ViewContext) {
|
||||
super(context);
|
||||
@@ -509,7 +500,7 @@ export class Minimap extends ViewPart {
|
||||
new Range(lineNumber, 1, lineNumber, 1),
|
||||
viewEvents.VerticalRevealType.Center,
|
||||
false,
|
||||
editorCommon.ScrollType.Smooth
|
||||
ScrollType.Smooth
|
||||
));
|
||||
});
|
||||
|
||||
@@ -583,13 +574,13 @@ export class Minimap extends ViewPart {
|
||||
private _getBuffer(): ImageData {
|
||||
if (!this._buffers) {
|
||||
this._buffers = new MinimapBuffers(
|
||||
this._canvas.domNode.getContext('2d'),
|
||||
this._canvas.domNode.getContext('2d')!,
|
||||
this._options.canvasInnerWidth,
|
||||
this._options.canvasInnerHeight,
|
||||
this._tokensColorTracker.getColor(ColorId.DefaultBackground)
|
||||
);
|
||||
}
|
||||
return this._buffers.getBuffer();
|
||||
return this._buffers!.getBuffer();
|
||||
}
|
||||
|
||||
private _onOptionsMaybeChanged(): boolean {
|
||||
@@ -742,7 +733,7 @@ export class Minimap extends ViewPart {
|
||||
getOrCreateMinimapCharRenderer(),
|
||||
dy,
|
||||
tabSize,
|
||||
lineInfo.data[lineIndex]
|
||||
lineInfo.data[lineIndex]!
|
||||
);
|
||||
}
|
||||
renderedLines[lineIndex] = new MinimapLine(dy);
|
||||
@@ -754,7 +745,7 @@ export class Minimap extends ViewPart {
|
||||
const dirtyHeight = dirtyY2 - dirtyY1;
|
||||
|
||||
// Finally, paint to the canvas
|
||||
const ctx = this._canvas.domNode.getContext('2d');
|
||||
const ctx = this._canvas.domNode.getContext('2d')!;
|
||||
ctx.putImageData(imageData, 0, 0, 0, dirtyY1, imageData.width, dirtyHeight);
|
||||
|
||||
// Save rendered data for reuse on next frame if possible
|
||||
@@ -770,7 +761,7 @@ export class Minimap extends ViewPart {
|
||||
startLineNumber: number,
|
||||
endLineNumber: number,
|
||||
minimapLineHeight: number,
|
||||
lastRenderData: RenderData,
|
||||
lastRenderData: RenderData | null,
|
||||
): [number, number, boolean[]] {
|
||||
|
||||
let needed: boolean[] = [];
|
||||
|
||||
@@ -3,19 +3,17 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./overlayWidgets';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { IOverlayWidget, OverlayWidgetPositionPreference } from 'vs/editor/browser/editorBrowser';
|
||||
import { ViewPart, PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { PartFingerprint, PartFingerprints, ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
|
||||
interface IWidgetData {
|
||||
widget: IOverlayWidget;
|
||||
preference: OverlayWidgetPositionPreference;
|
||||
preference: OverlayWidgetPositionPreference | null;
|
||||
domNode: FastDomNode<HTMLElement>;
|
||||
}
|
||||
|
||||
@@ -51,7 +49,7 @@ export class ViewOverlayWidgets extends ViewPart {
|
||||
|
||||
public dispose(): void {
|
||||
super.dispose();
|
||||
this._widgets = null;
|
||||
this._widgets = {};
|
||||
}
|
||||
|
||||
public getDomNode(): FastDomNode<HTMLElement> {
|
||||
@@ -91,7 +89,7 @@ export class ViewOverlayWidgets extends ViewPart {
|
||||
this.setShouldRender();
|
||||
}
|
||||
|
||||
public setWidgetPosition(widget: IOverlayWidget, preference: OverlayWidgetPositionPreference): boolean {
|
||||
public setWidgetPosition(widget: IOverlayWidget, preference: OverlayWidgetPositionPreference | null): boolean {
|
||||
let widgetData = this._widgets[widget.getId()];
|
||||
if (widgetData.preference === preference) {
|
||||
return false;
|
||||
@@ -110,7 +108,7 @@ export class ViewOverlayWidgets extends ViewPart {
|
||||
const domNode = widgetData.domNode.domNode;
|
||||
delete this._widgets[widgetId];
|
||||
|
||||
domNode.parentNode.removeChild(domNode);
|
||||
domNode.parentNode!.removeChild(domNode);
|
||||
this.setShouldRender();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,20 +2,19 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { TokenizationRegistry } from 'vs/editor/common/modes';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { editorOverviewRulerBorder, editorCursorForeground } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { ITheme } from 'vs/platform/theme/common/themeService';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { IConfiguration } from 'vs/editor/common/editorCommon';
|
||||
import { TokenizationRegistry } from 'vs/editor/common/modes';
|
||||
import { editorCursorForeground, editorOverviewRulerBorder } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { ITheme } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
class Settings {
|
||||
|
||||
@@ -24,13 +23,13 @@ class Settings {
|
||||
public readonly overviewRulerLanes: number;
|
||||
|
||||
public readonly renderBorder: boolean;
|
||||
public readonly borderColor: string;
|
||||
public readonly borderColor: string | null;
|
||||
|
||||
public readonly hideCursor: boolean;
|
||||
public readonly cursorColor: string;
|
||||
public readonly cursorColor: string | null;
|
||||
|
||||
public readonly themeType: 'light' | 'dark' | 'hc';
|
||||
public readonly backgroundColor: string;
|
||||
public readonly backgroundColor: string | null;
|
||||
|
||||
public readonly top: number;
|
||||
public readonly right: number;
|
||||
@@ -42,7 +41,7 @@ class Settings {
|
||||
public readonly x: number[];
|
||||
public readonly w: number[];
|
||||
|
||||
constructor(config: editorCommon.IConfiguration, theme: ITheme) {
|
||||
constructor(config: IConfiguration, theme: ITheme) {
|
||||
this.lineHeight = config.editor.lineHeight;
|
||||
this.pixelRatio = config.editor.pixelRatio;
|
||||
this.overviewRulerLanes = config.editor.viewInfo.overviewRulerLanes;
|
||||
@@ -214,7 +213,6 @@ export class DecorationsOverviewRuler extends ViewPart {
|
||||
this._domNode.setLayerHinting(true);
|
||||
this._domNode.setAttribute('aria-hidden', 'true');
|
||||
|
||||
this._settings = null;
|
||||
this._updateSettings(false);
|
||||
|
||||
this._tokensColorTrackerListener = TokenizationRegistry.onDidChange((e) => {
|
||||
@@ -233,7 +231,7 @@ export class DecorationsOverviewRuler extends ViewPart {
|
||||
|
||||
private _updateSettings(renderNow: boolean): boolean {
|
||||
const newSettings = new Settings(this._context.configuration, this._context.theme);
|
||||
if (this._settings !== null && this._settings.equals(newSettings)) {
|
||||
if (this._settings && this._settings.equals(newSettings)) {
|
||||
// nothing to do
|
||||
return false;
|
||||
}
|
||||
@@ -311,7 +309,7 @@ export class DecorationsOverviewRuler extends ViewPart {
|
||||
const minDecorationHeight = (Constants.MIN_DECORATION_HEIGHT * this._settings.pixelRatio) | 0;
|
||||
const halfMinDecorationHeight = (minDecorationHeight / 2) | 0;
|
||||
|
||||
const canvasCtx = this._domNode.domNode.getContext('2d');
|
||||
const canvasCtx = this._domNode.domNode.getContext('2d')!;
|
||||
if (this._settings.backgroundColor === null) {
|
||||
canvasCtx.clearRect(0, 0, canvasWidth, canvasHeight);
|
||||
} else {
|
||||
@@ -373,7 +371,7 @@ export class DecorationsOverviewRuler extends ViewPart {
|
||||
}
|
||||
|
||||
// Draw cursors
|
||||
if (!this._settings.hideCursor) {
|
||||
if (!this._settings.hideCursor && this._settings.cursorColor) {
|
||||
const cursorHeight = (2 * this._settings.pixelRatio) | 0;
|
||||
const halfCursorHeight = (cursorHeight / 2) | 0;
|
||||
const cursorX = this._settings.x[OverviewRulerLane.Full];
|
||||
|
||||
@@ -2,15 +2,14 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { IOverviewRuler } from 'vs/editor/browser/editorBrowser';
|
||||
import { OverviewRulerPosition } from 'vs/editor/common/config/editorOptions';
|
||||
import { ColorZone, OverviewRulerZone, OverviewZoneManager } from 'vs/editor/common/view/overviewZoneManager';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { OverviewRulerPosition } from 'vs/editor/common/config/editorOptions';
|
||||
import { OverviewRulerZone, OverviewZoneManager, ColorZone } from 'vs/editor/common/view/overviewZoneManager';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
|
||||
|
||||
export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
|
||||
|
||||
@@ -40,7 +39,6 @@ export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
|
||||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._zoneManager = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -119,7 +117,7 @@ export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
|
||||
let colorZones = this._zoneManager.resolveColorZones();
|
||||
let id2Color = this._zoneManager.getId2Color();
|
||||
|
||||
let ctx = this._domNode.domNode.getContext('2d');
|
||||
let ctx = this._domNode.domNode.getContext('2d')!;
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
if (colorZones.length > 0) {
|
||||
this._renderOneLane(ctx, colorZones, id2Color, width);
|
||||
|
||||
@@ -3,16 +3,14 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./rulers';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { editorRuler } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { editorRuler } from 'vs/editor/common/view/editorColorRegistry';
|
||||
|
||||
export class Rulers extends ViewPart {
|
||||
|
||||
@@ -81,7 +79,7 @@ export class Rulers extends ViewPart {
|
||||
|
||||
let removeCount = currentCount - desiredCount;
|
||||
while (removeCount > 0) {
|
||||
let node = this._renderedRulers.pop();
|
||||
let node = this._renderedRulers.pop()!;
|
||||
this.domNode.removeChild(node);
|
||||
removeCount--;
|
||||
}
|
||||
@@ -101,7 +99,7 @@ export class Rulers extends ViewPart {
|
||||
}
|
||||
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
let rulerColor = theme.getColor(editorRuler);
|
||||
const rulerColor = theme.getColor(editorRuler);
|
||||
if (rulerColor) {
|
||||
collector.addRule(`.monaco-editor .view-ruler { box-shadow: 1px 0 0 0 ${rulerColor} inset; }`);
|
||||
}
|
||||
|
||||
@@ -3,16 +3,14 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./scrollDecoration';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { scrollbarShadow } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
export class ScrollDecorationViewPart extends ViewPart {
|
||||
|
||||
@@ -97,7 +95,7 @@ export class ScrollDecorationViewPart extends ViewPart {
|
||||
}
|
||||
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
let shadow = theme.getColor(scrollbarShadow);
|
||||
const shadow = theme.getColor(scrollbarShadow);
|
||||
if (shadow) {
|
||||
collector.addRule(`.monaco-editor .scroll-decoration { box-shadow: ${shadow} 0 6px 6px -6px inset; }`);
|
||||
}
|
||||
|
||||
@@ -3,17 +3,15 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./selections';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { editorSelectionBackground, editorInactiveSelection, editorSelectionForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { HorizontalRange, LineVisibleRanges, RenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { HorizontalRange, LineVisibleRanges, RenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { editorInactiveSelection, editorSelectionBackground, editorSelectionForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
const enum CornerStyle {
|
||||
EXTERN,
|
||||
@@ -29,8 +27,8 @@ interface IVisibleRangeEndPointStyle {
|
||||
class HorizontalRangeWithStyle {
|
||||
public left: number;
|
||||
public width: number;
|
||||
public startStyle: IVisibleRangeEndPointStyle;
|
||||
public endStyle: IVisibleRangeEndPointStyle;
|
||||
public startStyle: IVisibleRangeEndPointStyle | null;
|
||||
public endStyle: IVisibleRangeEndPointStyle | null;
|
||||
|
||||
constructor(other: HorizontalRange) {
|
||||
this.left = other.left;
|
||||
@@ -80,7 +78,7 @@ export class SelectionsOverlay extends DynamicViewOverlay {
|
||||
private _roundedSelection: boolean;
|
||||
private _typicalHalfwidthCharacterWidth: number;
|
||||
private _selections: Range[];
|
||||
private _renderResult: string[];
|
||||
private _renderResult: string[] | null;
|
||||
|
||||
constructor(context: ViewContext) {
|
||||
super();
|
||||
@@ -95,8 +93,6 @@ export class SelectionsOverlay extends DynamicViewOverlay {
|
||||
|
||||
public dispose(): void {
|
||||
this._context.removeEventHandler(this);
|
||||
this._context = null;
|
||||
this._selections = null;
|
||||
this._renderResult = null;
|
||||
super.dispose();
|
||||
}
|
||||
@@ -158,10 +154,10 @@ export class SelectionsOverlay extends DynamicViewOverlay {
|
||||
return false;
|
||||
}
|
||||
|
||||
private _enrichVisibleRangesWithStyle(viewport: Range, linesVisibleRanges: LineVisibleRangesWithStyle[], previousFrame: LineVisibleRangesWithStyle[]): void {
|
||||
private _enrichVisibleRangesWithStyle(viewport: Range, linesVisibleRanges: LineVisibleRangesWithStyle[], previousFrame: LineVisibleRangesWithStyle[] | null): void {
|
||||
const epsilon = this._typicalHalfwidthCharacterWidth / 4;
|
||||
let previousFrameTop: HorizontalRangeWithStyle = null;
|
||||
let previousFrameBottom: HorizontalRangeWithStyle = null;
|
||||
let previousFrameTop: HorizontalRangeWithStyle | null = null;
|
||||
let previousFrameBottom: HorizontalRangeWithStyle | null = null;
|
||||
|
||||
if (previousFrame && previousFrame.length > 0 && linesVisibleRanges.length > 0) {
|
||||
|
||||
@@ -225,8 +221,8 @@ export class SelectionsOverlay extends DynamicViewOverlay {
|
||||
}
|
||||
} else if (previousFrameTop) {
|
||||
// Accept some hick-ups near the viewport edges to save on repaints
|
||||
startStyle.top = previousFrameTop.startStyle.top;
|
||||
endStyle.top = previousFrameTop.endStyle.top;
|
||||
startStyle.top = previousFrameTop.startStyle!.top;
|
||||
endStyle.top = previousFrameTop.endStyle!.top;
|
||||
}
|
||||
|
||||
if (i + 1 < len) {
|
||||
@@ -247,8 +243,8 @@ export class SelectionsOverlay extends DynamicViewOverlay {
|
||||
}
|
||||
} else if (previousFrameBottom) {
|
||||
// Accept some hick-ups near the viewport edges to save on repaints
|
||||
startStyle.bottom = previousFrameBottom.startStyle.bottom;
|
||||
endStyle.bottom = previousFrameBottom.endStyle.bottom;
|
||||
startStyle.bottom = previousFrameBottom.startStyle!.bottom;
|
||||
endStyle.bottom = previousFrameBottom.endStyle!.bottom;
|
||||
}
|
||||
|
||||
curLineRange.startStyle = startStyle;
|
||||
@@ -256,7 +252,7 @@ export class SelectionsOverlay extends DynamicViewOverlay {
|
||||
}
|
||||
}
|
||||
|
||||
private _getVisibleRangesWithStyle(selection: Range, ctx: RenderingContext, previousFrame: LineVisibleRangesWithStyle[]): LineVisibleRangesWithStyle[] {
|
||||
private _getVisibleRangesWithStyle(selection: Range, ctx: RenderingContext, previousFrame: LineVisibleRangesWithStyle[] | null): LineVisibleRangesWithStyle[] {
|
||||
let _linesVisibleRanges = ctx.linesVisibleRangesForRange(selection, true) || [];
|
||||
let linesVisibleRanges = _linesVisibleRanges.map(toStyled);
|
||||
let visibleRangesHaveGaps = this._visibleRangesHaveGaps(linesVisibleRanges);
|
||||
@@ -307,7 +303,9 @@ export class SelectionsOverlay extends DynamicViewOverlay {
|
||||
let visibleRange = lineVisibleRanges.ranges[j];
|
||||
|
||||
if (visibleRangesHaveStyle) {
|
||||
if (visibleRange.startStyle.top === CornerStyle.INTERN || visibleRange.startStyle.bottom === CornerStyle.INTERN) {
|
||||
const startStyle = visibleRange.startStyle!;
|
||||
const endStyle = visibleRange.endStyle!;
|
||||
if (startStyle.top === CornerStyle.INTERN || startStyle.bottom === CornerStyle.INTERN) {
|
||||
// Reverse rounded corner to the left
|
||||
|
||||
// First comes the selection (blue layer)
|
||||
@@ -315,15 +313,15 @@ export class SelectionsOverlay extends DynamicViewOverlay {
|
||||
|
||||
// Second comes the background (white layer) with inverse border radius
|
||||
let className = SelectionsOverlay.EDITOR_BACKGROUND_CLASS_NAME;
|
||||
if (visibleRange.startStyle.top === CornerStyle.INTERN) {
|
||||
if (startStyle.top === CornerStyle.INTERN) {
|
||||
className += ' ' + SelectionsOverlay.SELECTION_TOP_RIGHT;
|
||||
}
|
||||
if (visibleRange.startStyle.bottom === CornerStyle.INTERN) {
|
||||
if (startStyle.bottom === CornerStyle.INTERN) {
|
||||
className += ' ' + SelectionsOverlay.SELECTION_BOTTOM_RIGHT;
|
||||
}
|
||||
lineOutput += this._createSelectionPiece(top, lineHeight, className, visibleRange.left - SelectionsOverlay.ROUNDED_PIECE_WIDTH, SelectionsOverlay.ROUNDED_PIECE_WIDTH);
|
||||
}
|
||||
if (visibleRange.endStyle.top === CornerStyle.INTERN || visibleRange.endStyle.bottom === CornerStyle.INTERN) {
|
||||
if (endStyle.top === CornerStyle.INTERN || endStyle.bottom === CornerStyle.INTERN) {
|
||||
// Reverse rounded corner to the right
|
||||
|
||||
// First comes the selection (blue layer)
|
||||
@@ -331,10 +329,10 @@ export class SelectionsOverlay extends DynamicViewOverlay {
|
||||
|
||||
// Second comes the background (white layer) with inverse border radius
|
||||
let className = SelectionsOverlay.EDITOR_BACKGROUND_CLASS_NAME;
|
||||
if (visibleRange.endStyle.top === CornerStyle.INTERN) {
|
||||
if (endStyle.top === CornerStyle.INTERN) {
|
||||
className += ' ' + SelectionsOverlay.SELECTION_TOP_LEFT;
|
||||
}
|
||||
if (visibleRange.endStyle.bottom === CornerStyle.INTERN) {
|
||||
if (endStyle.bottom === CornerStyle.INTERN) {
|
||||
className += ' ' + SelectionsOverlay.SELECTION_BOTTOM_LEFT;
|
||||
}
|
||||
lineOutput += this._createSelectionPiece(top, lineHeight, className, visibleRange.left + visibleRange.width, SelectionsOverlay.ROUNDED_PIECE_WIDTH);
|
||||
@@ -343,16 +341,18 @@ export class SelectionsOverlay extends DynamicViewOverlay {
|
||||
|
||||
let className = SelectionsOverlay.SELECTION_CLASS_NAME;
|
||||
if (visibleRangesHaveStyle) {
|
||||
if (visibleRange.startStyle.top === CornerStyle.EXTERN) {
|
||||
const startStyle = visibleRange.startStyle!;
|
||||
const endStyle = visibleRange.endStyle!;
|
||||
if (startStyle.top === CornerStyle.EXTERN) {
|
||||
className += ' ' + SelectionsOverlay.SELECTION_TOP_LEFT;
|
||||
}
|
||||
if (visibleRange.startStyle.bottom === CornerStyle.EXTERN) {
|
||||
if (startStyle.bottom === CornerStyle.EXTERN) {
|
||||
className += ' ' + SelectionsOverlay.SELECTION_BOTTOM_LEFT;
|
||||
}
|
||||
if (visibleRange.endStyle.top === CornerStyle.EXTERN) {
|
||||
if (endStyle.top === CornerStyle.EXTERN) {
|
||||
className += ' ' + SelectionsOverlay.SELECTION_TOP_RIGHT;
|
||||
}
|
||||
if (visibleRange.endStyle.bottom === CornerStyle.EXTERN) {
|
||||
if (endStyle.bottom === CornerStyle.EXTERN) {
|
||||
className += ' ' + SelectionsOverlay.SELECTION_BOTTOM_RIGHT;
|
||||
}
|
||||
}
|
||||
@@ -363,7 +363,7 @@ export class SelectionsOverlay extends DynamicViewOverlay {
|
||||
}
|
||||
}
|
||||
|
||||
private _previousFrameVisibleRangesWithStyle: LineVisibleRangesWithStyle[][] = [];
|
||||
private _previousFrameVisibleRangesWithStyle: (LineVisibleRangesWithStyle[] | null)[] = [];
|
||||
public prepareRender(ctx: RenderingContext): void {
|
||||
|
||||
let output: string[] = [];
|
||||
@@ -374,7 +374,7 @@ export class SelectionsOverlay extends DynamicViewOverlay {
|
||||
output[lineIndex] = '';
|
||||
}
|
||||
|
||||
let thisFrameVisibleRangesWithStyle: LineVisibleRangesWithStyle[][] = [];
|
||||
let thisFrameVisibleRangesWithStyle: (LineVisibleRangesWithStyle[] | null)[] = [];
|
||||
for (let i = 0, len = this._selections.length; i < len; i++) {
|
||||
let selection = this._selections[i];
|
||||
if (selection.isEmpty()) {
|
||||
@@ -404,15 +404,15 @@ export class SelectionsOverlay extends DynamicViewOverlay {
|
||||
}
|
||||
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
let editorSelectionColor = theme.getColor(editorSelectionBackground);
|
||||
const editorSelectionColor = theme.getColor(editorSelectionBackground);
|
||||
if (editorSelectionColor) {
|
||||
collector.addRule(`.monaco-editor .focused .selected-text { background-color: ${editorSelectionColor}; }`);
|
||||
}
|
||||
let editorInactiveSelectionColor = theme.getColor(editorInactiveSelection);
|
||||
const editorInactiveSelectionColor = theme.getColor(editorInactiveSelection);
|
||||
if (editorInactiveSelectionColor) {
|
||||
collector.addRule(`.monaco-editor .selected-text { background-color: ${editorInactiveSelectionColor}; }`);
|
||||
}
|
||||
let editorSelectionForegroundColor = theme.getColor(editorSelectionForeground);
|
||||
const editorSelectionForegroundColor = theme.getColor(editorSelectionForeground);
|
||||
if (editorSelectionForegroundColor) {
|
||||
collector.addRule(`.monaco-editor .view-line span.inline-selected-text { color: ${editorSelectionForegroundColor}; }`);
|
||||
}
|
||||
|
||||
@@ -2,18 +2,17 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { Configuration } from 'vs/editor/browser/config/configuration';
|
||||
import { TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions';
|
||||
import { Configuration } from 'vs/editor/browser/config/configuration';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
|
||||
export interface IViewCursorRenderData {
|
||||
domNode: HTMLElement;
|
||||
@@ -48,7 +47,7 @@ export class ViewCursor {
|
||||
private _position: Position;
|
||||
|
||||
private _lastRenderedContent: string;
|
||||
private _renderData: ViewCursorRenderData;
|
||||
private _renderData: ViewCursorRenderData | null;
|
||||
|
||||
constructor(context: ViewContext) {
|
||||
this._context = context;
|
||||
@@ -118,7 +117,7 @@ export class ViewCursor {
|
||||
return true;
|
||||
}
|
||||
|
||||
private _prepareRender(ctx: RenderingContext): ViewCursorRenderData {
|
||||
private _prepareRender(ctx: RenderingContext): ViewCursorRenderData | null {
|
||||
let textContent = '';
|
||||
let textContentClassName = '';
|
||||
|
||||
@@ -138,8 +137,13 @@ export class ViewCursor {
|
||||
} else {
|
||||
width = dom.computeScreenAwareSize(1);
|
||||
}
|
||||
let left = visibleRange.left;
|
||||
if (width >= 2 && left >= 1) {
|
||||
// try to center cursor
|
||||
left -= 1;
|
||||
}
|
||||
const top = ctx.getVerticalOffsetForLineNumber(this._position.lineNumber) - ctx.bigNumbersDelta;
|
||||
return new ViewCursorRenderData(top, visibleRange.left, width, this._lineHeight, textContent, textContentClassName);
|
||||
return new ViewCursorRenderData(top, left, width, this._lineHeight, textContent, textContentClassName);
|
||||
}
|
||||
|
||||
const visibleRangeForCharacter = ctx.linesVisibleRangesForRange(new Range(this._position.lineNumber, this._position.column, this._position.lineNumber, this._position.column + 1), false);
|
||||
@@ -178,7 +182,7 @@ export class ViewCursor {
|
||||
this._renderData = this._prepareRender(ctx);
|
||||
}
|
||||
|
||||
public render(ctx: RestrictedRenderingContext): IViewCursorRenderData {
|
||||
public render(ctx: RestrictedRenderingContext): IViewCursorRenderData | null {
|
||||
if (!this._renderData) {
|
||||
this._domNode.setDisplay('none');
|
||||
return null;
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* -- smooth-caret-animation -- */
|
||||
.monaco-editor .cursors-layer.cursor-smooth-caret-animation > .cursor {
|
||||
transition: 80ms;
|
||||
}
|
||||
|
||||
/* -- block-outline-style -- */
|
||||
.monaco-editor .cursors-layer.cursor-block-outline-style > .cursor {
|
||||
box-sizing: border-box;
|
||||
|
||||
@@ -3,20 +3,18 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./viewCursors';
|
||||
import { ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { IViewCursorRenderData, ViewCursor } from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { TimeoutTimer, IntervalTimer } from 'vs/base/common/async';
|
||||
import { IntervalTimer, TimeoutTimer } from 'vs/base/common/async';
|
||||
import { ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { IViewCursorRenderData, ViewCursor } from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
|
||||
import { TextEditorCursorBlinkingStyle, TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { editorCursorBackground, editorCursorForeground } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { editorCursorForeground, editorCursorBackground } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { TextEditorCursorBlinkingStyle, TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions';
|
||||
|
||||
export class ViewCursors extends ViewPart {
|
||||
|
||||
@@ -25,6 +23,7 @@ export class ViewCursors extends ViewPart {
|
||||
private _readOnly: boolean;
|
||||
private _cursorBlinking: TextEditorCursorBlinkingStyle;
|
||||
private _cursorStyle: TextEditorCursorStyle;
|
||||
private _cursorSmoothCaretAnimation: boolean;
|
||||
private _selectionIsEmpty: boolean;
|
||||
|
||||
private _isVisible: boolean;
|
||||
@@ -47,6 +46,7 @@ export class ViewCursors extends ViewPart {
|
||||
this._readOnly = this._context.configuration.editor.readOnly;
|
||||
this._cursorBlinking = this._context.configuration.editor.viewInfo.cursorBlinking;
|
||||
this._cursorStyle = this._context.configuration.editor.viewInfo.cursorStyle;
|
||||
this._cursorSmoothCaretAnimation = this._context.configuration.editor.viewInfo.cursorSmoothCaretAnimation;
|
||||
this._selectionIsEmpty = true;
|
||||
|
||||
this._primaryCursor = new ViewCursor(this._context);
|
||||
@@ -89,6 +89,7 @@ export class ViewCursors extends ViewPart {
|
||||
if (e.viewInfo) {
|
||||
this._cursorBlinking = this._context.configuration.editor.viewInfo.cursorBlinking;
|
||||
this._cursorStyle = this._context.configuration.editor.viewInfo.cursorStyle;
|
||||
this._cursorSmoothCaretAnimation = this._context.configuration.editor.viewInfo.cursorSmoothCaretAnimation;
|
||||
}
|
||||
|
||||
this._primaryCursor.onConfigurationChanged(e);
|
||||
@@ -297,6 +298,9 @@ export class ViewCursors extends ViewPart {
|
||||
} else {
|
||||
result += ' cursor-solid';
|
||||
}
|
||||
if (this._cursorSmoothCaretAnimation) {
|
||||
result += ' cursor-smooth-caret-animation';
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -349,7 +353,7 @@ export class ViewCursors extends ViewPart {
|
||||
}
|
||||
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
let caret = theme.getColor(editorCursorForeground);
|
||||
const caret = theme.getColor(editorCursorForeground);
|
||||
if (caret) {
|
||||
let caretBackground = theme.getColor(editorCursorBackground);
|
||||
if (!caretBackground) {
|
||||
|
||||
@@ -2,24 +2,23 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { IViewZone } from 'vs/editor/browser/editorBrowser';
|
||||
import { ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { IViewWhitespaceViewportData } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { IViewWhitespaceViewportData } from 'vs/editor/common/viewModel/viewModel';
|
||||
|
||||
export interface IMyViewZone {
|
||||
whitespaceId: number;
|
||||
delegate: IViewZone;
|
||||
isVisible: boolean;
|
||||
domNode: FastDomNode<HTMLElement>;
|
||||
marginDomNode: FastDomNode<HTMLElement>;
|
||||
marginDomNode: FastDomNode<HTMLElement> | null;
|
||||
}
|
||||
|
||||
interface IComputedViewZoneProps {
|
||||
@@ -228,12 +227,12 @@ export class ViewZones extends ViewPart {
|
||||
|
||||
zone.domNode.removeAttribute('monaco-visible-view-zone');
|
||||
zone.domNode.removeAttribute('monaco-view-zone');
|
||||
zone.domNode.domNode.parentNode.removeChild(zone.domNode.domNode);
|
||||
zone.domNode.domNode.parentNode!.removeChild(zone.domNode.domNode);
|
||||
|
||||
if (zone.marginDomNode) {
|
||||
zone.marginDomNode.removeAttribute('monaco-visible-view-zone');
|
||||
zone.marginDomNode.removeAttribute('monaco-view-zone');
|
||||
zone.marginDomNode.domNode.parentNode.removeChild(zone.marginDomNode.domNode);
|
||||
zone.marginDomNode.domNode.parentNode!.removeChild(zone.marginDomNode.domNode);
|
||||
}
|
||||
|
||||
this.setShouldRender();
|
||||
@@ -263,7 +262,7 @@ export class ViewZones extends ViewPart {
|
||||
public shouldSuppressMouseDownOnViewZone(id: number): boolean {
|
||||
if (this._zones.hasOwnProperty(id.toString())) {
|
||||
let zone = this._zones[id.toString()];
|
||||
return zone.delegate.suppressMouseDown;
|
||||
return Boolean(zone.delegate.suppressMouseDown);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,45 +3,43 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./media/diffEditor';
|
||||
import * as nls from 'vs/nls';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { ISashEvent, IVerticalSashLayoutProvider, Sash, SashState } from 'vs/base/browser/ui/sash/sash';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { Range, IRange } from 'vs/editor/common/core/range';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations';
|
||||
import { renderViewLine, RenderLineInput } from 'vs/editor/common/viewLayout/viewLineRenderer';
|
||||
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
|
||||
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import { Configuration } from 'vs/editor/browser/config/configuration';
|
||||
import { Position, IPosition } from 'vs/editor/common/core/position';
|
||||
import { Selection, ISelection } from 'vs/editor/common/core/selection';
|
||||
import { InlineDecoration, InlineDecorationType, ViewLineRenderingData } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import * as editorOptions from 'vs/editor/common/config/editorOptions';
|
||||
import { registerThemingParticipant, IThemeService, ITheme, getThemeTypeSelector } from 'vs/platform/theme/common/themeService';
|
||||
import { scrollbarShadow, diffInserted, diffRemoved, defaultInsertColor, defaultRemoveColor, diffInsertedOutline, diffRemovedOutline, diffBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { OverviewRulerZone } from 'vs/editor/common/view/overviewZoneManager';
|
||||
import { IEditorWhitespace } from 'vs/editor/common/viewLayout/whitespaceComputer';
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
|
||||
import { DiffReview } from 'vs/editor/browser/widget/diffReview';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { IStringBuilder, createStringBuilder } from 'vs/editor/common/core/stringBuilder';
|
||||
import { IModelDeltaDecoration, IModelDecorationsChangeAccessor, ITextModel } from 'vs/editor/common/model';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Configuration } from 'vs/editor/browser/config/configuration';
|
||||
import { StableEditorScrollState } from 'vs/editor/browser/core/editorState';
|
||||
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import { DiffReview } from 'vs/editor/browser/widget/diffReview';
|
||||
import * as editorOptions from 'vs/editor/common/config/editorOptions';
|
||||
import { IPosition, Position } from 'vs/editor/common/core/position';
|
||||
import { IRange, Range } from 'vs/editor/common/core/range';
|
||||
import { ISelection, Selection } from 'vs/editor/common/core/selection';
|
||||
import { IStringBuilder, createStringBuilder } from 'vs/editor/common/core/stringBuilder';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IModelDecorationsChangeAccessor, IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model';
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
|
||||
import { IDiffComputationResult, IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { OverviewRulerZone } from 'vs/editor/common/view/overviewZoneManager';
|
||||
import { LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations';
|
||||
import { RenderLineInput, renderViewLine } from 'vs/editor/common/viewLayout/viewLineRenderer';
|
||||
import { IEditorWhitespace } from 'vs/editor/common/viewLayout/whitespaceComputer';
|
||||
import { InlineDecoration, InlineDecorationType, ViewLineRenderingData } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { defaultInsertColor, defaultRemoveColor, diffBorder, diffInserted, diffInsertedOutline, diffRemoved, diffRemovedOutline, scrollbarShadow } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { ITheme, IThemeService, getThemeTypeSelector, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
interface IEditorDiffDecorations {
|
||||
decorations: IModelDeltaDecoration[];
|
||||
@@ -173,7 +171,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
private _currentlyChangingViewZones: boolean;
|
||||
private _beginUpdateDecorationsTimeout: number;
|
||||
private _diffComputationToken: number;
|
||||
private _lineChanges: editorCommon.ILineChange[];
|
||||
private _diffComputationResult: IDiffComputationResult | null;
|
||||
|
||||
private _isVisible: boolean;
|
||||
private _isHandlingScrollEvent: boolean;
|
||||
@@ -283,7 +281,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
this._height = 0;
|
||||
this._reviewHeight = 0;
|
||||
|
||||
this._lineChanges = null;
|
||||
this._diffComputationResult = null;
|
||||
|
||||
const leftContextKeyService = this._contextKeyService.createScoped();
|
||||
leftContextKeyService.createKey('isInDiffLeftEditor', true);
|
||||
@@ -525,8 +523,11 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
return editorCommon.EditorType.IDiffEditor;
|
||||
}
|
||||
|
||||
public getLineChanges(): editorCommon.ILineChange[] {
|
||||
return this._lineChanges;
|
||||
public getLineChanges(): editorCommon.ILineChange[] | null {
|
||||
if (!this._diffComputationResult) {
|
||||
return null;
|
||||
}
|
||||
return this._diffComputationResult.changes;
|
||||
}
|
||||
|
||||
public getOriginalEditor(): editorBrowser.ICodeEditor {
|
||||
@@ -585,7 +586,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
// renderSideBySide
|
||||
if (renderSideBySideChanged) {
|
||||
if (this._renderSideBySide) {
|
||||
this._setStrategy(new DiffEdtorWidgetSideBySide(this._createDataSource(), this._enableSplitViewResizing, ));
|
||||
this._setStrategy(new DiffEdtorWidgetSideBySide(this._createDataSource(), this._enableSplitViewResizing));
|
||||
} else {
|
||||
this._setStrategy(new DiffEdtorWidgetInline(this._createDataSource(), this._enableSplitViewResizing));
|
||||
}
|
||||
@@ -621,7 +622,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
}
|
||||
|
||||
// Disable any diff computations that will come in
|
||||
this._lineChanges = null;
|
||||
this._diffComputationResult = null;
|
||||
this._diffComputationToken++;
|
||||
|
||||
if (model) {
|
||||
@@ -630,7 +631,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
// Begin comparing
|
||||
this._beginUpdateDecorations();
|
||||
} else {
|
||||
this._lineChanges = null;
|
||||
this._diffComputationResult = null;
|
||||
}
|
||||
|
||||
this._layoutOverviewViewport();
|
||||
@@ -644,7 +645,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
return this.modifiedEditor.getVisibleColumnFromPosition(position);
|
||||
}
|
||||
|
||||
public getPosition(): Position {
|
||||
public getPosition(): Position | null {
|
||||
return this.modifiedEditor.getPosition();
|
||||
}
|
||||
|
||||
@@ -676,11 +677,11 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
this.modifiedEditor.revealPositionInCenterIfOutsideViewport(position, scrollType);
|
||||
}
|
||||
|
||||
public getSelection(): Selection {
|
||||
public getSelection(): Selection | null {
|
||||
return this.modifiedEditor.getSelection();
|
||||
}
|
||||
|
||||
public getSelections(): Selection[] {
|
||||
public getSelections(): Selection[] | null {
|
||||
return this.modifiedEditor.getSelections();
|
||||
}
|
||||
|
||||
@@ -849,10 +850,10 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
this._beginUpdateDecorationsTimeout = window.setTimeout(() => this._beginUpdateDecorations(), DiffEditorWidget.UPDATE_DIFF_DECORATIONS_DELAY);
|
||||
}
|
||||
|
||||
private _lastOriginalWarning: URI = null;
|
||||
private _lastModifiedWarning: URI = null;
|
||||
private _lastOriginalWarning: URI | null = null;
|
||||
private _lastModifiedWarning: URI | null = null;
|
||||
|
||||
private static _equals(a: URI, b: URI): boolean {
|
||||
private static _equals(a: URI | null, b: URI | null): boolean {
|
||||
if (!a && !b) {
|
||||
return true;
|
||||
}
|
||||
@@ -893,7 +894,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
&& currentOriginalModel === this.originalEditor.getModel()
|
||||
&& currentModifiedModel === this.modifiedEditor.getModel()
|
||||
) {
|
||||
this._lineChanges = result;
|
||||
this._diffComputationResult = result;
|
||||
this._updateDecorationsRunner.schedule();
|
||||
this._onDidUpdateDiff.fire();
|
||||
}
|
||||
@@ -902,7 +903,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
&& currentOriginalModel === this.originalEditor.getModel()
|
||||
&& currentModifiedModel === this.modifiedEditor.getModel()
|
||||
) {
|
||||
this._lineChanges = null;
|
||||
this._diffComputationResult = null;
|
||||
this._updateDecorationsRunner.schedule();
|
||||
}
|
||||
});
|
||||
@@ -917,7 +918,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
if (!this.originalEditor.getModel() || !this.modifiedEditor.getModel()) {
|
||||
return;
|
||||
}
|
||||
let lineChanges = this._lineChanges || [];
|
||||
const lineChanges = (this._diffComputationResult ? this._diffComputationResult.changes : []);
|
||||
|
||||
let foreignOriginal = this._originalEditorState.getForeignViewZones(this.originalEditor.getWhitespaces());
|
||||
let foreignModified = this._modifiedEditorState.getForeignViewZones(this.modifiedEditor.getWhitespaces());
|
||||
@@ -944,7 +945,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
clonedOptions.folding = false;
|
||||
clonedOptions.codeLens = false;
|
||||
clonedOptions.fixedOverflowWidgets = true;
|
||||
clonedOptions.lineDecorationsWidth = '2ch';
|
||||
// clonedOptions.lineDecorationsWidth = '2ch';
|
||||
if (!clonedOptions.minimap) {
|
||||
clonedOptions.minimap = {};
|
||||
}
|
||||
@@ -1011,7 +1012,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
}
|
||||
}
|
||||
|
||||
private _computeOverviewViewport(): { height: number; top: number; } {
|
||||
private _computeOverviewViewport(): { height: number; top: number; } | null {
|
||||
let layoutInfo = this.modifiedEditor.getLayoutInfo();
|
||||
if (!layoutInfo) {
|
||||
return null;
|
||||
@@ -1069,7 +1070,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
this._strategy = newStrategy;
|
||||
newStrategy.applyColors(this._themeService.getTheme());
|
||||
|
||||
if (this._lineChanges) {
|
||||
if (this._diffComputationResult) {
|
||||
this._updateDecorations();
|
||||
}
|
||||
|
||||
@@ -1077,17 +1078,18 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
this._measureDomElement(true);
|
||||
}
|
||||
|
||||
private _getLineChangeAtOrBeforeLineNumber(lineNumber: number, startLineNumberExtractor: (lineChange: editorCommon.ILineChange) => number): editorCommon.ILineChange {
|
||||
if (this._lineChanges.length === 0 || lineNumber < startLineNumberExtractor(this._lineChanges[0])) {
|
||||
private _getLineChangeAtOrBeforeLineNumber(lineNumber: number, startLineNumberExtractor: (lineChange: editorCommon.ILineChange) => number): editorCommon.ILineChange | null {
|
||||
const lineChanges = (this._diffComputationResult ? this._diffComputationResult.changes : []);
|
||||
if (lineChanges.length === 0 || lineNumber < startLineNumberExtractor(lineChanges[0])) {
|
||||
// There are no changes or `lineNumber` is before the first change
|
||||
return null;
|
||||
}
|
||||
|
||||
let min = 0, max = this._lineChanges.length - 1;
|
||||
let min = 0, max = lineChanges.length - 1;
|
||||
while (min < max) {
|
||||
let mid = Math.floor((min + max) / 2);
|
||||
let midStart = startLineNumberExtractor(this._lineChanges[mid]);
|
||||
let midEnd = (mid + 1 <= max ? startLineNumberExtractor(this._lineChanges[mid + 1]) : Number.MAX_VALUE);
|
||||
let midStart = startLineNumberExtractor(lineChanges[mid]);
|
||||
let midEnd = (mid + 1 <= max ? startLineNumberExtractor(lineChanges[mid + 1]) : Number.MAX_VALUE);
|
||||
|
||||
if (lineNumber < midStart) {
|
||||
max = mid - 1;
|
||||
@@ -1099,7 +1101,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
max = mid;
|
||||
}
|
||||
}
|
||||
return this._lineChanges[min];
|
||||
return lineChanges[min];
|
||||
}
|
||||
|
||||
private _getEquivalentLineForOriginalLineNumber(lineNumber: number): number {
|
||||
@@ -1146,8 +1148,8 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
return originalEquivalentLineNumber + lineChangeOriginalLength - lineChangeModifiedLength + delta;
|
||||
}
|
||||
|
||||
public getDiffLineInformationForOriginal(lineNumber: number): editorBrowser.IDiffLineInformation {
|
||||
if (!this._lineChanges) {
|
||||
public getDiffLineInformationForOriginal(lineNumber: number): editorBrowser.IDiffLineInformation | null {
|
||||
if (!this._diffComputationResult) {
|
||||
// Cannot answer that which I don't know
|
||||
return null;
|
||||
}
|
||||
@@ -1156,8 +1158,8 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
};
|
||||
}
|
||||
|
||||
public getDiffLineInformationForModified(lineNumber: number): editorBrowser.IDiffLineInformation {
|
||||
if (!this._lineChanges) {
|
||||
public getDiffLineInformationForModified(lineNumber: number): editorBrowser.IDiffLineInformation | null {
|
||||
if (!this._diffComputationResult) {
|
||||
// Cannot answer that which I don't know
|
||||
return null;
|
||||
}
|
||||
@@ -1233,15 +1235,20 @@ abstract class DiffEditorWidgetStyle extends Disposable implements IDiffEditorWi
|
||||
public abstract layout(): number;
|
||||
}
|
||||
|
||||
interface IMyViewZone extends editorBrowser.IViewZone {
|
||||
interface IMyViewZone {
|
||||
shouldNotShrink?: boolean;
|
||||
afterLineNumber: number;
|
||||
heightInLines: number;
|
||||
minWidthInPx?: number;
|
||||
domNode: HTMLElement | null;
|
||||
marginDomNode?: HTMLElement | null;
|
||||
}
|
||||
|
||||
class ForeignViewZonesIterator {
|
||||
|
||||
private _index: number;
|
||||
private _source: IEditorWhitespace[];
|
||||
public current: IEditorWhitespace;
|
||||
public current: IEditorWhitespace | null;
|
||||
|
||||
constructor(source: IEditorWhitespace[]) {
|
||||
this._source = source;
|
||||
@@ -1272,7 +1279,7 @@ abstract class ViewZonesComputer {
|
||||
}
|
||||
|
||||
public getViewZones(): IEditorsZones {
|
||||
let result: IEditorsZones = {
|
||||
let result: { original: IMyViewZone[]; modified: IMyViewZone[]; } = {
|
||||
original: [],
|
||||
modified: []
|
||||
};
|
||||
@@ -1288,7 +1295,7 @@ abstract class ViewZonesComputer {
|
||||
return a.afterLineNumber - b.afterLineNumber;
|
||||
};
|
||||
|
||||
let addAndCombineIfPossible = (destination: editorBrowser.IViewZone[], item: IMyViewZone) => {
|
||||
let addAndCombineIfPossible = (destination: IMyViewZone[], item: IMyViewZone) => {
|
||||
if (item.domNode === null && destination.length > 0) {
|
||||
let lastItem = destination[destination.length - 1];
|
||||
if (lastItem.afterLineNumber === item.afterLineNumber && lastItem.domNode === null) {
|
||||
@@ -1335,10 +1342,17 @@ abstract class ViewZonesComputer {
|
||||
} else {
|
||||
viewZoneLineNumber = originalEndEquivalentLineNumber;
|
||||
}
|
||||
|
||||
let marginDomNode: HTMLDivElement | null = null;
|
||||
if (lineChange && lineChange.modifiedStartLineNumber <= modifiedForeignVZ.current.afterLineNumber && modifiedForeignVZ.current.afterLineNumber <= lineChange.modifiedEndLineNumber) {
|
||||
marginDomNode = this._createOriginalMarginDomNodeForModifiedForeignViewZoneInAddedRegion();
|
||||
}
|
||||
|
||||
stepOriginal.push({
|
||||
afterLineNumber: viewZoneLineNumber,
|
||||
heightInLines: modifiedForeignVZ.current.heightInLines,
|
||||
domNode: null
|
||||
domNode: null,
|
||||
marginDomNode: marginDomNode
|
||||
});
|
||||
modifiedForeignVZ.advance();
|
||||
}
|
||||
@@ -1444,9 +1458,11 @@ abstract class ViewZonesComputer {
|
||||
return result;
|
||||
}
|
||||
|
||||
protected abstract _produceOriginalFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone;
|
||||
protected abstract _createOriginalMarginDomNodeForModifiedForeignViewZoneInAddedRegion(): HTMLDivElement | null;
|
||||
|
||||
protected abstract _produceModifiedFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone;
|
||||
protected abstract _produceOriginalFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone | null;
|
||||
|
||||
protected abstract _produceModifiedFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone | null;
|
||||
}
|
||||
|
||||
function createDecoration(startLineNumber: number, startColumn: number, endLineNumber: number, endColumn: number, options: ModelDecorationOptions) {
|
||||
@@ -1737,7 +1753,11 @@ class SideBySideViewZonesComputer extends ViewZonesComputer {
|
||||
super(lineChanges, originalForeignVZ, modifiedForeignVZ);
|
||||
}
|
||||
|
||||
protected _produceOriginalFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone {
|
||||
protected _createOriginalMarginDomNodeForModifiedForeignViewZoneInAddedRegion(): HTMLDivElement | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected _produceOriginalFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone | null {
|
||||
if (lineChangeModifiedLength > lineChangeOriginalLength) {
|
||||
return {
|
||||
afterLineNumber: Math.max(lineChange.originalStartLineNumber, lineChange.originalEndLineNumber),
|
||||
@@ -1748,7 +1768,7 @@ class SideBySideViewZonesComputer extends ViewZonesComputer {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected _produceModifiedFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone {
|
||||
protected _produceModifiedFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone | null {
|
||||
if (lineChangeOriginalLength > lineChangeModifiedLength) {
|
||||
return {
|
||||
afterLineNumber: Math.max(lineChange.modifiedStartLineNumber, lineChange.modifiedEndLineNumber),
|
||||
@@ -1897,10 +1917,15 @@ class InlineViewZonesComputer extends ViewZonesComputer {
|
||||
this.renderIndicators = renderIndicators;
|
||||
}
|
||||
|
||||
protected _produceOriginalFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone {
|
||||
protected _createOriginalMarginDomNodeForModifiedForeignViewZoneInAddedRegion(): HTMLDivElement | null {
|
||||
let result = document.createElement('div');
|
||||
result.className = 'inline-added-margin-view-zone';
|
||||
return result;
|
||||
}
|
||||
|
||||
protected _produceOriginalFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone | null {
|
||||
let marginDomNode = document.createElement('div');
|
||||
marginDomNode.className = 'inline-added-margin-view-zone';
|
||||
Configuration.applyFontInfoSlow(marginDomNode, this.modifiedEditorConfiguration.fontInfo);
|
||||
|
||||
return {
|
||||
afterLineNumber: Math.max(lineChange.originalStartLineNumber, lineChange.originalEndLineNumber),
|
||||
@@ -1910,7 +1935,7 @@ class InlineViewZonesComputer extends ViewZonesComputer {
|
||||
};
|
||||
}
|
||||
|
||||
protected _produceModifiedFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone {
|
||||
protected _produceModifiedFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone | null {
|
||||
let decorations: InlineDecoration[] = [];
|
||||
if (lineChange.charChanges) {
|
||||
for (let j = 0, lengthJ = lineChange.charChanges.length; j < lengthJ; j++) {
|
||||
@@ -1982,6 +2007,7 @@ class InlineViewZonesComputer extends ViewZonesComputer {
|
||||
const containsRTL = ViewLineRenderingData.containsRTL(lineContent, isBasicASCII, originalModel.mightContainRTL());
|
||||
const output = renderViewLine(new RenderLineInput(
|
||||
(config.fontInfo.isMonospace && !config.viewInfo.disableMonospaceOptimizations),
|
||||
config.fontInfo.canUseHalfwidthRightwardsArrow,
|
||||
lineContent,
|
||||
false,
|
||||
isBasicASCII,
|
||||
@@ -2048,7 +2074,7 @@ registerThemingParticipant((theme, collector) => {
|
||||
collector.addRule(`.monaco-diff-editor.side-by-side .editor.modified { box-shadow: -6px 0 5px -5px ${shadow}; }`);
|
||||
}
|
||||
|
||||
let border = theme.getColor(diffBorder);
|
||||
const border = theme.getColor(diffBorder);
|
||||
if (border) {
|
||||
collector.addRule(`.monaco-diff-editor.side-by-side .editor.modified { border-left: 1px solid ${border}; }`);
|
||||
}
|
||||
|
||||
@@ -2,16 +2,15 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'vs/base/common/assert';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { IDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { ILineChange, ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
|
||||
import { IDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
|
||||
|
||||
interface IDiffRange {
|
||||
@@ -59,7 +58,7 @@ export class DiffNavigator {
|
||||
this.nextIdx = -1;
|
||||
this.ranges = [];
|
||||
this.ignoreSelectionChange = false;
|
||||
this.revealFirst = this._options.alwaysRevealFirst;
|
||||
this.revealFirst = Boolean(this._options.alwaysRevealFirst);
|
||||
|
||||
// hook up to diff editor for diff, disposal, and caret move
|
||||
this._disposables.push(this._editor.onDidDispose(() => this.dispose()));
|
||||
@@ -104,7 +103,7 @@ export class DiffNavigator {
|
||||
}
|
||||
}
|
||||
|
||||
private _compute(lineChanges: ILineChange[]): void {
|
||||
private _compute(lineChanges: ILineChange[] | null): void {
|
||||
|
||||
// new ranges
|
||||
this.ranges = [];
|
||||
@@ -151,6 +150,10 @@ export class DiffNavigator {
|
||||
private _initIdx(fwd: boolean): void {
|
||||
let found = false;
|
||||
let position = this._editor.getPosition();
|
||||
if (!position) {
|
||||
this.nextIdx = 0;
|
||||
return;
|
||||
}
|
||||
for (let i = 0, len = this.ranges.length; i < len && !found; i++) {
|
||||
let range = this.ranges[i].range;
|
||||
if (position.isBeforeOrEqual(range.getStartPosition())) {
|
||||
@@ -216,7 +219,7 @@ export class DiffNavigator {
|
||||
dispose(this._disposables);
|
||||
this._disposables.length = 0;
|
||||
this._onDidUpdate.dispose();
|
||||
this.ranges = null;
|
||||
this.ranges = [];
|
||||
this.disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,35 +2,34 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./media/diffReview';
|
||||
import * as nls from 'vs/nls';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { renderViewLine2 as renderViewLine, RenderLineInput } from 'vs/editor/common/viewLayout/viewLineRenderer';
|
||||
import { LineTokens } from 'vs/editor/common/core/lineTokens';
|
||||
import { Configuration } from 'vs/editor/browser/config/configuration';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { ColorId, MetadataConsts, FontStyle } from 'vs/editor/common/modes';
|
||||
import * as editorOptions from 'vs/editor/common/config/editorOptions';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { scrollbarShadow } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditorWidget';
|
||||
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
import { editorLineNumbers } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { registerEditorAction, EditorAction, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Configuration } from 'vs/editor/browser/config/configuration';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { EditorAction, ServicesAccessor, registerEditorAction } from 'vs/editor/browser/editorExtensions';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditorWidget';
|
||||
import * as editorOptions from 'vs/editor/common/config/editorOptions';
|
||||
import { LineTokens } from 'vs/editor/common/core/lineTokens';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { ILineChange, ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { ITextModel, TextModelResolvedOptions } from 'vs/editor/common/model';
|
||||
import { ColorId, FontStyle, MetadataConsts } from 'vs/editor/common/modes';
|
||||
import { editorLineNumbers } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { RenderLineInput, renderViewLine2 as renderViewLine } from 'vs/editor/common/viewLayout/viewLineRenderer';
|
||||
import { ViewLineRenderingData } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { scrollbarShadow } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
const DIFF_LINES_PADDING = 3;
|
||||
|
||||
@@ -263,7 +262,7 @@ export class DiffReview extends Disposable {
|
||||
|
||||
if (jumpToLineNumber !== -1) {
|
||||
this._diffEditor.setPosition(new Position(jumpToLineNumber, 1));
|
||||
this._diffEditor.revealPosition(new Position(jumpToLineNumber, 1), editorCommon.ScrollType.Immediate);
|
||||
this._diffEditor.revealPosition(new Position(jumpToLineNumber, 1), ScrollType.Immediate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,7 +358,7 @@ export class DiffReview extends Disposable {
|
||||
return DiffReview._mergeAdjacent(lineChanges, originalModel.getLineCount(), modifiedModel.getLineCount());
|
||||
}
|
||||
|
||||
private static _mergeAdjacent(lineChanges: editorCommon.ILineChange[], originalLineCount: number, modifiedLineCount: number): Diff[] {
|
||||
private static _mergeAdjacent(lineChanges: ILineChange[], originalLineCount: number, modifiedLineCount: number): Diff[] {
|
||||
if (!lineChanges || lineChanges.length === 0) {
|
||||
return [];
|
||||
}
|
||||
@@ -769,6 +768,7 @@ export class DiffReview extends Disposable {
|
||||
const containsRTL = ViewLineRenderingData.containsRTL(lineContent, isBasicASCII, model.mightContainRTL());
|
||||
const r = renderViewLine(new RenderLineInput(
|
||||
(config.fontInfo.isMonospace && !config.viewInfo.disableMonospaceOptimizations),
|
||||
config.fontInfo.canUseHalfwidthRightwardsArrow,
|
||||
lineContent,
|
||||
false,
|
||||
isBasicASCII,
|
||||
@@ -791,7 +791,7 @@ export class DiffReview extends Disposable {
|
||||
// theming
|
||||
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
let lineNumbers = theme.getColor(editorLineNumbers);
|
||||
const lineNumbers = theme.getColor(editorLineNumbers);
|
||||
if (lineNumbers) {
|
||||
collector.addRule(`.monaco-diff-editor .diff-review-line-number { color: ${lineNumbers}; }`);
|
||||
}
|
||||
|
||||
@@ -2,20 +2,19 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditorWidget';
|
||||
import { IConfigurationChangedEvent, IDiffEditorOptions, IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import { IConfigurationChangedEvent, IEditorOptions, IDiffEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditorWidget';
|
||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
export class EmbeddedCodeEditorWidget extends CodeEditorWidget {
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
opacity: 0.7;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50% 50%;
|
||||
background-position: center;
|
||||
background-size: 11px 11px;
|
||||
}
|
||||
.monaco-editor.hc-black .insert-sign,
|
||||
.monaco-diff-editor.hc-black .insert-sign,
|
||||
|
||||
Reference in New Issue
Block a user