/*** Copyright (c) Meta Platforms, Inc. and affiliates.** This source code is licensed under the MIT license found in the* LICENSE file in the root directory of this source tree.** @flow*/import {TEXT_NODE} from './HTMLNodeType';
/*** Given any node return the first leaf node without children.** @param {DOMElement|DOMTextNode} node* @return {DOMElement|DOMTextNode}*/function getLeafNode(node: ?(Node | Element)) {
while (node && node.firstChild) {
node = node.firstChild;
}return node;
}/*** Get the next sibling within a container. This will walk up the* DOM if a node's siblings have been exhausted.** @param {DOMElement|DOMTextNode} node* @return {?DOMElement|DOMTextNode}*/function getSiblingNode(node: ?(Node | Element)) {
while (node) {
if (node.nextSibling) {
return node.nextSibling;
}node = node.parentNode;
}}/*** Get object describing the nodes which contain characters at offset.** @param {DOMElement|DOMTextNode} root* @param {number} offset* @return {?object}*/function getNodeForCharacterOffset(root: Element, offset: number): ?Object {
let node = getLeafNode(root);
let nodeStart = 0;
let nodeEnd = 0;
while (node) {
if (node.nodeType === TEXT_NODE) {
nodeEnd = nodeStart + node.textContent.length;
if (nodeStart <= offset && nodeEnd >= offset) {
return {
node: node,
offset: offset - nodeStart,
};}nodeStart = nodeEnd;
}node = getLeafNode(getSiblingNode(node));
}}export default getNodeForCharacterOffset;