提交 8827aaf6 编写于 作者: A Alex Dima

Code Review for before/after decorations

上级 de4571c6
......@@ -26,16 +26,14 @@ export class CodeEditorServiceImpl extends AbstractCodeEditorService {
public registerDecorationType(key:string, options: IDecorationRenderOptions, parentTypeKey?: string): void {
let provider = this._decorationOptionProviders[key];
if (provider) {
provider.dispose();
delete this._decorationOptionProviders[key];
}
if (!parentTypeKey) {
provider = new DecorationTypeOptionsProvider(this._styleSheet, key, options);
} else {
provider = new DecorationSubTypeOptionsProvider(this._styleSheet, key, parentTypeKey, options);
if (!provider) {
if (!parentTypeKey) {
provider = new DecorationTypeOptionsProvider(this._styleSheet, key, options);
} else {
provider = new DecorationSubTypeOptionsProvider(this._styleSheet, key, parentTypeKey, options);
}
this._decorationOptionProviders[key] = provider;
}
this._decorationOptionProviders[key] = provider;
provider.refCount++;
}
......@@ -81,7 +79,7 @@ class DecorationSubTypeOptionsProvider implements IModelDecorationOptionsProvide
var themedOpts = getThemedRenderOptions(options);
this._beforeContentClassName = DecorationRenderHelper.handle(
this._beforeContentClassName = DecorationRenderHelper.createCSSRules(
styleSheet,
key,
parentTypeKey,
......@@ -92,7 +90,7 @@ class DecorationSubTypeOptionsProvider implements IModelDecorationOptionsProvide
}
);
this._afterContentClassName = DecorationRenderHelper.handle(
this._afterContentClassName = DecorationRenderHelper.createCSSRules(
styleSheet,
key,
parentTypeKey,
......@@ -104,7 +102,7 @@ class DecorationSubTypeOptionsProvider implements IModelDecorationOptionsProvide
);
if (this._beforeContentClassName || this._afterContentClassName) {
this._disposable = toDisposable(() => {
dom.removeCSSRulesContainingSelector(CSSNameHelper.getDeletionPrefixFor(key), styleSheet);
dom.removeCSSRulesContainingSelector(CSSNameHelper.getDeletionSubstring(key), styleSheet);
});
}
}
......@@ -145,7 +143,7 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
constructor(styleSheet: HTMLStyleElement, key:string, options:IDecorationRenderOptions) {
var themedOpts = getThemedRenderOptions(options);
this.className = DecorationRenderHelper.handle(
this.className = DecorationRenderHelper.createCSSRules(
styleSheet,
key,
null,
......@@ -156,7 +154,7 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
}
);
this.inlineClassName = DecorationRenderHelper.handle(
this.inlineClassName = DecorationRenderHelper.createCSSRules(
styleSheet,
key,
null,
......@@ -167,7 +165,7 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
}
);
this.beforeContentClassName = DecorationRenderHelper.handle(
this.beforeContentClassName = DecorationRenderHelper.createCSSRules(
styleSheet,
key,
null,
......@@ -178,7 +176,7 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
}
);
this.afterContentClassName = DecorationRenderHelper.handle(
this.afterContentClassName = DecorationRenderHelper.createCSSRules(
styleSheet,
key,
null,
......@@ -189,7 +187,7 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
}
);
this.glyphMarginClassName = DecorationRenderHelper.handle(
this.glyphMarginClassName = DecorationRenderHelper.createCSSRules(
styleSheet,
key,
null,
......@@ -214,7 +212,7 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
}
this._disposable = toDisposable(() => {
dom.removeCSSRulesContainingSelector(CSSNameHelper.getDeletionPrefixFor(key), styleSheet);
dom.removeCSSRulesContainingSelector(CSSNameHelper.getDeletionSubstring(key), styleSheet);
});
}
......@@ -349,7 +347,10 @@ class DecorationRenderHelper {
return cssTextArr.length !== lenBefore;
}
public static handle(styleSheet: HTMLStyleElement, key:string, parentKey: string, ruleType:ModelDecorationCSSRuleType, cssTexts: {light:string, dark:string}): string {
/**
* Create CSS rules for `cssTexts` with the generated class names from `ruleType`
*/
public static createCSSRules(styleSheet: HTMLStyleElement, key:string, parentKey: string, ruleType:ModelDecorationCSSRuleType, cssTexts: {light:string, dark:string}): string {
function createCSSSelector(themeType:ThemeType, cssText:string) {
let selector = CSSNameHelper.getSelector(themeType, key, parentKey, ruleType);
dom.createCSSRule(selector, cssText, styleSheet);
......@@ -418,7 +419,7 @@ class CSSNameHelper {
return selector;
}
public static getDeletionPrefixFor(key:string): string {
public static getDeletionSubstring(key:string): string {
return '.ced-' + key + '-';
}
}
......
......@@ -9,6 +9,7 @@ import {ViewPart} from 'vs/editor/browser/view/viewPart';
import {FastDomNode, createFastDomNode} from 'vs/base/browser/styleMutator';
import {ViewContext} from 'vs/editor/common/view/viewContext';
import {ViewLinesViewportData} from 'vs/editor/common/viewLayout/viewLinesViewportData';
import {InlineDecoration} from 'vs/editor/common/viewModel/viewModel';
export interface IVisibleLineData {
getDomNode(): HTMLElement;
......@@ -24,7 +25,7 @@ export interface IVisibleLineData {
getLineOuterHTML(out:string[], lineNumber: number, deltaTop: number): void;
getLineInnerHTML(lineNumber: number): string;
shouldUpdateHTML(startLineNumber:number, lineNumber:number, inlineDecorations:editorCommon.IModelDecoration[]): boolean;
shouldUpdateHTML(startLineNumber:number, lineNumber:number, inlineDecorations:InlineDecoration[]): boolean;
layoutLine(lineNumber: number, deltaTop:number): void;
}
......@@ -33,7 +34,7 @@ interface IRendererContext {
rendLineNumberStart: number;
lines: IVisibleLineData[];
linesLength: number;
getInlineDecorationsForLineInViewport(lineNumber:number): editorCommon.IModelDecoration[];
getInlineDecorationsForLineInViewport(lineNumber:number): InlineDecoration[];
viewportTop: number;
viewportHeight: number;
scrollDomNode: HTMLElement;
......@@ -501,8 +502,8 @@ class ViewLayerRenderer {
ctx.lines.splice(removeIndex, removeCount);
}
private static _resolveInlineDecorations(ctx: IRendererContext): editorCommon.IModelDecoration[][] {
let result: editorCommon.IModelDecoration[][] = [];
private static _resolveInlineDecorations(ctx: IRendererContext): InlineDecoration[][] {
let result: InlineDecoration[][] = [];
for (let i = 0, len = ctx.linesLength; i < len; i++) {
let lineNumber = i + ctx.rendLineNumberStart;
result[i] = ctx.getInlineDecorationsForLineInViewport(lineNumber);
......
......@@ -5,7 +5,7 @@
'use strict';
import {StyleMutator, FastDomNode, createFastDomNode} from 'vs/base/browser/styleMutator';
import {IScrollEvent, IConfigurationChangedEvent, EditorLayoutInfo, IModelDecoration} from 'vs/editor/common/editorCommon';
import {IScrollEvent, IConfigurationChangedEvent, EditorLayoutInfo} from 'vs/editor/common/editorCommon';
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
import {IVisibleLineData, ViewLayer} from 'vs/editor/browser/view/viewLayer';
import {DynamicViewOverlay} from 'vs/editor/browser/view/dynamicViewOverlay';
......@@ -13,6 +13,7 @@ import {Configuration} from 'vs/editor/browser/config/configuration';
import {ViewContext} from 'vs/editor/common/view/viewContext';
import {IRenderingContext, IRestrictedRenderingContext} from 'vs/editor/common/view/renderingContext';
import {ILayoutProvider} from 'vs/editor/browser/viewLayout/layoutProvider';
import {InlineDecoration} from 'vs/editor/common/viewModel/viewModel';
export class ViewOverlays extends ViewLayer {
......@@ -151,7 +152,7 @@ class ViewOverlayLine implements IVisibleLineData {
}
}
shouldUpdateHTML(startLineNumber:number, lineNumber:number, inlineDecorations:IModelDecoration[]): boolean {
shouldUpdateHTML(startLineNumber:number, lineNumber:number, inlineDecorations:InlineDecoration[]): boolean {
let newPieces = '';
for (let i = 0, len = this._dynamicOverlays.length; i < len; i++) {
let dynamicOverlay = this._dynamicOverlays[i];
......
......@@ -6,7 +6,7 @@
import * as browser from 'vs/base/browser/browser';
import {FastDomNode, createFastDomNode} from 'vs/base/browser/styleMutator';
import {IConfigurationChangedEvent, IModelDecoration} from 'vs/editor/common/editorCommon';
import {IConfigurationChangedEvent} from 'vs/editor/common/editorCommon';
import {LineParts, createLineParts, getColumnOfLinePartOffset} from 'vs/editor/common/viewLayout/viewLineParts';
import {renderLine, RenderLineInput} from 'vs/editor/common/viewLayout/viewLineRenderer';
import {ClassNames} from 'vs/editor/browser/editorBrowser';
......@@ -14,6 +14,7 @@ import {IVisibleLineData} from 'vs/editor/browser/view/viewLayer';
import {RangeUtil} from 'vs/editor/browser/viewParts/lines/rangeUtil';
import {ViewContext} from 'vs/editor/common/view/viewContext';
import {HorizontalRange} from 'vs/editor/common/view/renderingContext';
import {InlineDecoration} from 'vs/editor/common/viewModel/viewModel';
export class ViewLine implements IVisibleLineData {
......@@ -100,7 +101,7 @@ export class ViewLine implements IVisibleLineData {
this._isInvalid = true;
}
public shouldUpdateHTML(startLineNumber:number, lineNumber:number, inlineDecorations:IModelDecoration[]): boolean {
public shouldUpdateHTML(startLineNumber:number, lineNumber:number, inlineDecorations:InlineDecoration[]): boolean {
let newLineParts:LineParts = null;
if (this._isMaybeInvalid || this._isInvalid) {
......
......@@ -27,6 +27,7 @@ import {ViewLineToken, ViewLineTokens} from 'vs/editor/common/core/viewLineToken
import {Configuration} from 'vs/editor/browser/config/configuration';
import {Position} from 'vs/editor/common/core/position';
import {Selection} from 'vs/editor/common/core/selection';
import {InlineDecoration} from 'vs/editor/common/viewModel/viewModel';
interface IEditorDiffDecorations {
decorations:editorCommon.IModelDeltaDecoration[];
......@@ -1786,19 +1787,19 @@ class InlineViewZonesComputer extends ViewZonesComputer {
}
_produceModifiedFromDiff(lineChange:editorCommon.ILineChange, lineChangeOriginalLength:number, lineChangeModifiedLength:number): IMyViewZone {
var decorations:editorCommon.IModelDecoration[] = [],
var decorations:InlineDecoration[] = [],
j:number,
lengthJ:number,
charChange:editorCommon.ICharChange,
tempDecoration:editorCommon.IModelDecoration;
charChange:editorCommon.ICharChange;
if (lineChange.charChanges) {
for (j = 0, lengthJ = lineChange.charChanges.length; j < lengthJ; j++) {
charChange = lineChange.charChanges[j];
if (isChangeOrDelete(charChange)) {
tempDecoration = <any>createDecoration(charChange.originalStartLineNumber, charChange.originalStartColumn, charChange.originalEndLineNumber, charChange.originalEndColumn, 'char-delete', false);
tempDecoration.options.inlineClassName = tempDecoration.options.className;
decorations.push(tempDecoration);
decorations.push(new InlineDecoration(
new Range(charChange.originalStartLineNumber, charChange.originalStartColumn, charChange.originalEndLineNumber, charChange.originalEndColumn),
'char-delete'
));
}
}
}
......@@ -1822,7 +1823,7 @@ class InlineViewZonesComputer extends ViewZonesComputer {
};
}
private renderOriginalLine(count:number, originalModel:editorCommon.IModel, config:editorCommon.InternalEditorOptions, tabSize:number, lineNumber:number, decorations:editorCommon.IModelDecoration[]): string[] {
private renderOriginalLine(count:number, originalModel:editorCommon.IModel, config:editorCommon.InternalEditorOptions, tabSize:number, lineNumber:number, decorations:InlineDecoration[]): string[] {
let lineContent = originalModel.getLineContent(lineNumber);
let lineTokens = new ViewLineTokens([new ViewLineToken(0, '')], 0, lineContent.length);
......@@ -1862,7 +1863,7 @@ function isChangeOrDelete(lineChange:editorCommon.IChange): boolean {
return lineChange.originalEndLineNumber > 0;
}
function createDecoration(startLineNumber:number, startColumn:number, endLineNumber:number, endColumn:number, className:string, isWholeLine:boolean): editorCommon.IModelDeltaDecoration {
function createDecoration(startLineNumber:number, startColumn:number, endLineNumber:number, endColumn:number, className:string, isWholeLine:boolean) {
return {
range: new Range(startLineNumber, startColumn, endLineNumber, endColumn),
options: {
......
......@@ -103,6 +103,9 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr
protected _instantiationService: IInstantiationService;
protected _keybindingService: IKeybindingService;
/**
* map from "parent" decoration type to live decoration ids.
*/
private _decorationTypeKeysToIds: {[decorationTypeKey:string]:string[]};
private _decorationTypeSubtypes: {[decorationTypeKey:string]:{ [subtype:string]:boolean}};
......@@ -667,6 +670,8 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr
// identify custom reder options by a hash code over all keys and values
// For custom render options register a decoration type if necessary
let subType = hash(decorationOption.renderOptions).toString(16);
// The fact that `decorationTypeKey` appears in the typeKey has no influence
// it is just a mechanism to get predictable and unique keys (repeatable for the same options and unique across clients)
typeKey = decorationTypeKey + '-' + subType;
if (!oldDecorationsSubTypes[subType] && !newDecorationsSubTypes[subType]) {
// decoration type did not exist before, register new one
......@@ -681,16 +686,16 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr
newModelDecorations.push({ range: decorationOption.range, options: opts });
}
// update all decorations
let oldDecorationsIds = this._decorationTypeKeysToIds[decorationTypeKey] || [];
this._decorationTypeKeysToIds[decorationTypeKey] = this.deltaDecorations(oldDecorationsIds, newModelDecorations);
// remove decoration sub types that are no longer used, deregister decoration type if necessary
for (let subType in oldDecorationsSubTypes) {
if (!newDecorationsSubTypes[subType]) {
this._codeEditorService.removeDecorationType(decorationTypeKey + '-' + subType);
}
}
// update all decorations
let oldDecorationsIds = this._decorationTypeKeysToIds[decorationTypeKey] || [];
this._decorationTypeKeysToIds[decorationTypeKey] = this.deltaDecorations(oldDecorationsIds, newModelDecorations);
}
public removeDecorations(decorationTypeKey: string): void {
......@@ -960,6 +965,15 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr
_postDetachModelCleanup(detachedModel:editorCommon.IModel): void {
if (detachedModel) {
this._decorationTypeKeysToIds = {};
if (this._decorationTypeSubtypes) {
for (let decorationType in this._decorationTypeSubtypes) {
let subTypes = this._decorationTypeSubtypes[decorationType];
for (let subType in subTypes) {
this._codeEditorService.removeDecorationType(decorationType + '-' + subType);
}
}
this._decorationTypeSubtypes = {};
}
detachedModel.removeAllDecorationsWithOwnerId(this.id);
}
}
......@@ -983,20 +997,6 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr
this.viewModel = null;
}
if (this._decorationTypeKeysToIds) {
for (let decorationType in this._decorationTypeKeysToIds) {
let decorationIdsBySubType = this._decorationTypeKeysToIds[decorationType];
if (decorationIdsBySubType) {
for (let subType in decorationIdsBySubType) {
if (subType.length > 0) {
this._codeEditorService.removeDecorationType(decorationType + '-' + subType);
}
}
}
}
}
var result = this.model;
this.model = null;
......
......@@ -3514,11 +3514,11 @@ export interface IContentDecorationRenderOptions {
contentText?: string;
contentIconPath?: string;
border?: string;
textDecoration?: string;
color?: string;
backgroundColor?: string;
border?: string;
textDecoration?: string;
margin?: string;
width?: string;
height?: string;
......@@ -3536,12 +3536,8 @@ export interface IDecorationRenderOptions extends IThemeDecorationRenderOptions
}
export interface IThemeDecorationInstanceRenderOptions {
before?: {
content?: string;
};
after?: {
content?: string;
};
before?: IContentDecorationRenderOptions;
after?: IContentDecorationRenderOptions;
}
export interface IDecorationInstanceRenderOptions extends IThemeDecorationInstanceRenderOptions {
......
......@@ -8,12 +8,13 @@ import * as strings from 'vs/base/common/strings';
import {Arrays} from 'vs/editor/common/core/arrays';
import {Range} from 'vs/editor/common/core/range';
import {ViewLineToken, ViewLineTokens} from 'vs/editor/common/core/viewLineToken';
import {InlineDecoration} from 'vs/editor/common/viewModel/viewModel';
function cmpLineDecorations(a:ILineDecoration, b:ILineDecoration): number {
function cmpLineDecorations(a:InlineDecoration, b:InlineDecoration): number {
return Range.compareRangesUsingStarts(a.range, b.range);
}
export function createLineParts(lineNumber:number, minLineColumn:number, lineContent:string, tabSize:number, lineTokens:ViewLineTokens, rawLineDecorations:ILineDecoration[], renderWhitespace:boolean, indentGuides:boolean): LineParts {
export function createLineParts(lineNumber:number, minLineColumn:number, lineContent:string, tabSize:number, lineTokens:ViewLineTokens, rawLineDecorations:InlineDecoration[], renderWhitespace:boolean, indentGuides:boolean): LineParts {
if (indentGuides || renderWhitespace) {
let oldLength = rawLineDecorations.length;
rawLineDecorations = insertCustomLineDecorations(indentGuides, renderWhitespace, lineNumber, lineContent, tabSize, lineTokens.getFauxIndentLength(), rawLineDecorations);
......@@ -95,16 +96,11 @@ function trimEmptyTrailingPart(parts: ViewLineToken[], lineContent: string): Vie
const _tab = '\t'.charCodeAt(0);
const _space = ' '.charCodeAt(0);
function insertOneCustomLineDecoration(dest:ILineDecoration[], lineNumber:number, startColumn:number, endColumn:number, className:string): void {
dest.push({
range: new Range(lineNumber, startColumn, lineNumber, endColumn),
options: {
inlineClassName: className
}
});
function insertOneCustomLineDecoration(dest:InlineDecoration[], lineNumber:number, startColumn:number, endColumn:number, className:string): void {
dest.push(new InlineDecoration(new Range(lineNumber, startColumn, lineNumber, endColumn), className));
}
function insertCustomLineDecorations(indentGuides:boolean, renderWhitespace:boolean, lineNumber:number, lineContent: string, tabSize:number, fauxIndentLength: number, rawLineDecorations: ILineDecoration[]): ILineDecoration[] {
function insertCustomLineDecorations(indentGuides:boolean, renderWhitespace:boolean, lineNumber:number, lineContent: string, tabSize:number, fauxIndentLength: number, rawLineDecorations: InlineDecoration[]): InlineDecoration[] {
if (!indentGuides && !renderWhitespace) {
return rawLineDecorations;
}
......@@ -175,7 +171,7 @@ function insertCustomLineDecorations(indentGuides:boolean, renderWhitespace:bool
return insertCustomLineDecorationsWithStateMachine(lineNumber, lineContent, tabSize, rawLineDecorations, sm_endIndex, sm_decoration);
}
function insertCustomLineDecorationsWithStateMachine(lineNumber:number, lineContent: string, tabSize:number, rawLineDecorations: ILineDecoration[], sm_endIndex: number[], sm_decoration: string[]): ILineDecoration[] {
function insertCustomLineDecorationsWithStateMachine(lineNumber:number, lineContent: string, tabSize:number, rawLineDecorations: InlineDecoration[], sm_endIndex: number[], sm_decoration: string[]): InlineDecoration[] {
let lineLength = lineContent.length;
let currentStateIndex = 0;
let stateEndIndex = sm_endIndex[currentStateIndex];
......@@ -243,7 +239,7 @@ function createFastViewLineParts(lineTokens:ViewLineTokens, lineContent:string):
return new LineParts(parts);
}
function createViewLineParts(lineNumber:number, minLineColumn:number, lineTokens:ViewLineTokens, lineContent:string, rawLineDecorations:ILineDecoration[]): LineParts {
function createViewLineParts(lineNumber:number, minLineColumn:number, lineTokens:ViewLineTokens, lineContent:string, rawLineDecorations:InlineDecoration[]): LineParts {
// lineDecorations might overlap on top of each other, so they need to be normalized
var lineDecorations = LineDecorationsNormalizer.normalize(lineNumber, minLineColumn, rawLineDecorations),
lineDecorationsIndex = 0,
......@@ -360,13 +356,6 @@ class Stack {
}
}
export interface ILineDecoration {
range: Range;
options: {
inlineClassName?: string;
};
}
export class LineDecorationsNormalizer {
/**
* A number that is guaranteed to be larger than the maximum line column
......@@ -376,7 +365,7 @@ export class LineDecorationsNormalizer {
/**
* Normalize line decorations. Overlapping decorations will generate multiple segments
*/
public static normalize(lineNumber:number, minLineColumn:number, lineDecorations:ILineDecoration[]): DecorationSegment[] {
public static normalize(lineNumber:number, minLineColumn:number, lineDecorations:InlineDecoration[]): DecorationSegment[] {
var result:DecorationSegment[] = [];
......@@ -386,7 +375,7 @@ export class LineDecorationsNormalizer {
var stack = new Stack(),
nextStartOffset = 0,
d:ILineDecoration,
d:InlineDecoration,
currentStartOffset:number,
currentEndOffset:number,
i:number,
......@@ -418,7 +407,7 @@ export class LineDecorationsNormalizer {
if (stack.count === 0) {
nextStartOffset = currentStartOffset;
}
stack.insert(currentEndOffset, d.options.inlineClassName);
stack.insert(currentEndOffset, d.inlineClassName);
}
stack.consumeLowerThan(LineDecorationsNormalizer.MAX_LINE_LENGTH, nextStartOffset, result);
......
......@@ -5,7 +5,7 @@
'use strict';
import {IModelDecoration} from 'vs/editor/common/editorCommon';
import {IDecorationsViewportData} from 'vs/editor/common/viewModel/viewModel';
import {IDecorationsViewportData, InlineDecoration} from 'vs/editor/common/viewModel/viewModel';
import {Range} from 'vs/editor/common/core/range';
export interface IPartialViewLinesViewportData {
......@@ -44,7 +44,7 @@ export class ViewLinesViewportData {
visibleRange:Range;
private _decorations: IModelDecoration[];
private _inlineDecorations: IModelDecoration[][];
private _inlineDecorations: InlineDecoration[][];
constructor(partialData:IPartialViewLinesViewportData, visibleRange:Range, decorationsData:IDecorationsViewportData) {
this.viewportTop = partialData.viewportTop|0;
......@@ -63,7 +63,7 @@ export class ViewLinesViewportData {
return this._decorations;
}
public getInlineDecorationsForLineInViewport(lineNumber:number): IModelDecoration[] {
public getInlineDecorationsForLineInViewport(lineNumber:number): InlineDecoration[] {
lineNumber = lineNumber|0;
return this._inlineDecorations[lineNumber - this.startLineNumber];
}
......
......@@ -13,7 +13,10 @@ import {Selection} from 'vs/editor/common/core/selection';
export interface IDecorationsViewportData {
decorations: IModelDecoration[];
inlineDecorations: IModelDecoration[][];
/**
* inline decorations grouped by each line in the viewport
*/
inlineDecorations: InlineDecoration[][];
}
export interface IViewModel extends IEventEmitter {
......@@ -45,3 +48,15 @@ export interface IViewModel extends IEventEmitter {
convertModelSelectionToViewSelection(modelSelection:Selection): Selection;
modelPositionIsVisible(position:IPosition): boolean;
}
export class InlineDecoration {
_inlineDecorationBrand: void;
range: Range;
inlineClassName: string;
constructor(range:Range, inlineClassName:string) {
this.range = range;
this.inlineClassName = inlineClassName;
}
}
......@@ -7,16 +7,12 @@
import {IDisposable} from 'vs/base/common/lifecycle';
import {Range} from 'vs/editor/common/core/range';
import * as editorCommon from 'vs/editor/common/editorCommon';
import {IDecorationsViewportData} from 'vs/editor/common/viewModel/viewModel';
import {IDecorationsViewportData, InlineDecoration} from 'vs/editor/common/viewModel/viewModel';
export interface IModelRangeToViewRangeConverter {
convertModelRangeToViewRange(modelRange:editorCommon.IRange, isWholeLine:boolean): Range;
}
interface IViewModelDecoration extends editorCommon.IModelDecoration {
modelRange: editorCommon.IRange;
}
interface IViewModelDecorationSource {
id: string;
ownerId: number;
......@@ -24,7 +20,7 @@ interface IViewModelDecorationSource {
options: editorCommon.IModelDecorationOptions;
}
class ViewModelDecoration implements IViewModelDecoration {
class ViewModelDecoration {
id: string;
ownerId: number;
range: Range;
......@@ -45,7 +41,7 @@ export class ViewModelDecorations implements IDisposable {
private editorId:number;
private configuration:editorCommon.IConfiguration;
private converter:IModelRangeToViewRangeConverter;
private decorations:IViewModelDecoration[];
private decorations:ViewModelDecoration[];
private _cachedModelDecorationsResolver:IDecorationsViewportData;
private _cachedModelDecorationsResolverStartLineNumber:number;
......@@ -81,7 +77,7 @@ export class ViewModelDecorations implements IDisposable {
i:number,
len:number,
theirDecoration:editorCommon.IModelDecoration,
myDecoration:IViewModelDecoration;
myDecoration:ViewModelDecoration;
this.decorations = [];
for (i = 0, len = decorations.length; i < len; i++) {
......@@ -125,7 +121,7 @@ export class ViewModelDecorations implements IDisposable {
// Interpret changed decorations
var usedMap:{[id:string]:boolean;} = {},
myDecoration:IViewModelDecoration;
myDecoration:ViewModelDecoration;
for (i = 0, len = this.decorations.length; i < len; i++) {
myDecoration = this.decorations[i];
......@@ -178,7 +174,7 @@ export class ViewModelDecorations implements IDisposable {
public onLineMappingChanged(emit:(eventType:string, payload:any)=>void): void {
var decorations = this.decorations,
d:IViewModelDecoration,
d:ViewModelDecoration,
i:number,
newRange:Range,
somethingChanged:boolean = false,
......@@ -226,12 +222,12 @@ export class ViewModelDecorations implements IDisposable {
private _getDecorationsViewportData(startLineNumber: number, endLineNumber: number): IDecorationsViewportData {
var decorationsInViewport: editorCommon.IModelDecoration[] = [],
inlineDecorations: editorCommon.IModelDecoration[][] = [],
inlineDecorations: InlineDecoration[][] = [],
j: number,
intersectedStartLineNumber: number,
intersectedEndLineNumber: number,
decorations = this.decorations,
d:editorCommon.IModelDecoration,
d:ViewModelDecoration,
r:editorCommon.IRange,
i:number,
len:number;
......@@ -254,29 +250,29 @@ export class ViewModelDecorations implements IDisposable {
decorationsInViewport.push(d);
if (d.options.inlineClassName) {
let inlineDecoration = new InlineDecoration(d.range, d.options.inlineClassName);
intersectedStartLineNumber = Math.max(startLineNumber, r.startLineNumber);
intersectedEndLineNumber = Math.min(endLineNumber, r.endLineNumber);
for (j = intersectedStartLineNumber; j <= intersectedEndLineNumber; j++) {
inlineDecorations[j - startLineNumber].push(d);
inlineDecorations[j - startLineNumber].push(inlineDecoration);
}
}
if (d.options.beforeContentClassName && r.startLineNumber >= startLineNumber) {
let beforeDecoration = {
id: d.id + '$beforeContent',
ownerId: d.ownerId,
range: new Range(r.startLineNumber, r.startColumn, r.startLineNumber, r.startColumn + 1),
options: { inlineClassName: d.options.beforeContentClassName, stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges }
};
inlineDecorations[r.startLineNumber - startLineNumber].push(beforeDecoration);
// TODO: What happens if the startLineNumber and startColumn is at the end of a line?
let inlineDecoration = new InlineDecoration(
new Range(r.startLineNumber, r.startColumn, r.startLineNumber, r.startColumn + 1),
d.options.beforeContentClassName
);
inlineDecorations[r.startLineNumber - startLineNumber].push(inlineDecoration);
}
if (d.options.afterContentClassName && r.endLineNumber <= endLineNumber) {
let afterDecoration = {
id: d.id + '$afterContent',
ownerId: d.ownerId,
range: new Range(r.endLineNumber, r.endColumn - 1, r.endLineNumber, r.endColumn),
options: { inlineClassName: d.options.afterContentClassName, stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges }
};
inlineDecorations[r.endLineNumber - startLineNumber].push(afterDecoration);
if (r.endColumn > 1) {
let inlineDecoration = new InlineDecoration(
new Range(r.endLineNumber, r.endColumn - 1, r.endLineNumber, r.endColumn),
d.options.afterContentClassName
);
inlineDecorations[r.endLineNumber - startLineNumber].push(inlineDecoration);
}
}
}
......
......@@ -5,20 +5,16 @@
'use strict';
import * as assert from 'assert';
import {DecorationSegment, ILineDecoration, LineDecorationsNormalizer, getColumnOfLinePartOffset, createLineParts} from 'vs/editor/common/viewLayout/viewLineParts';
import {DecorationSegment, LineDecorationsNormalizer, getColumnOfLinePartOffset, createLineParts} from 'vs/editor/common/viewLayout/viewLineParts';
import {Range} from 'vs/editor/common/core/range';
import {RenderLineInput, renderLine} from 'vs/editor/common/viewLayout/viewLineRenderer';
import {ViewLineToken, ViewLineTokens} from 'vs/editor/common/core/viewLineToken';
import {InlineDecoration} from 'vs/editor/common/viewModel/viewModel';
suite('Editor ViewLayout - ViewLineParts', () => {
function newDecoration(startLineNumber:number, startColumn:number, endLineNumber:number, endColumn:number, inlineClassName:string): ILineDecoration {
return {
range: new Range(startLineNumber, startColumn, endLineNumber, endColumn),
options: {
inlineClassName: inlineClassName
}
};
function newDecoration(startLineNumber:number, startColumn:number, endLineNumber:number, endColumn:number, inlineClassName:string): InlineDecoration {
return new InlineDecoration(new Range(startLineNumber, startColumn, endLineNumber, endColumn), inlineClassName);
}
test('Bug 9827:Overlapping inline decorations can cause wrong inline class to be applied', () => {
......
......@@ -832,7 +832,7 @@ declare namespace vscode {
/**
* A message that should be rendered when hovering over the decoration.
*/
hoverMessage: MarkedString | MarkedString[];
hoverMessage?: MarkedString | MarkedString[];
/**
* Render options applied to the current decoration. For performance reasons, keep the
......@@ -841,22 +841,16 @@ declare namespace vscode {
renderOptions?: DecorationInstanceRenderOptions;
}
export interface ThemableDecorationInstanceAttachmentRenderOptions {
content?: string;
color?: string;
backgroundColor?: string;
}
export interface ThemableDecorationInstanceRenderOptions {
/**
* Defines the rendering options of the attachment that is inserted before the decorated text
*/
before?: ThemableDecorationInstanceAttachmentRenderOptions;
before?: ThemableDecorationAttachmentRenderOptions;
/**
* Defines the rendering options of the attachment that is inserted after the decorated text
*/
after?: ThemableDecorationInstanceAttachmentRenderOptions;
after?: ThemableDecorationAttachmentRenderOptions;
}
export interface DecorationInstanceRenderOptions extends ThemableDecorationInstanceRenderOptions {
......
......@@ -156,7 +156,7 @@ function fromMarkedStringOrMarkedStringArr(something: vscode.MarkedString | vsco
}
function isDecorationOptions(something: any): something is vscode.DecorationOptions {
return (typeof something.range !== 'undefined') || (typeof something.after !== 'undefined') || (typeof something.before !== 'undefined');
return (typeof something.range !== 'undefined');
}
function isDecorationOptionsArr(something: vscode.Range[]|vscode.DecorationOptions[]): something is vscode.DecorationOptions[] {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册