(visually, cm, lineObj, lineNo, dir)
| 6840 | } |
| 6841 | |
| 6842 | function endOfLine(visually, cm, lineObj, lineNo, dir) { |
| 6843 | if (visually) { |
| 6844 | if (cm.doc.direction == "rtl") { dir = -dir; } |
| 6845 | var order = getOrder(lineObj, cm.doc.direction); |
| 6846 | if (order) { |
| 6847 | var part = dir < 0 ? lst(order) : order[0]; |
| 6848 | var moveInStorageOrder = (dir < 0) == (part.level == 1); |
| 6849 | var sticky = moveInStorageOrder ? "after" : "before"; |
| 6850 | var ch; |
| 6851 | // With a wrapped rtl chunk (possibly spanning multiple bidi parts), |
| 6852 | // it could be that the last bidi part is not on the last visual line, |
| 6853 | // since visual lines contain content order-consecutive chunks. |
| 6854 | // Thus, in rtl, we are looking for the first (content-order) character |
| 6855 | // in the rtl chunk that is on the last line (that is, the same line |
| 6856 | // as the last (content-order) character). |
| 6857 | if (part.level > 0 || cm.doc.direction == "rtl") { |
| 6858 | var prep = prepareMeasureForLine(cm, lineObj); |
| 6859 | ch = dir < 0 ? lineObj.text.length - 1 : 0; |
| 6860 | var targetTop = measureCharPrepared(cm, prep, ch).top; |
| 6861 | ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch); |
| 6862 | if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1); } |
| 6863 | } else { ch = dir < 0 ? part.to : part.from; } |
| 6864 | return new Pos(lineNo, ch, sticky) |
| 6865 | } |
| 6866 | } |
| 6867 | return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after") |
| 6868 | } |
| 6869 | |
| 6870 | function moveVisually(cm, line, start, dir) { |
| 6871 | var bidi = getOrder(line, cm.doc.direction); |
no test coverage detected