(cm, prepared, ch, bias)
| 1556 | var nullRect = {left: 0, right: 0, top: 0, bottom: 0}; |
| 1557 | |
| 1558 | function measureCharInner(cm, prepared, ch, bias) { |
| 1559 | var map = prepared.map; |
| 1560 | |
| 1561 | var node, start, end, collapse; |
| 1562 | // First, search the line map for the text node corresponding to, |
| 1563 | // or closest to, the target character. |
| 1564 | for (var i = 0; i < map.length; i += 3) { |
| 1565 | var mStart = map[i], mEnd = map[i + 1]; |
| 1566 | if (ch < mStart) { |
| 1567 | start = 0; end = 1; |
| 1568 | collapse = "left"; |
| 1569 | } else if (ch < mEnd) { |
| 1570 | start = ch - mStart; |
| 1571 | end = start + 1; |
| 1572 | } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { |
| 1573 | end = mEnd - mStart; |
| 1574 | start = end - 1; |
| 1575 | if (ch >= mEnd) collapse = "right"; |
| 1576 | } |
| 1577 | if (start != null) { |
| 1578 | node = map[i + 2]; |
| 1579 | if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) |
| 1580 | collapse = bias; |
| 1581 | if (bias == "left" && start == 0) |
| 1582 | while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { |
| 1583 | node = map[(i -= 3) + 2]; |
| 1584 | collapse = "left"; |
| 1585 | } |
| 1586 | if (bias == "right" && start == mEnd - mStart) |
| 1587 | while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { |
| 1588 | node = map[(i += 3) + 2]; |
| 1589 | collapse = "right"; |
| 1590 | } |
| 1591 | break; |
| 1592 | } |
| 1593 | } |
| 1594 | |
| 1595 | var rect; |
| 1596 | if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. |
| 1597 | while (start && isExtendingChar(prepared.line.text.charAt(mStart + start))) --start; |
| 1598 | while (mStart + end < mEnd && isExtendingChar(prepared.line.text.charAt(mStart + end))) ++end; |
| 1599 | if (ie_upto8 && start == 0 && end == mEnd - mStart) { |
| 1600 | rect = node.parentNode.getBoundingClientRect(); |
| 1601 | } else if (ie && cm.options.lineWrapping) { |
| 1602 | var rects = range(node, start, end).getClientRects(); |
| 1603 | if (rects.length) |
| 1604 | rect = rects[bias == "right" ? rects.length - 1 : 0]; |
| 1605 | else |
| 1606 | rect = nullRect; |
| 1607 | } else { |
| 1608 | rect = range(node, start, end).getBoundingClientRect(); |
| 1609 | } |
| 1610 | } else { // If it is a widget, simply get the box for the whole widget. |
| 1611 | if (start > 0) collapse = bias = "right"; |
| 1612 | var rects; |
| 1613 | if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) |
| 1614 | rect = rects[bias == "right" ? rects.length - 1 : 0]; |
| 1615 | else |
no test coverage detected