{"version":3,"file":"index.cjs","names":["Extension","Plugin","PluginKey","Extension","dropCursor","Extension","Plugin","PluginKey","DecorationSet","Decoration","Extension","gapCursor","callOrReturn","getExtensionField","PluginKey","Decoration","isNodeEmpty","DecorationSet","getChangedRanges","DecorationSet","Plugin","DecorationSet","Extension","isNodeSelection","Extension","Plugin","PluginKey","DecorationSet","Decoration","Extension","PluginKey","Plugin","Extension","undo","redo","history"],"sources":["../src/character-count/character-count.ts","../src/drop-cursor/drop-cursor.ts","../src/focus/focus.ts","../src/gap-cursor/gap-cursor.ts","../src/placeholder/constants.ts","../src/placeholder/utils/createPlaceholderDecoration.ts","../src/placeholder/utils/buildPlaceholderDecorations.ts","../src/placeholder/utils/resolveTopLevelRange.ts","../src/placeholder/utils/placeholderStateField.ts","../src/placeholder/utils/preparePlaceholderAttribute.ts","../src/placeholder/plugins/PlaceholderPlugin.ts","../src/placeholder/placeholder.ts","../src/selection/selection.ts","../src/trailing-node/trailing-node.ts","../src/undo-redo/undo-redo.ts"],"sourcesContent":["import { Extension } from '@tiptap/core'\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\nexport interface CharacterCountOptions {\n  /**\n   * The maximum number of characters that should be allowed. Defaults to `0`.\n   * @default null\n   * @example 180\n   */\n  limit: number | null | undefined\n  /**\n   * The mode by which the size is calculated. If set to `textSize`, the textContent of the document is used.\n   * If set to `nodeSize`, the nodeSize of the document is used.\n   * @default 'textSize'\n   * @example 'textSize'\n   */\n  mode: 'textSize' | 'nodeSize'\n  /**\n   * Sets whether the content will be automatically trimmed when programatically setting content over the limit.\n   * If set to false, the user will be able to trim the text manually.\n   * @default true\n   * @example false\n   */\n  autoTrim?: boolean\n  /**\n   * The text counter function to use. Defaults to a simple character count.\n   * @default (text) => text.length\n   * @example (text) => [...new Intl.Segmenter().segment(text)].length\n   */\n  textCounter: (text: string) => number\n  /**\n   * The word counter function to use. Defaults to a simple word count.\n   * @default (text) => text.split(' ').filter(word => word !== '').length\n   * @example (text) => text.split(/\\s+/).filter(word => word !== '').length\n   */\n  wordCounter: (text: string) => number\n}\n\nexport interface CharacterCountStorage {\n  /**\n   * Get the number of characters for the current document.\n   * @param options The options for the character count. (optional)\n   * @param options.node The node to get the characters from. Defaults to the current document.\n   * @param options.mode The mode by which the size is calculated. If set to `textSize`, the textContent of the document is used.\n   */\n  characters: (options?: { node?: ProseMirrorNode; mode?: 'textSize' | 'nodeSize' }) => number\n\n  /**\n   * Get the number of words for the current document.\n   * @param options The options for the character count. (optional)\n   * @param options.node The node to get the words from. Defaults to the current document.\n   */\n  words: (options?: { node?: ProseMirrorNode }) => number\n}\n\ndeclare module '@tiptap/core' {\n  interface Storage {\n    characterCount: CharacterCountStorage\n  }\n}\n\n/**\n * This extension allows you to count the characters and words of your document.\n * @see https://tiptap.dev/api/extensions/character-count\n */\nexport const CharacterCount = Extension.create<CharacterCountOptions, CharacterCountStorage>({\n  name: 'characterCount',\n\n  addOptions() {\n    return {\n      limit: null,\n      autoTrim: true,\n      mode: 'textSize',\n      textCounter: text => text.length,\n      wordCounter: text => text.split(' ').filter(word => word !== '').length,\n    }\n  },\n\n  addStorage() {\n    return {\n      characters: () => 0,\n      words: () => 0,\n    }\n  },\n\n  onBeforeCreate() {\n    this.storage.characters = options => {\n      const node = options?.node || this.editor.state.doc\n      const mode = options?.mode || this.options.mode\n\n      if (mode === 'textSize') {\n        const text = node.textBetween(0, node.content.size, undefined, ' ')\n\n        return this.options.textCounter(text)\n      }\n\n      return node.nodeSize\n    }\n\n    this.storage.words = options => {\n      const node = options?.node || this.editor.state.doc\n      const text = node.textBetween(0, node.content.size, ' ', ' ')\n\n      return this.options.wordCounter(text)\n    }\n  },\n\n  addProseMirrorPlugins() {\n    let initialEvaluationDone = false\n\n    return [\n      new Plugin({\n        key: new PluginKey('characterCount'),\n        appendTransaction: (transactions, oldState, newState) => {\n          if (initialEvaluationDone) {\n            return\n          }\n\n          const limit = this.options.limit\n          const autoTrim = this.options.autoTrim\n\n          if (limit === null || limit === undefined || limit === 0 || autoTrim === false) {\n            initialEvaluationDone = true\n            return\n          }\n\n          const initialContentSize = this.storage.characters({ node: newState.doc })\n\n          if (initialContentSize > limit) {\n            const over = initialContentSize - limit\n            const from = 0\n            const to = over\n\n            console.warn(\n              `[CharacterCount] Initial content exceeded limit of ${limit} characters. Content was automatically trimmed.`,\n            )\n            const tr = newState.tr.deleteRange(from, to)\n            initialEvaluationDone = true\n            return tr\n          }\n\n          initialEvaluationDone = true\n        },\n        filterTransaction: (transaction, state) => {\n          const limit = this.options.limit\n\n          // Nothing has changed or no limit is defined. Ignore it.\n          if (!transaction.docChanged || limit === 0 || limit === null || limit === undefined) {\n            return true\n          }\n\n          const oldSize = this.storage.characters({ node: state.doc })\n          const newSize = this.storage.characters({ node: transaction.doc })\n\n          // Everything is in the limit. Good.\n          if (newSize <= limit) {\n            return true\n          }\n\n          // The limit has already been exceeded but will be reduced.\n          if (oldSize > limit && newSize > limit && newSize <= oldSize) {\n            return true\n          }\n\n          // The limit has already been exceeded and will be increased further.\n          if (oldSize > limit && newSize > limit && newSize > oldSize) {\n            return false\n          }\n\n          const isPaste = transaction.getMeta('paste')\n\n          // Block all exceeding transactions that were not pasted.\n          if (!isPaste) {\n            return false\n          }\n\n          // For pasted content, we try to remove the exceeding content.\n          const pos = transaction.selection.$head.pos\n          const over = newSize - limit\n          const from = pos - over\n          const to = pos\n\n          // It’s probably a bad idea to mutate transactions within `filterTransaction`\n          // but for now this is working fine.\n          transaction.deleteRange(from, to)\n\n          // In some situations, the limit will continue to be exceeded after trimming.\n          // This happens e.g. when truncating within a complex node (e.g. table)\n          // and ProseMirror has to close this node again.\n          // If this is the case, we prevent the transaction completely.\n          const updatedSize = this.storage.characters({ node: transaction.doc })\n\n          if (updatedSize > limit) {\n            return false\n          }\n\n          return true\n        },\n      }),\n    ]\n  },\n})\n","import { Extension } from '@tiptap/core'\nimport { dropCursor } from '@tiptap/pm/dropcursor'\n\nexport interface DropcursorOptions {\n  /**\n   * The color of the drop cursor. Use `false` to apply no color and rely only on class.\n   * @default 'currentColor'\n   * @example 'red'\n   */\n  color?: string | false\n\n  /**\n   * The width of the drop cursor\n   * @default 1\n   * @example 2\n   */\n  width: number | undefined\n\n  /**\n   * The class of the drop cursor\n   * @default undefined\n   * @example 'drop-cursor'\n   */\n  class: string | undefined\n}\n\n/**\n * This extension allows you to add a drop cursor to your editor.\n * A drop cursor is a line that appears when you drag and drop content\n * in-between nodes.\n * @see https://tiptap.dev/api/extensions/dropcursor\n */\nexport const Dropcursor = Extension.create<DropcursorOptions>({\n  name: 'dropCursor',\n\n  addOptions() {\n    return {\n      color: 'currentColor',\n      width: 1,\n      class: undefined,\n    }\n  },\n\n  addProseMirrorPlugins() {\n    return [dropCursor(this.options)]\n  },\n})\n","import { Extension } from '@tiptap/core'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { Decoration, DecorationSet } from '@tiptap/pm/view'\n\nexport interface FocusOptions {\n  /**\n   * The class name that should be added to the focused node.\n   * @default 'has-focus'\n   * @example 'is-focused'\n   */\n  className: string\n\n  /**\n   * The mode by which the focused node is determined.\n   * - All: All nodes are marked as focused.\n   * - Deepest: Only the deepest node is marked as focused.\n   * - Shallowest: Only the shallowest node is marked as focused.\n   *\n   * @default 'all'\n   * @example 'deepest'\n   * @example 'shallowest'\n   */\n  mode: 'all' | 'deepest' | 'shallowest'\n}\n\n/**\n * This extension allows you to add a class to the focused node.\n * @see https://www.tiptap.dev/api/extensions/focus\n */\nexport const Focus = Extension.create<FocusOptions>({\n  name: 'focus',\n\n  addOptions() {\n    return {\n      className: 'has-focus',\n      mode: 'all',\n    }\n  },\n\n  addProseMirrorPlugins() {\n    return [\n      new Plugin({\n        key: new PluginKey('focus'),\n        props: {\n          decorations: ({ doc, selection }) => {\n            const { isEditable, isFocused } = this.editor\n            const { anchor } = selection\n            const decorations: Decoration[] = []\n\n            if (!isEditable || !isFocused) {\n              return DecorationSet.create(doc, [])\n            }\n\n            // Maximum Levels\n            let maxLevels = 0\n\n            if (this.options.mode === 'deepest') {\n              doc.descendants((node, pos) => {\n                if (node.isText) {\n                  return\n                }\n\n                const isCurrent = anchor >= pos && anchor <= pos + node.nodeSize - 1\n\n                if (!isCurrent) {\n                  return false\n                }\n\n                maxLevels += 1\n              })\n            }\n\n            // Loop through current\n            let currentLevel = 0\n\n            doc.descendants((node, pos) => {\n              if (node.isText) {\n                return false\n              }\n\n              const isCurrent = anchor >= pos && anchor <= pos + node.nodeSize - 1\n\n              if (!isCurrent) {\n                return false\n              }\n\n              currentLevel += 1\n\n              const outOfScope =\n                (this.options.mode === 'deepest' && maxLevels - currentLevel > 0) ||\n                (this.options.mode === 'shallowest' && currentLevel > 1)\n\n              if (outOfScope) {\n                return this.options.mode === 'deepest'\n              }\n\n              decorations.push(\n                Decoration.node(pos, pos + node.nodeSize, {\n                  class: this.options.className,\n                }),\n              )\n            })\n\n            return DecorationSet.create(doc, decorations)\n          },\n        },\n      }),\n    ]\n  },\n})\n","import type { ParentConfig } from '@tiptap/core'\nimport { callOrReturn, Extension, getExtensionField } from '@tiptap/core'\nimport { gapCursor } from '@tiptap/pm/gapcursor'\n\ndeclare module '@tiptap/core' {\n  interface NodeConfig<Options, Storage> {\n    /**\n     * A function to determine whether the gap cursor is allowed at the current position. Must return `true` or `false`.\n     * @default null\n     */\n    allowGapCursor?:\n      | boolean\n      | null\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<NodeConfig<Options>>['allowGapCursor']\n        }) => boolean | null)\n  }\n}\n\n/**\n * This extension allows you to add a gap cursor to your editor.\n * A gap cursor is a cursor that appears when you click on a place\n * where no content is present, for example inbetween nodes.\n * @see https://tiptap.dev/api/extensions/gapcursor\n */\nexport const Gapcursor = Extension.create({\n  name: 'gapCursor',\n\n  addProseMirrorPlugins() {\n    return [gapCursor()]\n  },\n\n  extendNodeSchema(extension) {\n    const context = {\n      name: extension.name,\n      options: extension.options,\n      storage: extension.storage,\n    }\n\n    return {\n      allowGapCursor: callOrReturn(getExtensionField(extension, 'allowGapCursor', context)) ?? null,\n    }\n  },\n})\n","import { PluginKey } from '@tiptap/pm/state'\nimport type { DecorationSet } from '@tiptap/pm/view'\n\n/** The default data attribute label */\nexport const DEFAULT_DATA_ATTRIBUTE = 'placeholder'\n\n/** The plugin key used to store and read the placeholder decoration set */\nexport const PLUGIN_KEY = new PluginKey<DecorationSet>('tiptap__placeholder')\n","import type { Editor } from '@tiptap/core'\nimport type { Node } from '@tiptap/pm/model'\nimport { Decoration } from '@tiptap/pm/view'\n\nimport type { PlaceholderOptions } from '../types.js'\n\n/**\n * Creates a ProseMirror node decoration that applies a placeholder\n * CSS class and data attribute to an empty node.\n * @param options.editor - The editor instance\n * @param options.pos - The position of the node in the document\n * @param options.node - The ProseMirror node\n * @param options.isEmptyDoc - Whether the entire document is empty\n * @param options.hasAnchor - Whether the selection anchor is within the node\n * @param options.dataAttribute - The data attribute name (e.g. `data-placeholder`)\n * @param options.classes - CSS classes for empty nodes and the empty editor\n * @param options.placeholder - The placeholder text or a function that returns it\n * @returns A ProseMirror node decoration with placeholder classes and data attribute\n */\nexport function createPlaceholderDecoration(options: {\n  editor: Editor\n  pos: number\n  node: Node\n  isEmptyDoc: boolean\n  hasAnchor: boolean\n  dataAttribute: string\n  classes: {\n    emptyEditor: PlaceholderOptions['emptyEditorClass']\n    emptyNode: string\n  }\n  placeholder: PlaceholderOptions['placeholder']\n}) {\n  const {\n    editor,\n    placeholder,\n    dataAttribute,\n    pos,\n    node,\n    isEmptyDoc,\n    hasAnchor,\n    classes: { emptyNode, emptyEditor },\n  } = options\n  const classes = [emptyNode]\n\n  if (isEmptyDoc) {\n    classes.push(emptyEditor)\n  }\n\n  return Decoration.node(pos, pos + node.nodeSize, {\n    class: classes.join(' '),\n    [dataAttribute]:\n      typeof placeholder === 'function'\n        ? placeholder({\n            editor,\n            node,\n            pos,\n            hasAnchor,\n          })\n        : placeholder,\n  })\n}\n","import type { Editor } from '@tiptap/core'\nimport { isNodeEmpty } from '@tiptap/core'\nimport type { Node } from '@tiptap/pm/model'\nimport type { Selection } from '@tiptap/pm/state'\nimport type { Decoration } from '@tiptap/pm/view'\nimport { DecorationSet } from '@tiptap/pm/view'\n\nimport type { PlaceholderOptions } from '../types.js'\nimport { createPlaceholderDecoration } from './createPlaceholderDecoration.js'\n\nfunction resolveEmptyNodeClass(\n  emptyNodeClass: PlaceholderOptions['emptyNodeClass'],\n  props: { editor: Editor; node: Node; pos: number; hasAnchor: boolean },\n): string {\n  return typeof emptyNodeClass === 'function' ? emptyNodeClass(props) : emptyNodeClass\n}\n\n/**\n * Scans a document range for empty textblocks that should receive placeholder\n * decorations. Used by the slow path and incremental state updates.\n */\nexport function scanRangeForDecorations({\n  editor,\n  options,\n  dataAttribute,\n  doc,\n  selection,\n  from,\n  to,\n}: {\n  editor: Editor\n  options: PlaceholderOptions\n  dataAttribute: string\n  doc: Node\n  selection: Selection\n  from: number\n  to: number\n}): Decoration[] {\n  const { anchor } = selection\n  const decorations: Decoration[] = []\n  const isEmptyDoc = editor.isEmpty\n\n  doc.nodesBetween(from, to, (node, pos) => {\n    const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize\n    const isEmpty = !node.isLeaf && isNodeEmpty(node)\n\n    if (!node.type.isTextblock) {\n      return options.includeChildren\n    }\n\n    if ((hasAnchor || !options.showOnlyCurrent) && isEmpty) {\n      decorations.push(\n        createPlaceholderDecoration({\n          editor,\n          isEmptyDoc,\n          dataAttribute,\n          hasAnchor,\n          placeholder: options.placeholder,\n          classes: {\n            emptyEditor: options.emptyEditorClass,\n            emptyNode: resolveEmptyNodeClass(options.emptyNodeClass, {\n              editor,\n              node,\n              pos,\n              hasAnchor,\n            }),\n          },\n          node,\n          pos,\n        }),\n      )\n    }\n\n    return options.includeChildren\n  })\n\n  return decorations\n}\n\n/**\n * Builds the placeholder decorations for the current document state.\n * @param options.editor - The editor instance.\n * @param options.options - The resolved placeholder options.\n * @param options.dataAttribute - The prepared `data-*` attribute name.\n * @param options.doc - The current document node.\n * @param options.selection - The current selection.\n * @returns A decoration set, or `null` when no placeholders should be shown.\n */\nexport function buildPlaceholderDecorations({\n  editor,\n  options,\n  dataAttribute,\n  doc,\n  selection,\n}: {\n  editor: Editor\n  options: PlaceholderOptions\n  dataAttribute: string\n  doc: Node\n  selection: Selection\n}): DecorationSet | null {\n  const active = editor.isEditable || !options.showOnlyWhenEditable\n\n  if (!active) {\n    return null\n  }\n\n  const { anchor } = selection\n  const decorations: Decoration[] = []\n  const isEmptyDoc = editor.isEmpty\n\n  const useResolvedPath = options.showOnlyCurrent && !options.includeChildren\n\n  if (useResolvedPath) {\n    const resolved = doc.resolve(anchor)\n\n    // When the selection spans the whole document (e.g. an `AllSelection`\n    // after Cmd+A), the anchor resolves to the document level (depth 0). In\n    // that case the relevant textblock is the node directly after the\n    // position rather than an ancestor. otherwise the placeholder would\n    // disappear after selecting all and deleting.\n    const node = resolved.depth > 0 ? resolved.node(1) : resolved.nodeAfter\n    const nodeStart = resolved.depth > 0 ? resolved.before(1) : anchor\n\n    if (node && node.type.isTextblock && isNodeEmpty(node)) {\n      const hasAnchor = anchor >= nodeStart && anchor <= nodeStart + node.nodeSize\n\n      decorations.push(\n        createPlaceholderDecoration({\n          editor,\n          isEmptyDoc,\n          dataAttribute,\n          hasAnchor,\n          placeholder: options.placeholder,\n          classes: {\n            emptyEditor: options.emptyEditorClass,\n            emptyNode: resolveEmptyNodeClass(options.emptyNodeClass, {\n              editor,\n              node,\n              pos: nodeStart,\n              hasAnchor,\n            }),\n          },\n          node,\n          pos: nodeStart,\n        }),\n      )\n    }\n  } else {\n    decorations.push(\n      ...scanRangeForDecorations({\n        editor,\n        options,\n        dataAttribute,\n        doc,\n        selection,\n        from: 0,\n        to: doc.content.size,\n      }),\n    )\n  }\n\n  return DecorationSet.create(doc, decorations)\n}\n","import type { Node } from '@tiptap/pm/model'\n\n/**\n * Resolves a document position to the `[from, to)` range of its containing\n * top-level block node in absolute document positions.\n */\nexport function resolveTopLevelRange(doc: Node, pos: number): { from: number; to: number } {\n  const resolved = doc.resolve(pos)\n\n  if (resolved.depth === 0) {\n    const node = resolved.nodeAfter ?? resolved.nodeBefore\n\n    if (!node) {\n      return { from: pos, to: pos }\n    }\n\n    const nodePos = resolved.nodeAfter ? pos : pos - node.nodeSize\n\n    return { from: nodePos, to: nodePos + node.nodeSize }\n  }\n\n  const topLevelPos = resolved.before(1)\n  const node = resolved.node(1)\n\n  return { from: topLevelPos, to: topLevelPos + node.nodeSize }\n}\n\n/**\n * Converts an absolute document range to content-relative positions used by\n * `Node#nodesBetween` and `Node#forEach` offsets.\n */\nexport function toContentRelativeRange(\n  doc: Node,\n  range: { from: number; to: number },\n): { from: number; to: number } {\n  return {\n    from: Math.max(0, range.from - 1),\n    to: Math.min(doc.content.size, range.to - 1),\n  }\n}\n\n/**\n * Returns the top-level block ranges that intersect a document change range.\n * Input `from`/`to` are absolute positions (e.g. from `getChangedRanges`).\n * Returned ranges are content-relative, matching `Node#forEach` offsets.\n */\nexport function getTopLevelBlocksInRange(\n  doc: Node,\n  from: number,\n  to: number,\n): Array<{ from: number; to: number }> {\n  const ranges: Array<{ from: number; to: number }> = []\n\n  doc.forEach((node, offset) => {\n    const nodeStart = offset\n    const nodeEnd = nodeStart + node.nodeSize\n    const absNodeStart = nodeStart + 1\n    const absNodeEnd = nodeEnd + 1\n\n    if (absNodeStart < to && absNodeEnd > from) {\n      ranges.push({ from: nodeStart, to: nodeEnd })\n    }\n  })\n\n  return ranges\n}\n\n/**\n * Sorts ranges by start position and merges overlapping or adjacent ranges.\n */\nexport function mergeRanges(\n  ranges: Array<{ from: number; to: number }>,\n): Array<{ from: number; to: number }> {\n  if (ranges.length === 0) {\n    return []\n  }\n\n  const sorted = [...ranges].sort((a, b) => a.from - b.from)\n  const merged: Array<{ from: number; to: number }> = [{ ...sorted[0] }]\n\n  for (let i = 1; i < sorted.length; i += 1) {\n    const last = merged[merged.length - 1]\n    const current = sorted[i]\n\n    if (current.from <= last.to) {\n      last.to = Math.max(last.to, current.to)\n    } else {\n      merged.push({ ...current })\n    }\n  }\n\n  return merged\n}\n","import type { Editor } from '@tiptap/core'\nimport { getChangedRanges } from '@tiptap/core'\nimport type { Node } from '@tiptap/pm/model'\nimport type { EditorState, StateField, Transaction } from '@tiptap/pm/state'\nimport type { Selection } from '@tiptap/pm/state'\nimport { DecorationSet } from '@tiptap/pm/view'\n\nimport type { PlaceholderOptions } from '../types.js'\nimport {\n  buildPlaceholderDecorations,\n  scanRangeForDecorations,\n} from './buildPlaceholderDecorations.js'\nimport {\n  getTopLevelBlocksInRange,\n  mergeRanges,\n  resolveTopLevelRange,\n  toContentRelativeRange,\n} from './resolveTopLevelRange.js'\n\n/** Options passed to {@link createPlaceholderStateField}. */\nexport type CreatePlaceholderStateFieldOptions = {\n  editor: Editor\n  options: PlaceholderOptions\n  dataAttribute: string\n}\n\n/**\n * Expands a single changed range to the top-level blocks it touches.\n * Also resolves blocks at range boundaries so split/merge edits update\n * adjacent empty nodes (e.g. a new paragraph after Enter).\n */\nfunction collectBlocksForChange(\n  doc: Node,\n  change: { from: number; to: number },\n): Array<{ from: number; to: number }> {\n  const ranges = getTopLevelBlocksInRange(doc, change.from, change.to)\n\n  ranges.push(toContentRelativeRange(doc, resolveTopLevelRange(doc, change.from)))\n\n  if (change.to > change.from) {\n    ranges.push(\n      toContentRelativeRange(\n        doc,\n        resolveTopLevelRange(doc, Math.min(change.to, doc.content.size + 1) - 1),\n      ),\n    )\n  } else if (change.from < doc.content.size + 1) {\n    ranges.push(\n      toContentRelativeRange(\n        doc,\n        resolveTopLevelRange(doc, Math.min(change.from + 1, doc.content.size)),\n      ),\n    )\n  }\n\n  return ranges\n}\n\n/**\n * Collects content-relative top-level block ranges that need placeholder\n * decorations recomputed after a transaction.\n */\nfunction collectRescanRanges(\n  tr: Transaction,\n  oldState: EditorState,\n  newState: EditorState,\n): Array<{ from: number; to: number }> {\n  const ranges: Array<{ from: number; to: number }> = []\n\n  if (tr.docChanged) {\n    const changes = getChangedRanges(tr)\n\n    for (const change of changes) {\n      ranges.push(...collectBlocksForChange(newState.doc, change.newRange))\n    }\n  }\n\n  if (tr.selectionSet) {\n    ranges.push(\n      toContentRelativeRange(\n        newState.doc,\n        resolveTopLevelRange(newState.doc, tr.mapping.map(oldState.selection.anchor)),\n      ),\n    )\n    ranges.push(\n      toContentRelativeRange(\n        newState.doc,\n        resolveTopLevelRange(newState.doc, newState.selection.anchor),\n      ),\n    )\n  }\n\n  return mergeRanges(ranges)\n}\n\n/** Clamps a content-relative range to `[0, doc.content.size]`. */\nfunction clampRange(from: number, to: number, doc: Node): { from: number; to: number } {\n  const clampedFrom = Math.max(0, Math.min(from, doc.content.size))\n  const clampedTo = Math.max(clampedFrom, Math.min(to, doc.content.size))\n\n  return { from: clampedFrom, to: clampedTo }\n}\n\n/**\n * Removes and rebuilds placeholder decorations within the given ranges.\n * Only drops decorations fully contained in a range so mapped decorations\n * on neighbouring blocks (e.g. at a block boundary) are kept intact.\n */\nfunction updateDecorationsInRanges({\n  decorations,\n  ranges,\n  editor,\n  options,\n  dataAttribute,\n  doc,\n  selection,\n}: {\n  decorations: DecorationSet\n  ranges: Array<{ from: number; to: number }>\n  editor: Editor\n  options: PlaceholderOptions\n  dataAttribute: string\n  doc: Node\n  selection: Selection\n}): DecorationSet {\n  let next = decorations\n\n  for (const range of ranges) {\n    const { from, to } = clampRange(range.from, range.to, doc)\n    const existing = next\n      .find(from, to)\n      .filter(decoration => decoration.from >= from && decoration.to <= to)\n\n    if (existing.length) {\n      next = next.remove(existing)\n    }\n\n    const newDecos = scanRangeForDecorations({\n      editor,\n      options,\n      dataAttribute,\n      doc,\n      selection,\n      from,\n      to,\n    })\n\n    if (newDecos.length) {\n      next = next.add(doc, newDecos)\n    }\n  }\n\n  return next\n}\n\n/**\n * Creates the incremental `StateField<DecorationSet>` used by the slow path\n * (`showOnlyCurrent: false` or `includeChildren: true`).\n *\n * Decorations are mapped through each transaction and only recomputed for\n * top-level blocks touched by document or selection changes.\n * @param options.editor - The editor instance.\n * @param options.options - The resolved placeholder options.\n * @param options.dataAttribute - The prepared `data-*` attribute name.\n * @returns A ProseMirror state field storing the placeholder decoration set.\n */\nexport function createPlaceholderStateField({\n  editor,\n  options,\n  dataAttribute,\n}: CreatePlaceholderStateFieldOptions): StateField<DecorationSet> {\n  return {\n    init(_config, state: EditorState) {\n      const decorations = buildPlaceholderDecorations({\n        editor,\n        options,\n        dataAttribute,\n        doc: state.doc,\n        selection: state.selection,\n      })\n\n      return decorations ?? DecorationSet.empty\n    },\n\n    apply(tr: Transaction, prev: DecorationSet, oldState: EditorState, newState: EditorState) {\n      if (!tr.docChanged && !tr.selectionSet) {\n        return prev\n      }\n\n      const mapped = prev.map(tr.mapping, tr.doc)\n      const ranges = collectRescanRanges(tr, oldState, newState)\n\n      return updateDecorationsInRanges({\n        decorations: mapped,\n        ranges,\n        editor,\n        options,\n        dataAttribute,\n        doc: newState.doc,\n        selection: newState.selection,\n      })\n    },\n  }\n}\n","/**\n * Prepares the placeholder attribute by ensuring it is properly formatted.\n * @param attr - The placeholder attribute string.\n * @returns The prepared placeholder attribute string.\n */\nexport function preparePlaceholderAttribute(attr: string): string {\n  return (\n    attr\n      // replace whitespace with dashes\n      .replace(/\\s+/g, '-')\n      // replace non-alphanumeric  characters\n      // or special chars like $, %, &, etc.\n      // but not dashes\n      .replace(/[^a-zA-Z0-9-]/g, '')\n      // and replace any numeric character at the start\n      .replace(/^[0-9-]+/, '')\n      // and finally replace any stray, leading dashes\n      .replace(/^-+/, '')\n      .toLowerCase()\n  )\n}\n","import type { Editor } from '@tiptap/core'\nimport { Plugin } from '@tiptap/pm/state'\nimport { DecorationSet } from '@tiptap/pm/view'\n\nimport { DEFAULT_DATA_ATTRIBUTE, PLUGIN_KEY } from '../constants.js'\nimport type { PlaceholderOptions } from '../types.js'\nimport { buildPlaceholderDecorations } from '../utils/buildPlaceholderDecorations.js'\nimport { createPlaceholderStateField } from '../utils/placeholderStateField.js'\nimport { preparePlaceholderAttribute } from '../utils/preparePlaceholderAttribute.js'\n\nexport type CreatePluginOptions = {\n  editor: Editor\n  options: PlaceholderOptions\n}\n\n/**\n * Creates the ProseMirror plugin that renders placeholder decorations.\n * @param options.editor - The editor instance.\n * @param options.options - The resolved placeholder options.\n * @returns The configured placeholder plugin.\n */\nexport function createPlaceholderPlugin({ editor, options }: CreatePluginOptions) {\n  const dataAttribute = options.dataAttribute\n    ? `data-${preparePlaceholderAttribute(options.dataAttribute)}`\n    : `data-${DEFAULT_DATA_ATTRIBUTE}`\n\n  const useResolvedPath = options.showOnlyCurrent && !options.includeChildren\n\n  return new Plugin({\n    key: PLUGIN_KEY,\n    ...(useResolvedPath\n      ? {}\n      : {\n          state: createPlaceholderStateField({ editor, options, dataAttribute }),\n        }),\n    props: {\n      decorations: useResolvedPath\n        ? ({ doc, selection }) =>\n            buildPlaceholderDecorations({ editor, options, dataAttribute, doc, selection })\n        : state => {\n            if (options.showOnlyWhenEditable && !editor.isEditable) {\n              return DecorationSet.empty\n            }\n\n            return PLUGIN_KEY.getState(state) ?? DecorationSet.empty\n          },\n    },\n  })\n}\n","import { Extension } from '@tiptap/core'\n\nimport { DEFAULT_DATA_ATTRIBUTE } from './constants.js'\nimport { createPlaceholderPlugin } from './plugins/PlaceholderPlugin.js'\nimport type { PlaceholderOptions } from './types.js'\n\n/**\n * This extension allows you to add a placeholder to your editor.\n * A placeholder is a text that appears when the editor or a node is empty.\n * @see https://www.tiptap.dev/api/extensions/placeholder\n */\nexport const Placeholder = Extension.create<PlaceholderOptions>({\n  name: 'placeholder',\n\n  addOptions() {\n    return {\n      emptyEditorClass: 'is-editor-empty',\n      emptyNodeClass: 'is-empty',\n      dataAttribute: DEFAULT_DATA_ATTRIBUTE,\n      placeholder: 'Write something …',\n      showOnlyWhenEditable: true,\n      showOnlyCurrent: true,\n      includeChildren: false,\n    }\n  },\n\n  addProseMirrorPlugins() {\n    return [createPlaceholderPlugin({ editor: this.editor, options: this.options })]\n  },\n})\n","import { Extension, isNodeSelection, type Editor } from '@tiptap/core'\nimport { Plugin, PluginKey, type EditorState } from '@tiptap/pm/state'\nimport type { EditorView } from '@tiptap/pm/view'\nimport { Decoration, DecorationSet } from '@tiptap/pm/view'\n\nexport type SelectionOptions = {\n  /**\n   * The class name that should be added to the selected text.\n   * @default 'selection'\n   * @example 'is-selected'\n   */\n  className: string\n}\n\n/**\n * Whether the native browser selection should be cleared on blur and restored on focus.\n * Only applies to non-empty text selections in an editable editor.\n */\nfunction shouldSyncDomSelection(state: EditorState, editor: Editor): boolean {\n  return !state.selection.empty && !isNodeSelection(state.selection) && editor.isEditable\n}\n\n/**\n * Whether the selection decoration should be rendered to keep the selection\n * visible while the editor is blurred (and not dragging).\n */\nfunction shouldPreserveSelection(state: EditorState, editor: Editor): boolean {\n  return shouldSyncDomSelection(state, editor) && !editor.isFocused && !editor.view.dragging\n}\n\nfunction clearDomSelection() {\n  window.getSelection()?.removeAllRanges()\n}\n\n/**\n * Sync the native selection from the editor state.\n * @see https://prosemirror.net/docs/ref/#view.EditorView.focus\n */\nfunction restoreDomSelection(view: EditorView) {\n  view.focus()\n}\n\n/**\n * This extension allows you to add a class to the selected text when the editor is blurred.\n * It clears the native browser selection on blur (so `::selection` styles do not overlap the\n * decoration) and restores it when the editor is focused again.\n * @see https://www.tiptap.dev/api/extensions/selection\n */\nexport const Selection = Extension.create<SelectionOptions>({\n  name: 'selection',\n\n  addOptions() {\n    return {\n      className: 'selection',\n    }\n  },\n\n  addProseMirrorPlugins() {\n    const { editor, options } = this\n\n    return [\n      new Plugin({\n        key: new PluginKey('selection'),\n        props: {\n          decorations(state) {\n            if (!shouldPreserveSelection(state, editor)) {\n              return null\n            }\n\n            return DecorationSet.create(state.doc, [\n              Decoration.inline(state.selection.from, state.selection.to, {\n                class: options.className,\n              }),\n            ])\n          },\n          handleDOMEvents: {\n            blur(view) {\n              if (!shouldSyncDomSelection(view.state, editor)) {\n                return false\n              }\n\n              clearDomSelection()\n\n              return false\n            },\n            focus(view) {\n              if (!shouldSyncDomSelection(view.state, editor)) {\n                return false\n              }\n\n              requestAnimationFrame(() => {\n                if (!editor.isDestroyed && view.hasFocus()) {\n                  restoreDomSelection(view)\n                }\n              })\n\n              return false\n            },\n          },\n        },\n      }),\n    ]\n  },\n})\n\nexport default Selection\n","import { Extension } from '@tiptap/core'\nimport type { Node, NodeType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\nexport const skipTrailingNodeMeta = 'skipTrailingNode'\n\nfunction nodeEqualsType({\n  types,\n  node,\n}: {\n  types: NodeType | NodeType[]\n  node: Node | null | undefined\n}) {\n  return (node && Array.isArray(types) && types.includes(node.type)) || node?.type === types\n}\n\n/**\n * Extension based on:\n * - https://github.com/ueberdosis/tiptap/blob/v1/packages/tiptap-extensions/src/extensions/TrailingNode.js\n * - https://github.com/remirror/remirror/blob/e0f1bec4a1e8073ce8f5500d62193e52321155b9/packages/prosemirror-trailing-node/src/trailing-node-plugin.ts\n */\n\nexport interface TrailingNodeOptions {\n  /**\n   * The node type that should be inserted at the end of the document.\n   * @note the node will always be added to the `notAfter` lists to\n   * prevent an infinite loop.\n   * @default undefined\n   */\n  node?: string\n  /**\n   * The node types after which the trailing node should not be inserted.\n   * @default ['paragraph']\n   */\n  notAfter?: string | string[]\n}\n\n/**\n * This extension allows you to add an extra node at the end of the document.\n * @see https://www.tiptap.dev/api/extensions/trailing-node\n */\nexport const TrailingNode = Extension.create<TrailingNodeOptions>({\n  name: 'trailingNode',\n\n  addOptions() {\n    return {\n      node: undefined,\n      notAfter: [],\n    }\n  },\n\n  addProseMirrorPlugins() {\n    const plugin = new PluginKey(this.name)\n    const defaultNode =\n      this.options.node ||\n      this.editor.schema.topNodeType.contentMatch.defaultType?.name ||\n      'paragraph'\n\n    const disabledNodes = Object.entries(this.editor.schema.nodes)\n      .map(([, value]) => value)\n      .filter(node => (this.options.notAfter || []).concat(defaultNode).includes(node.name))\n\n    return [\n      new Plugin({\n        key: plugin,\n        appendTransaction: (transactions, __, state) => {\n          const { doc, tr, schema } = state\n          const shouldInsertNodeAtEnd = plugin.getState(state)\n          const endPosition = doc.content.size\n          const type = schema.nodes[defaultNode]\n\n          if (transactions.some(transaction => transaction.getMeta(skipTrailingNodeMeta))) {\n            return\n          }\n\n          if (!shouldInsertNodeAtEnd) {\n            return\n          }\n\n          return tr.insert(endPosition, type.create())\n        },\n        state: {\n          init: (_, state) => {\n            const lastNode = state.tr.doc.lastChild\n\n            return !nodeEqualsType({ node: lastNode, types: disabledNodes })\n          },\n          apply: (tr, value) => {\n            if (!tr.docChanged) {\n              return value\n            }\n\n            // Ignore transactions from UniqueID extension to prevent infinite loops\n            // when UniqueID adds IDs to newly inserted trailing nodes\n            if (tr.getMeta('__uniqueIDTransaction')) {\n              return value\n            }\n\n            const lastNode = tr.doc.lastChild\n\n            return !nodeEqualsType({ node: lastNode, types: disabledNodes })\n          },\n        },\n      }),\n    ]\n  },\n})\n","import { Extension } from '@tiptap/core'\nimport { history, redo, undo } from '@tiptap/pm/history'\n\nexport interface UndoRedoOptions {\n  /**\n   * The amount of history events that are collected before the oldest events are discarded.\n   * @default 100\n   * @example 50\n   */\n  depth: number\n\n  /**\n   * The delay (in milliseconds) between changes after which a new group should be started.\n   * @default 500\n   * @example 1000\n   */\n  newGroupDelay: number\n}\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    undoRedo: {\n      /**\n       * Undo recent changes\n       * @example editor.commands.undo()\n       */\n      undo: () => ReturnType\n      /**\n       * Reapply reverted changes\n       * @example editor.commands.redo()\n       */\n      redo: () => ReturnType\n    }\n  }\n}\n\n/**\n * This extension allows you to undo and redo recent changes.\n * @see https://www.tiptap.dev/api/extensions/undo-redo\n *\n * **Important**: If the `@tiptap/extension-collaboration` package is used, make sure to remove\n * the `undo-redo` extension, as it is not compatible with the `collaboration` extension.\n *\n * `@tiptap/extension-collaboration` uses its own history implementation.\n */\nexport const UndoRedo = Extension.create<UndoRedoOptions>({\n  name: 'undoRedo',\n\n  addOptions() {\n    return {\n      depth: 100,\n      newGroupDelay: 500,\n    }\n  },\n\n  addCommands() {\n    return {\n      undo:\n        () =>\n        ({ state, dispatch }) => {\n          return undo(state, dispatch)\n        },\n      redo:\n        () =>\n        ({ state, dispatch }) => {\n          return redo(state, dispatch)\n        },\n    }\n  },\n\n  addProseMirrorPlugins() {\n    return [history(this.options)]\n  },\n\n  addKeyboardShortcuts() {\n    return {\n      'Mod-z': () => this.editor.commands.undo(),\n      'Shift-Mod-z': () => this.editor.commands.redo(),\n      'Mod-y': () => this.editor.commands.redo(),\n\n      // Russian keyboard layouts\n      'Mod-я': () => this.editor.commands.undo(),\n      'Shift-Mod-я': () => this.editor.commands.redo(),\n    }\n  },\n})\n"],"mappings":"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"}