(cm, prepared, ch, bias)
| 2477 | } |
| 2478 | |
| 2479 | function measureCharInner(cm, prepared, ch, bias) { |
| 2480 | var place = nodeAndOffsetInLineMap(prepared.map, ch, bias); |
| 2481 | var node = place.node, start = place.start, end = place.end, collapse = place.collapse; |
| 2482 | |
| 2483 | var rect; |
| 2484 | if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. |
| 2485 | for (var i$1 = 0; i$1 < 4; i$1++) { // Retry a maximum of 4 times when nonsense rectangles are returned |
| 2486 | while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) { --start; } |
| 2487 | while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) { ++end; } |
| 2488 | if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) |
| 2489 | { rect = node.parentNode.getBoundingClientRect(); } |
| 2490 | else |
| 2491 | { rect = getUsefulRect(range(node, start, end).getClientRects(), bias); } |
| 2492 | if (rect.left || rect.right || start == 0) { break } |
| 2493 | end = start; |
| 2494 | start = start - 1; |
| 2495 | collapse = "right"; |
| 2496 | } |
| 2497 | if (ie && ie_version < 11) { rect = maybeUpdateRectForZooming(cm.display.measure, rect); } |
| 2498 | } else { // If it is a widget, simply get the box for the whole widget. |
| 2499 | if (start > 0) { collapse = bias = "right"; } |
| 2500 | var rects; |
| 2501 | if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) |
| 2502 | { rect = rects[bias == "right" ? rects.length - 1 : 0]; } |
| 2503 | else |
| 2504 | { rect = node.getBoundingClientRect(); } |
| 2505 | } |
| 2506 | if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) { |
| 2507 | var rSpan = node.parentNode.getClientRects()[0]; |
| 2508 | if (rSpan) |
| 2509 | { rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}; } |
| 2510 | else |
| 2511 | { rect = nullRect; } |
| 2512 | } |
| 2513 | |
| 2514 | var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top; |
| 2515 | var mid = (rtop + rbot) / 2; |
| 2516 | var heights = prepared.view.measure.heights; |
| 2517 | var i = 0; |
| 2518 | for (; i < heights.length - 1; i++) |
| 2519 | { if (mid < heights[i]) { break } } |
| 2520 | var top = i ? heights[i - 1] : 0, bot = heights[i]; |
| 2521 | var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, |
| 2522 | right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, |
| 2523 | top: top, bottom: bot}; |
| 2524 | if (!rect.left && !rect.right) { result.bogus = true; } |
| 2525 | if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; } |
| 2526 | |
| 2527 | return result |
| 2528 | } |
| 2529 | |
| 2530 | // Work around problem with bounding client rects on ranges being |
| 2531 | // returned incorrectly when zoomed on IE10 and below. |
no test coverage detected