* 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)
| 5734 | * Exported only for testing. |
| 5735 | */ |
| 5736 | function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) { |
| 5737 | var length = 0; |
| 5738 | var start = -1; |
| 5739 | var end = -1; |
| 5740 | var indexWithinAnchor = 0; |
| 5741 | var indexWithinFocus = 0; |
| 5742 | var node = outerNode; |
| 5743 | var parentNode = null; |
| 5744 | |
| 5745 | outer: while (true) { |
| 5746 | var next = null; |
| 5747 | |
| 5748 | while (true) { |
| 5749 | if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) { |
| 5750 | start = length + anchorOffset; |
| 5751 | } |
| 5752 | if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) { |
| 5753 | end = length + focusOffset; |
| 5754 | } |
| 5755 | |
| 5756 | if (node.nodeType === TEXT_NODE) { |
| 5757 | length += node.nodeValue.length; |
| 5758 | } |
| 5759 | |
| 5760 | if ((next = node.firstChild) === null) { |
| 5761 | break; |
| 5762 | } |
| 5763 | // Moving from `node` to its first child `next`. |
| 5764 | parentNode = node; |
| 5765 | node = next; |
| 5766 | } |
| 5767 | |
| 5768 | while (true) { |
| 5769 | if (node === outerNode) { |
| 5770 | // If `outerNode` has children, this is always the second time visiting |
| 5771 | // it. If it has no children, this is still the first loop, and the only |
| 5772 | // valid selection is anchorNode and focusNode both equal to this node |
| 5773 | // and both offsets 0, in which case we will have handled above. |
| 5774 | break outer; |
| 5775 | } |
| 5776 | if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) { |
| 5777 | start = length; |
| 5778 | } |
| 5779 | if (parentNode === focusNode && ++indexWithinFocus === focusOffset) { |
| 5780 | end = length; |
| 5781 | } |
| 5782 | if ((next = node.nextSibling) !== null) { |
| 5783 | break; |
| 5784 | } |
| 5785 | node = parentNode; |
| 5786 | parentNode = node.parentNode; |
| 5787 | } |
| 5788 | |
| 5789 | // Moving from `node` to its next sibling `next`. |
| 5790 | node = next; |
| 5791 | } |
| 5792 | |
| 5793 | if (start === -1 || end === -1) { |