Skip to content

Commit 3eaa89b

Browse files
committed
Make sure coordsChar doesn't return positions in collapsed spans
Closes #5392
1 parent a748038 commit 3eaa89b

File tree

3 files changed

+25
-7
lines changed

3 files changed

+25
-7
lines changed

src/line/spans.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,16 @@ function collapsedSpanAtSide(line, start) {
218218
export function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) }
219219
export function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) }
220220

221+
export function collapsedSpanAround(line, ch) {
222+
let sps = sawCollapsedSpans && line.markedSpans, found
223+
if (sps) for (let i = 0; i < sps.length; ++i) {
224+
let sp = sps[i]
225+
if (sp.marker.collapsed && (sp.from == null || sp.from < ch) && (sp.to == null || sp.to > ch) &&
226+
(!found || compareCollapsedMarkers(found, sp.marker) < 0)) found = sp.marker
227+
}
228+
return found
229+
}
230+
221231
// Test whether there exists a collapsed span that partially
222232
// overlaps (covers the start or end, but not both) of a new span.
223233
// Such overlap is not allowed.

src/measurement/position_measurement.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { buildLineContent, LineView } from "../line/line_data.js"
22
import { clipPos, Pos } from "../line/pos.js"
3-
import { collapsedSpanAtEnd, heightAtLine, lineIsHidden, visualLine } from "../line/spans.js"
3+
import { collapsedSpanAround, heightAtLine, lineIsHidden, visualLine } from "../line/spans.js"
44
import { getLine, lineAtHeight, lineNo, updateLineHeight } from "../line/utils_line.js"
55
import { bidiOther, getBidiPartAt, getOrder } from "../util/bidi.js"
66
import { chrome, android, ie, ie_version } from "../util/browser.js"
@@ -430,12 +430,11 @@ export function coordsChar(cm, x, y) {
430430
let lineObj = getLine(doc, lineN)
431431
for (;;) {
432432
let found = coordsCharInner(cm, lineObj, lineN, x, y)
433-
let merged = collapsedSpanAtEnd(lineObj)
434-
let mergedPos = merged && merged.find(0, true)
435-
if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
436-
lineN = lineNo(lineObj = mergedPos.to.line)
437-
else
438-
return found
433+
let collapsed = collapsedSpanAround(lineObj, found.ch + (found.xRel > 0 ? 1 : 0))
434+
if (!collapsed) return found
435+
let rangeEnd = collapsed.find(1)
436+
if (rangeEnd.line == lineN) return rangeEnd
437+
lineObj = getLine(doc, lineN = rangeEnd.line)
439438
}
440439
}
441440

test/test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,15 @@ testCM("hiddenLinesSelectAll", function(cm) { // Issue #484
889889
eqCursorPos(cm.getCursor(false), Pos(10, 4));
890890
});
891891

892+
testCM("clickFold", function(cm) { // Issue #5392
893+
cm.setValue("foo { bar }")
894+
var widget = document.createElement("span")
895+
widget.textContent = "<>"
896+
cm.markText(Pos(0, 5), Pos(0, 10), {replacedWith: widget})
897+
var after = cm.charCoords(Pos(0, 10))
898+
var foundOn = cm.coordsChar({left: after.left - 1, top: after.top + 4})
899+
is(foundOn.ch <= 5 || foundOn.ch >= 10, "Position is not inside the folded range")
900+
})
892901

893902
testCM("everythingFolded", function(cm) {
894903
addDoc(cm, 2, 2);

0 commit comments

Comments
 (0)