{"version":3,"file":"index.cjs","names":["isNodeSelection","Extension","Plugin","PluginKey","DecorationSet","Decoration"],"sources":["../../src/selection/selection.ts"],"sourcesContent":["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({\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"],"mappings":";;;;;;;;;AAkBA,SAAS,uBAAuB,OAAoB,QAAyB;CAC3E,OAAO,CAAC,MAAM,UAAU,SAAS,EAAA,GAACA,aAAAA,gBAAAA,CAAgB,MAAM,SAAS,KAAK,OAAO;AAC/E;;;;;AAMA,SAAS,wBAAwB,OAAoB,QAAyB;CAC5E,OAAO,uBAAuB,OAAO,MAAM,KAAK,CAAC,OAAO,aAAa,CAAC,OAAO,KAAK;AACpF;AAEA,SAAS,oBAAoB;;CAC3B,CAAA,uBAAA,OAAO,aAAa,OAAA,QAAA,yBAAA,KAAA,KAAA,qBAAG,gBAAgB;AACzC;;;;;AAMA,SAAS,oBAAoB,MAAkB;CAC7C,KAAK,MAAM;AACb;;;;;;;AAQA,MAAa,YAAYC,aAAAA,UAAU,OAAyB;CAC1D,MAAM;CAEN,aAAa;EACX,OAAO,EACL,WAAW,YACb;CACF;CAEA,wBAAwB;EACtB,MAAM,EAAE,QAAQ,YAAY;EAE5B,OAAO,CACL,IAAIC,iBAAAA,OAAO;GACT,KAAK,IAAIC,iBAAAA,UAAU,WAAW;GAC9B,OAAO;IACL,YAAY,OAAO;KACjB,IAAI,CAAC,wBAAwB,OAAO,MAAM,GACxC,OAAO;KAGT,OAAOC,gBAAAA,cAAc,OAAO,MAAM,KAAK,CACrCC,gBAAAA,WAAW,OAAO,MAAM,UAAU,MAAM,MAAM,UAAU,IAAI,EAC1D,OAAO,QAAQ,UACjB,CAAC,CACH,CAAC;IACH;IACA,iBAAiB;KACf,KAAK,MAAM;MACT,IAAI,CAAC,uBAAuB,KAAK,OAAO,MAAM,GAC5C,OAAO;MAGT,kBAAkB;MAElB,OAAO;KACT;KACA,MAAM,MAAM;MACV,IAAI,CAAC,uBAAuB,KAAK,OAAO,MAAM,GAC5C,OAAO;MAGT,4BAA4B;OAC1B,IAAI,CAAC,OAAO,eAAe,KAAK,SAAS,GACvC,oBAAoB,IAAI;MAE5B,CAAC;MAED,OAAO;KACT;IACF;GACF;EACF,CAAC,CACH;CACF;AACF,CAAC"}