Skip to content
Snippets Groups Projects
Commit 8f87175e authored by Pavel Strashkin's avatar Pavel Strashkin Committed by Marijn Haverbeke
Browse files

[show-hint addon] Fix event delegation for UL/LI

It's possible to provide custom markup for hint elements that are LI
tags and that breaks event delegation logic that expects UL to have
text-only LI nodes. As a result if you have elements inside LI and
click/dblclick on those, nothing happens and selected hint is not
applied. The fix improves event delegation in the way to find nearest
parent element to event target that is a hint element at the same time.
parent a98a0269
No related branches found
No related tags found
Loading
(function() {
"use strict";
var HINT_ELEMENT_CLASS = "CodeMirror-hint";
var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";
CodeMirror.showHint = function(cm, getHints, options) {
// We want a single cursor position.
if (cm.somethingSelected()) return;
......@@ -152,7 +155,7 @@
var completions = data.list;
for (var i = 0; i < completions.length; ++i) {
var elt = hints.appendChild(document.createElement("li")), cur = completions[i];
var className = "CodeMirror-hint" + (i ? "" : " CodeMirror-hint-active");
var className = HINT_ELEMENT_CLASS + (i ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
if (cur.className != null) className = cur.className + " " + className;
elt.className = className;
if (cur.render) cur.render(elt, data, cur);
......@@ -216,13 +219,15 @@
});
CodeMirror.on(hints, "dblclick", function(e) {
var t = e.target || e.srcElement;
if (t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
var t = widget.getHintElement(hints, e.target || e.srcElement);
if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
});
CodeMirror.on(hints, "click", function(e) {
var t = e.target || e.srcElement;
if (t.hintId != null) widget.changeActive(t.hintId);
var t = widget.getHintElement(hints, e.target || e.srcElement);
if (t && t.hintId != null) widget.changeActive(t.hintId);
});
CodeMirror.on(hints, "mousedown", function() {
setTimeout(function(){cm.focus();}, 20);
});
......@@ -257,9 +262,9 @@
i = avoidWrap ? 0 : this.data.list.length - 1;
if (this.selectedHint == i) return;
var node = this.hints.childNodes[this.selectedHint];
node.className = node.className.replace(" CodeMirror-hint-active", "");
node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
node = this.hints.childNodes[this.selectedHint = i];
node.className += " CodeMirror-hint-active";
node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
if (node.offsetTop < this.hints.scrollTop)
this.hints.scrollTop = node.offsetTop - 3;
else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
......@@ -269,6 +274,25 @@
screenAmount: function() {
return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
},
getHintElement: function (parentEl, el) {
while (el && el !== parentEl && !this.isHintElement(el)) {
el = el.parentNode;
}
return el === parentEl
? void(0)
: el
;
},
isHintElement: function (el) {
return el &&
el.nodeName &&
el.nodeName.toUpperCase() === 'LI' &&
el.className.indexOf(HINT_ELEMENT_CLASS) >= 0
;
}
};
})();
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment