* Returns {start, end} where `start` is the character/codepoint index of * (anchorNode, anchorOffset) within the textContent of `outerNode`, and * `end` is the index of (focusNode, focusOffset). * * Returns null if you pass in garbage input but we should probably just crash. * * Exported only
(outerNode, anchorNode, anchorOffset, focusNode, focusOffset)
| 6624 | * Exported only for testing. |
| 6625 | */ |
| 6626 | function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) { |
| 6627 | var length = 0; |
| 6628 | var start = -1; |
| 6629 | var end = -1; |
| 6630 | var indexWithinAnchor = 0; |
| 6631 | var indexWithinFocus = 0; |
| 6632 | var node = outerNode; |
| 6633 | var parentNode = null; |
| 6634 | |
| 6635 | outer: while (true) { |
| 6636 | var next = null; |
| 6637 | |
| 6638 | while (true) { |
| 6639 | if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) { |
| 6640 | start = length + anchorOffset; |
| 6641 | } |
| 6642 | if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) { |
| 6643 | end = length + focusOffset; |
| 6644 | } |
| 6645 | |
| 6646 | if (node.nodeType === TEXT_NODE) { |
| 6647 | length += node.nodeValue.length; |
| 6648 | } |
| 6649 | |
| 6650 | if ((next = node.firstChild) === null) { |
| 6651 | break; |
| 6652 | } |
| 6653 | // Moving from `node` to its first child `next`. |
| 6654 | parentNode = node; |
| 6655 | node = next; |
| 6656 | } |
| 6657 | |
| 6658 | while (true) { |
| 6659 | if (node === outerNode) { |
| 6660 | // If `outerNode` has children, this is always the second time visiting |
| 6661 | // it. If it has no children, this is still the first loop, and the only |
| 6662 | // valid selection is anchorNode and focusNode both equal to this node |
| 6663 | // and both offsets 0, in which case we will have handled above. |
| 6664 | break outer; |
| 6665 | } |
| 6666 | if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) { |
| 6667 | start = length; |
| 6668 | } |
| 6669 | if (parentNode === focusNode && ++indexWithinFocus === focusOffset) { |
| 6670 | end = length; |
| 6671 | } |
| 6672 | if ((next = node.nextSibling) !== null) { |
| 6673 | break; |
| 6674 | } |
| 6675 | node = parentNode; |
| 6676 | parentNode = node.parentNode; |
| 6677 | } |
| 6678 | |
| 6679 | // Moving from `node` to its next sibling `next`. |
| 6680 | node = next; |
| 6681 | } |
| 6682 | |
| 6683 | if (start === -1 || end === -1) { |