Skip to content

Commit 2c3f743

Browse files
committed
Simplify usage of ViewLayer
1 parent 4e849f2 commit 2c3f743

9 files changed

Lines changed: 191 additions & 154 deletions

File tree

src/vs/editor/browser/view/viewLayer.ts

Lines changed: 64 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55
'use strict';
66

7-
import { ViewPart } from 'vs/editor/browser/view/viewPart';
87
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
9-
import { ViewContext } from 'vs/editor/common/view/viewContext';
108
import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
119
import * as viewEvents from 'vs/editor/common/view/viewEvents';
1210

@@ -32,28 +30,23 @@ export interface IVisibleLine {
3230
layoutLine(lineNumber: number, deltaTop: number): void;
3331
}
3432

35-
interface IRendererContext<T extends IVisibleLine> {
36-
readonly domNode: HTMLElement;
37-
rendLineNumberStart: number;
38-
lines: T[];
39-
linesLength: number;
40-
readonly viewportData: ViewportData;
41-
}
42-
4333
export interface ILine {
4434
onContentChanged(): void;
4535
onTokensChanged(): void;
4636
}
4737

4838
export class RenderedLinesCollection<T extends ILine> {
39+
private readonly _createLine: () => T;
4940
private _lines: T[];
5041
private _rendLineNumberStart: number;
51-
private _createLine: () => T;
5242

5343
constructor(createLine: () => T) {
54-
this._lines = [];
55-
this._rendLineNumberStart = 1;
5644
this._createLine = createLine;
45+
this._set(1, []);
46+
}
47+
48+
public flush(): void {
49+
this._set(1, []);
5750
}
5851

5952
_set(rendLineNumberStart: number, lines: T[]): void {
@@ -251,27 +244,29 @@ export class RenderedLinesCollection<T extends ILine> {
251244
}
252245
}
253246

254-
export abstract class ViewLayer<T extends IVisibleLine> extends ViewPart {
247+
export interface IVisibleLinesHost<T extends IVisibleLine> {
248+
createVisibleLine(): T;
249+
}
255250

256-
protected domNode: FastDomNode<HTMLElement>;
257-
protected _linesCollection: RenderedLinesCollection<T>;
258-
private _renderer: ViewLayerRenderer<T>;
251+
export class VisibleLinesCollection<T extends IVisibleLine> {
259252

260-
constructor(context: ViewContext) {
261-
super(context);
253+
private readonly _host: IVisibleLinesHost<T>;
254+
public readonly domNode: FastDomNode<HTMLElement>;
255+
private readonly _linesCollection: RenderedLinesCollection<T>;
262256

257+
constructor(host: IVisibleLinesHost<T>) {
258+
this._host = host;
263259
this.domNode = this._createDomNode();
264-
265-
this._linesCollection = new RenderedLinesCollection<T>(() => this._createLine());
266-
267-
this._renderer = new ViewLayerRenderer<T>(
268-
() => this._createLine()
269-
);
260+
this._linesCollection = new RenderedLinesCollection<T>(() => this._host.createVisibleLine());
270261
}
271262

272-
public dispose(): void {
273-
super.dispose();
274-
this._linesCollection = null;
263+
private _createDomNode(): FastDomNode<HTMLElement> {
264+
let domNode = createFastDomNode(document.createElement('div'));
265+
domNode.setClassName('view-layer');
266+
domNode.setPosition('absolute');
267+
domNode.domNode.setAttribute('role', 'presentation');
268+
domNode.domNode.setAttribute('aria-hidden', 'true');
269+
return domNode;
275270
}
276271

277272
// ---- begin view event handlers
@@ -281,7 +276,7 @@ export abstract class ViewLayer<T extends IVisibleLine> extends ViewPart {
281276
}
282277

283278
public onFlushed(e: viewEvents.ViewFlushedEvent): boolean {
284-
this._linesCollection = new RenderedLinesCollection<T>(() => this._createLine());
279+
this._linesCollection.flush();
285280
// No need to clear the dom node because a full .innerHTML will occur in ViewLayerRenderer._render
286281
return true;
287282
}
@@ -334,56 +329,61 @@ export abstract class ViewLayer<T extends IVisibleLine> extends ViewPart {
334329

335330
// ---- end view event handlers
336331

337-
public _renderLines(viewportData: ViewportData): void {
332+
public getStartLineNumber(): number {
333+
return this._linesCollection.getStartLineNumber();
334+
}
335+
336+
public getEndLineNumber(): number {
337+
return this._linesCollection.getEndLineNumber();
338+
}
339+
340+
public getVisibleLine(lineNumber: number): T {
341+
return this._linesCollection.getLine(lineNumber);
342+
}
343+
344+
public renderLines(viewportData: ViewportData): void {
338345

339346
let inp = this._linesCollection._get();
340347

348+
let renderer = new ViewLayerRenderer<T>(this.domNode.domNode, this._host, viewportData);
349+
341350
let ctx: IRendererContext<T> = {
342-
domNode: this.domNode.domNode,
343351
rendLineNumberStart: inp.rendLineNumberStart,
344352
lines: inp.lines,
345-
linesLength: inp.lines.length,
346-
viewportData: viewportData
353+
linesLength: inp.lines.length
347354
};
348355

349356
// Decide if this render will do a single update (single large .innerHTML) or many updates (inserting/removing dom nodes)
350-
let resCtx = this._renderer.renderWithManyUpdates(ctx, viewportData.startLineNumber, viewportData.endLineNumber, viewportData.relativeVerticalOffset);
357+
let resCtx = renderer.render(ctx, viewportData.startLineNumber, viewportData.endLineNumber, viewportData.relativeVerticalOffset);
351358

352359
this._linesCollection._set(resCtx.rendLineNumberStart, resCtx.lines);
353360
}
361+
}
354362

355-
private _createDomNode(): FastDomNode<HTMLElement> {
356-
let domNode = createFastDomNode(document.createElement('div'));
357-
domNode.setClassName('view-layer');
358-
domNode.setPosition('absolute');
359-
domNode.domNode.setAttribute('role', 'presentation');
360-
domNode.domNode.setAttribute('aria-hidden', 'true');
361-
return domNode;
362-
}
363-
364-
protected abstract _createLine(): T;
363+
interface IRendererContext<T extends IVisibleLine> {
364+
rendLineNumberStart: number;
365+
lines: T[];
366+
linesLength: number;
365367
}
366368

367369
class ViewLayerRenderer<T extends IVisibleLine> {
368370

369-
private _createLine: () => T;
370-
371-
constructor(createLine: () => T) {
372-
this._createLine = createLine;
373-
}
371+
readonly domNode: HTMLElement;
372+
readonly host: IVisibleLinesHost<T>;
373+
readonly viewportData: ViewportData;
374374

375-
public renderWithManyUpdates(ctx: IRendererContext<T>, startLineNumber: number, stopLineNumber: number, deltaTop: number[]): IRendererContext<T> {
376-
return this._render(ctx, startLineNumber, stopLineNumber, deltaTop);
375+
constructor(domNode: HTMLElement, host: IVisibleLinesHost<T>, viewportData: ViewportData) {
376+
this.domNode = domNode;
377+
this.host = host;
378+
this.viewportData = viewportData;
377379
}
378380

379-
private _render(inContext: IRendererContext<T>, startLineNumber: number, stopLineNumber: number, deltaTop: number[]): IRendererContext<T> {
381+
public render(inContext: IRendererContext<T>, startLineNumber: number, stopLineNumber: number, deltaTop: number[]): IRendererContext<T> {
380382

381383
let ctx: IRendererContext<T> = {
382-
domNode: inContext.domNode,
383384
rendLineNumberStart: inContext.rendLineNumberStart,
384385
lines: inContext.lines.slice(0),
385-
linesLength: inContext.linesLength,
386-
viewportData: inContext.viewportData,
386+
linesLength: inContext.linesLength
387387
};
388388

389389
if ((ctx.rendLineNumberStart + ctx.linesLength - 1 < startLineNumber) || (stopLineNumber < ctx.rendLineNumberStart)) {
@@ -392,7 +392,7 @@ class ViewLayerRenderer<T extends IVisibleLine> {
392392
ctx.linesLength = stopLineNumber - startLineNumber + 1;
393393
ctx.lines = [];
394394
for (let x = startLineNumber; x <= stopLineNumber; x++) {
395-
ctx.lines[x - startLineNumber] = this._createLine();
395+
ctx.lines[x - startLineNumber] = this.host.createVisibleLine();
396396
}
397397
this._finishRendering(ctx, true, deltaTop);
398398
return ctx;
@@ -467,7 +467,7 @@ class ViewLayerRenderer<T extends IVisibleLine> {
467467
let newLines: T[] = [];
468468
let newLinesLen = 0;
469469
for (let lineNumber = fromLineNumber; lineNumber <= toLineNumber; lineNumber++) {
470-
newLines[newLinesLen++] = this._createLine();
470+
newLines[newLinesLen++] = this.host.createVisibleLine();
471471
}
472472
ctx.lines = newLines.concat(ctx.lines);
473473
}
@@ -476,7 +476,7 @@ class ViewLayerRenderer<T extends IVisibleLine> {
476476
for (let i = 0; i < removeCount; i++) {
477477
let lineDomNode = ctx.lines[i].getDomNode();
478478
if (lineDomNode) {
479-
ctx.domNode.removeChild(lineDomNode);
479+
this.domNode.removeChild(lineDomNode);
480480
}
481481
}
482482
ctx.lines.splice(0, removeCount);
@@ -486,7 +486,7 @@ class ViewLayerRenderer<T extends IVisibleLine> {
486486
let newLines: T[] = [];
487487
let newLinesLen = 0;
488488
for (let lineNumber = fromLineNumber; lineNumber <= toLineNumber; lineNumber++) {
489-
newLines[newLinesLen++] = this._createLine();
489+
newLines[newLinesLen++] = this.host.createVisibleLine();
490490
}
491491
ctx.lines = ctx.lines.concat(newLines);
492492
}
@@ -497,21 +497,21 @@ class ViewLayerRenderer<T extends IVisibleLine> {
497497
for (let i = 0; i < removeCount; i++) {
498498
let lineDomNode = ctx.lines[removeIndex + i].getDomNode();
499499
if (lineDomNode) {
500-
ctx.domNode.removeChild(lineDomNode);
500+
this.domNode.removeChild(lineDomNode);
501501
}
502502
}
503503
ctx.lines.splice(removeIndex, removeCount);
504504
}
505505

506506
private _finishRenderingNewLines(ctx: IRendererContext<T>, domNodeIsEmpty: boolean, newLinesHTML: string[], wasNew: boolean[]): void {
507-
let lastChild = <HTMLElement>ctx.domNode.lastChild;
507+
let lastChild = <HTMLElement>this.domNode.lastChild;
508508
if (domNodeIsEmpty || !lastChild) {
509-
ctx.domNode.innerHTML = newLinesHTML.join('');
509+
this.domNode.innerHTML = newLinesHTML.join('');
510510
} else {
511511
lastChild.insertAdjacentHTML('afterend', newLinesHTML.join(''));
512512
}
513513

514-
let currChild = <HTMLElement>ctx.domNode.lastChild;
514+
let currChild = <HTMLElement>this.domNode.lastChild;
515515
for (let i = ctx.linesLength - 1; i >= 0; i--) {
516516
let line = ctx.lines[i];
517517
if (wasNew[i]) {
@@ -553,7 +553,7 @@ class ViewLayerRenderer<T extends IVisibleLine> {
553553
wasNew[i] = false;
554554
wasInvalid[i] = false;
555555

556-
let renderResult = line.renderLine(lineNumber, deltaTop[i], ctx.viewportData);
556+
let renderResult = line.renderLine(lineNumber, deltaTop[i], this.viewportData);
557557

558558
if (renderResult !== null) {
559559
// Line needs rendering
@@ -581,4 +581,3 @@ class ViewLayerRenderer<T extends IVisibleLine> {
581581
}
582582
}
583583
}
584-

src/vs/editor/browser/view/viewOverlays.ts

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,28 @@
77
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
88
import { IConfiguration } from 'vs/editor/common/editorCommon';
99
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
10-
import { IVisibleLine, ViewLayer } from 'vs/editor/browser/view/viewLayer';
10+
import { IVisibleLine, VisibleLinesCollection, IVisibleLinesHost } from 'vs/editor/browser/view/viewLayer';
1111
import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay';
1212
import { Configuration } from 'vs/editor/browser/config/configuration';
1313
import { ViewContext } from 'vs/editor/common/view/viewContext';
1414
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
1515
import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
1616
import * as viewEvents from 'vs/editor/common/view/viewEvents';
17+
import { ViewPart } from 'vs/editor/browser/view/viewPart';
1718

18-
export class ViewOverlays extends ViewLayer<ViewOverlayLine> {
19+
export class ViewOverlays extends ViewPart implements IVisibleLinesHost<ViewOverlayLine> {
1920

21+
private readonly _visibleLines: VisibleLinesCollection<ViewOverlayLine>;
22+
protected readonly domNode: FastDomNode<HTMLElement>;
2023
private _dynamicOverlays: DynamicViewOverlay[];
2124
private _isFocused: boolean;
2225

2326
constructor(context: ViewContext) {
2427
super(context);
2528

29+
this._visibleLines = new VisibleLinesCollection<ViewOverlayLine>(this);
30+
this.domNode = this._visibleLines.domNode;
31+
2632
this._dynamicOverlays = [];
2733
this._isFocused = false;
2834

@@ -58,34 +64,57 @@ export class ViewOverlays extends ViewLayer<ViewOverlayLine> {
5864
return this.domNode.domNode;
5965
}
6066

67+
// ---- begin IVisibleLinesHost
68+
69+
public createVisibleLine(): ViewOverlayLine {
70+
return new ViewOverlayLine(this._context.configuration, this._dynamicOverlays);
71+
}
72+
73+
// ---- end IVisibleLinesHost
74+
6175
public addDynamicOverlay(overlay: DynamicViewOverlay): void {
6276
this._dynamicOverlays.push(overlay);
6377
}
6478

6579
// ----- event handlers
6680

6781
public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean {
68-
super.onConfigurationChanged(e);
69-
let startLineNumber = this._linesCollection.getStartLineNumber();
70-
let endLineNumber = this._linesCollection.getEndLineNumber();
82+
this._visibleLines.onConfigurationChanged(e);
83+
let startLineNumber = this._visibleLines.getStartLineNumber();
84+
let endLineNumber = this._visibleLines.getEndLineNumber();
7185
for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) {
72-
let line = this._linesCollection.getLine(lineNumber);
86+
let line = this._visibleLines.getVisibleLine(lineNumber);
7387
line.onConfigurationChanged(e);
7488
}
7589
return true;
7690
}
77-
91+
public onFlushed(e: viewEvents.ViewFlushedEvent): boolean {
92+
return this._visibleLines.onFlushed(e);
93+
}
7894
public onFocusChanged(e: viewEvents.ViewFocusChangedEvent): boolean {
7995
this._isFocused = e.isFocused;
8096
return true;
8197
}
82-
83-
// ----- end event handlers
84-
85-
_createLine(): ViewOverlayLine {
86-
return new ViewOverlayLine(this._context.configuration, this._dynamicOverlays);
98+
public onLinesChanged(e: viewEvents.ViewLinesChangedEvent): boolean {
99+
return this._visibleLines.onLinesChanged(e);
100+
}
101+
public onLinesDeleted(e: viewEvents.ViewLinesDeletedEvent): boolean {
102+
return this._visibleLines.onLinesDeleted(e);
103+
}
104+
public onLinesInserted(e: viewEvents.ViewLinesInsertedEvent): boolean {
105+
return this._visibleLines.onLinesInserted(e);
106+
}
107+
public onScrollChanged(e: viewEvents.ViewScrollChangedEvent): boolean {
108+
return this._visibleLines.onScrollChanged(e) || true;
109+
}
110+
public onTokensChanged(e: viewEvents.ViewTokensChangedEvent): boolean {
111+
return this._visibleLines.onTokensChanged(e);
112+
}
113+
public onZonesChanged(e: viewEvents.ViewZonesChangedEvent): boolean {
114+
return this._visibleLines.onZonesChanged(e);
87115
}
88116

117+
// ----- end event handlers
89118

90119
public prepareRender(ctx: RenderingContext): void {
91120
let toRender = this._dynamicOverlays.filter(overlay => overlay.shouldRender());
@@ -107,7 +136,7 @@ export class ViewOverlays extends ViewLayer<ViewOverlayLine> {
107136
}
108137

109138
_viewOverlaysRender(ctx: RestrictedRenderingContext): void {
110-
super._renderLines(ctx.viewportData);
139+
this._visibleLines.renderLines(ctx.viewportData);
111140
}
112141
}
113142

@@ -211,13 +240,11 @@ export class ContentViewOverlays extends ViewOverlays {
211240
export class MarginViewOverlays extends ViewOverlays {
212241

213242
private _contentLeft: number;
214-
private _canUseTranslate3d: boolean;
215243

216244
constructor(context: ViewContext) {
217245
super(context);
218246

219247
this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft;
220-
this._canUseTranslate3d = this._context.configuration.editor.viewInfo.canUseTranslate3d;
221248

222249
this.domNode.setClassName(editorBrowser.ClassNames.MARGIN_VIEW_OVERLAYS);
223250
this.domNode.setWidth(1);
@@ -231,10 +258,6 @@ export class MarginViewOverlays extends ViewOverlays {
231258
Configuration.applyFontInfo(this.domNode, this._context.configuration.editor.fontInfo);
232259
shouldRender = true;
233260
}
234-
if (e.viewInfo.canUseTranslate3d) {
235-
this._canUseTranslate3d = this._context.configuration.editor.viewInfo.canUseTranslate3d;
236-
shouldRender = true;
237-
}
238261
if (e.layoutInfo) {
239262
this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft;
240263
shouldRender = true;

0 commit comments

Comments
 (0)