From e60f4b7dd88b71e227f79200932c028ca047d78e Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke <marijn@haverbeke.nl> Date: Tue, 19 Jul 2016 13:26:35 +0200 Subject: [PATCH] Don't trust bounding client rects for characters In some cases, on wrapping points, they span the whole line Issue #4097 --- lib/codemirror.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/lib/codemirror.js b/lib/codemirror.js index d89b3b48..c78a6f22 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -2688,6 +2688,16 @@ return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd}; } + function getUsefulRect(rects, bias) { + var rect = nullRect + if (bias == "left") for (var i = 0; i < rects.length; i++) { + if ((rect = rects[i]).left != rect.right) break + } else for (var i = rects.length - 1; i >= 0; i--) { + if ((rect = rects[i]).left != rect.right) break + } + return rect + } + function measureCharInner(cm, prepared, ch, bias) { var place = nodeAndOffsetInLineMap(prepared.map, ch, bias); var node = place.node, start = place.start, end = place.end, collapse = place.collapse; @@ -2697,17 +2707,10 @@ for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) --start; while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) ++end; - if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) { + if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) rect = node.parentNode.getBoundingClientRect(); - } else if (ie && cm.options.lineWrapping) { - var rects = range(node, start, end).getClientRects(); - if (rects.length) - rect = rects[bias == "right" ? rects.length - 1 : 0]; - else - rect = nullRect; - } else { - rect = range(node, start, end).getBoundingClientRect() || nullRect; - } + else + rect = getUsefulRect(range(node, start, end).getClientRects(), bias) if (rect.left || rect.right || start == 0) break; end = start; start = start - 1; -- GitLab