Skip to content

Commit 8cc2b9a

Browse files
authored
Merge pull request #20807 from michelkaporin/exception-widget
Fixes #16860: Improving exception experience
2 parents 57f33e1 + 87eed20 commit 8cc2b9a

File tree

14 files changed

+175
-48
lines changed

14 files changed

+175
-48
lines changed

src/vs/editor/contrib/gotoError/browser/gotoError.css

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* Copyright (c) Microsoft Corporation. All rights reserved.
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
5+
56
/* marker zone */
67

78
.monaco-editor .marker-widget {
@@ -12,11 +13,31 @@
1213
white-space: nowrap;
1314
}
1415

16+
.monaco-editor .zone-widget .zone-widget-container.marker-error-widget {
17+
border-top-color: #ff5a5a;
18+
border-bottom-color: #ff5a5a;
19+
}
20+
21+
.monaco-editor .zone-widget .zone-widget-container.marker-warning-widget {
22+
border-top-color: #5aac5a;
23+
border-bottom-color: #5aac5a;
24+
}
25+
26+
.monaco-editor .zone-widget-arrow.below.marker-error-widget {
27+
border-bottom-color: #ff5a5a;
28+
}
29+
30+
.monaco-editor .zone-widget-arrow.below.marker-warning-widget {
31+
border-bottom-color: #5aac5a;
32+
}
33+
1534
.monaco-editor.vs-dark .marker-widget {
1635
background-color: #2D2D30;
1736
}
1837

38+
1939
/* High Contrast Theming */
40+
2041
.monaco-editor.hc-black .marker-widget {
2142
background-color: #0C141F;
2243
}

