export function normalizeRange()

in packages/dom/src/normalize-range.ts [70:113]


export function normalizeRange(range: Range, scope?: Range): TextRange {
  const document = ownerDocument(range);
  const walker = document.createTreeWalker(document, NodeFilter.SHOW_TEXT, {
    acceptNode(node: Text) {
      return !scope || scope.intersectsNode(node)
        ? NodeFilter.FILTER_ACCEPT
        : NodeFilter.FILTER_REJECT;
    },
  });

  let [startContainer, startOffset] = snapBoundaryPointToTextNode(
    range.startContainer,
    range.startOffset,
  );

  // If we point at the end of a text node, move to the start of the next one.
  // The step is repeated to skip over empty text nodes.
  walker.currentNode = startContainer;
  while (startOffset === startContainer.length && walker.nextNode()) {
    startContainer = walker.currentNode as Text;
    startOffset = 0;
  }

  // Set the range’s start; note this might move its end too.
  range.setStart(startContainer, startOffset);

  let [endContainer, endOffset] = snapBoundaryPointToTextNode(
    range.endContainer,
    range.endOffset,
  );

  // If we point at the start of a text node, move to the end of the previous one.
  // The step is repeated to skip over empty text nodes.
  walker.currentNode = endContainer;
  while (endOffset === 0 && walker.previousNode()) {
    endContainer = walker.currentNode as Text;
    endOffset = endContainer.length;
  }

  // Set the range’s end; note this might move its start too.
  range.setEnd(endContainer, endOffset);

  return range as TextRange;
}