* 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)
| 6511 | * Exported only for testing. |
| 6512 | */ |
| 6513 | function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) { |
| 6514 | var length = 0; |
| 6515 | var start = -1; |
| 6516 | var end = -1; |
| 6517 | var indexWithinAnchor = 0; |
| 6518 | var indexWithinFocus = 0; |
| 6519 | var node = outerNode; |
| 6520 | var parentNode = null; |
| 6521 | |
| 6522 | outer: while (true) { |
| 6523 | var next = null; |
| 6524 | |
| 6525 | while (true) { |
| 6526 | if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) { |
| 6527 | start = length + anchorOffset; |
| 6528 | } |
| 6529 | if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) { |
| 6530 | end = length + focusOffset; |
| 6531 | } |
| 6532 | |
| 6533 | if (node.nodeType === TEXT_NODE) { |
| 6534 | length += node.nodeValue.length; |
| 6535 | } |
| 6536 | |
| 6537 | if ((next = node.firstChild) === null) { |
| 6538 | break; |
| 6539 | } |
| 6540 | // Moving from `node` to its first child `next`. |
| 6541 | parentNode = node; |
| 6542 | node = next; |
| 6543 | } |
| 6544 | |
| 6545 | while (true) { |
| 6546 | if (node === outerNode) { |
| 6547 | // If `outerNode` has children, this is always the second time visiting |
| 6548 | // it. If it has no children, this is still the first loop, and the only |
| 6549 | // valid selection is anchorNode and focusNode both equal to this node |
| 6550 | // and both offsets 0, in which case we will have handled above. |
| 6551 | break outer; |
| 6552 | } |
| 6553 | if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) { |
| 6554 | start = length; |
| 6555 | } |
| 6556 | if (parentNode === focusNode && ++indexWithinFocus === focusOffset) { |
| 6557 | end = length; |
| 6558 | } |
| 6559 | if ((next = node.nextSibling) !== null) { |
| 6560 | break; |
| 6561 | } |
| 6562 | node = parentNode; |
| 6563 | parentNode = node.parentNode; |
| 6564 | } |
| 6565 | |
| 6566 | // Moving from `node` to its next sibling `next`. |
| 6567 | node = next; |
| 6568 | } |
| 6569 | |
| 6570 | if (start === -1 || end === -1) { |