Skip to content

Commit

Permalink
feat: Add option to use SVG gutter icons (#5107)
Browse files Browse the repository at this point in the history
* add option for using SVG icons

Adds an option (useSvgGutterIcons) to use SVG gutter icons (only annotation icons for now) to the VirtualRendererOptions.
  • Loading branch information
akoreman committed Apr 5, 2023
1 parent 10eab4f commit 82eb439
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 8 deletions.
6 changes: 5 additions & 1 deletion Makefile.dryice.js
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,11 @@ function extractCss(callback) {
}
var buffer = Buffer.from(data.slice(i + 1), "base64");
imageCounter++;
var imageName = name + "-" + imageCounter + ".png";
var imageName;
if (/^image\/svg\+xml/.test(data))
imageName = name + "-" + imageCounter + ".svg";
else
imageName = name + "-" + imageCounter + ".png";
images[imageName] = buffer;
console.log("url(\"" + directory + "/" + imageName + "\")");
return "url(\"" + directory + "/" + imageName + "\")";
Expand Down
1 change: 1 addition & 0 deletions ace.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ export namespace Ace {
theme: string;
hasCssTransforms: boolean;
maxPixelHeight: number;
useSvgGutterIcons: boolean;
}

export interface MouseHandlerOptions {
Expand Down
31 changes: 29 additions & 2 deletions src/css/editor.css.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ module.exports = `
pointer-events: none;
}
.ace_gutter-cell {
.ace_gutter-cell, .ace_gutter-cell_svg-icons {
position: absolute;
top: 0;
left: 0;
Expand All @@ -115,6 +115,11 @@ module.exports = `
background-repeat: no-repeat;
}
.ace_gutter-cell_svg-icons .ace_icon_svg{
margin-left: -14px;
float: left;
}
.ace_gutter-cell.ace_error, .ace_icon.ace_error {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==");
background-repeat: no-repeat;
Expand All @@ -136,6 +141,19 @@ module.exports = `
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC");
}
.ace_icon_svg.ace_error {
-webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiI+CjxnIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlPSJyZWQiIHNoYXBlLXJlbmRlcmluZz0iZ2VvbWV0cmljUHJlY2lzaW9uIj4KPGNpcmNsZSBmaWxsPSJub25lIiBjeD0iOCIgY3k9IjgiIHI9IjciIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPGxpbmUgeDE9IjExIiB5MT0iNSIgeDI9IjUiIHkyPSIxMSIvPgo8bGluZSB4MT0iMTEiIHkxPSIxMSIgeDI9IjUiIHkyPSI1Ii8+CjwvZz4KPC9zdmc+");
background-color: crimson;
}
.ace_icon_svg.ace_warning {
-webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiI+CjxnIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlPSJkYXJrb3JhbmdlIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+Cjxwb2x5Z29uIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGZpbGw9Im5vbmUiIHBvaW50cz0iOCAxIDE1IDE1IDEgMTUgOCAxIi8+CjxyZWN0IHg9IjgiIHk9IjEyIiB3aWR0aD0iMC4wMSIgaGVpZ2h0PSIwLjAxIi8+CjxsaW5lIHgxPSI4IiB5MT0iNiIgeDI9IjgiIHkyPSIxMCIvPgo8L2c+Cjwvc3ZnPg==");
background-color: darkorange;
}
.ace_icon_svg.ace_info {
-webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiI+CjxnIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlPSJibHVlIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+CjxjaXJjbGUgZmlsbD0ibm9uZSIgY3g9IjgiIGN5PSI4IiByPSI3IiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjxwb2x5bGluZSBwb2ludHM9IjggMTEgOCA4Ii8+Cjxwb2x5bGluZSBwb2ludHM9IjkgOCA2IDgiLz4KPGxpbmUgeDE9IjEwIiB5MT0iMTEiIHgyPSI2IiB5Mj0iMTEiLz4KPHJlY3QgeD0iOCIgeT0iNSIgd2lkdGg9IjAuMDEiIGhlaWdodD0iMC4wMSIvPgo8L2c+Cjwvc3ZnPg==");
background-color: royalblue;
}
.ace_scrollbar {
contain: strict;
position: absolute;
Expand Down Expand Up @@ -437,7 +455,16 @@ module.exports = `
width: 18px;
}
.ace_folding-enabled > .ace_gutter-cell {
.ace_icon_svg {
display: inline-block;
width: 12px;
vertical-align: top;
-webkit-mask-repeat: no-repeat;
-webkit-mask-size: 12px;
-webkit-mask-position: center;
}
.ace_folding-enabled > .ace_gutter-cell, .ace_folding-enabled > .ace_gutter-cell_svg-icons {
padding-right: 13px;
}
Expand Down
1 change: 1 addition & 0 deletions src/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -2883,6 +2883,7 @@ config.defineOptions(Editor.prototype, "editor", {
maxPixelHeight: "renderer",
useTextareaForIME: "renderer",
useResizeObserver: "renderer",
useSvgGutterIcons: "renderer",

scrollSpeed: "$mouseHandler",
dragDelay: "$mouseHandler",
Expand Down
3 changes: 3 additions & 0 deletions src/ext/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ var optionGroups = {
},
"Custom scrollbar": {
path: "customScrollbar"
},
"Use SVG gutter icons": {
path: "useSvgGutterIcons"
}
}
};
Expand Down
29 changes: 26 additions & 3 deletions src/layer/gutter.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ class Gutter{

var textNode = element.childNodes[0];
var foldWidget = element.childNodes[1];
var annotationNode = element.childNodes[2];

var firstLineNumber = session.$firstLineNumber;

Expand All @@ -287,7 +288,27 @@ class Gutter{
var foldWidgets = this.$showFoldWidgets && session.foldWidgets;
var foldStart = fold ? fold.start.row : Number.MAX_VALUE;

var className = "ace_gutter-cell ";
var lineHeight = config.lineHeight + "px";

var className;
if (this.$useSvgGutterIcons){
className = "ace_gutter-cell_svg-icons ";

if (this.$annotations[row]){
annotationNode.className = "ace_icon_svg" + this.$annotations[row].className;

dom.setStyle(annotationNode.style, "height", lineHeight);
dom.setStyle(annotationNode.style, "display", "block");
}
else {
dom.setStyle(annotationNode.style, "display", "none");
}
}
else {
className = "ace_gutter-cell ";
dom.setStyle(annotationNode.style, "display", "none");
}

if (this.$highlightGutterLine) {
if (row == this.$cursorRow || (fold && row < this.$cursorRow && row >= foldStart && this.$cursorRow <= fold.end.row)) {
className += "ace_gutter-active-line ";
Expand Down Expand Up @@ -324,8 +345,7 @@ class Gutter{
if (foldWidget.className != className)
foldWidget.className = className;

var foldHeight = config.lineHeight + "px";
dom.setStyle(foldWidget.style, "height", foldHeight);
dom.setStyle(foldWidget.style, "height", lineHeight);
dom.setStyle(foldWidget.style, "display", "inline-block");
} else {
if (foldWidget) {
Expand Down Expand Up @@ -415,6 +435,9 @@ function onCreateCell(element) {

var foldWidget = dom.createElement("span");
element.appendChild(foldWidget);

var annotationNode = dom.createElement("span");
element.appendChild(annotationNode);

return element;
}
Expand Down
4 changes: 3 additions & 1 deletion src/mouse/default_gutter_handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,11 @@ function GutterHandler(mouseHandler) {
info: {singular: "information message", plural: "information messages"}
};

var iconClassName = gutter.$useSvgGutterIcons ? "ace_icon_svg" : "ace_icon";

// Construct the body of the tooltip.
for (var i = 0; i < annotation.text.length; i++) {
var line = `<span class='ace_${annotation.type[i]} ace_icon' aria-label='${annotationLabels[annotation.type[i]].singular}' role=img> </span> ${annotation.text[i]}`;
var line = `<span class='ace_${annotation.type[i]} ${iconClassName}' aria-label='${annotationLabels[annotation.type[i]].singular}' role=img> </span> ${annotation.text[i]}`;
annotationMessages[annotation.type[i]].push(line);
}
var tooltipBody = "<div class='ace_gutter-tooltip_body'>";
Expand Down
18 changes: 18 additions & 0 deletions src/mouse/default_gutter_handler_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,24 @@ module.exports = {
assert.ok(/info test/.test(tooltipBody.textContent));
}, 100);
},
"test: gutter svg icons" : function() {
var editor = this.editor;
var value = "";

editor.session.setMode(new Mode());
editor.setOption("useSvgGutterIcons", true);
editor.setValue(value, -1);
editor.session.setAnnotations([{row: 0, column: 0, type: "error", text: "error test"}]);
editor.renderer.$loop._flush();

var lines = editor.renderer.$gutterLayer.$lines;
var line = lines.cells[0].element;
assert.ok(/ace_gutter-cell_svg-icons/.test(line.className));

var annotation = line.children[2];
assert.ok(/ace_icon_svg/.test(annotation.className));
},


tearDown : function() {
this.editor.destroy();
Expand Down
2 changes: 1 addition & 1 deletion src/mouse/mouse_handler_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ module.exports = {
editor.setValue(value, -1);
editor.renderer.$loop._flush();
var lines = editor.renderer.$gutterLayer.$lines;
var toggler = lines.cells[0].element.lastChild;
var toggler = lines.cells[0].element.children[1];
var rect = toggler.getBoundingClientRect();
if (!rect.left) rect.left = 100; // for mockdom
toggler.dispatchEvent(MouseEvent("down", {x: rect.left, y: rect.top}));
Expand Down
6 changes: 6 additions & 0 deletions src/virtual_renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,12 @@ config.defineOptions(VirtualRenderer.prototype, "renderer", {
},
initialValue: true
},
useSvgGutterIcons: {
set: function(value){
this.$gutterLayer.$useSvgGutterIcons = value;
},
initialValue: false
},
fadeFoldWidgets: {
set: function(show) {
dom.setCssClass(this.$gutter, "ace_fade-fold-widgets", show);
Expand Down

0 comments on commit 82eb439

Please sign in to comment.