Files
react/packages/react-dom-bindings/src/client/getNodeForCharacterOffset.js
T
Sebastian Markbåge 21aee59e45 Delete unused DOM files (#26387)
These used to be used by partial render.

ReactDOMDispatcher ended up not being used in this way.

Move shared DOM files to client. These are only used by client
abstractions now. They're inlined in the Fizz code so they're no longer
shared.
2023-03-14 19:52:57 -04:00

72 lines
1.6 KiB
JavaScript

/**
* 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;