(cm, lineObj, lineNo, x, y)
| 2911 | } |
| 2912 | |
| 2913 | function coordsCharInner(cm, lineObj, lineNo, x, y) { |
| 2914 | var innerOff = y - heightAtLine(lineObj); |
| 2915 | var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth; |
| 2916 | var preparedMeasure = prepareMeasureForLine(cm, lineObj); |
| 2917 | |
| 2918 | function getX(ch) { |
| 2919 | var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure); |
| 2920 | wrongLine = true; |
| 2921 | if (innerOff > sp.bottom) return sp.left - adjust; |
| 2922 | else if (innerOff < sp.top) return sp.left + adjust; |
| 2923 | else wrongLine = false; |
| 2924 | return sp.left; |
| 2925 | } |
| 2926 | |
| 2927 | var bidi = getOrder(lineObj), dist = lineObj.text.length; |
| 2928 | var from = lineLeft(lineObj), to = lineRight(lineObj); |
| 2929 | var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine; |
| 2930 | |
| 2931 | if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1); |
| 2932 | // Do a binary search between these bounds. |
| 2933 | for (;;) { |
| 2934 | if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) { |
| 2935 | var ch = x < fromX || x - fromX <= toX - x ? from : to; |
| 2936 | var outside = ch == from ? fromOutside : toOutside |
| 2937 | var xDiff = x - (ch == from ? fromX : toX); |
| 2938 | // This is a kludge to handle the case where the coordinates |
| 2939 | // are after a line-wrapped line. We should replace it with a |
| 2940 | // more general handling of cursor positions around line |
| 2941 | // breaks. (Issue #4078) |
| 2942 | if (toOutside && !bidi && !/\s/.test(lineObj.text.charAt(ch)) && xDiff > 0 && |
| 2943 | ch < lineObj.text.length && preparedMeasure.view.measure.heights.length > 1) { |
| 2944 | var charSize = measureCharPrepared(cm, preparedMeasure, ch, "right"); |
| 2945 | if (innerOff <= charSize.bottom && innerOff >= charSize.top && Math.abs(x - charSize.right) < xDiff) { |
| 2946 | outside = false |
| 2947 | ch++ |
| 2948 | xDiff = x - charSize.right |
| 2949 | } |
| 2950 | } |
| 2951 | while (isExtendingChar(lineObj.text.charAt(ch))) ++ch; |
| 2952 | var pos = PosWithInfo(lineNo, ch, outside, xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0); |
| 2953 | return pos; |
| 2954 | } |
| 2955 | var step = Math.ceil(dist / 2), middle = from + step; |
| 2956 | if (bidi) { |
| 2957 | middle = from; |
| 2958 | for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1); |
| 2959 | } |
| 2960 | var middleX = getX(middle); |
| 2961 | if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;} |
| 2962 | else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;} |
| 2963 | } |
| 2964 | } |
| 2965 | |
| 2966 | var measureText; |
| 2967 | // Compute the default text height. |
no test coverage detected