Skip to content

Commit 9f7ce5a

Browse files
committed
Rewrite selection drawing again
To take document direction into account
1 parent 5fd2133 commit 9f7ce5a

1 file changed

Lines changed: 35 additions & 33 deletions

File tree

src/display/selection.js

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ function drawSelectionRange(cm, range, output) {
5454
let fragment = document.createDocumentFragment()
5555
let padding = paddingH(cm.display), leftSide = padding.left
5656
let rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right
57+
let docLTR = doc.direction == "ltr"
5758

5859
function add(left, top, width, bottom) {
5960
if (top < 0) top = 0
@@ -72,42 +73,43 @@ function drawSelectionRange(cm, range, output) {
7273
return charCoords(cm, Pos(line, ch), "div", lineObj, bias)
7374
}
7475

76+
function wrapX(pos, dir, side) {
77+
let extent = wrappedLineExtentChar(cm, lineObj, null, pos)
78+
let prop = (dir == "ltr") == (side == "after") ? "left" : "right"
79+
let ch = side == "after" ? extent.begin : extent.end - (/\s/.test(lineObj.text.charAt(extent.end - 1)) ? 2 : 1)
80+
return coords(ch, prop)[prop]
81+
}
82+
7583
let order = getOrder(lineObj, doc.direction)
7684
iterateBidiSections(order, fromArg || 0, toArg == null ? lineLen : toArg, (from, to, dir, i) => {
77-
let fromPos = coords(from, dir == "ltr" ? "left" : "right")
78-
let toPos = coords(to - 1, dir == "ltr" ? "right" : "left")
79-
if (dir == "ltr") {
80-
let fromLeft = fromArg == null && from == 0 ? leftSide : fromPos.left
81-
let toRight = toArg == null && to == lineLen ? rightSide : toPos.right
82-
if (toPos.top - fromPos.top <= 3) { // Single line
83-
add(fromLeft, toPos.top, toRight - fromLeft, toPos.bottom)
84-
} else { // Multiple lines
85-
add(fromLeft, fromPos.top, null, fromPos.bottom)
86-
if (fromPos.bottom < toPos.top) add(leftSide, fromPos.bottom, null, toPos.top)
87-
add(leftSide, toPos.top, toPos.right, toPos.bottom)
88-
}
89-
} else if (from < to) { // RTL
90-
let fromRight = fromArg == null && from == 0 ? rightSide : fromPos.right
91-
let toLeft = toArg == null && to == lineLen ? leftSide : toPos.left
92-
if (toPos.top - fromPos.top <= 3) { // Single line
93-
add(toLeft, toPos.top, fromRight - toLeft, toPos.bottom)
94-
} else { // Multiple lines
95-
let topLeft = leftSide
96-
if (i) {
97-
let topEnd = wrappedLineExtentChar(cm, lineObj, null, from).end
98-
// The coordinates returned for an RTL wrapped space tend to
99-
// be complete bogus, so try to skip that here.
100-
topLeft = coords(topEnd - (/\s/.test(lineObj.text.charAt(topEnd - 1)) ? 2 : 1), "left").left
101-
}
102-
add(topLeft, fromPos.top, fromRight - topLeft, fromPos.bottom)
103-
if (fromPos.bottom < toPos.top) add(leftSide, fromPos.bottom, null, toPos.top)
104-
let botWidth = null
105-
if (i < order.length - 1 || true) {
106-
let botStart = wrappedLineExtentChar(cm, lineObj, null, to).begin
107-
botWidth = coords(botStart, "right").right - toLeft
108-
}
109-
add(toLeft, toPos.top, botWidth, toPos.bottom)
85+
let ltr = dir == "ltr"
86+
let fromPos = coords(from, ltr ? "left" : "right")
87+
let toPos = coords(to - 1, ltr ? "right" : "left")
88+
89+
let openStart = fromArg == null && from == 0, openEnd = toArg == null && to == lineLen
90+
let first = i == 0, last = !order || i == order.length - 1
91+
if (toPos.top - fromPos.top <= 3) { // Single line
92+
let openLeft = (docLTR ? openStart : openEnd) && first
93+
let openRight = (docLTR ? openEnd : openStart) && last
94+
let left = openLeft ? leftSide : (ltr ? fromPos : toPos).left
95+
let right = openRight ? rightSide : (ltr ? toPos : fromPos).right
96+
add(left, fromPos.top, right - left, fromPos.bottom)
97+
} else { // Multiple lines
98+
let topLeft, topRight, botLeft, botRight
99+
if (ltr) {
100+
topLeft = docLTR && openStart && first ? leftSide : fromPos.left
101+
topRight = docLTR ? rightSide : wrapX(from, dir, "before")
102+
botLeft = docLTR ? leftSide : wrapX(to, dir, "after")
103+
botRight = docLTR && openEnd && last ? rightSide : toPos.right
104+
} else {
105+
topLeft = !docLTR ? leftSide : wrapX(from, dir, "before")
106+
topRight = !docLTR && openStart && first ? rightSide : fromPos.right
107+
botLeft = !docLTR && openEnd && last ? leftSide : toPos.left
108+
botRight = !docLTR ? rightSide : wrapX(to, dir, "after")
110109
}
110+
add(topLeft, fromPos.top, topRight - topLeft, fromPos.bottom)
111+
if (fromPos.bottom < toPos.top) add(leftSide, fromPos.bottom, null, toPos.top)
112+
add(botLeft, toPos.top, botRight - botLeft, toPos.bottom)
111113
}
112114

113115
if (!start || cmpCoords(fromPos, start) < 0) start = fromPos

0 commit comments

Comments
 (0)