{
// ----- event handlers
+ public onConfigurationChanged(e: IConfigurationChangedEvent): boolean {
+ super.onConfigurationChanged(e);
+ let startLineNumber = this._linesCollection.getStartLineNumber();
+ let endLineNumber = this._linesCollection.getEndLineNumber();
+ for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) {
+ let line = this._linesCollection.getLine(lineNumber);
+ line.onConfigurationChanged(e);
+ }
+ return true;
+ }
+
public onViewFocusChanged(isFocused: boolean): boolean {
this._isFocused = isFocused;
return true;
@@ -108,7 +119,7 @@ export class ViewOverlayLine implements IVisibleLine {
private _configuration: IConfiguration;
private _dynamicOverlays: DynamicViewOverlay[];
private _domNode: FastDomNode;
- private _renderPieces: string;
+ private _renderedContent: string;
private _lineHeight: number;
constructor(configuration: IConfiguration, dynamicOverlays: DynamicViewOverlay[]) {
@@ -117,7 +128,7 @@ export class ViewOverlayLine implements IVisibleLine {
this._dynamicOverlays = dynamicOverlays;
this._domNode = null;
- this._renderPieces = null;
+ this._renderedContent = null;
}
public getDomNode(): HTMLElement {
@@ -142,36 +153,29 @@ export class ViewOverlayLine implements IVisibleLine {
}
}
- public shouldUpdateHTML(lineNumber: number, viewportData: ViewportData): boolean {
- let newPieces = '';
+ public renderLine(lineNumber: number, deltaTop: number, viewportData: ViewportData): string {
+ let result = '';
for (let i = 0, len = this._dynamicOverlays.length; i < len; i++) {
let dynamicOverlay = this._dynamicOverlays[i];
- newPieces += dynamicOverlay.render(viewportData.startLineNumber, lineNumber);
+ result += dynamicOverlay.render(viewportData.startLineNumber, lineNumber);
}
- let piecesEqual = (this._renderPieces === newPieces);
-
- if (!piecesEqual) {
- this._renderPieces = newPieces;
+ if (this._renderedContent === result) {
+ // No rendering needed
+ return null;
}
- return !piecesEqual;
- }
+ this._renderedContent = result;
- public getLineOuterHTML(out: string[], lineNumber: number, deltaTop: number): void {
- out.push(``);
- out.push(this.getLineInnerHTML(lineNumber));
- out.push(`
`);
- }
-
- private getLineInnerHTML(lineNumber: number): string {
- return this._renderPieces;
+ return `${result}
`;
}
public layoutLine(lineNumber: number, deltaTop: number): void {
- this._domNode.setLineNumber(String(lineNumber));
- this._domNode.setTop(deltaTop);
- this._domNode.setHeight(this._lineHeight);
+ if (this._domNode) {
+ this._domNode.setLineNumber(String(lineNumber));
+ this._domNode.setTop(deltaTop);
+ this._domNode.setHeight(this._lineHeight);
+ }
}
}
diff --git a/src/vs/editor/browser/viewParts/lines/viewLine.ts b/src/vs/editor/browser/viewParts/lines/viewLine.ts
index 2473b803fc7a6c14dc3ad3594b7e99d9456a20c5..cb1ef2b6b7d8fc2de3a5c03c80e2b490aa3ca486 100644
--- a/src/vs/editor/browser/viewParts/lines/viewLine.ts
+++ b/src/vs/editor/browser/viewParts/lines/viewLine.ts
@@ -8,9 +8,9 @@ import * as browser from 'vs/base/browser/browser';
import * as platform from 'vs/base/common/platform';
import * as strings from 'vs/base/common/strings';
import { FastDomNode, createFastDomNode } from 'vs/base/browser/styleMutator';
-import { IConfiguration, IConfigurationChangedEvent } from 'vs/editor/common/editorCommon';
+import { IConfiguration } from 'vs/editor/common/editorCommon';
import { Decoration } from 'vs/editor/common/viewLayout/viewLineParts';
-import { renderViewLine, RenderLineInput, RenderLineOutput, CharacterMapping } from 'vs/editor/common/viewLayout/viewLineRenderer';
+import { renderViewLine, RenderLineInput, CharacterMapping } from 'vs/editor/common/viewLayout/viewLineRenderer';
import { ClassNames } from 'vs/editor/browser/editorBrowser';
import { IVisibleLine } from 'vs/editor/browser/view/viewLayer';
import { RangeUtil } from 'vs/editor/browser/viewParts/lines/rangeUtil';
@@ -65,7 +65,7 @@ export class DomReadingContext {
}
-class ViewLineOptions {
+export class ViewLineOptions {
public readonly renderWhitespace: 'none' | 'boundary' | 'all';
public readonly renderControlCharacters: boolean;
public readonly spaceWidth: number;
@@ -99,14 +99,12 @@ class ViewLineOptions {
export class ViewLine implements IVisibleLine {
- private readonly _configuration: IConfiguration;
private _options: ViewLineOptions;
private _isMaybeInvalid: boolean;
private _renderedViewLine: IRenderedViewLine;
- constructor(configuration: IConfiguration) {
- this._configuration = configuration;
- this._options = new ViewLineOptions(this._configuration);
+ constructor(options: ViewLineOptions) {
+ this._options = options;
this._isMaybeInvalid = true;
this._renderedViewLine = null;
}
@@ -136,28 +134,22 @@ export class ViewLine implements IVisibleLine {
public onModelDecorationsChanged(): void {
this._isMaybeInvalid = true;
}
- public onConfigurationChanged(e: IConfigurationChangedEvent): void {
- let newOptions = new ViewLineOptions(this._configuration);
- if (this._options.equals(newOptions)) {
- // Nothing changed
- return;
- }
+ public onOptionsChanged(newOptions: ViewLineOptions): void {
this._isMaybeInvalid = true;
this._options = newOptions;
}
- public shouldUpdateHTML(lineNumber: number, viewportData: ViewportData): boolean {
+ public renderLine(lineNumber: number, deltaTop: number, viewportData: ViewportData): string {
if (this._isMaybeInvalid === false) {
// it appears that nothing relevant has changed
- return false;
+ return null;
}
+
this._isMaybeInvalid = false;
const lineData = viewportData.getViewLineRenderingData(lineNumber);
-
const options = this._options;
const actualInlineDecorations = Decoration.filter(lineData.inlineDecorations, lineNumber, lineData.minColumn, lineData.maxColumn);
-
let renderLineInput = new RenderLineInput(
options.useMonospaceOptimizations,
lineData.content,
@@ -174,7 +166,7 @@ export class ViewLine implements IVisibleLine {
if (this._renderedViewLine && this._renderedViewLine.input.equals(renderLineInput)) {
// no need to do anything, we have the same render input
- return false;
+ return null;
}
const output = renderViewLine(renderLineInput);
@@ -192,40 +184,31 @@ export class ViewLine implements IVisibleLine {
renderedViewLine = new FastRenderedViewLine(
this._renderedViewLine ? this._renderedViewLine.domNode : null,
renderLineInput,
- output
+ output.characterMapping
);
}
}
if (!renderedViewLine) {
- let isWhitespaceOnly = /^\s*$/.test(renderLineInput.lineContent);
renderedViewLine = createRenderedLine(
this._renderedViewLine ? this._renderedViewLine.domNode : null,
renderLineInput,
- isWhitespaceOnly,
- output
+ output.characterMapping,
+ output.containsRTL
);
}
this._renderedViewLine = renderedViewLine;
- return true;
- }
-
- public getLineOuterHTML(out: string[], lineNumber: number, deltaTop: number): void {
- out.push(``);
- out.push(this.getLineInnerHTML(lineNumber));
- out.push(`
`);
- }
-
- private getLineInnerHTML(lineNumber: number): string {
- return this._renderedViewLine.html;
+ return `${output.html}
`;
}
public layoutLine(lineNumber: number, deltaTop: number): void {
- this._renderedViewLine.domNode.setLineNumber(String(lineNumber));
- this._renderedViewLine.domNode.setTop(deltaTop);
- this._renderedViewLine.domNode.setHeight(this._options.lineHeight);
+ if (this._renderedViewLine && this._renderedViewLine.domNode) {
+ this._renderedViewLine.domNode.setLineNumber(String(lineNumber));
+ this._renderedViewLine.domNode.setTop(deltaTop);
+ this._renderedViewLine.domNode.setHeight(this._options.lineHeight);
+ }
}
// --- end IVisibleLineData
@@ -249,7 +232,6 @@ export class ViewLine implements IVisibleLine {
interface IRenderedViewLine {
domNode: FastDomNode;
readonly input: RenderLineInput;
- readonly html: string;
getWidth(): number;
getVisibleRangesForRange(startColumn: number, endColumn: number, context: DomReadingContext): HorizontalRange[];
getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number;
@@ -262,20 +244,18 @@ class FastRenderedViewLine implements IRenderedViewLine {
public domNode: FastDomNode;
public readonly input: RenderLineInput;
- public readonly html: string;
private readonly _characterMapping: CharacterMapping;
private readonly _charWidth: number;
private readonly _charOffset: Uint32Array;
- constructor(domNode: FastDomNode, renderLineInput: RenderLineInput, renderLineOutput: RenderLineOutput) {
+ constructor(domNode: FastDomNode, renderLineInput: RenderLineInput, characterMapping: CharacterMapping) {
this.domNode = domNode;
this.input = renderLineInput;
- this.html = renderLineOutput.output;
- this._characterMapping = renderLineOutput.characterMapping;
+ this._characterMapping = characterMapping;
this._charWidth = renderLineInput.spaceWidth;
- this._charOffset = FastRenderedViewLine._createCharOffset(renderLineOutput.characterMapping);
+ this._charOffset = FastRenderedViewLine._createCharOffset(characterMapping);
}
private static _createCharOffset(characterMapping: CharacterMapping): Uint32Array {
@@ -357,7 +337,6 @@ class RenderedViewLine {
public domNode: FastDomNode;
public readonly input: RenderLineInput;
- public readonly html: string;
protected readonly _characterMapping: CharacterMapping;
private readonly _isWhitespaceOnly: boolean;
@@ -368,16 +347,15 @@ class RenderedViewLine {
*/
private _pixelOffsetCache: Int32Array;
- constructor(domNode: FastDomNode, renderLineInput: RenderLineInput, isWhitespaceOnly: boolean, renderLineOutput: RenderLineOutput) {
+ constructor(domNode: FastDomNode, renderLineInput: RenderLineInput, characterMapping: CharacterMapping, containsRTL: boolean) {
this.domNode = domNode;
this.input = renderLineInput;
- this.html = renderLineOutput.output;
- this._characterMapping = renderLineOutput.characterMapping;
- this._isWhitespaceOnly = isWhitespaceOnly;
+ this._characterMapping = characterMapping;
+ this._isWhitespaceOnly = /^\s*$/.test(renderLineInput.lineContent);
this._cachedWidth = -1;
this._pixelOffsetCache = null;
- if (!renderLineOutput.containsRTL) {
+ if (!containsRTL) {
this._pixelOffsetCache = new Int32Array(this._characterMapping.length + 1);
for (let column = 0, len = this._characterMapping.length; column <= len; column++) {
this._pixelOffsetCache[column] = -1;
@@ -560,17 +538,17 @@ class WebKitRenderedViewLine extends RenderedViewLine {
}
}
-const createRenderedLine: (domNode: FastDomNode, renderLineInput: RenderLineInput, isWhitespaceOnly: boolean, renderLineOutput: RenderLineOutput) => RenderedViewLine = (function () {
+const createRenderedLine: (domNode: FastDomNode, renderLineInput: RenderLineInput, characterMapping: CharacterMapping, containsRTL: boolean) => RenderedViewLine = (function () {
if (browser.isWebKit) {
return createWebKitRenderedLine;
}
return createNormalRenderedLine;
})();
-function createWebKitRenderedLine(domNode: FastDomNode, renderLineInput: RenderLineInput, isWhitespaceOnly: boolean, renderLineOutput: RenderLineOutput): RenderedViewLine {
- return new WebKitRenderedViewLine(domNode, renderLineInput, isWhitespaceOnly, renderLineOutput);
+function createWebKitRenderedLine(domNode: FastDomNode, renderLineInput: RenderLineInput, characterMapping: CharacterMapping, containsRTL: boolean): RenderedViewLine {
+ return new WebKitRenderedViewLine(domNode, renderLineInput, characterMapping, containsRTL);
}
-function createNormalRenderedLine(domNode: FastDomNode, renderLineInput: RenderLineInput, isWhitespaceOnly: boolean, renderLineOutput: RenderLineOutput): RenderedViewLine {
- return new RenderedViewLine(domNode, renderLineInput, isWhitespaceOnly, renderLineOutput);
+function createNormalRenderedLine(domNode: FastDomNode, renderLineInput: RenderLineInput, characterMapping: CharacterMapping, containsRTL: boolean): RenderedViewLine {
+ return new RenderedViewLine(domNode, renderLineInput, characterMapping, containsRTL);
}
diff --git a/src/vs/editor/browser/viewParts/lines/viewLines.ts b/src/vs/editor/browser/viewParts/lines/viewLines.ts
index f4c7720cb47b1d62671d35c401b1ecb2b0a9dc11..bf509351bc9b31faac38414d068ddf3db69dfcad 100644
--- a/src/vs/editor/browser/viewParts/lines/viewLines.ts
+++ b/src/vs/editor/browser/viewParts/lines/viewLines.ts
@@ -12,7 +12,7 @@ import { Position } from 'vs/editor/common/core/position';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { ClassNames } from 'vs/editor/browser/editorBrowser';
import { ViewLayer } from 'vs/editor/browser/view/viewLayer';
-import { DomReadingContext, ViewLine } from 'vs/editor/browser/viewParts/lines/viewLine';
+import { ViewLineOptions, DomReadingContext, ViewLine } from 'vs/editor/browser/viewParts/lines/viewLine';
import { Configuration } from 'vs/editor/browser/config/configuration';
import { ViewContext } from 'vs/editor/common/view/viewContext';
import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
@@ -66,6 +66,7 @@ export class ViewLines extends ViewLayer implements IViewLines {
private _isViewportWrapping: boolean;
private _revealHorizontalRightPadding: number;
private _canUseTranslate3d: boolean;
+ private _viewLineOptions: ViewLineOptions;
// --- width
private _maxLineWidth: number;
@@ -79,7 +80,8 @@ export class ViewLines extends ViewLayer implements IViewLines {
this._lineHeight = this._context.configuration.editor.lineHeight;
this._isViewportWrapping = this._context.configuration.editor.wrappingInfo.isViewportWrapping;
this._revealHorizontalRightPadding = this._context.configuration.editor.viewInfo.revealHorizontalRightPadding;
- this._canUseTranslate3d = context.configuration.editor.viewInfo.canUseTranslate3d;
+ this._canUseTranslate3d = this._context.configuration.editor.viewInfo.canUseTranslate3d;
+ this._viewLineOptions = new ViewLineOptions(this._context.configuration);
this._layoutProvider = layoutProvider;
PartFingerprints.write(this.domNode.domNode, PartFingerprint.ViewLines);
@@ -112,7 +114,7 @@ export class ViewLines extends ViewLayer implements IViewLines {
// ---- begin view event handlers
public onConfigurationChanged(e: editorCommon.IConfigurationChangedEvent): boolean {
- let shouldRender = super.onConfigurationChanged(e);
+ super.onConfigurationChanged(e);
if (e.wrappingInfo) {
this._maxLineWidth = 0;
}
@@ -133,7 +135,19 @@ export class ViewLines extends ViewLayer implements IViewLines {
Configuration.applyFontInfo(this.domNode, this._context.configuration.editor.fontInfo);
}
- return shouldRender;
+ let newViewLineOptions = new ViewLineOptions(this._context.configuration);
+ if (!this._viewLineOptions.equals(newViewLineOptions)) {
+ this._viewLineOptions = newViewLineOptions;
+
+ let startLineNumber = this._linesCollection.getStartLineNumber();
+ let endLineNumber = this._linesCollection.getEndLineNumber();
+ for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) {
+ let line = this._linesCollection.getLine(lineNumber);
+ line.onOptionsChanged(this._viewLineOptions);
+ }
+ }
+
+ return true;
}
public onLayoutChanged(layoutInfo: editorCommon.EditorLayoutInfo): boolean {
@@ -350,8 +364,8 @@ export class ViewLines extends ViewLayer implements IViewLines {
// --- implementation
- _createLine(): ViewLine {
- return new ViewLine(this._context.configuration);
+ protected _createLine(): ViewLine {
+ return new ViewLine(this._viewLineOptions);
}
private _updateLineWidths(): void {
diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts
index 585718b20ed02bc6a3e3dd712990b606784eec75..425fc7a068243ac812dc507bc530f9ac69a4cb4a 100644
--- a/src/vs/editor/browser/widget/diffEditorWidget.ts
+++ b/src/vs/editor/browser/widget/diffEditorWidget.ts
@@ -1916,7 +1916,7 @@ class InlineViewZonesComputer extends ViewZonesComputer {
myResult.push('" style="top:');
myResult.push(String(count * config.lineHeight));
myResult.push('px;width:1000000px;">');
- myResult = myResult.concat(r.output);
+ myResult = myResult.concat(r.html);
myResult.push('');
return myResult;
diff --git a/src/vs/editor/common/viewLayout/viewLineRenderer.ts b/src/vs/editor/common/viewLayout/viewLineRenderer.ts
index 7af02248dc008e9c348747970feec21c4a040654..092cb84529b739003b44292bddb4d34c79d74604 100644
--- a/src/vs/editor/common/viewLayout/viewLineRenderer.ts
+++ b/src/vs/editor/common/viewLayout/viewLineRenderer.ts
@@ -204,13 +204,13 @@ export class RenderLineOutput {
_renderLineOutputBrand: void;
readonly characterMapping: CharacterMapping;
- readonly output: string;
+ readonly html: string;
readonly containsRTL: boolean;
readonly containsForeignElements: boolean;
- constructor(characterMapping: CharacterMapping, output: string, containsRTL: boolean, containsForeignElements: boolean) {
+ constructor(characterMapping: CharacterMapping, html: string, containsRTL: boolean, containsForeignElements: boolean) {
this.characterMapping = characterMapping;
- this.output = output;
+ this.html = html;
this.containsRTL = containsRTL;
this.containsForeignElements = containsForeignElements;
}
diff --git a/src/vs/editor/test/common/viewLayout/viewLineParts.test.ts b/src/vs/editor/test/common/viewLayout/viewLineParts.test.ts
index c40b9f83ed98e42aaeeb5ab3bbb96df8e6590ef3..e110f7cbf36bae40bee6af973b05ae69b0f27094 100644
--- a/src/vs/editor/test/common/viewLayout/viewLineParts.test.ts
+++ b/src/vs/editor/test/common/viewLayout/viewLineParts.test.ts
@@ -70,7 +70,7 @@ suite('Editor ViewLayout - ViewLineParts', () => {
false
));
- assert.deepEqual(actual.output.split(/> {
@@ -97,7 +97,7 @@ suite('Editor ViewLayout - ViewLineParts', () => {
''
].join('');
- assert.deepEqual(actual.output, expected);
+ assert.deepEqual(actual.html, expected);
});
test('issue #19207: Link in Monokai is not rendered correctly', () => {
@@ -138,7 +138,7 @@ suite('Editor ViewLayout - ViewLineParts', () => {
''
].join('');
- assert.deepEqual(actual.output, expected);
+ assert.deepEqual(actual.html, expected);
});
test('createLineParts simple', () => {
@@ -391,7 +391,7 @@ suite('Editor ViewLayout - ViewLineParts', () => {
// bb---------
// -cccccc----
- assert.deepEqual(actual.output, [
+ assert.deepEqual(actual.html, [
'',
'H',
'e',
diff --git a/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts b/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts
index 5b6c1499768a70c761c450432b7a2ae1957eb746..e72c847a82b1b0c933c9b6fcefbd3c9e4b7ed738 100644
--- a/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts
+++ b/src/vs/editor/test/common/viewLayout/viewLineRenderer.test.ts
@@ -30,7 +30,7 @@ suite('viewLineRenderer.renderLine', () => {
false
));
- assert.equal(_actual.output, '' + expected + '');
+ assert.equal(_actual.html, '' + expected + '');
assertCharacterMapping(_actual.characterMapping, expectedCharOffsetInPart);
assertPartLengths(_actual.characterMapping, expectedPartLengts);
}
@@ -77,7 +77,7 @@ suite('viewLineRenderer.renderLine', () => {
false
));
- assert.equal(_actual.output, '' + expected + '');
+ assert.equal(_actual.html, '' + expected + '');
assertCharacterMapping(_actual.characterMapping, expectedCharOffsetInPart);
assertPartLengths(_actual.characterMapping, expectedPartLengts);
}
@@ -136,7 +136,7 @@ suite('viewLineRenderer.renderLine', () => {
'…'
].join('');
- assert.equal(_actual.output, '' + expectedOutput + '');
+ assert.equal(_actual.html, '' + expectedOutput + '');
assertCharacterMapping(_actual.characterMapping, [
[0],
[0],
@@ -211,7 +211,7 @@ suite('viewLineRenderer.renderLine', () => {
false
));
- assert.equal(_actual.output, '' + expectedOutput + '');
+ assert.equal(_actual.html, '' + expectedOutput + '');
assertCharacterMapping(_actual.characterMapping, expectedOffsetsArr);
assertPartLengths(_actual.characterMapping, [4, 4, 6, 1, 5, 1, 4, 1, 1, 1, 3, 15, 2, 3]);
});
@@ -270,7 +270,7 @@ suite('viewLineRenderer.renderLine', () => {
false
));
- assert.equal(_actual.output, '' + expectedOutput + '');
+ assert.equal(_actual.html, '' + expectedOutput + '');
assertCharacterMapping(_actual.characterMapping, expectedOffsetsArr);
assertPartLengths(_actual.characterMapping, [12, 12, 24, 1, 21, 2, 1, 20, 1, 1]);
});
@@ -329,7 +329,7 @@ suite('viewLineRenderer.renderLine', () => {
false
));
- assert.equal(_actual.output, '' + expectedOutput + '');
+ assert.equal(_actual.html, '' + expectedOutput + '');
assertCharacterMapping(_actual.characterMapping, expectedOffsetsArr);
assertPartLengths(_actual.characterMapping, [12, 12, 24, 1, 21, 2, 1, 20, 1, 1]);
});
@@ -365,7 +365,7 @@ suite('viewLineRenderer.renderLine', () => {
false
));
- assert.equal(_actual.output, '' + expectedOutput + '');
+ assert.equal(_actual.html, '' + expectedOutput + '');
assert.equal(_actual.containsRTL, true);
});
@@ -390,7 +390,7 @@ suite('viewLineRenderer.renderLine', () => {
'none',
false
));
- assert.equal(actual.output, '' + expectedOutput.join('') + '', message);
+ assert.equal(actual.html, '' + expectedOutput.join('') + '', message);
}
// A token with 49 chars
@@ -484,7 +484,7 @@ suite('viewLineRenderer.renderLine', () => {
'none',
false
));
- assert.equal(actual.output, '' + expectedOutput.join('') + '');
+ assert.equal(actual.html, '' + expectedOutput.join('') + '');
assert.equal(actual.containsRTL, true);
});