(visually, cm, lineObj, lineNo, dir)
| 6785 | } |
| 6786 | |
| 6787 | function endOfLine(visually, cm, lineObj, lineNo, dir) { |
| 6788 | if (visually) { |
| 6789 | var order = getOrder(lineObj, cm.doc.direction); |
| 6790 | if (order) { |
| 6791 | var part = dir < 0 ? lst(order) : order[0]; |
| 6792 | var moveInStorageOrder = (dir < 0) == (part.level == 1); |
| 6793 | var sticky = moveInStorageOrder ? "after" : "before"; |
| 6794 | var ch; |
| 6795 | // With a wrapped rtl chunk (possibly spanning multiple bidi parts), |
| 6796 | // it could be that the last bidi part is not on the last visual line, |
| 6797 | // since visual lines contain content order-consecutive chunks. |
| 6798 | // Thus, in rtl, we are looking for the first (content-order) character |
| 6799 | // in the rtl chunk that is on the last line (that is, the same line |
| 6800 | // as the last (content-order) character). |
| 6801 | if (part.level > 0 || cm.doc.direction == "rtl") { |
| 6802 | var prep = prepareMeasureForLine(cm, lineObj); |
| 6803 | ch = dir < 0 ? lineObj.text.length - 1 : 0; |
| 6804 | var targetTop = measureCharPrepared(cm, prep, ch).top; |
| 6805 | ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch); |
| 6806 | if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1); } |
| 6807 | } else { ch = dir < 0 ? part.to : part.from; } |
| 6808 | return new Pos(lineNo, ch, sticky) |
| 6809 | } |
| 6810 | } |
| 6811 | return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after") |
| 6812 | } |
| 6813 | |
| 6814 | function moveVisually(cm, line, start, dir) { |
| 6815 | var bidi = getOrder(line, cm.doc.direction); |
no test coverage detected