|
@@ -2,59 +2,62 @@
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
+import { createFastDomNode } from '../../../../base/browser/fastDomNode.js';
|
|
|
+import { ArrayQueue } from '../../../../base/common/arrays.js';
|
|
|
import './glyphMargin.css';
|
|
|
import { DynamicViewOverlay } from '../../view/dynamicViewOverlay.js';
|
|
|
+import { ViewPart } from '../../view/viewPart.js';
|
|
|
+import { Range } from '../../../common/core/range.js';
|
|
|
+/**
|
|
|
+ * Represents a decoration that should be shown along the lines from `startLineNumber` to `endLineNumber`.
|
|
|
+ * This can end up producing multiple `LineDecorationToRender`.
|
|
|
+ */
|
|
|
export class DecorationToRender {
|
|
|
- constructor(startLineNumber, endLineNumber, className, zIndex, decorationLane) {
|
|
|
+ constructor(startLineNumber, endLineNumber, className, zIndex) {
|
|
|
this._decorationToRenderBrand = undefined;
|
|
|
this.startLineNumber = +startLineNumber;
|
|
|
this.endLineNumber = +endLineNumber;
|
|
|
this.className = String(className);
|
|
|
this.zIndex = zIndex !== null && zIndex !== void 0 ? zIndex : 0;
|
|
|
- this.decorationLane = decorationLane !== null && decorationLane !== void 0 ? decorationLane : 1;
|
|
|
}
|
|
|
}
|
|
|
-export class RenderedDecoration {
|
|
|
+/**
|
|
|
+ * A decoration that should be shown along a line.
|
|
|
+ */
|
|
|
+export class LineDecorationToRender {
|
|
|
constructor(className, zIndex) {
|
|
|
this.className = className;
|
|
|
this.zIndex = zIndex;
|
|
|
}
|
|
|
}
|
|
|
-export class LineRenderedDecorations {
|
|
|
+/**
|
|
|
+ * Decorations to render on a visible line.
|
|
|
+ */
|
|
|
+export class VisibleLineDecorationsToRender {
|
|
|
constructor() {
|
|
|
- this.lanes = [];
|
|
|
+ this.decorations = [];
|
|
|
}
|
|
|
- add(lane, decoration) {
|
|
|
- while (lane >= this.lanes.length) {
|
|
|
- this.lanes.push([]);
|
|
|
- }
|
|
|
- this.lanes[lane].push(decoration);
|
|
|
- }
|
|
|
- getLaneDecorations(laneIndex) {
|
|
|
- if (laneIndex < this.lanes.length) {
|
|
|
- return this.lanes[laneIndex];
|
|
|
- }
|
|
|
- return [];
|
|
|
+ add(decoration) {
|
|
|
+ this.decorations.push(decoration);
|
|
|
}
|
|
|
- isEmpty() {
|
|
|
- for (const lane of this.lanes) {
|
|
|
- if (lane.length > 0) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
- return true;
|
|
|
+ getDecorations() {
|
|
|
+ return this.decorations;
|
|
|
}
|
|
|
}
|
|
|
export class DedupOverlay extends DynamicViewOverlay {
|
|
|
- _render(visibleStartLineNumber, visibleEndLineNumber, decorations, decorationLaneCount) {
|
|
|
+ /**
|
|
|
+ * Returns an array with an element for each visible line number.
|
|
|
+ */
|
|
|
+ _render(visibleStartLineNumber, visibleEndLineNumber, decorations) {
|
|
|
const output = [];
|
|
|
for (let lineNumber = visibleStartLineNumber; lineNumber <= visibleEndLineNumber; lineNumber++) {
|
|
|
const lineIndex = lineNumber - visibleStartLineNumber;
|
|
|
- output[lineIndex] = new LineRenderedDecorations();
|
|
|
+ output[lineIndex] = new VisibleLineDecorationsToRender();
|
|
|
}
|
|
|
if (decorations.length === 0) {
|
|
|
return output;
|
|
|
}
|
|
|
+ // Sort decorations by className, then by startLineNumber and then by endLineNumber
|
|
|
decorations.sort((a, b) => {
|
|
|
if (a.className === b.className) {
|
|
|
if (a.startLineNumber === b.startLineNumber) {
|
|
@@ -72,8 +75,8 @@ export class DedupOverlay extends DynamicViewOverlay {
|
|
|
const zIndex = d.zIndex;
|
|
|
let startLineIndex = Math.max(d.startLineNumber, visibleStartLineNumber) - visibleStartLineNumber;
|
|
|
const endLineIndex = Math.min(d.endLineNumber, visibleEndLineNumber) - visibleStartLineNumber;
|
|
|
- const lane = Math.min(d.decorationLane, decorationLaneCount);
|
|
|
if (prevClassName === className) {
|
|
|
+ // Here we avoid rendering the same className multiple times on the same line
|
|
|
startLineIndex = Math.max(prevEndLineIndex + 1, startLineIndex);
|
|
|
prevEndLineIndex = Math.max(prevEndLineIndex, endLineIndex);
|
|
|
}
|
|
@@ -82,35 +85,44 @@ export class DedupOverlay extends DynamicViewOverlay {
|
|
|
prevEndLineIndex = endLineIndex;
|
|
|
}
|
|
|
for (let i = startLineIndex; i <= prevEndLineIndex; i++) {
|
|
|
- output[i].add(lane, new RenderedDecoration(className, zIndex));
|
|
|
+ output[i].add(new LineDecorationToRender(className, zIndex));
|
|
|
}
|
|
|
}
|
|
|
return output;
|
|
|
}
|
|
|
}
|
|
|
-export class GlyphMarginOverlay extends DedupOverlay {
|
|
|
+export class GlyphMarginWidgets extends ViewPart {
|
|
|
constructor(context) {
|
|
|
- super();
|
|
|
+ super(context);
|
|
|
+ this._widgets = {};
|
|
|
this._context = context;
|
|
|
const options = this._context.configuration.options;
|
|
|
- const layoutInfo = options.get(140 /* EditorOption.layoutInfo */);
|
|
|
+ const layoutInfo = options.get(141 /* EditorOption.layoutInfo */);
|
|
|
+ this.domNode = createFastDomNode(document.createElement('div'));
|
|
|
+ this.domNode.setClassName('glyph-margin-widgets');
|
|
|
+ this.domNode.setPosition('absolute');
|
|
|
+ this.domNode.setTop(0);
|
|
|
this._lineHeight = options.get(64 /* EditorOption.lineHeight */);
|
|
|
this._glyphMargin = options.get(55 /* EditorOption.glyphMargin */);
|
|
|
this._glyphMarginLeft = layoutInfo.glyphMarginLeft;
|
|
|
this._glyphMarginWidth = layoutInfo.glyphMarginWidth;
|
|
|
this._glyphMarginDecorationLaneCount = layoutInfo.glyphMarginDecorationLaneCount;
|
|
|
- this._renderResult = null;
|
|
|
- this._context.addEventHandler(this);
|
|
|
+ this._managedDomNodes = [];
|
|
|
+ this._decorationGlyphsToRender = [];
|
|
|
}
|
|
|
dispose() {
|
|
|
- this._context.removeEventHandler(this);
|
|
|
- this._renderResult = null;
|
|
|
+ this._managedDomNodes = [];
|
|
|
+ this._decorationGlyphsToRender = [];
|
|
|
+ this._widgets = {};
|
|
|
super.dispose();
|
|
|
}
|
|
|
+ getWidgets() {
|
|
|
+ return Object.values(this._widgets);
|
|
|
+ }
|
|
|
// --- begin event handlers
|
|
|
onConfigurationChanged(e) {
|
|
|
const options = this._context.configuration.options;
|
|
|
- const layoutInfo = options.get(140 /* EditorOption.layoutInfo */);
|
|
|
+ const layoutInfo = options.get(141 /* EditorOption.layoutInfo */);
|
|
|
this._lineHeight = options.get(64 /* EditorOption.lineHeight */);
|
|
|
this._glyphMargin = options.get(55 /* EditorOption.glyphMargin */);
|
|
|
this._glyphMarginLeft = layoutInfo.glyphMarginLeft;
|
|
@@ -140,78 +152,241 @@ export class GlyphMarginOverlay extends DedupOverlay {
|
|
|
return true;
|
|
|
}
|
|
|
// --- end event handlers
|
|
|
- _getDecorations(ctx) {
|
|
|
+ // --- begin widget management
|
|
|
+ addWidget(widget) {
|
|
|
+ const domNode = createFastDomNode(widget.getDomNode());
|
|
|
+ this._widgets[widget.getId()] = {
|
|
|
+ widget: widget,
|
|
|
+ preference: widget.getPosition(),
|
|
|
+ domNode: domNode,
|
|
|
+ renderInfo: null
|
|
|
+ };
|
|
|
+ domNode.setPosition('absolute');
|
|
|
+ domNode.setDisplay('none');
|
|
|
+ domNode.setAttribute('widgetId', widget.getId());
|
|
|
+ this.domNode.appendChild(domNode);
|
|
|
+ this.setShouldRender();
|
|
|
+ }
|
|
|
+ setWidgetPosition(widget, preference) {
|
|
|
+ const myWidget = this._widgets[widget.getId()];
|
|
|
+ if (myWidget.preference.lane === preference.lane
|
|
|
+ && myWidget.preference.zIndex === preference.zIndex
|
|
|
+ && Range.equalsRange(myWidget.preference.range, preference.range)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ myWidget.preference = preference;
|
|
|
+ this.setShouldRender();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ removeWidget(widget) {
|
|
|
var _a;
|
|
|
+ const widgetId = widget.getId();
|
|
|
+ if (this._widgets[widgetId]) {
|
|
|
+ const widgetData = this._widgets[widgetId];
|
|
|
+ const domNode = widgetData.domNode.domNode;
|
|
|
+ delete this._widgets[widgetId];
|
|
|
+ (_a = domNode.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(domNode);
|
|
|
+ this.setShouldRender();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // --- end widget management
|
|
|
+ _collectDecorationBasedGlyphRenderRequest(ctx, requests) {
|
|
|
+ var _a, _b, _c;
|
|
|
+ const visibleStartLineNumber = ctx.visibleRange.startLineNumber;
|
|
|
+ const visibleEndLineNumber = ctx.visibleRange.endLineNumber;
|
|
|
const decorations = ctx.getDecorationsInViewport();
|
|
|
- const r = [];
|
|
|
- let rLen = 0;
|
|
|
- for (let i = 0, len = decorations.length; i < len; i++) {
|
|
|
- const d = decorations[i];
|
|
|
+ for (const d of decorations) {
|
|
|
const glyphMarginClassName = d.options.glyphMarginClassName;
|
|
|
- const zIndex = d.options.zIndex;
|
|
|
- const lane = (_a = d.options.glyphMargin) === null || _a === void 0 ? void 0 : _a.position;
|
|
|
- if (glyphMarginClassName) {
|
|
|
- r[rLen++] = new DecorationToRender(d.range.startLineNumber, d.range.endLineNumber, glyphMarginClassName, zIndex, lane);
|
|
|
+ if (!glyphMarginClassName) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ const startLineNumber = Math.max(d.range.startLineNumber, visibleStartLineNumber);
|
|
|
+ const endLineNumber = Math.min(d.range.endLineNumber, visibleEndLineNumber);
|
|
|
+ const lane = Math.min((_b = (_a = d.options.glyphMargin) === null || _a === void 0 ? void 0 : _a.position) !== null && _b !== void 0 ? _b : 1, this._glyphMarginDecorationLaneCount);
|
|
|
+ const zIndex = (_c = d.options.zIndex) !== null && _c !== void 0 ? _c : 0;
|
|
|
+ for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) {
|
|
|
+ requests.push(new DecorationBasedGlyphRenderRequest(lineNumber, lane, zIndex, glyphMarginClassName));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ _collectWidgetBasedGlyphRenderRequest(ctx, requests) {
|
|
|
+ const visibleStartLineNumber = ctx.visibleRange.startLineNumber;
|
|
|
+ const visibleEndLineNumber = ctx.visibleRange.endLineNumber;
|
|
|
+ for (const widget of Object.values(this._widgets)) {
|
|
|
+ const range = widget.preference.range;
|
|
|
+ if (range.endLineNumber < visibleStartLineNumber || range.startLineNumber > visibleEndLineNumber) {
|
|
|
+ // The widget is not in the viewport
|
|
|
+ continue;
|
|
|
}
|
|
|
+ // The widget is in the viewport, find a good line for it
|
|
|
+ const widgetLineNumber = Math.max(range.startLineNumber, visibleStartLineNumber);
|
|
|
+ const lane = Math.min(widget.preference.lane, this._glyphMarginDecorationLaneCount);
|
|
|
+ requests.push(new WidgetBasedGlyphRenderRequest(widgetLineNumber, lane, widget.preference.zIndex, widget));
|
|
|
}
|
|
|
- return r;
|
|
|
}
|
|
|
+ _collectSortedGlyphRenderRequests(ctx) {
|
|
|
+ const requests = [];
|
|
|
+ this._collectDecorationBasedGlyphRenderRequest(ctx, requests);
|
|
|
+ this._collectWidgetBasedGlyphRenderRequest(ctx, requests);
|
|
|
+ // sort requests by lineNumber ASC, lane ASC, zIndex DESC, type DESC (widgets first), className ASC
|
|
|
+ // don't change this sort unless you understand `prepareRender` below.
|
|
|
+ requests.sort((a, b) => {
|
|
|
+ if (a.lineNumber === b.lineNumber) {
|
|
|
+ if (a.lane === b.lane) {
|
|
|
+ if (a.zIndex === b.zIndex) {
|
|
|
+ if (b.type === a.type) {
|
|
|
+ if (a.type === 0 /* GlyphRenderRequestType.Decoration */ && b.type === 0 /* GlyphRenderRequestType.Decoration */) {
|
|
|
+ return (a.className < b.className ? -1 : 1);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return b.type - a.type;
|
|
|
+ }
|
|
|
+ return b.zIndex - a.zIndex;
|
|
|
+ }
|
|
|
+ return a.lane - b.lane;
|
|
|
+ }
|
|
|
+ return a.lineNumber - b.lineNumber;
|
|
|
+ });
|
|
|
+ return requests;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * Will store render information in each widget's renderInfo and in `_decorationGlyphsToRender`.
|
|
|
+ */
|
|
|
prepareRender(ctx) {
|
|
|
if (!this._glyphMargin) {
|
|
|
- this._renderResult = null;
|
|
|
+ this._decorationGlyphsToRender = [];
|
|
|
return;
|
|
|
}
|
|
|
- const visibleStartLineNumber = ctx.visibleRange.startLineNumber;
|
|
|
- const visibleEndLineNumber = ctx.visibleRange.endLineNumber;
|
|
|
- const decorationsToRender = this._getDecorations(ctx);
|
|
|
- const toRender = this._render(visibleStartLineNumber, visibleEndLineNumber, decorationsToRender, this._glyphMarginDecorationLaneCount);
|
|
|
- const lineHeight = this._lineHeight.toString();
|
|
|
- const width = (Math.round(this._glyphMarginWidth / this._glyphMarginDecorationLaneCount)).toString();
|
|
|
- const common = '" style="width:' + width + 'px' + ';height:' + lineHeight + 'px;';
|
|
|
- const output = [];
|
|
|
- for (let lineNumber = visibleStartLineNumber; lineNumber <= visibleEndLineNumber; lineNumber++) {
|
|
|
- const lineIndex = lineNumber - visibleStartLineNumber;
|
|
|
- const renderInfo = toRender[lineIndex];
|
|
|
- if (renderInfo.isEmpty()) {
|
|
|
- output[lineIndex] = '';
|
|
|
+ for (const widget of Object.values(this._widgets)) {
|
|
|
+ widget.renderInfo = null;
|
|
|
+ }
|
|
|
+ const requests = new ArrayQueue(this._collectSortedGlyphRenderRequests(ctx));
|
|
|
+ const decorationGlyphsToRender = [];
|
|
|
+ while (requests.length > 0) {
|
|
|
+ const first = requests.peek();
|
|
|
+ if (!first) {
|
|
|
+ // not possible
|
|
|
+ break;
|
|
|
}
|
|
|
- else {
|
|
|
- let css = '';
|
|
|
- for (let lane = 1; lane <= this._glyphMarginDecorationLaneCount; lane += 1) {
|
|
|
- const decorations = renderInfo.getLaneDecorations(lane);
|
|
|
- if (decorations.length === 0) {
|
|
|
- continue;
|
|
|
+ // Requests are sorted by lineNumber and lane, so we read all requests for this particular location
|
|
|
+ const requestsAtLocation = requests.takeWhile((el) => el.lineNumber === first.lineNumber && el.lane === first.lane);
|
|
|
+ if (!requestsAtLocation || requestsAtLocation.length === 0) {
|
|
|
+ // not possible
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ const winner = requestsAtLocation[0];
|
|
|
+ if (winner.type === 0 /* GlyphRenderRequestType.Decoration */) {
|
|
|
+ // combine all decorations with the same z-index
|
|
|
+ const classNames = [];
|
|
|
+ // requests are sorted by zIndex, type, and className so we can dedup className by looking at the previous one
|
|
|
+ for (const request of requestsAtLocation) {
|
|
|
+ if (request.zIndex !== winner.zIndex || request.type !== winner.type) {
|
|
|
+ break;
|
|
|
}
|
|
|
- decorations.sort((a, b) => b.zIndex - a.zIndex);
|
|
|
- // Render winning decorations with the same zIndex together
|
|
|
- const winningDecoration = decorations[0];
|
|
|
- const winningDecorationClassNames = [winningDecoration.className];
|
|
|
- for (let i = 1; i < decorations.length; i += 1) {
|
|
|
- const decoration = decorations[i];
|
|
|
- if (decoration.zIndex !== winningDecoration.zIndex) {
|
|
|
- break;
|
|
|
- }
|
|
|
- winningDecorationClassNames.push(decoration.className);
|
|
|
+ if (classNames.length === 0 || classNames[classNames.length - 1] !== request.className) {
|
|
|
+ classNames.push(request.className);
|
|
|
}
|
|
|
- const left = (this._glyphMarginLeft + (lane - 1) * this._lineHeight).toString();
|
|
|
- css += ('<div class="cgmr codicon '
|
|
|
- + winningDecorationClassNames.join(' ') // TODO@joyceerhl Implement overflow for remaining decorations
|
|
|
- + common
|
|
|
- + 'left:' + left + 'px;"></div>');
|
|
|
}
|
|
|
- output[lineIndex] = css;
|
|
|
+ decorationGlyphsToRender.push(winner.accept(classNames.join(' '))); // TODO@joyceerhl Implement overflow for remaining decorations
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // widgets cannot be combined
|
|
|
+ winner.widget.renderInfo = {
|
|
|
+ lineNumber: winner.lineNumber,
|
|
|
+ lane: winner.lane,
|
|
|
+ };
|
|
|
}
|
|
|
}
|
|
|
- this._renderResult = output;
|
|
|
+ this._decorationGlyphsToRender = decorationGlyphsToRender;
|
|
|
}
|
|
|
- render(startLineNumber, lineNumber) {
|
|
|
- if (!this._renderResult) {
|
|
|
- return '';
|
|
|
+ render(ctx) {
|
|
|
+ if (!this._glyphMargin) {
|
|
|
+ for (const widget of Object.values(this._widgets)) {
|
|
|
+ widget.domNode.setDisplay('none');
|
|
|
+ }
|
|
|
+ while (this._managedDomNodes.length > 0) {
|
|
|
+ const domNode = this._managedDomNodes.pop();
|
|
|
+ domNode === null || domNode === void 0 ? void 0 : domNode.domNode.remove();
|
|
|
+ }
|
|
|
+ return;
|
|
|
}
|
|
|
- const lineIndex = lineNumber - startLineNumber;
|
|
|
- if (lineIndex < 0 || lineIndex >= this._renderResult.length) {
|
|
|
- return '';
|
|
|
+ const width = (Math.round(this._glyphMarginWidth / this._glyphMarginDecorationLaneCount));
|
|
|
+ // Render widgets
|
|
|
+ for (const widget of Object.values(this._widgets)) {
|
|
|
+ if (!widget.renderInfo) {
|
|
|
+ // this widget is not visible
|
|
|
+ widget.domNode.setDisplay('none');
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ const top = ctx.viewportData.relativeVerticalOffset[widget.renderInfo.lineNumber - ctx.viewportData.startLineNumber];
|
|
|
+ const left = this._glyphMarginLeft + (widget.renderInfo.lane - 1) * this._lineHeight;
|
|
|
+ widget.domNode.setDisplay('block');
|
|
|
+ widget.domNode.setTop(top);
|
|
|
+ widget.domNode.setLeft(left);
|
|
|
+ widget.domNode.setWidth(width);
|
|
|
+ widget.domNode.setHeight(this._lineHeight);
|
|
|
+ }
|
|
|
}
|
|
|
- return this._renderResult[lineIndex];
|
|
|
+ // Render decorations, reusing previous dom nodes as possible
|
|
|
+ for (let i = 0; i < this._decorationGlyphsToRender.length; i++) {
|
|
|
+ const dec = this._decorationGlyphsToRender[i];
|
|
|
+ const top = ctx.viewportData.relativeVerticalOffset[dec.lineNumber - ctx.viewportData.startLineNumber];
|
|
|
+ const left = this._glyphMarginLeft + (dec.lane - 1) * this._lineHeight;
|
|
|
+ let domNode;
|
|
|
+ if (i < this._managedDomNodes.length) {
|
|
|
+ domNode = this._managedDomNodes[i];
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ domNode = createFastDomNode(document.createElement('div'));
|
|
|
+ this._managedDomNodes.push(domNode);
|
|
|
+ this.domNode.appendChild(domNode);
|
|
|
+ }
|
|
|
+ domNode.setClassName(`cgmr codicon ` + dec.combinedClassName);
|
|
|
+ domNode.setPosition(`absolute`);
|
|
|
+ domNode.setTop(top);
|
|
|
+ domNode.setLeft(left);
|
|
|
+ domNode.setWidth(width);
|
|
|
+ domNode.setHeight(this._lineHeight);
|
|
|
+ }
|
|
|
+ // remove extra dom nodes
|
|
|
+ while (this._managedDomNodes.length > this._decorationGlyphsToRender.length) {
|
|
|
+ const domNode = this._managedDomNodes.pop();
|
|
|
+ domNode === null || domNode === void 0 ? void 0 : domNode.domNode.remove();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+/**
|
|
|
+ * A request to render a decoration in the glyph margin at a certain location.
|
|
|
+ */
|
|
|
+class DecorationBasedGlyphRenderRequest {
|
|
|
+ constructor(lineNumber, lane, zIndex, className) {
|
|
|
+ this.lineNumber = lineNumber;
|
|
|
+ this.lane = lane;
|
|
|
+ this.zIndex = zIndex;
|
|
|
+ this.className = className;
|
|
|
+ this.type = 0 /* GlyphRenderRequestType.Decoration */;
|
|
|
+ }
|
|
|
+ accept(combinedClassName) {
|
|
|
+ return new DecorationBasedGlyph(this.lineNumber, this.lane, combinedClassName);
|
|
|
+ }
|
|
|
+}
|
|
|
+/**
|
|
|
+ * A request to render a widget in the glyph margin at a certain location.
|
|
|
+ */
|
|
|
+class WidgetBasedGlyphRenderRequest {
|
|
|
+ constructor(lineNumber, lane, zIndex, widget) {
|
|
|
+ this.lineNumber = lineNumber;
|
|
|
+ this.lane = lane;
|
|
|
+ this.zIndex = zIndex;
|
|
|
+ this.widget = widget;
|
|
|
+ this.type = 1 /* GlyphRenderRequestType.Widget */;
|
|
|
+ }
|
|
|
+}
|
|
|
+class DecorationBasedGlyph {
|
|
|
+ constructor(lineNumber, lane, combinedClassName) {
|
|
|
+ this.lineNumber = lineNumber;
|
|
|
+ this.lane = lane;
|
|
|
+ this.combinedClassName = combinedClassName;
|
|
|
}
|
|
|
}
|