Skip to content

Commit 67d318e

Browse files
authoredJul 5, 2023
fix: bug in guttertooltip when tooltipsFollowsMouse set to false (#5217)
Fixes a bug where an error is thrown when hovering over the gutter with tooltipsFollowsMouse == true and scrolled. Additionally, adds tooltipsFollowsMouse to kitchen-sink to make it easier to test this option.
1 parent a6c8bf3 commit 67d318e

File tree

4 files changed

+54
-5
lines changed

4 files changed

+54
-5
lines changed
 

‎src/ext/options.js

+4
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ var optionGroups = {
203203
},
204204
"Keyboard Accessibility Mode": {
205205
path: "enableKeyboardAccessibility"
206+
},
207+
"Gutter tooltip follows mouse": {
208+
path: "tooltipFollowsMouse",
209+
defaultValue: true
206210
}
207211
}
208212
};

‎src/mouse/default_gutter_handler.js

+11-5
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,17 @@ function GutterHandler(mouseHandler) {
5757
if (mouseHandler.$tooltipFollowsMouse) {
5858
moveTooltip(mouseEvent);
5959
} else {
60-
var gutterElement = gutter.$lines.cells[row].element.querySelector("[class*=ace_icon]");
61-
var rect = gutterElement.getBoundingClientRect();
62-
var style = tooltip.getElement().style;
63-
style.left = rect.right + "px";
64-
style.top = rect.bottom + "px";
60+
var gutterRow = mouseEvent.getGutterRow();
61+
var gutterCell = gutter.$lines.get(gutterRow);
62+
if (gutterCell) {
63+
var gutterElement = gutterCell.element.querySelector(".ace_gutter_annotation");
64+
var rect = gutterElement.getBoundingClientRect();
65+
var style = tooltip.getElement().style;
66+
style.left = rect.right + "px";
67+
style.top = rect.bottom + "px";
68+
} else {
69+
moveTooltip(mouseEvent);
70+
}
6571
}
6672
}
6773

‎src/mouse/default_gutter_handler_test.js

+27
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,33 @@ module.exports = {
217217
// Annotation node should NOT have fold class.
218218
var annotation = lines.cells[0].element.children[2];
219219
assert.notOk(/fold/.test(annotation.className));
220+
},"test: sets position correctly when tooltipFollowsMouse false" : function(done) {
221+
var editor = this.editor;
222+
var value = "";
223+
224+
editor.session.setMode(new Mode());
225+
editor.setValue(value, -1);
226+
editor.session.setAnnotations([{row: 0, column: 0, text: "error test", type: "error"}]);
227+
editor.setOption("tooltipFollowsMouse", false);
228+
editor.setOption("useSvgGutterIcons", true);
229+
editor.renderer.$loop._flush();
230+
231+
var lines = editor.renderer.$gutterLayer.$lines;
232+
var annotation = lines.cells[0].element.childNodes[2].firstChild;
233+
assert.ok(/ace_error/.test(annotation.className));
234+
235+
var rect = annotation.getBoundingClientRect();
236+
annotation.dispatchEvent(new MouseEvent("move", {x: rect.left, y: rect.top}));
237+
238+
// Wait for the tooltip to appear after its timeout.
239+
setTimeout(function() {
240+
editor.renderer.$loop._flush();
241+
var tooltip = editor.container.querySelector(".ace_tooltip");
242+
assert.ok(/error test/.test(tooltip.textContent));
243+
assert.equal(tooltip.style.left, `${rect.right}px`);
244+
assert.equal(tooltip.style.top, `${rect.bottom}px`);
245+
done();
246+
}, 100);
220247
},
221248

222249
tearDown : function() {

‎src/mouse/mouse_event.js

+12
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ class MouseEvent {
4848
this.$pos = this.editor.renderer.screenToTextCoordinates(this.clientX, this.clientY);
4949
return this.$pos;
5050
}
51+
52+
/**
53+
* Get the relative position within the gutter.
54+
*
55+
* @return {Number} 'row' within the gutter.
56+
*/
57+
getGutterRow() {
58+
var documentRow = this.getDocumentPosition().row;
59+
var screenRow = this.editor.session.documentToScreenRow(documentRow, 0);
60+
var screenTopRow = this.editor.session.documentToScreenRow(this.editor.renderer.$gutterLayer.$lines.get(0).row, 0);
61+
return screenRow - screenTopRow;
62+
}
5163

5264
/**
5365
* Check if the mouse cursor is inside of the text selection

0 commit comments

Comments
 (0)
Please sign in to comment.