Skip to content

Commit e55b563

Browse files
authored
Merge pull request #15588 from rebornix/EnhancedDiffView
Enhanced diff view
2 parents 6665030 + 7ae1335 commit e55b563

21 files changed

+380
-48
lines changed

src/vs/editor/browser/editorBrowser.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,10 @@ export interface IViewZone {
211211
* The dom node of the view zone
212212
*/
213213
domNode: HTMLElement;
214+
/**
215+
* An optional dom node for the view zone that will be placed in the margin area.
216+
*/
217+
marginDomNode?: HTMLElement;
214218
/**
215219
* Callback which gives the relative top of the view zone as it appears (taking scrolling into account).
216220
*/

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ import { GlyphMarginOverlay } from 'vs/editor/browser/viewParts/glyphMargin/glyp
3030
import { LineNumbersOverlay } from 'vs/editor/browser/viewParts/lineNumbers/lineNumbers';
3131
import { IndentGuidesOverlay } from 'vs/editor/browser/viewParts/indentGuides/indentGuides';
3232
import { ViewLines } from 'vs/editor/browser/viewParts/lines/viewLines';
33+
import { Margin } from 'vs/editor/browser/viewParts/margin/margin';
3334
import { LinesDecorationsOverlay } from 'vs/editor/browser/viewParts/linesDecorations/linesDecorations';
35+
import { MarginViewLineDecorationsOverlay } from 'vs/editor/browser/viewParts/marginDecorations/marginDecorations';
3436
import { ViewOverlayWidgets } from 'vs/editor/browser/viewParts/overlayWidgets/overlayWidgets';
3537
import { DecorationsOverviewRuler } from 'vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler';
3638
import { OverviewRuler } from 'vs/editor/browser/viewParts/overviewRuler/overviewRuler';
@@ -237,9 +239,14 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
237239
let marginViewOverlays = new MarginViewOverlays(this._context, this.layoutProvider);
238240
this.viewParts.push(marginViewOverlays);
239241
marginViewOverlays.addDynamicOverlay(new GlyphMarginOverlay(this._context));
242+
marginViewOverlays.addDynamicOverlay(new MarginViewLineDecorationsOverlay(this._context));
240243
marginViewOverlays.addDynamicOverlay(new LinesDecorationsOverlay(this._context));
241244
marginViewOverlays.addDynamicOverlay(new LineNumbersOverlay(this._context));
242245

246+
let margin = new Margin(this._context, this.layoutProvider);
247+
margin.domNode.appendChild(this.viewZones.marginDomNode);
248+
margin.domNode.appendChild(marginViewOverlays.getDomNode());
249+
this.viewParts.push(margin);
243250

244251
// Content widgets
245252
this.contentWidgets = new ViewContentWidgets(this._context, this.domNode);
@@ -271,7 +278,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
271278
this.linesContent.appendChild(this.viewLines.getDomNode());
272279
this.linesContent.appendChild(this.contentWidgets.domNode);
273280
this.linesContent.appendChild(this.viewCursors.getDomNode());
274-
this.overflowGuardContainer.appendChild(marginViewOverlays.getDomNode());
281+
this.overflowGuardContainer.appendChild(margin.domNode);
275282
this.overflowGuardContainer.appendChild(this.linesContentContainer);
276283
this.overflowGuardContainer.appendChild(scrollDecoration.getDomNode());
277284
this.overflowGuardContainer.appendChild(this.overlayWidgets.domNode);

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

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ export class MarginViewOverlays extends ViewOverlays {
233233
this._contentLeft = context.configuration.editor.layoutInfo.contentLeft;
234234
this._canUseTranslate3d = context.configuration.editor.viewInfo.canUseTranslate3d;
235235

236-
this.domNode.setClassName(editorBrowser.ClassNames.MARGIN_VIEW_OVERLAYS + ' monaco-editor-background');
236+
this.domNode.setClassName(editorBrowser.ClassNames.MARGIN_VIEW_OVERLAYS);
237237
this.domNode.setWidth(1);
238238

239239
Configuration.applyFontInfo(this.domNode, this._context.configuration.editor.fontInfo);
@@ -283,14 +283,6 @@ export class MarginViewOverlays extends ViewOverlays {
283283

284284
_viewOverlaysRender(ctx: IRestrictedRenderingContext): void {
285285
super._viewOverlaysRender(ctx);
286-
if (this._canUseTranslate3d) {
287-
let transform = 'translate3d(0px, ' + ctx.linesViewportData.visibleRangesDeltaTop + 'px, 0px)';
288-
this.domNode.setTransform(transform);
289-
this.domNode.setTop(0);
290-
} else {
291-
this.domNode.setTransform('');
292-
this.domNode.setTop(ctx.linesViewportData.visibleRangesDeltaTop);
293-
}
294286
let height = Math.min(this._layoutProvider.getTotalHeight(), 1000000);
295287
this.domNode.setHeight(height);
296288
this.domNode.setWidth(this._contentLeft);

src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
vertical-align: middle;
1111
box-sizing: border-box;
1212
cursor: default;
13+
height: 100%;
1314
}
1415

1516
.monaco-editor .relative-current-line-number {

src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,20 +97,15 @@ export class LineNumbersOverlay extends DynamicViewOverlay {
9797
// --- end event handlers
9898

9999
public prepareRender(ctx: IRenderingContext): void {
100-
if (!this.shouldRender()) {
101-
throw new Error('I did not ask to render!');
102-
}
103-
104100
if (!this._renderLineNumbers) {
105101
this._renderResult = null;
106102
return;
107103
}
108104

109105
let lineHeightClassName = (platform.isLinux ? (this._lineHeight % 2 === 0 ? ' lh-even' : ' lh-odd') : '');
110-
let lineHeight = this._lineHeight.toString();
111106
let visibleStartLineNumber = ctx.visibleRange.startLineNumber;
112107
let visibleEndLineNumber = ctx.visibleRange.endLineNumber;
113-
let common = '<div class="' + ClassNames.LINE_NUMBERS + lineHeightClassName + '" style="left:' + this._lineNumbersLeft.toString() + 'px;width:' + this._lineNumbersWidth.toString() + 'px;height:' + lineHeight + 'px;">';
108+
let common = '<div class="' + ClassNames.LINE_NUMBERS + lineHeightClassName + '" style="left:' + this._lineNumbersLeft.toString() + 'px;width:' + this._lineNumbersWidth.toString() + 'px;">';
114109

115110
let output: string[] = [];
116111
for (let lineNumber = visibleStartLineNumber; lineNumber <= visibleEndLineNumber; lineNumber++) {

src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@
1414
*/
1515
.monaco-editor .margin-view-overlays .cldr {
1616
position: absolute;
17+
height: 100%;
1718
}

src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import { IRenderingContext } from 'vs/editor/common/view/renderingContext';
1414
export class LinesDecorationsOverlay extends DedupOverlay {
1515

1616
private _context: ViewContext;
17-
private _lineHeight: number;
1817

1918
private _decorationsLeft: number;
2019
private _decorationsWidth: number;
@@ -23,7 +22,6 @@ export class LinesDecorationsOverlay extends DedupOverlay {
2322
constructor(context: ViewContext) {
2423
super();
2524
this._context = context;
26-
this._lineHeight = this._context.configuration.editor.lineHeight;
2725
this._decorationsLeft = 0;
2826
this._decorationsWidth = 0;
2927
this._renderResult = null;
@@ -63,9 +61,6 @@ export class LinesDecorationsOverlay extends DedupOverlay {
6361
return false;
6462
}
6563
public onConfigurationChanged(e: editorCommon.IConfigurationChangedEvent): boolean {
66-
if (e.lineHeight) {
67-
this._lineHeight = this._context.configuration.editor.lineHeight;
68-
}
6964
return true;
7065
}
7166
public onLayoutChanged(layoutInfo: editorCommon.EditorLayoutInfo): boolean {
@@ -95,18 +90,13 @@ export class LinesDecorationsOverlay extends DedupOverlay {
9590
}
9691

9792
public prepareRender(ctx: IRenderingContext): void {
98-
if (!this.shouldRender()) {
99-
throw new Error('I did not ask to render!');
100-
}
101-
10293
let visibleStartLineNumber = ctx.visibleRange.startLineNumber;
10394
let visibleEndLineNumber = ctx.visibleRange.endLineNumber;
10495
let toRender = this._render(visibleStartLineNumber, visibleEndLineNumber, this._getDecorations(ctx));
10596

106-
let lineHeight = this._lineHeight.toString();
10797
let left = this._decorationsLeft.toString();
10898
let width = this._decorationsWidth.toString();
109-
let common = '" style="left:' + left + 'px;width:' + width + 'px' + ';height:' + lineHeight + 'px;"></div>';
99+
let common = '" style="left:' + left + 'px;width:' + width + 'px;"></div>';
110100

111101
let output: string[] = [];
112102
for (let lineNumber = visibleStartLineNumber; lineNumber <= visibleEndLineNumber; lineNumber++) {
@@ -126,10 +116,6 @@ export class LinesDecorationsOverlay extends DedupOverlay {
126116
if (!this._renderResult) {
127117
return '';
128118
}
129-
let lineIndex = lineNumber - startLineNumber;
130-
if (lineIndex < 0 || lineIndex >= this._renderResult.length) {
131-
throw new Error('Unexpected render request');
132-
}
133-
return this._renderResult[lineIndex];
119+
return this._renderResult[lineNumber - startLineNumber];
134120
}
135121
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
'use strict';
7+
8+
import { StyleMutator } from 'vs/base/browser/styleMutator';
9+
import * as editorCommon from 'vs/editor/common/editorCommon';
10+
import { ViewPart } from 'vs/editor/browser/view/viewPart';
11+
import { ViewContext } from 'vs/editor/common/view/viewContext';
12+
import { IRenderingContext, IRestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
13+
import { ILayoutProvider } from 'vs/editor/browser/viewLayout/layoutProvider';
14+
15+
export class Margin extends ViewPart {
16+
public domNode: HTMLElement;
17+
private _layoutProvider: ILayoutProvider;
18+
private _canUseTranslate3d: boolean;
19+
private _height: number;
20+
private _contentLeft: number;
21+
22+
constructor(context: ViewContext, layoutProvider: ILayoutProvider) {
23+
super(context);
24+
this._layoutProvider = layoutProvider;
25+
this._canUseTranslate3d = this._context.configuration.editor.viewInfo.canUseTranslate3d;
26+
this.domNode = this._createDomNode();
27+
this._height = this._context.configuration.editor.layoutInfo.contentHeight;
28+
this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft;
29+
}
30+
31+
public dispose(): void {
32+
super.dispose();
33+
}
34+
35+
public _createDomNode(): HTMLElement {
36+
let domNode = document.createElement('div');
37+
domNode.className = 'margin monaco-editor-background';
38+
domNode.style.position = 'absolute';
39+
domNode.setAttribute('role', 'presentation');
40+
domNode.setAttribute('aria-hidden', 'true');
41+
return domNode;
42+
}
43+
44+
// --- begin event handlers
45+
46+
public onConfigurationChanged(e: editorCommon.IConfigurationChangedEvent): boolean {
47+
if (e.viewInfo.canUseTranslate3d) {
48+
this._canUseTranslate3d = this._context.configuration.editor.viewInfo.canUseTranslate3d;
49+
}
50+
51+
return super.onConfigurationChanged(e);
52+
}
53+
54+
public onScrollChanged(e: editorCommon.IScrollEvent): boolean {
55+
return super.onScrollChanged(e) || e.scrollTopChanged;
56+
}
57+
58+
public onLayoutChanged(layoutInfo: editorCommon.EditorLayoutInfo): boolean {
59+
this._contentLeft = layoutInfo.contentLeft;
60+
return super.onLayoutChanged(layoutInfo) || true;
61+
}
62+
63+
// --- end event handlers
64+
65+
public prepareRender(ctx: IRenderingContext): void {
66+
// Nothing to read
67+
}
68+
69+
public render(ctx: IRestrictedRenderingContext): void {
70+
if (this._canUseTranslate3d) {
71+
let transform = 'translate3d(0px, ' + ctx.linesViewportData.visibleRangesDeltaTop + 'px, 0px)';
72+
StyleMutator.setTransform(this.domNode, transform);
73+
StyleMutator.setTop(this.domNode, 0);
74+
} else {
75+
StyleMutator.setTransform(this.domNode, '');
76+
StyleMutator.setTop(this.domNode, ctx.linesViewportData.visibleRangesDeltaTop);
77+
}
78+
79+
let height = Math.min(this._layoutProvider.getTotalHeight(), 1000000);
80+
StyleMutator.setHeight(this.domNode, height);
81+
StyleMutator.setWidth(this.domNode, this._contentLeft);
82+
}
83+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
/*
7+
Keeping name short for faster parsing.
8+
cmdr = core margin decorations rendering (div)
9+
*/
10+
.monaco-editor .margin-view-overlays .cmdr {
11+
position: absolute;
12+
left: 0;
13+
width: 100%;
14+
height: 100%;
15+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
'use strict';
7+
8+
import 'vs/css!./marginDecorations';
9+
import * as editorCommon from 'vs/editor/common/editorCommon';
10+
import { DecorationToRender, DedupOverlay } from 'vs/editor/browser/viewParts/glyphMargin/glyphMargin';
11+
import { ViewContext } from 'vs/editor/common/view/viewContext';
12+
import { IRenderingContext } from 'vs/editor/common/view/renderingContext';
13+
14+
export class MarginViewLineDecorationsOverlay extends DedupOverlay {
15+
private _context: ViewContext;
16+
private _renderResult: string[];
17+
18+
constructor(context: ViewContext) {
19+
super();
20+
this._context = context;
21+
this._renderResult = null;
22+
this._context.addEventHandler(this);
23+
}
24+
25+
public dispose(): void {
26+
this._context.removeEventHandler(this);
27+
this._context = null;
28+
this._renderResult = null;
29+
}
30+
31+
// --- begin event handlers
32+
33+
public onModelFlushed(): boolean {
34+
return true;
35+
}
36+
public onModelDecorationsChanged(e: editorCommon.IViewDecorationsChangedEvent): boolean {
37+
return true;
38+
}
39+
public onModelLinesDeleted(e: editorCommon.IViewLinesDeletedEvent): boolean {
40+
return true;
41+
}
42+
public onModelLineChanged(e: editorCommon.IViewLineChangedEvent): boolean {
43+
return true;
44+
}
45+
public onModelLinesInserted(e: editorCommon.IViewLinesInsertedEvent): boolean {
46+
return true;
47+
}
48+
public onCursorPositionChanged(e: editorCommon.IViewCursorPositionChangedEvent): boolean {
49+
return false;
50+
}
51+
public onCursorSelectionChanged(e: editorCommon.IViewCursorSelectionChangedEvent): boolean {
52+
return false;
53+
}
54+
public onCursorRevealRange(e: editorCommon.IViewRevealRangeEvent): boolean {
55+
return false;
56+
}
57+
public onConfigurationChanged(e: editorCommon.IConfigurationChangedEvent): boolean {
58+
return true;
59+
}
60+
public onLayoutChanged(layoutInfo: editorCommon.EditorLayoutInfo): boolean {
61+
return true;
62+
}
63+
public onScrollChanged(e: editorCommon.IScrollEvent): boolean {
64+
return e.scrollTopChanged;
65+
}
66+
public onZonesChanged(): boolean {
67+
return true;
68+
}
69+
70+
// --- end event handlers
71+
72+
protected _getDecorations(ctx: IRenderingContext): DecorationToRender[] {
73+
let decorations = ctx.getDecorationsInViewport();
74+
let r: DecorationToRender[] = [];
75+
for (let i = 0, len = decorations.length; i < len; i++) {
76+
let d = decorations[i];
77+
if (d.options.marginClassName) {
78+
r.push(new DecorationToRender(d.range.startLineNumber, d.range.endLineNumber, d.options.marginClassName));
79+
}
80+
}
81+
return r;
82+
}
83+
84+
public prepareRender(ctx: IRenderingContext): void {
85+
let visibleStartLineNumber = ctx.visibleRange.startLineNumber;
86+
let visibleEndLineNumber = ctx.visibleRange.endLineNumber;
87+
let toRender = this._render(visibleStartLineNumber, visibleEndLineNumber, this._getDecorations(ctx));
88+
89+
let output: string[] = [];
90+
for (let lineNumber = visibleStartLineNumber; lineNumber <= visibleEndLineNumber; lineNumber++) {
91+
let lineIndex = lineNumber - visibleStartLineNumber;
92+
let classNames = toRender[lineIndex];
93+
let lineOutput = '';
94+
for (let i = 0, len = classNames.length; i < len; i++) {
95+
lineOutput += '<div class="cmdr ' + classNames[i] + '" style=""></div>';
96+
}
97+
output[lineIndex] = lineOutput;
98+
}
99+
100+
this._renderResult = output;
101+
}
102+
103+
public render(startLineNumber: number, lineNumber: number): string {
104+
if (!this._renderResult) {
105+
return '';
106+
}
107+
return this._renderResult[lineNumber - startLineNumber];
108+
}
109+
}

0 commit comments

Comments
 (0)