Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: summary of annotations in folded lines #5117

Merged
merged 28 commits into from
Apr 21, 2023
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
67e7fcc
fix: gutter tooltip anchoring
akoreman Apr 6, 2023
8109ed8
add semicolon
akoreman Apr 6, 2023
89841a5
Change anchor point to be on icon
akoreman Apr 6, 2023
33facc4
set tooltipFollowsMouse back to true by default
akoreman Apr 6, 2023
9acd13c
small css change
akoreman Apr 6, 2023
598ca4a
whitespace fix
akoreman Apr 6, 2023
68bb9d7
Merge branch 'ajaxorg:master' into gutter_tooltip_fix
akoreman Apr 8, 2023
3190131
Refactoring
akoreman Apr 10, 2023
e59b8d8
Merge branch 'ajaxorg:master' into gutter_tooltip_fix
akoreman Apr 12, 2023
a579507
Merge branch 'ajaxorg:master' into gutter_tooltip_fix
akoreman Apr 13, 2023
fafb66d
Merge branch 'ajaxorg:master' into gutter_tooltip_fix
akoreman Apr 14, 2023
b308c0a
add summary of annotations in folded code
akoreman Apr 14, 2023
27d6197
add SVG icons for lines with folded annotations
akoreman Apr 15, 2023
0153067
fix icon positioning
akoreman Apr 15, 2023
4e8a3c0
fix failing tests
akoreman Apr 15, 2023
4a4ca09
add test
akoreman Apr 16, 2023
78b2f81
tweak new tests
akoreman Apr 16, 2023
3a26660
add annotations in fold as optional
akoreman Apr 16, 2023
448fd2c
add tooltip check to tests
akoreman Apr 18, 2023
095bf2b
refactor and cleanup
akoreman Apr 18, 2023
9dcf632
refactoring
akoreman Apr 19, 2023
6083beb
Change name kitchen-sink option
akoreman Apr 19, 2023
a4a2652
make svg viewbox size consistent
akoreman Apr 20, 2023
15bd2d0
test tweak
akoreman Apr 20, 2023
39fb5f4
Merge branch 'ajaxorg:master' into gutter_tooltip_fix
akoreman Apr 20, 2023
0c0727b
change array copy to use Array.from
akoreman Apr 20, 2023
99f9d36
test fix
akoreman Apr 20, 2023
3b180cb
tweak
akoreman Apr 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ace.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ export namespace Ace {
hasCssTransforms: boolean;
maxPixelHeight: number;
useSvgGutterIcons: boolean;
showFoldedAnnotations: boolean;
}

export interface MouseHandlerOptions {
Expand Down
33 changes: 20 additions & 13 deletions src/css/editor.css.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ module.exports = `
pointer-events: none;
}

.ace_gutter-cell, .ace_gutter-cell_svg-icons {
.ace_gutter-cell, .ace_gutter-cell_svg-icons {
position: absolute;
top: 0;
left: 0;
Expand All @@ -120,18 +120,23 @@ module.exports = `
background-repeat: no-repeat;
}