src/vs/editor/contrib/gotoError/browser/gotoError.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,15 +265,16 @@ class MarkerNavigationWidget extends ZoneWidget {
265265
this._message.update(marker);
266266

267267
this._model.withoutWatchingEditorPosition(() => {
268+
const errorWidgetClass = 'marker-error-widget', warningWidgetClass = 'marker-warning-widget';
268269

269270
// update frame color (only applied on 'show')
270271
switch (marker.severity) {
271272
case Severity.Error:
272-
this.options.frameColor = '#ff5a5a';
273+
this.setCssClass(errorWidgetClass, warningWidgetClass);
273274
break;
274275
case Severity.Warning:
275276
case Severity.Info:
276-
this.options.frameColor = '#5aac5a';
277+
this.setCssClass(warningWidgetClass, errorWidgetClass);
277278
break;
278279
}
279280

src/vs/editor/contrib/referenceSearch/browser/referencesWidget.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
border-bottom-width: 1px;
1010
}
1111

12+
.monaco-editor .reference-zone-widget.zone-widget-arrow.below {
13+
background: transparent;
14+
}
15+
1216
.monaco-editor .zone-widget .zone-widget-container.reference-zone-widget.results-loaded {
1317
-webkit-transition: height 100ms ease-in;
1418
transition: height 100ms ease-in;

src/vs/editor/contrib/referenceSearch/browser/referencesWidget.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ export class ReferenceWidget extends PeekViewWidget {
505505
private _contextService: IWorkspaceContextService,
506506
private _instantiationService: IInstantiationService
507507
) {
508-
super(editor, { frameColor: '#007ACC', showFrame: false, showArrow: true, isResizeable: true });
508+
super(editor, { showFrame: false, showArrow: true, isResizeable: true });
509509

510510
this._instantiationService = this._instantiationService.createChild(new ServiceCollection([IPeekViewService, this]));
511511
this.create();
@@ -543,7 +543,7 @@ export class ReferenceWidget extends PeekViewWidget {
543543
protected _fillBody(containerElement: HTMLElement): void {
544544
var container = $(containerElement);
545545

546-
container.addClass('reference-zone-widget');
546+
this.setCssClass('reference-zone-widget');
547547

548548
// message pane
549549
container.div({ 'class': 'messages' }, div => {

src/vs/editor/contrib/zoneWidget/browser/peekViewWidget.css

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
.monaco-editor .peekview-widget .head {
77
background-color: #fff;
8-
border-top: 1px solid;
98
-webkit-box-sizing: border-box;
109
-o-box-sizing: border-box;
1110
-moz-box-sizing: border-box;
@@ -49,8 +48,8 @@
4948

5049
.monaco-editor .peekview-widget > .body {
5150
border-top: 1px solid;
52-
border-bottom: 1px solid;
5351
position: relative;
52+
border-color: rgb(0, 122, 204);
5453
}
5554

5655
/* Dark Theme */

src/vs/editor/contrib/zoneWidget/browser/peekViewWidget.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,11 @@ export abstract class PeekViewWidget extends ZoneWidget implements IPeekViewServ
7777

7878
public show(where: any, heightInLines: number): void {
7979
this._isActive = true;
80-
81-
this._headElement.style.borderTopColor = this.options.frameColor;
82-
this._bodyElement.style.borderTopColor = this.options.frameColor;
83-
this._bodyElement.style.borderBottomColor = this.options.frameColor;
84-
8580
super.show(where, heightInLines);
8681
}
8782

8883
protected _fillContainer(container: HTMLElement): void {
89-
$(container).addClass('peekview-widget');
84+
this.setCssClass('peekview-widget');
9085

9186
this._headElement = <HTMLDivElement>$('.head').getHTMLElement();
9287
this._bodyElement = <HTMLDivElement>$('.body').getHTMLElement();

src/vs/editor/contrib/zoneWidget/browser/zoneWidget.css

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@
1616
}
1717

1818
.monaco-editor .zone-widget-arrow.below {
19-
border-bottom-color: yellowGreen;
19+
border-bottom-color: rgb(0, 122, 204);
2020
}
2121

2222
.monaco-editor .zone-widget .zone-widget-container {
2323
border-top-style: solid;
2424
border-bottom-style: solid;
2525
border-top-width: 0;
2626
border-bottom-width: 0;
27-
border-top-color: yellowGreen;
28-
border-bottom-color: yellowGreen;
27+
border-top-color: rgb(0, 122, 204);
28+
border-bottom-color: rgb(0, 122, 204);
2929
position: relative;
3030
}

src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, IViewZone, IViewZo
1818
export interface IOptions {
1919
showFrame?: boolean;
2020
showArrow?: boolean;
21-
frameColor?: string;
2221
frameWidth?: number;
2322
className?: string;
2423
isAccessible?: boolean;
@@ -28,7 +27,6 @@ export interface IOptions {
2827
const defaultOptions: IOptions = {
2928
showArrow: true,
3029
showFrame: true,
31-
frameColor: '',
3230
className: ''
3331
};
3432

@@ -103,6 +101,7 @@ export abstract class ZoneWidget extends Widget implements IHorizontalSashLayout
103101
public domNode: HTMLElement;
104102
public editor: ICodeEditor;
105103
public options: IOptions;
104+
private arrow: HTMLElement = null;
106105

107106
constructor(editor: ICodeEditor, options: IOptions = {}) {
108107
super();
@@ -148,8 +147,12 @@ export abstract class ZoneWidget extends Widget implements IHorizontalSashLayout
148147
this.container = document.createElement('div');
149148
dom.addClass(this.container, 'zone-widget-container');
150149
this.domNode.appendChild(this.container);
151-
this._fillContainer(this.container);
150+
if (this.options.showArrow) {
151+
this.arrow = document.createElement('div');
152+
this.arrow.className = 'zone-widget-arrow below';
153+
}
152154

155+
this._fillContainer(this.container);
153156
this._initSash();
154157
}
155158

@@ -232,22 +235,17 @@ export abstract class ZoneWidget extends Widget implements IHorizontalSashLayout
232235

233236
// Render the widget as zone (rendering) and widget (lifecycle)
234237
let viewZoneDomNode = document.createElement('div'),
235-
arrow = document.createElement('div'),
236238
lineHeight = this.editor.getConfiguration().lineHeight,
237239
arrowHeight = 0, frameThickness = 0;
238240

239241
// Render the arrow one 1/3 of an editor line height
240242
if (this.options.showArrow) {
241243
arrowHeight = Math.round(lineHeight / 3);
244+
this.arrow.style.top = -arrowHeight + 'px';
245+
this.arrow.style.borderWidth = arrowHeight + 'px';
246+
this.arrow.style.left = this.editor.getOffsetForColumn(position.lineNumber, position.column) + 'px';
242247

243-
arrow = document.createElement('div');
244-
arrow.className = 'zone-widget-arrow below';
245-
arrow.style.top = -arrowHeight + 'px';
246-
arrow.style.borderWidth = arrowHeight + 'px';
247-
arrow.style.left = this.editor.getOffsetForColumn(position.lineNumber, position.column) + 'px';
248-
arrow.style.borderBottomColor = this.options.frameColor;
249-
250-
viewZoneDomNode.appendChild(arrow);
248+
viewZoneDomNode.appendChild(this.arrow);
251249
}
252250

253251
// Render the frame as 1/9 of an editor line height
@@ -281,8 +279,6 @@ export abstract class ZoneWidget extends Widget implements IHorizontalSashLayout
281279

282280
if (this.options.showFrame) {
283281
const width = this.options.frameWidth ? this.options.frameWidth : frameThickness;
284-
this.container.style.borderTopColor = this.options.frameColor;
285-
this.container.style.borderBottomColor = this.options.frameColor;
286282
this.container.style.borderTopWidth = width + 'px';
287283
this.container.style.borderBottomWidth = width + 'px';
288284
}
@@ -302,6 +298,20 @@ export abstract class ZoneWidget extends Widget implements IHorizontalSashLayout
302298
this.editor.revealLine(revealLineNumber);
303299
}
304300

301+
protected setCssClass(className: string, classToReplace?: string): void {
302+
if (classToReplace) {
303+
this.container.classList.remove(classToReplace);
304+
if (this.arrow) {
305+
this.arrow.classList.remove(classToReplace);
306+
}
307+
}
308+
309+
this.container.classList.add(className);
310+
if (this.arrow) {
311+
this.arrow.classList.add(className);
312+
}
313+
}
314+
305315
protected abstract _fillContainer(container: HTMLElement): void;
306316

307317
protected _onWidth(widthInPixel: number): void {

src/vs/workbench/parts/debug/browser/breakpointWidget.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export class BreakpointWidget extends ZoneWidget {
3737
@IContextViewService private contextViewService: IContextViewService,
3838
@IDebugService private debugService: IDebugService
3939
) {
40-
super(editor, { showFrame: true, showArrow: false, frameColor: '#007ACC', frameWidth: 1 });
40+
super(editor, { showFrame: true, showArrow: false, frameWidth: 1 });
4141

4242
this.toDispose = [];
4343
this.hitCountInput = '';
@@ -62,7 +62,7 @@ export class BreakpointWidget extends ZoneWidget {
6262
}
6363

6464
protected _fillContainer(container: HTMLElement): void {
65-
dom.addClass(container, 'breakpoint-widget monaco-editor-background');
65+
this.setCssClass('breakpoint-widget');
6666
const uri = this.editor.getModel().uri;
6767
const breakpoint = this.debugService.getModel().getBreakpoints().filter(bp => bp.lineNumber === this.lineNumber && bp.uri.toString() === uri.toString()).pop();
6868

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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+
import 'vs/css!../browser/media/exceptionWidget';
7+
import * as nls from 'vs/nls';
8+
import * as dom from 'vs/base/browser/dom';
9+
import { ZoneWidget } from 'vs/editor/contrib/zoneWidget/browser/zoneWidget';
10+
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
11+
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
12+
import { IDebugService } from 'vs/workbench/parts/debug/common/debug';
13+
const $ = dom.$;
14+
15+
export class ExceptionWidget extends ZoneWidget {
16+
17+
constructor(editor: ICodeEditor, private lineNumber: number,
18+
@IContextViewService private contextViewService: IContextViewService,
19+
@IDebugService private debugService: IDebugService
20+
) {
21+
super(editor, { showFrame: true, showArrow: true, frameWidth: 1 });
22+
23+
this.create();
24+
}
25+
26+
protected _fillContainer(container: HTMLElement): void {
27+
this.setCssClass('exception-widget');
28+
29+
let title = $('.title');
30+
title.textContent = nls.localize('exceptionThrown', 'Exception occured.');
31+
dom.append(container, title);
32+
33+
const thread = this.debugService.getViewModel().focusedThread;
34+
if (thread && thread.stoppedDetails) {
35+
let msg = $('.message');
36+
msg.textContent = thread.stoppedDetails.text;
37+
dom.append(container, msg);
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)