diff --git a/src/display/selection.js b/src/display/selection.js index d9b69d4921932f62fcecf3aaa1a4933cf18ca73e..32c9a611fe2228ecbdd847ffaaba023b380610d7 100644 --- a/src/display/selection.js +++ b/src/display/selection.js @@ -46,6 +46,8 @@ export function drawSelectionCursor(cm, head, output) { } } +function cmpCoords(a, b) { return a.top - b.top || a.left - b.left } + // Draws the given range as a highlighted selection function drawSelectionRange(cm, range, output) { let display = cm.display, doc = cm.doc @@ -71,29 +73,37 @@ function drawSelectionRange(cm, range, output) { } iterateBidiSections(getOrder(lineObj, doc.direction), fromArg || 0, toArg == null ? lineLen : toArg, (from, to, dir) => { - let leftPos = coords(from, "left"), rightPos, left, right - if (from == to) { - rightPos = leftPos - left = right = leftPos.left - } else { - rightPos = coords(to - 1, "right") - if (dir == "rtl") { let tmp = leftPos; leftPos = rightPos; rightPos = tmp } - left = leftPos.left - right = rightPos.right + let fromPos, toPos + if (dir == "ltr") { + fromPos = coords(from, "left") + toPos = coords(to - 1, "right") + let fromLeft = fromArg == null && from == 0 ? leftSide : fromPos.left + let toRight = toArg == null && to == lineLen ? rightSide : toPos.right + if (toPos.top - fromPos.top <= 3) { // Single line + add(fromLeft, toPos.top, toRight - fromLeft, toPos.bottom) + } else { // Multiple lines + add(fromLeft, fromPos.top, null, fromPos.bottom) + if (fromPos.bottom < toPos.top) add(leftSide, fromPos.bottom, null, toPos.top) + add(leftSide, toPos.top, toPos.right, toPos.bottom) + } + } else { // RTL + fromPos = coords(from, "right") + toPos = coords(to - 1, "left") + let fromRight = fromArg == null && from == 0 ? rightSide : fromPos.right + let toLeft = toArg == null && to == lineLen ? leftSide : toPos.left + if (toPos.top - fromPos.top <= 3) { // Single line + add(toLeft, toPos.top, fromRight - toLeft, toPos.bottom) + } else { // Multiple lines + add(leftSide, fromPos.top, fromRight - leftSide, fromPos.bottom) + if (fromPos.bottom < toPos.top) add(leftSide, fromPos.bottom, null, toPos.top) + add(toLeft, toPos.top, null, toPos.bottom) + } } - if (fromArg == null && from == 0) left = leftSide - if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part - add(left, leftPos.top, null, leftPos.bottom) - left = leftSide - if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top) - } - if (toArg == null && to == lineLen) right = rightSide - if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left) - start = leftPos - if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right) - end = rightPos - if (left < leftSide + 1) left = leftSide - add(left, rightPos.top, right - left, rightPos.bottom) + + if (!start || cmpCoords(fromPos, start) < 0) start = fromPos + if (cmpCoords(toPos, start) < 0) start = toPos + if (!end || cmpCoords(fromPos, end) < 0) end = fromPos + if (cmpCoords(toPos, end) < 0) end = toPos }) return {start: start, end: end} } diff --git a/test/test.js b/test/test.js index 59b760d5ae0eaaa604f84167a7d7c66dfc183b10..0f1d8f830f7bb3f3c4939cd652a09f3d9ce6222e 100644 --- a/test/test.js +++ b/test/test.js @@ -2468,6 +2468,12 @@ for (var i = 0; i < 5; ++i) { } */ +testCM("bidi_wrapped_selection", function(cm) { + cm.setSelection(Pos(0, 10), Pos(0, 190)) + is(byClassName(cm.getWrapperElement(), "CodeMirror-selected").length >= 3) + is(false) +}, {value: new Array(10).join(" Ùتي تم تضمينها Ùتي تم"), lineWrapping: true}) + testCM("delete_wrapped", function(cm) { makeItWrapAfter(cm, Pos(0, 2)); cm.doc.setCursor(Pos(0, 3, "after"));