{"version":3,"file":"create-dom-range.cjs","sources":["../src/create-dom-range.ts"],"sourcesContent":["/**\n * MIT License\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport type { LexicalEditor, LexicalNode } from \"lexical\";\nimport { $isTextNode } from \"lexical\";\n\nfunction getDOMTextNode(element: Node | null): Text | null {\n  let node = element;\n\n  while (node !== null) {\n    if (node.nodeType === Node.TEXT_NODE) {\n      return node as Text;\n    }\n\n    node = node.firstChild;\n  }\n\n  return null;\n}\n\nfunction getDOMIndexWithinParent(node: ChildNode): [ParentNode, number] {\n  const parent = node.parentNode;\n\n  if (parent === null) {\n    throw new Error(\"Should never happen\");\n  }\n\n  return [parent, Array.from(parent.childNodes).indexOf(node)];\n}\n\n/**\n * Creates a selection range for the DOM.\n * @param editor - The lexical editor.\n * @param anchorNode - The anchor node of a selection.\n * @param _anchorOffset - The amount of space offset from the anchor to the focus.\n * @param focusNode - The current focus.\n * @param _focusOffset - The amount of space offset from the focus to the anchor.\n * @returns The range of selection for the DOM that was created.\n */\nexport function createDOMRange(\n  editor: LexicalEditor,\n  anchorNode: LexicalNode,\n  _anchorOffset: number,\n  focusNode: LexicalNode,\n  _focusOffset: number\n): Range | null {\n  const anchorKey = anchorNode.getKey();\n  const focusKey = focusNode.getKey();\n  const range = document.createRange();\n  let anchorDOM: Node | Text | null = editor.getElementByKey(anchorKey);\n  let focusDOM: Node | Text | null = editor.getElementByKey(focusKey);\n  let anchorOffset = _anchorOffset;\n  let focusOffset = _focusOffset;\n\n  if ($isTextNode(anchorNode)) {\n    anchorDOM = getDOMTextNode(anchorDOM);\n  }\n\n  if ($isTextNode(focusNode)) {\n    focusDOM = getDOMTextNode(focusDOM);\n  }\n\n  if (\n    anchorNode === undefined ||\n    focusNode === undefined ||\n    anchorDOM === null ||\n    focusDOM === null\n  ) {\n    return null;\n  }\n\n  if (anchorDOM.nodeName === \"BR\") {\n    [anchorDOM, anchorOffset] = getDOMIndexWithinParent(anchorDOM as ChildNode);\n  }\n\n  if (focusDOM.nodeName === \"BR\") {\n    [focusDOM, focusOffset] = getDOMIndexWithinParent(focusDOM as ChildNode);\n  }\n\n  const firstChild = anchorDOM.firstChild;\n\n  if (\n    anchorDOM === focusDOM &&\n    firstChild !== null &&\n    firstChild.nodeName === \"BR\" &&\n    anchorOffset === 0 &&\n    focusOffset === 0\n  ) {\n    focusOffset = 1;\n  }\n\n  try {\n    range.setStart(anchorDOM, anchorOffset);\n    range.setEnd(focusDOM, focusOffset);\n  } catch {\n    return null;\n  }\n\n  if (\n    range.collapsed &&\n    (anchorOffset !== focusOffset || anchorKey !== focusKey)\n  ) {\n    // Range is backwards, we need to reverse it\n    range.setStart(focusDOM, focusOffset);\n    range.setEnd(anchorDOM, anchorOffset);\n  }\n\n  return range;\n}\n"],"names":["$isTextNode"],"mappings":"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"}