.ace_gutter-cell_svg-icons .ace_icon_svg{
.ace_gutter-cell_svg-icons .ace_icon_svg {
margin-left: -14px;
float: left;
}

.ace_gutter-cell.ace_error, .ace_icon.ace_error {
.ace_gutter-cell .ace_icon {
margin-left: -18px;
float: left;
}

.ace_gutter-cell.ace_error, .ace_icon.ace_error, .ace_icon.ace_error_fold {
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;
background-position: 2px center;
}

.ace_gutter-cell.ace_warning, .ace_icon.ace_warning {
.ace_gutter-cell.ace_warning, .ace_icon.ace_warning, .ace_icon.ace_warning_fold {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==");
background-repeat: no-repeat;
background-position: 2px center;
Expand Down Expand Up @@ -159,6 +164,15 @@ module.exports = `
background-color: royalblue;
}

.ace_icon_svg.ace_error_fold {
-webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAxNiIgZmlsbD0ibm9uZSI+CiAgPHBhdGggZD0ibSAxOC45Mjk4NTEsNy44Mjk4MDc2IGMgMC4xNDYzNTMsNi4zMzc0NjA0IC02LjMyMzE0Nyw3Ljc3Nzg0NDQgLTcuNDc3OTEyLDcuNzc3ODQ0NCAtMi4xMDcyNzI2LC0wLjEyODc1IDUuMTE3Njc4LDAuMzU2MjQ5IDUuMDUxNjk4LC03Ljg3MDA2MTggLTAuNjA0NjcyLC04LjAwMzk3MzQ5IC03LjA3NzI3MDYsLTcuNTYzMTE4OSAtNC44NTczLC03LjQzMDM5NTU2IDEuNjA2LC0wLjExNTE0MjI1IDYuODk3NDg1LDEuMjYyNTQ1OTYgNy4yODM1MTQsNy41MjI2MTI5NiB6IiBmaWxsPSJjcmltc29uIiBzdHJva2Utd2lkdGg9IjIiLz4KICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0ibSA4LjExNDc1NjIsMi4wNTI5ODI4IGMgMy4zNDkxNjk4LDAgNi4wNjQxMzI4LDIuNjc2ODYyNyA2LjA2NDEzMjgsNS45Nzg5NTMgMCwzLjMwMjExMjIgLTIuNzE0OTYzLDUuOTc4OTIwMiAtNi4wNjQxMzI4LDUuOTc4OTIwMiAtMy4zNDkxNDczLDAgLTYuMDY0MTc3MiwtMi42NzY4MDggLTYuMDY0MTc3MiwtNS45Nzg5MjAyIDAuMDA1MzksLTMuMjk5ODg2MSAyLjcxNzI2NTYsLTUuOTczNjQwOCA2LjA2NDE3NzIsLTUuOTc4OTUzIHogbSAwLC0xLjczNTgyNzE5IGMgLTQuMzIxNDgzNiwwIC03LjgyNDc0MDM4LDMuNDU0MDE4NDkgLTcuODI0NzQwMzgsNy43MTQ3ODAxOSAwLDQuMjYwNzI4MiAzLjUwMzI1Njc4LDcuNzE0NzQ1MiA3LjgyNDc0MDM4LDcuNzE0NzQ1MiA0LjMyMTQ0OTgsMCA3LjgyNDY5OTgsLTMuNDU0MDE3IDcuODI0Njk5OCwtNy43MTQ3NDUyIDAsLTIuMDQ2MDkxNCAtMC44MjQzOTIsLTQuMDA4MzY3MiAtMi4yOTE3NTYsLTUuNDU1MTc0NiBDIDEyLjE4MDIyNSwxLjEyOTk2NDggMTAuMTkwMDEzLDAuMzE3MTU1NjEgOC4xMTQ3NTYyLDAuMzE3MTU1NjEgWiBNIDYuOTM3NDU2Myw4LjI0MDU5ODUgNC42NzE4Njg1LDEwLjQ4NTg1MiA2LjAwODY4MTQsMTEuODc2NzI4IDguMzE3MDAzNSw5LjYwMDc5MTEgMTAuNjI1MzM3LDExLjg3NjcyOCAxMS45NjIxMzgsMTAuNDg1ODUyIDkuNjk2NTUwOCw4LjI0MDU5ODUgMTEuOTYyMTM4LDYuMDA2ODA2NiAxMC41NzMyNDYsNC42Mzc0MzM1IDguMzE3MDAzNSw2Ljg3MzQyOTcgNi4wNjA3NjA3LDQuNjM3NDMzNSA0LjY3MTg2ODUsNi4wMDY4MDY2IFoiIGZpbGw9ImNyaW1zb24iIHN0cm9rZS13aWR0aD0iMiIvPgo8L3N2Zz4=");
background-color: crimson;
}
.ace_icon_svg.ace_warning_fold {
-webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAyMCAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNC43NzY5IDE0LjczMzdMOC42NTE5MiAyLjQ4MzY5QzguMzI5NDYgMS44Mzg3NyA3LjQwOTEzIDEuODM4NzcgNy4wODY2NyAyLjQ4MzY5TDAuOTYxNjY5IDE0LjczMzdDMC42NzA3NzUgMTUuMzE1NSAxLjA5MzgzIDE2IDEuNzQ0MjkgMTZIMTMuOTk0M0MxNC42NDQ4IDE2IDE1LjA2NzggMTUuMzE1NSAxNC43NzY5IDE0LjczMzdaTTMuMTYwMDcgMTQuMjVMNy44NjkyOSA0LjgzMTU2TDEyLjU3ODUgMTQuMjVIMy4xNjAwN1pNOC43NDQyOSAxMS42MjVWMTMuMzc1SDYuOTk0MjlWMTEuNjI1SDguNzQ0MjlaTTYuOTk0MjkgMTAuNzVWNy4yNUg4Ljc0NDI5VjEwLjc1SDYuOTk0MjlaIiBmaWxsPSIjRUM3MjExIi8+CjxwYXRoIGQ9Ik0xMS4xOTkxIDIuOTUyMzhDMTAuODgwOSAyLjMxNDY3IDEwLjM1MzcgMS44MDUyNiA5LjcwNTUgMS41MDlMMTEuMDQxIDEuMDY5NzhDMTEuNjg4MyAwLjk0OTgxNCAxMi4zMzcgMS4yNzI2MyAxMi42MzE3IDEuODYxNDFMMTcuNjEzNiAxMS44MTYxQzE4LjM1MjcgMTMuMjkyOSAxNy41OTM4IDE1LjA4MDQgMTYuMDE4IDE1LjU3NDVDMTYuNDA0NCAxNC40NTA3IDE2LjMyMzEgMTMuMjE4OCAxNS43OTI0IDEyLjE1NTVMMTEuMTk5MSAyLjk1MjM4WiIgZmlsbD0iI0VDNzIxMSIvPgo8L3N2Zz4=");
background-color: darkorange;
}

.ace_scrollbar {
contain: strict;
position: absolute;
Expand Down Expand Up @@ -447,17 +461,10 @@ module.exports = `
outline: 1px solid black;
}

.ace_gutter-tooltip_header {
font-weight: bold;
}

.ace_gutter-tooltip_body {
padding-top: 5px;
}

.ace_gutter-tooltip .ace_icon {
.ace_icon {
display: inline-block;
width: 18px;
vertical-align: top;
}

.ace_icon_svg {
Expand Down
1 change: 1 addition & 0 deletions src/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -2932,6 +2932,7 @@ config.defineOptions(Editor.prototype, "editor", {
useTextareaForIME: "renderer",
useResizeObserver: "renderer",
useSvgGutterIcons: "renderer",
showFoldedAnnotations: "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 @@ -198,6 +198,9 @@ var optionGroups = {
"Use SVG gutter icons": {
path: "useSvgGutterIcons"
},
"Show annotations folded lines": {
InspiredGuy marked this conversation as resolved.
Show resolved Hide resolved
path: "showFoldedAnnotations"
},
"Keyboard Accessibility Mode": {
path: "enableKeyboardAccessibility"
}
Expand Down
70 changes: 48 additions & 22 deletions src/layer/gutter.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,25 +290,9 @@ class Gutter{

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");
}

var className = this.$useSvgGutterIcons ? "ace_gutter-cell_svg-icons " : "ace_gutter-cell ";
var iconClassName = this.$useSvgGutterIcons ? "ace_icon_svg" : "ace_icon";

if (this.$highlightGutterLine) {
if (row == this.$cursorRow || (fold && row < this.$cursorRow && row >= foldStart && this.$cursorRow <= fold.end.row)) {
className += "ace_gutter-active-line ";
Expand All @@ -324,7 +308,7 @@ class Gutter{
className += breakpoints[row];
if (decorations[row])
className += decorations[row];
if (this.$annotations[row])
if (this.$annotations[row] && row !== foldStart)
className += this.$annotations[row].className;
if (element.className != className)
element.className = className;
Expand All @@ -338,8 +322,29 @@ class Gutter{

if (c) {
var className = "ace_fold-widget ace_" + c;
if (c == "start" && row == foldStart && row < fold.end.row)
if (c == "start" && row == foldStart && row < fold.end.row){
className += " ace_closed";
var foldAnnotationClass;
var annotationInFold = false;

for (var i = row + 1; i <= fold.end.row; i++){
if (!this.$annotations[i])
continue;

if (this.$annotations[i].className === " ace_error"){
InspiredGuy marked this conversation as resolved.
Show resolved Hide resolved
annotationInFold = true;
foldAnnotationClass = " ace_error_fold";
break;
}
if (this.$annotations[i].className === " ace_warning"){
akoreman marked this conversation as resolved.
Show resolved Hide resolved
annotationInFold = true;
foldAnnotationClass = " ace_warning_fold";
continue;
}
}

element.className += foldAnnotationClass;
}
else
className += " ace_open";
if (foldWidget.className != className)
Expand All @@ -352,6 +357,28 @@ class Gutter{
dom.setStyle(foldWidget.style, "display", "none");
}
}

if (annotationInFold && this.$showFoldedAnnotations){
annotationNode.className = iconClassName;
annotationNode.className += foldAnnotationClass;

dom.setStyle(annotationNode.style, "height", lineHeight);
dom.setStyle(annotationNode.style, "display", "block");
}
else if (this.$annotations[row]){
annotationNode.className = iconClassName;

if (this.$useSvgGutterIcons)
annotationNode.className += this.$annotations[row].className;
else
element.classList.add(this.$annotations[row].className.replace(" ", ""));

dom.setStyle(annotationNode.style, "height", lineHeight);
dom.setStyle(annotationNode.style, "display", "block");
}
else {
dom.setStyle(annotationNode.style, "display", "none");
}

var text = (gutterRenderer
? gutterRenderer.getText(session, row)
Expand All @@ -372,7 +399,6 @@ class Gutter{
this.$highlightGutterLine = highlightGutterLine;
}


setShowLineNumbers(show) {
this.$renderer = !show && {
getWidth: function() {return 0;},
Expand Down
110 changes: 73 additions & 37 deletions src/mouse/default_gutter_handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,60 @@ function GutterHandler(mouseHandler) {
});


var tooltipTimeout, mouseEvent, tooltipAnnotation;
var tooltipTimeout, mouseEvent, tooltipContent;

var annotationLabels = {
error: {singular: "error", plural: "errors"},
warning: {singular: "warning", plural: "warnings"},
info: {singular: "information message", plural: "information messages"}
};

function showTooltip() {
var row = mouseEvent.getDocumentPosition().row;
var annotation = gutter.$annotations[row];
if (!annotation)
var annotationsInRow = gutter.$annotations[row];
var annotation;

if (annotationsInRow)
annotation = {text: [...annotationsInRow.text], type: [...annotationsInRow.type]};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's not use code constructs that cannot be efficiently compiled for old browsers, also why do we need to copy the array here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to add an element to the array used to construct the tooltip so I want to copy the array by value. Switched to a different implementation for that to not use spread.

else
annotation = {text: [], type: []};

// If the tooltip is for a row which has a closed fold, check whether there are
// annotations in the folded lines. If so, add a summary to the list of annotations.
var fold = gutter.session.getNextFoldLine(row);
InspiredGuy marked this conversation as resolved.
Show resolved Hide resolved
if (fold && gutter.$showFoldedAnnotations){
var annotationsInFold = {error: [], warning: [], info: []};
var mostSevereAnnotationInFoldType;

for (var i = row + 1; i <= fold.end.row; i++){
if (!gutter.$annotations[i])
continue;

for (var j = 0; j < gutter.$annotations[i].text.length; j++) {
var annotationType = gutter.$annotations[i].type[j];
annotationsInFold[annotationType].push(gutter.$annotations[i].text[j]);

if (annotationType === "error"){
mostSevereAnnotationInFoldType = "error_fold";
continue;
}

if (annotationType === "warning"){
mostSevereAnnotationInFoldType = "warning_fold";
continue;
}
}
}

if (mostSevereAnnotationInFoldType === "error_fold" || mostSevereAnnotationInFoldType === "warning_fold"){
var summaryFoldedAnnotations = `${annotationsToSummaryString(annotationsInFold)} in folded code.`;

annotation.text.push(summaryFoldedAnnotations);
annotation.type.push(mostSevereAnnotationInFoldType);
}
}

if (annotation.text.length === 0)
return hideTooltip();

var maxRow = editor.session.getLength();
Expand All @@ -51,39 +99,16 @@ function GutterHandler(mouseHandler) {
}

var annotationMessages = {error: [], warning: [], info: []};
var annotationLabels = {
error: {singular: "error", plural: "errors"},
warning: {singular: "warning", plural: "warnings"},
info: {singular: "information message", plural: "information messages"}
};

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

// Construct the body of the tooltip.
// Construct the contents of the tooltip.
for (var i = 0; i < annotation.text.length; 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 line = `<span class='ace_${annotation.type[i]} ${iconClassName}' aria-label='${annotationLabels[annotation.type[i].replace("_fold","")].singular}' role=img> </span> ${annotation.text[i]}`;
annotationMessages[annotation.type[i].replace("_fold","")].push(line);
}
var tooltipBody = "<div class='ace_gutter-tooltip_body'>";
tooltipBody += [].concat(annotationMessages.error, annotationMessages.warning, annotationMessages.info).join("<br>");
tooltipBody += '</div>';

// Construct the header of the tooltip.
var isMoreThanOneAnnotationType = false;
var tooltipHeader = "<div class='ace_gutter-tooltip_header'>";
for (var i = 0; i < 3; i++){
var annotationType = ['error', 'warning', 'info'][i];
if (annotationMessages[annotationType].length > 0){
var label = annotationMessages[annotationType].length === 1 ? annotationLabels[annotationType].singular : annotationLabels[annotationType].plural;
tooltipHeader += `${isMoreThanOneAnnotationType ? ', ' : ''}${annotationMessages[annotationType].length} ${label}`;
isMoreThanOneAnnotationType = true;
}
}
tooltipHeader += "</div>";

tooltipAnnotation = tooltipHeader + tooltipBody;

tooltip.setHtml(tooltipAnnotation);
tooltipContent = [].concat(annotationMessages.error, annotationMessages.warning, annotationMessages.info).join("<br>");

tooltip.setHtml(tooltipContent);
tooltip.setClassName("ace_gutter-tooltip");
tooltip.$element.setAttribute("aria-live", "polite");

Expand All @@ -94,7 +119,7 @@ function GutterHandler(mouseHandler) {
if (mouseHandler.$tooltipFollowsMouse) {
moveTooltip(mouseEvent);
} else {
var gutterElement = mouseEvent.domEvent.target;
var gutterElement = gutter.$lines.cells[row].element.querySelector("[class*=ace_icon]");
var rect = gutterElement.getBoundingClientRect();
var style = tooltip.getElement().style;
style.left = rect.right + "px";
Expand All @@ -105,14 +130,25 @@ function GutterHandler(mouseHandler) {
function hideTooltip() {
if (tooltipTimeout)
tooltipTimeout = clearTimeout(tooltipTimeout);
if (tooltipAnnotation) {
if (tooltipContent) {
tooltip.hide();
tooltipAnnotation = null;
tooltipContent = null;
editor._signal("hideGutterTooltip", tooltip);
editor.off("mousewheel", hideTooltip);
}
}

function annotationsToSummaryString(annotations) {
const summary = [];
const annotationTypes = ['error', 'warning', 'info'];
for (const annotationType of annotationTypes) {
if (!annotations[annotationType].length) continue;
const label = annotations[annotationType].length === 1 ? annotationLabels[annotationType].singular : annotationLabels[annotationType].plural;
summary.push(`${annotations[annotationType].length} ${label}`);
}
return summary.join(", ");
}

function moveTooltip(e) {
tooltip.setPosition(e.x, e.y);
}
Expand All @@ -122,7 +158,7 @@ function GutterHandler(mouseHandler) {
if (dom.hasCssClass(target, "ace_fold-widget"))
return hideTooltip();

if (tooltipAnnotation && mouseHandler.$tooltipFollowsMouse)
if (tooltipContent && mouseHandler.$tooltipFollowsMouse)
moveTooltip(e);

mouseEvent = e;
Expand All @@ -139,7 +175,7 @@ function GutterHandler(mouseHandler) {

event.addListener(editor.renderer.$gutter, "mouseout", function(e) {
mouseEvent = null;
if (!tooltipAnnotation || tooltipTimeout)
if (!tooltipContent || tooltipTimeout)
return;

tooltipTimeout = setTimeout(function() {
Expand Down
Loading