* 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)
| 6373 | * Exported only for testing. |
| 6374 | */ |
| 6375 | function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) { |
| 6376 | var length = 0; |
| 6377 | var start = -1; |
| 6378 | var end = -1; |
| 6379 | var indexWithinAnchor = 0; |
| 6380 | var indexWithinFocus = 0; |
| 6381 | var node = outerNode; |
| 6382 | var parentNode = null; |
| 6383 | |
| 6384 | outer: while (true) { |
| 6385 | var next = null; |
| 6386 | |
| 6387 | while (true) { |
| 6388 | if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) { |
| 6389 | start = length + anchorOffset; |
| 6390 | } |
| 6391 | if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) { |
| 6392 | end = length + focusOffset; |
| 6393 | } |
| 6394 | |
| 6395 | if (node.nodeType === TEXT_NODE) { |
| 6396 | length += node.nodeValue.length; |
| 6397 | } |
| 6398 | |
| 6399 | if ((next = node.firstChild) === null) { |
| 6400 | break; |
| 6401 | } |
| 6402 | // Moving from `node` to its first child `next`. |
| 6403 | parentNode = node; |
| 6404 | node = next; |
| 6405 | } |
| 6406 | |
| 6407 | while (true) { |
| 6408 | if (node === outerNode) { |
| 6409 | // If `outerNode` has children, this is always the second time visiting |
| 6410 | // it. If it has no children, this is still the first loop, and the only |
| 6411 | // valid selection is anchorNode and focusNode both equal to this node |
| 6412 | // and both offsets 0, in which case we will have handled above. |
| 6413 | break outer; |
| 6414 | } |
| 6415 | if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) { |
| 6416 | start = length; |
| 6417 | } |
| 6418 | if (parentNode === focusNode && ++indexWithinFocus === focusOffset) { |
| 6419 | end = length; |
| 6420 | } |
| 6421 | if ((next = node.nextSibling) !== null) { |
| 6422 | break; |
| 6423 | } |
| 6424 | node = parentNode; |
| 6425 | parentNode = node.parentNode; |
| 6426 | } |
| 6427 | |
| 6428 | // Moving from `node` to its next sibling `next`. |
| 6429 | node = next; |
| 6430 | } |
| 6431 | |
| 6432 | if (start === -1 || end === -1) { |