* 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)
| 5606 | * Exported only for testing. |
| 5607 | */ |
| 5608 | function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) { |
| 5609 | var length = 0; |
| 5610 | var start = -1; |
| 5611 | var end = -1; |
| 5612 | var indexWithinAnchor = 0; |
| 5613 | var indexWithinFocus = 0; |
| 5614 | var node = outerNode; |
| 5615 | var parentNode = null; |
| 5616 | |
| 5617 | outer: while (true) { |
| 5618 | var next = null; |
| 5619 | |
| 5620 | while (true) { |
| 5621 | if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) { |
| 5622 | start = length + anchorOffset; |
| 5623 | } |
| 5624 | if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) { |
| 5625 | end = length + focusOffset; |
| 5626 | } |
| 5627 | |
| 5628 | if (node.nodeType === TEXT_NODE) { |
| 5629 | length += node.nodeValue.length; |
| 5630 | } |
| 5631 | |
| 5632 | if ((next = node.firstChild) === null) { |
| 5633 | break; |
| 5634 | } |
| 5635 | // Moving from `node` to its first child `next`. |
| 5636 | parentNode = node; |
| 5637 | node = next; |
| 5638 | } |
| 5639 | |
| 5640 | while (true) { |
| 5641 | if (node === outerNode) { |
| 5642 | // If `outerNode` has children, this is always the second time visiting |
| 5643 | // it. If it has no children, this is still the first loop, and the only |
| 5644 | // valid selection is anchorNode and focusNode both equal to this node |
| 5645 | // and both offsets 0, in which case we will have handled above. |
| 5646 | break outer; |
| 5647 | } |
| 5648 | if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) { |
| 5649 | start = length; |
| 5650 | } |
| 5651 | if (parentNode === focusNode && ++indexWithinFocus === focusOffset) { |
| 5652 | end = length; |
| 5653 | } |
| 5654 | if ((next = node.nextSibling) !== null) { |
| 5655 | break; |
| 5656 | } |
| 5657 | node = parentNode; |
| 5658 | parentNode = node.parentNode; |
| 5659 | } |
| 5660 | |
| 5661 | // Moving from `node` to its next sibling `next`. |
| 5662 | node = next; |
| 5663 | } |
| 5664 | |
| 5665 | if (start === -1 || end === -1) { |