@bikdotai/bik-component-library 0.0.806 → 0.0.807-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/cjs/components/feature-announcements/FeatureAnnouncementProvider.js.map +1 -1
  2. package/dist/cjs/editor/BikEditor.styles.js +8 -2
  3. package/dist/cjs/editor/BikEditor.styles.js.map +1 -1
  4. package/dist/cjs/editor/BikEditor.utils.js +1 -1
  5. package/dist/cjs/editor/BikEditor.utils.js.map +1 -1
  6. package/dist/cjs/editor/extensions/buildExtensions.js +1 -1
  7. package/dist/cjs/editor/extensions/buildExtensions.js.map +1 -1
  8. package/dist/cjs/editor/extensions/mention/MentionExtension.js +1 -1
  9. package/dist/cjs/editor/extensions/mention/MentionExtension.js.map +1 -1
  10. package/dist/cjs/editor/extensions/plainClipboard/ClipboardNormalizationExtension.js +2 -0
  11. package/dist/cjs/editor/extensions/plainClipboard/ClipboardNormalizationExtension.js.map +1 -0
  12. package/dist/cjs/editor/extensions/plainClipboard/PlainClipboardExtension.js +1 -1
  13. package/dist/cjs/editor/extensions/plainClipboard/PlainClipboardExtension.js.map +1 -1
  14. package/dist/cjs/editor/extensions/plainClipboard/pasteUtils.js +2 -0
  15. package/dist/cjs/editor/extensions/plainClipboard/pasteUtils.js.map +1 -0
  16. package/dist/cjs/editor/extensions/slashCommand/SlashCommandExtension.js +1 -1
  17. package/dist/cjs/editor/extensions/slashCommand/SlashCommandExtension.js.map +1 -1
  18. package/dist/cjs/editor/serializers/toLiveChatText.js +1 -1
  19. package/dist/cjs/editor/serializers/toLiveChatText.js.map +1 -1
  20. package/dist/cjs/editor/serializers/toWhatsAppText.js +1 -1
  21. package/dist/cjs/editor/serializers/toWhatsAppText.js.map +1 -1
  22. package/dist/cjs/src/components/QueryBuilder/Triggers/EVENTS/components/EventsTrigger.d.ts +1 -1
  23. package/dist/cjs/src/components/QueryBuilder/Triggers/EVENTS/selectors/useIGTriggerNameCacheSelector.d.ts +1 -1
  24. package/dist/cjs/src/components/QueryBuilder/Triggers/IG/components/IGTrigger.d.ts +1 -1
  25. package/dist/cjs/src/components/QueryBuilder/Triggers/IG/selectors/useIGTriggerNameCacheSelector.d.ts +1 -1
  26. package/dist/cjs/src/components/QueryBuilder/Triggers/components/BaseTriggerQueryBuilderNode.d.ts +2 -2
  27. package/dist/cjs/src/components/bik-layout/MockMenus.d.ts +1 -0
  28. package/dist/cjs/src/editor/BikEditor.utils.d.ts +15 -10
  29. package/dist/cjs/src/editor/extensions/plainClipboard/ClipboardNormalizationExtension.d.ts +7 -0
  30. package/dist/cjs/src/editor/extensions/plainClipboard/pasteUtils.d.ts +21 -0
  31. package/dist/cjs/src/editor/serializers/toWhatsAppText.d.ts +2 -2
  32. package/dist/esm/components/feature-announcements/FeatureAnnouncementProvider.js.map +1 -1
  33. package/dist/esm/editor/BikEditor.styles.js +6 -0
  34. package/dist/esm/editor/BikEditor.styles.js.map +1 -1
  35. package/dist/esm/editor/BikEditor.utils.js +1 -1
  36. package/dist/esm/editor/BikEditor.utils.js.map +1 -1
  37. package/dist/esm/editor/extensions/buildExtensions.js +1 -1
  38. package/dist/esm/editor/extensions/buildExtensions.js.map +1 -1
  39. package/dist/esm/editor/extensions/mention/MentionExtension.js +1 -1
  40. package/dist/esm/editor/extensions/mention/MentionExtension.js.map +1 -1
  41. package/dist/esm/editor/extensions/plainClipboard/ClipboardNormalizationExtension.js +2 -0
  42. package/dist/esm/editor/extensions/plainClipboard/ClipboardNormalizationExtension.js.map +1 -0
  43. package/dist/esm/editor/extensions/plainClipboard/PlainClipboardExtension.js +1 -1
  44. package/dist/esm/editor/extensions/plainClipboard/PlainClipboardExtension.js.map +1 -1
  45. package/dist/esm/editor/extensions/plainClipboard/pasteUtils.js +2 -0
  46. package/dist/esm/editor/extensions/plainClipboard/pasteUtils.js.map +1 -0
  47. package/dist/esm/editor/extensions/slashCommand/SlashCommandExtension.js +1 -1
  48. package/dist/esm/editor/extensions/slashCommand/SlashCommandExtension.js.map +1 -1
  49. package/dist/esm/editor/serializers/toLiveChatText.js +1 -1
  50. package/dist/esm/editor/serializers/toLiveChatText.js.map +1 -1
  51. package/dist/esm/editor/serializers/toWhatsAppText.js +1 -1
  52. package/dist/esm/editor/serializers/toWhatsAppText.js.map +1 -1
  53. package/dist/esm/src/components/QueryBuilder/Triggers/EVENTS/components/EventsTrigger.d.ts +1 -1
  54. package/dist/esm/src/components/QueryBuilder/Triggers/EVENTS/selectors/useIGTriggerNameCacheSelector.d.ts +1 -1
  55. package/dist/esm/src/components/QueryBuilder/Triggers/IG/components/IGTrigger.d.ts +1 -1
  56. package/dist/esm/src/components/QueryBuilder/Triggers/IG/selectors/useIGTriggerNameCacheSelector.d.ts +1 -1
  57. package/dist/esm/src/components/QueryBuilder/Triggers/components/BaseTriggerQueryBuilderNode.d.ts +2 -2
  58. package/dist/esm/src/components/bik-layout/MockMenus.d.ts +1 -0
  59. package/dist/esm/src/editor/BikEditor.utils.d.ts +15 -10
  60. package/dist/esm/src/editor/extensions/plainClipboard/ClipboardNormalizationExtension.d.ts +7 -0
  61. package/dist/esm/src/editor/extensions/plainClipboard/pasteUtils.d.ts +21 -0
  62. package/dist/esm/src/editor/serializers/toWhatsAppText.d.ts +2 -2
  63. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"MentionExtension.js","sources":["../../../../../src/editor/extensions/mention/MentionExtension.ts"],"sourcesContent":["import { mergeAttributes } from '@tiptap/core';\nimport Mention from '@tiptap/extension-mention';\nimport { ReactRenderer } from '@tiptap/react';\nimport type { ReactNode } from 'react';\nimport type {\n\tMentionDropdownRenderProps,\n\tMentionItem,\n} from '../../BikEditor.types';\nimport {\n\tcreateSuggestionPopup,\n\ttype SuggestionPopup,\n} from '../suggestionPopup';\nimport { MentionDropdown } from './MentionDropdown';\n\nfunction buildRender(\n\tonSelect?: (item: MentionItem, char: '@' | '#') => void,\n\tchar: '@' | '#' = '@',\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode,\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode,\n) {\n\treturn () => {\n\t\tlet component: ReactRenderer;\n\t\tlet popup: SuggestionPopup;\n\n\t\treturn {\n\t\t\tonStart: (props: any) => {\n\t\t\t\tcomponent = new ReactRenderer(MentionDropdown, {\n\t\t\t\t\tprops: { ...props, renderItem, renderDropdown },\n\t\t\t\t\teditor: props.editor,\n\t\t\t\t});\n\t\t\t\tpopup = createSuggestionPopup(component.element, props.clientRect);\n\t\t\t},\n\t\t\tonUpdate: (props: any) => {\n\t\t\t\tcomponent.updateProps({ ...props, renderItem, renderDropdown });\n\t\t\t\tif (!props.items?.length) {\n\t\t\t\t\tpopup.hide();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tpopup.show();\n\t\t\t\tpopup.updatePosition(props.clientRect);\n\t\t\t},\n\t\t\tonKeyDown: (props: any) => {\n\t\t\t\tif (props.event.key === 'Escape') {\n\t\t\t\t\tpopup.hide();\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn (component.ref as any)?.onKeyDown(props) ?? false;\n\t\t\t},\n\t\t\tonExit: () => {\n\t\t\t\tpopup.destroy();\n\t\t\t\tcomponent.destroy();\n\t\t\t},\n\t\t};\n\t};\n}\n\nexport function buildAgentMentionExtension(\n\tagentsRef: { current: MentionItem[] },\n\tonSelect?: (item: MentionItem, char: '@' | '#') => void,\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode,\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode,\n) {\n\treturn Mention.extend({ name: 'mentionAgent' }).configure({\n\t\tHTMLAttributes: { class: 'bik-mention bik-mention--agent' },\n\t\trenderText: ({ options, node }) =>\n\t\t\t`${options.suggestion.char}${node.attrs['label']}`,\n\t\trenderHTML: ({ options, node }) => [\n\t\t\t'span',\n\t\t\tmergeAttributes(options.HTMLAttributes),\n\t\t\t`${options.suggestion.char}${node.attrs['label']}`,\n\t\t],\n\t\tsuggestion: {\n\t\t\tchar: '@',\n\t\t\titems: ({ query }: { query: string }) =>\n\t\t\t\tagentsRef.current.filter((a) =>\n\t\t\t\t\ta.label.toLowerCase().includes(query.toLowerCase()),\n\t\t\t\t),\n\t\t\tcommand: ({ editor, range, props }: any) => {\n\t\t\t\teditor\n\t\t\t\t\t.chain()\n\t\t\t\t\t.focus()\n\t\t\t\t\t.deleteRange(range)\n\t\t\t\t\t.insertContent({\n\t\t\t\t\t\ttype: 'mentionAgent',\n\t\t\t\t\t\tattrs: { id: props.id, label: props.label },\n\t\t\t\t\t})\n\t\t\t\t\t.run();\n\t\t\t\tonSelect?.(props, '@');\n\t\t\t},\n\t\t\trender: buildRender(onSelect, '@', renderItem, renderDropdown),\n\t\t},\n\t});\n}\n\nexport function buildTeamMentionExtension(\n\tteamsRef: { current: MentionItem[] },\n\tonSelect?: (item: MentionItem, char: '@' | '#') => void,\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode,\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode,\n) {\n\treturn Mention.extend({ name: 'mentionTeam' }).configure({\n\t\tHTMLAttributes: { class: 'bik-mention bik-mention--team' },\n\t\trenderText: ({ options, node }) =>\n\t\t\t`${options.suggestion.char}${node.attrs['label']}`,\n\t\trenderHTML: ({ options, node }) => [\n\t\t\t'span',\n\t\t\tmergeAttributes(options.HTMLAttributes),\n\t\t\t`${options.suggestion.char}${node.attrs['label']}`,\n\t\t],\n\t\tsuggestion: {\n\t\t\tchar: '#',\n\t\t\titems: ({ query }: { query: string }) =>\n\t\t\t\tteamsRef.current.filter((t) =>\n\t\t\t\t\tt.label.toLowerCase().includes(query.toLowerCase()),\n\t\t\t\t),\n\t\t\tcommand: ({ editor, range, props }: any) => {\n\t\t\t\teditor\n\t\t\t\t\t.chain()\n\t\t\t\t\t.focus()\n\t\t\t\t\t.deleteRange(range)\n\t\t\t\t\t.insertContent({\n\t\t\t\t\t\ttype: 'mentionTeam',\n\t\t\t\t\t\tattrs: { id: props.id, label: props.label },\n\t\t\t\t\t})\n\t\t\t\t\t.run();\n\t\t\t\tonSelect?.(props, '#');\n\t\t\t},\n\t\t\trender: buildRender(onSelect, '#', renderItem, renderDropdown),\n\t\t},\n\t});\n}\n"],"names":["buildRender","onSelect","renderItem","arguments","length","undefined","renderDropdown","component","popup","onStart","props","ReactRenderer","MentionDropdown","editor","createSuggestionPopup","element","clientRect","onUpdate","updateProps","Object","assign","_a","items","show","updatePosition","hide","onKeyDown","event","key","_b","ref","onExit","destroy","buildAgentMentionExtension","agentsRef","Mention","extend","name","configure","HTMLAttributes","class","renderText","_ref","options","node","suggestion","char","attrs","renderHTML","_ref2","mergeAttributes","_ref3","query","current","filter","a","label","toLowerCase","includes","command","_ref4","range","chain","focus","deleteRange","insertContent","type","id","run","render","buildTeamMentionExtension","teamsRef","_ref5","_ref6","_ref7","t","_ref8"],"mappings":"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"}
1
+ {"version":3,"file":"MentionExtension.js","sources":["../../../../../src/editor/extensions/mention/MentionExtension.ts"],"sourcesContent":["import { mergeAttributes } from '@tiptap/core';\nimport Mention from '@tiptap/extension-mention';\nimport { ReactRenderer } from '@tiptap/react';\nimport type { ReactNode } from 'react';\nimport type {\n\tMentionDropdownRenderProps,\n\tMentionItem,\n} from '../../BikEditor.types';\nimport {\n\tcreateSuggestionPopup,\n\ttype SuggestionPopup,\n} from '../suggestionPopup';\nimport { MentionDropdown } from './MentionDropdown';\n\nfunction buildRender(\n\tonSelect?: (item: MentionItem, char: '@' | '#') => void,\n\tchar: '@' | '#' = '@',\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode,\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode,\n) {\n\treturn () => {\n\t\tlet component: ReactRenderer;\n\t\tlet popup: SuggestionPopup;\n\n\t\treturn {\n\t\t\tonStart: (props: any) => {\n\t\t\t\tcomponent = new ReactRenderer(MentionDropdown, {\n\t\t\t\t\tprops: { ...props, renderItem, renderDropdown },\n\t\t\t\t\teditor: props.editor,\n\t\t\t\t});\n\t\t\t\tpopup = createSuggestionPopup(component.element, props.clientRect);\n\t\t\t},\n\t\t\tonUpdate: (props: any) => {\n\t\t\t\tcomponent.updateProps({ ...props, renderItem, renderDropdown });\n\t\t\t\tif (!props.items?.length) {\n\t\t\t\t\tpopup.hide();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tpopup.show();\n\t\t\t\tpopup.updatePosition(props.clientRect);\n\t\t\t},\n\t\t\tonKeyDown: (props: any) => {\n\t\t\t\tif (props.event.key === 'Escape') {\n\t\t\t\t\tpopup.hide();\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn (component.ref as any)?.onKeyDown(props) ?? false;\n\t\t\t},\n\t\t\tonExit: () => {\n\t\t\t\tpopup.destroy();\n\t\t\t\tcomponent.destroy();\n\t\t\t},\n\t\t};\n\t};\n}\n\nexport function buildAgentMentionExtension(\n\tagentsRef: { current: MentionItem[] },\n\tonSelect?: (item: MentionItem, char: '@' | '#') => void,\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode,\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode,\n) {\n\treturn Mention.extend({ name: 'mentionAgent' }).configure({\n\t\tHTMLAttributes: { class: 'bik-mention bik-mention--agent' },\n\t\trenderText: ({ options, node }) =>\n\t\t\t`${options.suggestion.char}${node.attrs['label']}`,\n\t\trenderHTML: ({ options, node }) => [\n\t\t\t'span',\n\t\t\tmergeAttributes(options.HTMLAttributes),\n\t\t\t`${options.suggestion.char}${node.attrs['label']}`,\n\t\t],\n\t\tsuggestion: {\n\t\t\tchar: '@',\n\t\t\tallowSpaces: true,\n\t\t\titems: ({ query }: { query: string }) =>\n\t\t\t\tagentsRef.current.filter((a) =>\n\t\t\t\t\ta.label.toLowerCase().includes(query.toLowerCase()),\n\t\t\t\t),\n\t\t\tcommand: ({ editor, range, props }: any) => {\n\t\t\t\teditor\n\t\t\t\t\t.chain()\n\t\t\t\t\t.focus()\n\t\t\t\t\t.deleteRange(range)\n\t\t\t\t\t.insertContent({\n\t\t\t\t\t\ttype: 'mentionAgent',\n\t\t\t\t\t\tattrs: { id: props.id, label: props.label },\n\t\t\t\t\t})\n\t\t\t\t\t.run();\n\t\t\t\tonSelect?.(props, '@');\n\t\t\t},\n\t\t\trender: buildRender(onSelect, '@', renderItem, renderDropdown),\n\t\t},\n\t});\n}\n\nexport function buildTeamMentionExtension(\n\tteamsRef: { current: MentionItem[] },\n\tonSelect?: (item: MentionItem, char: '@' | '#') => void,\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode,\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode,\n) {\n\treturn Mention.extend({ name: 'mentionTeam' }).configure({\n\t\tHTMLAttributes: { class: 'bik-mention bik-mention--team' },\n\t\trenderText: ({ options, node }) =>\n\t\t\t`${options.suggestion.char}${node.attrs['label']}`,\n\t\trenderHTML: ({ options, node }) => [\n\t\t\t'span',\n\t\t\tmergeAttributes(options.HTMLAttributes),\n\t\t\t`${options.suggestion.char}${node.attrs['label']}`,\n\t\t],\n\t\tsuggestion: {\n\t\t\tchar: '#',\n\t\t\tallowSpaces: true,\n\t\t\titems: ({ query }: { query: string }) =>\n\t\t\t\tteamsRef.current.filter((t) =>\n\t\t\t\t\tt.label.toLowerCase().includes(query.toLowerCase()),\n\t\t\t\t),\n\t\t\tcommand: ({ editor, range, props }: any) => {\n\t\t\t\teditor\n\t\t\t\t\t.chain()\n\t\t\t\t\t.focus()\n\t\t\t\t\t.deleteRange(range)\n\t\t\t\t\t.insertContent({\n\t\t\t\t\t\ttype: 'mentionTeam',\n\t\t\t\t\t\tattrs: { id: props.id, label: props.label },\n\t\t\t\t\t})\n\t\t\t\t\t.run();\n\t\t\t\tonSelect?.(props, '#');\n\t\t\t},\n\t\t\trender: buildRender(onSelect, '#', renderItem, renderDropdown),\n\t\t},\n\t});\n}\n"],"names":["buildRender","onSelect","renderItem","arguments","length","undefined","renderDropdown","component","popup","onStart","props","ReactRenderer","MentionDropdown","editor","createSuggestionPopup","element","clientRect","onUpdate","updateProps","Object","assign","_a","items","show","updatePosition","hide","onKeyDown","event","key","_b","ref","onExit","destroy","buildAgentMentionExtension","agentsRef","Mention","extend","name","configure","HTMLAttributes","class","renderText","_ref","options","node","suggestion","char","attrs","renderHTML","_ref2","mergeAttributes","allowSpaces","_ref3","query","current","filter","a","label","toLowerCase","includes","command","_ref4","range","chain","focus","deleteRange","insertContent","type","id","run","render","buildTeamMentionExtension","teamsRef","_ref5","_ref6","_ref7","t","_ref8"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{Extension as t}from"../../../node_modules/@tiptap/core/dist/index.js";import{DOMParser as e,Slice as r}from"@tiptap/pm/model";import{Plugin as o}from"@tiptap/pm/state";import{BLOCK_SELECTOR as i,cleanBlockBrs as a,normalizeBlanks as n}from"./pasteUtils.js";const l=t.create({name:"clipboardNormalization",addProseMirrorPlugins:()=>[new o({props:{handlePaste(t,o){var l,p,d;if(null===(p=null===(l=o.clipboardData)||void 0===l?void 0:l.files)||void 0===p?void 0:p.length)return!1;const s=null===(d=o.clipboardData)||void 0===d?void 0:d.getData("text/html");if(!s)return!1;if(s.includes("data-pm-slice"))return!1;const c=document.createElement("div");if(c.innerHTML=s,!c.querySelector(i))return!1;a(c);const m=t.state.schema,u=e.fromSchema(m).parseSlice(c),f=n(u.content),v=new r(f,u.openStart,u.openEnd);return t.dispatch(t.state.tr.replaceSelection(v)),!0}}})]});export{l as ClipboardNormalizationExtension};
2
+ //# sourceMappingURL=ClipboardNormalizationExtension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClipboardNormalizationExtension.js","sources":["../../../../../src/editor/extensions/plainClipboard/ClipboardNormalizationExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport { DOMParser as ProseMirrorDOMParser, Slice } from '@tiptap/pm/model';\nimport { Plugin } from '@tiptap/pm/state';\nimport { BLOCK_SELECTOR, cleanBlockBrs, normalizeBlanks } from './pasteUtils';\n\n/**\n * Lightweight paste normalizer for rich-paste editors (email).\n * Fixes Google Docs' standalone `<br>` between paragraphs and collapses\n * consecutive empty paragraphs — but keeps ALL formatting marks intact.\n */\nexport const ClipboardNormalizationExtension = Extension.create({\n\tname: 'clipboardNormalization',\n\taddProseMirrorPlugins() {\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tprops: {\n\t\t\t\t\thandlePaste(_view, event) {\n\t\t\t\t\t\tif (event.clipboardData?.files?.length) return false;\n\t\t\t\t\t\tconst html = event.clipboardData?.getData('text/html');\n\t\t\t\t\t\tif (!html) return false;\n\t\t\t\t\t\tif (html.includes('data-pm-slice')) return false;\n\n\t\t\t\t\t\tconst container = document.createElement('div');\n\t\t\t\t\t\tcontainer.innerHTML = html;\n\t\t\t\t\t\tif (!container.querySelector(BLOCK_SELECTOR)) return false;\n\n\t\t\t\t\t\tcleanBlockBrs(container);\n\t\t\t\t\t\tconst schema = _view.state.schema;\n\t\t\t\t\t\tconst parsed =\n\t\t\t\t\t\t\tProseMirrorDOMParser.fromSchema(schema).parseSlice(container);\n\t\t\t\t\t\tconst cleaned = normalizeBlanks(parsed.content);\n\t\t\t\t\t\tconst slice = new Slice(cleaned, parsed.openStart, parsed.openEnd);\n\t\t\t\t\t\t_view.dispatch(_view.state.tr.replaceSelection(slice));\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["ClipboardNormalizationExtension","Extension","create","name","addProseMirrorPlugins","Plugin","props","handlePaste","_view","event","_b","clipboardData","_a","files","length","html","_c","getData","includes","container","document","createElement","innerHTML","querySelector","BLOCK_SELECTOR","cleanBlockBrs","schema","state","parsed","ProseMirrorDOMParser","fromSchema","parseSlice","cleaned","normalizeBlanks","content","slice","Slice","openStart","openEnd","dispatch","tr","replaceSelection"],"mappings":"8QAUaA,EAAkCC,EAAUC,OAAO,CAC/DC,KAAM,yBACNC,sBAAqBA,IACb,CACN,IAAIC,EAAO,CACVC,MAAO,CACNC,YAAYC,EAAOC,aAClB,WAAIC,EAAqB,UAArBD,EAAME,qBAAe,IAAAC,OAAA,EAAAA,EAAAC,4BAAOC,OAAQ,OAAO,EAC/C,MAAMC,EAA0B,QAAnBC,EAAAP,EAAME,qBAAa,IAAAK,OAAA,EAAAA,EAAEC,QAAQ,aAC1C,IAAKF,EAAM,OAAO,EAClB,GAAIA,EAAKG,SAAS,iBAAkB,OAAO,EAE3C,MAAMC,EAAYC,SAASC,cAAc,OAEzC,GADAF,EAAUG,UAAYP,GACjBI,EAAUI,cAAcC,GAAiB,OAAO,EAErDC,EAAcN,GACd,MAAMO,EAASlB,EAAMmB,MAAMD,OACrBE,EACLC,EAAqBC,WAAWJ,GAAQK,WAAWZ,GAC9Ca,EAAUC,EAAgBL,EAAOM,SACjCC,EAAQ,IAAIC,EAAMJ,EAASJ,EAAOS,UAAWT,EAAOU,SAE1D,OADA9B,EAAM+B,SAAS/B,EAAMmB,MAAMa,GAAGC,iBAAiBN,KACxC,CACR"}
@@ -1,2 +1,2 @@
1
- import{Extension as t}from"../../../node_modules/@tiptap/core/dist/index.js";import{Slice as a,Fragment as e}from"@tiptap/pm/model";import{Plugin as o}from"@tiptap/pm/state";const r=t.create({name:"plainClipboard",addProseMirrorPlugins:()=>[new o({props:{handlePaste(t,o){var r,i,l,p;if(null===(i=null===(r=o.clipboardData)||void 0===r?void 0:r.files)||void 0===i?void 0:i.length)return!1;const n=null===(l=o.clipboardData)||void 0===l?void 0:l.getData("text/html"),d=null===(p=o.clipboardData)||void 0===p?void 0:p.getData("text/plain");if(!d||!n)return!1;const s=t.state.schema,m=d.split("\n").map((t=>s.node("paragraph",null,t?[s.text(t)]:[]))),c=new a(e.fromArray(m),1,1);return t.dispatch(t.state.tr.replaceSelection(c)),!0}}})]});export{r as PlainClipboardExtension};
1
+ import{Extension as t}from"../../../node_modules/@tiptap/core/dist/index.js";import{DOMParser as e,Slice as r,Fragment as a}from"@tiptap/pm/model";import{Plugin as o}from"@tiptap/pm/state";import{BLOCK_SELECTOR as i,cleanBlockBrs as n,normalizeBlanks as l,stripRichMarks as p}from"./pasteUtils.js";const d=t.create({name:"plainClipboard",addProseMirrorPlugins:()=>[new o({props:{handlePaste(t,o){var d,s,c,m;if(null===(s=null===(d=o.clipboardData)||void 0===d?void 0:d.files)||void 0===s?void 0:s.length)return!1;const u=null===(c=o.clipboardData)||void 0===c?void 0:c.getData("text/html"),f=null===(m=o.clipboardData)||void 0===m?void 0:m.getData("text/plain");if(!f)return!1;if(null==u?void 0:u.includes("data-pm-slice"))return!1;const v=t.state.schema;if(u){const a=document.createElement("div");a.innerHTML=u;if(a.querySelector(i)){n(a);const o=e.fromSchema(v).parseSlice(a),i=l(p(o.content)),d=new r(i,o.openStart,o.openEnd);return t.dispatch(t.state.tr.replaceSelection(d)),!0}}const h=f.split("\n").map((t=>v.node("paragraph",null,t?[v.text(t)]:[]))),S=new r(a.fromArray(h),1,1);return t.dispatch(t.state.tr.replaceSelection(S)),!0}}})]});export{d as PlainClipboardExtension};
2
2
  //# sourceMappingURL=PlainClipboardExtension.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlainClipboardExtension.js","sources":["../../../../../src/editor/extensions/plainClipboard/PlainClipboardExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport { Fragment, Slice } from '@tiptap/pm/model';\nimport { Plugin } from '@tiptap/pm/state';\n\nexport const PlainClipboardExtension = Extension.create({\n\tname: 'plainClipboard',\n\taddProseMirrorPlugins() {\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tprops: {\n\t\t\t\t\thandlePaste(_view, event) {\n\t\t\t\t\t\tif (event.clipboardData?.files?.length) return false; // let ImagePaste handle\n\t\t\t\t\t\tconst html = event.clipboardData?.getData('text/html');\n\t\t\t\t\t\tconst text = event.clipboardData?.getData('text/plain');\n\t\t\t\t\t\tif (!text || !html) return false;\n\n\t\t\t\t\t\tconst schema = _view.state.schema;\n\t\t\t\t\t\t// Split on each newline so that multi-paragraph pastes produce\n\t\t\t\t\t\t// separate paragraph nodes matching the behaviour of pressing\n\t\t\t\t\t\t// Enter between lines. Using schema.text() collapses all newlines\n\t\t\t\t\t\t// because ProseMirror text nodes cannot contain '\\n'.\n\t\t\t\t\t\tconst paragraphs = text\n\t\t\t\t\t\t\t.split('\\n')\n\t\t\t\t\t\t\t.map((line) =>\n\t\t\t\t\t\t\t\tschema.node('paragraph', null, line ? [schema.text(line)] : []),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\tconst slice = new Slice(Fragment.fromArray(paragraphs), 1, 1);\n\t\t\t\t\t\t_view.dispatch(_view.state.tr.replaceSelection(slice));\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["PlainClipboardExtension","Extension","create","name","addProseMirrorPlugins","Plugin","props","handlePaste","_view","event","_b","clipboardData","_a","files","length","html","_c","getData","text","_d","schema","state","paragraphs","split","map","line","node","slice","Slice","Fragment","fromArray","dispatch","tr","replaceSelection"],"mappings":"oLAIaA,EAA0BC,EAAUC,OAAO,CACvDC,KAAM,iBACNC,sBAAqBA,IACb,CACN,IAAIC,EAAO,CACVC,MAAO,CACNC,YAAYC,EAAOC,eAClB,WAAIC,EAAqB,UAArBD,EAAME,qBAAe,IAAAC,OAAA,EAAAA,EAAAC,4BAAOC,OAAQ,OAAO,EAC/C,MAAMC,EAA0B,QAAnBC,EAAAP,EAAME,qBAAa,IAAAK,OAAA,EAAAA,EAAEC,QAAQ,aACpCC,EAA0B,QAAnBC,EAAAV,EAAME,qBAAa,IAAAQ,OAAA,EAAAA,EAAEF,QAAQ,cAC1C,IAAKC,IAASH,EAAM,OAAO,EAE3B,MAAMK,EAASZ,EAAMa,MAAMD,OAKrBE,EAAaJ,EACjBK,MAAM,MACNC,KAAKC,GACLL,EAAOM,KAAK,YAAa,KAAMD,EAAO,CAACL,EAAOF,KAAKO,IAAS,MAExDE,EAAQ,IAAIC,EAAMC,EAASC,UAAUR,GAAa,EAAG,GAE3D,OADAd,EAAMuB,SAASvB,EAAMa,MAAMW,GAAGC,iBAAiBN,KACxC,CACR"}
1
+ {"version":3,"file":"PlainClipboardExtension.js","sources":["../../../../../src/editor/extensions/plainClipboard/PlainClipboardExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport {\n\tFragment,\n\tDOMParser as ProseMirrorDOMParser,\n\tSlice,\n} from '@tiptap/pm/model';\nimport { Plugin } from '@tiptap/pm/state';\nimport {\n\tBLOCK_SELECTOR,\n\tcleanBlockBrs,\n\tnormalizeBlanks,\n\tstripRichMarks,\n} from './pasteUtils';\n\nexport const PlainClipboardExtension = Extension.create({\n\tname: 'plainClipboard',\n\taddProseMirrorPlugins() {\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tprops: {\n\t\t\t\t\thandlePaste(_view, event) {\n\t\t\t\t\t\tif (event.clipboardData?.files?.length) return false;\n\t\t\t\t\t\tconst html = event.clipboardData?.getData('text/html');\n\t\t\t\t\t\tconst text = event.clipboardData?.getData('text/plain');\n\t\t\t\t\t\tif (!text) return false;\n\n\t\t\t\t\t\tif (html?.includes('data-pm-slice')) return false;\n\n\t\t\t\t\t\tconst schema = _view.state.schema;\n\n\t\t\t\t\t\tif (html) {\n\t\t\t\t\t\t\tconst container = document.createElement('div');\n\t\t\t\t\t\t\tcontainer.innerHTML = html;\n\t\t\t\t\t\t\tconst hasBlocks = container.querySelector(BLOCK_SELECTOR);\n\t\t\t\t\t\t\tif (hasBlocks) {\n\t\t\t\t\t\t\t\tcleanBlockBrs(container);\n\t\t\t\t\t\t\t\tconst parsed =\n\t\t\t\t\t\t\t\t\tProseMirrorDOMParser.fromSchema(schema).parseSlice(container);\n\t\t\t\t\t\t\t\tconst cleaned = normalizeBlanks(stripRichMarks(parsed.content));\n\t\t\t\t\t\t\t\tconst slice = new Slice(\n\t\t\t\t\t\t\t\t\tcleaned,\n\t\t\t\t\t\t\t\t\tparsed.openStart,\n\t\t\t\t\t\t\t\t\tparsed.openEnd,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t_view.dispatch(_view.state.tr.replaceSelection(slice));\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst paragraphs = text\n\t\t\t\t\t\t\t.split('\\n')\n\t\t\t\t\t\t\t.map((line) =>\n\t\t\t\t\t\t\t\tschema.node('paragraph', null, line ? [schema.text(line)] : []),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\tconst slice = new Slice(Fragment.fromArray(paragraphs), 1, 1);\n\t\t\t\t\t\t_view.dispatch(_view.state.tr.replaceSelection(slice));\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["PlainClipboardExtension","Extension","create","name","addProseMirrorPlugins","Plugin","props","handlePaste","_view","event","_b","clipboardData","_a","files","length","html","_c","getData","text","_d","includes","schema","state","container","document","createElement","innerHTML","querySelector","BLOCK_SELECTOR","cleanBlockBrs","parsed","ProseMirrorDOMParser","fromSchema","parseSlice","cleaned","normalizeBlanks","stripRichMarks","content","slice","Slice","openStart","openEnd","dispatch","tr","replaceSelection","paragraphs","split","map","line","node","Fragment","fromArray"],"mappings":"gTAcaA,EAA0BC,EAAUC,OAAO,CACvDC,KAAM,iBACNC,sBAAqBA,IACb,CACN,IAAIC,EAAO,CACVC,MAAO,CACNC,YAAYC,EAAOC,eAClB,WAAIC,EAAqB,UAArBD,EAAME,qBAAe,IAAAC,OAAA,EAAAA,EAAAC,4BAAOC,OAAQ,OAAO,EAC/C,MAAMC,EAA0B,QAAnBC,EAAAP,EAAME,qBAAa,IAAAK,OAAA,EAAAA,EAAEC,QAAQ,aACpCC,EAA0B,QAAnBC,EAAAV,EAAME,qBAAa,IAAAQ,OAAA,EAAAA,EAAEF,QAAQ,cAC1C,IAAKC,EAAM,OAAO,EAElB,GAAIH,aAAI,EAAJA,EAAMK,SAAS,iBAAkB,OAAO,EAE5C,MAAMC,EAASb,EAAMc,MAAMD,OAE3B,GAAIN,EAAM,CACT,MAAMQ,EAAYC,SAASC,cAAc,OACzCF,EAAUG,UAAYX,EAEtB,GADkBQ,EAAUI,cAAcC,GAC3B,CACdC,EAAcN,GACd,MAAMO,EACLC,EAAqBC,WAAWX,GAAQY,WAAWV,GAC9CW,EAAUC,EAAgBC,EAAeN,EAAOO,UAChDC,EAAQ,IAAIC,EACjBL,EACAJ,EAAOU,UACPV,EAAOW,SAGR,OADAjC,EAAMkC,SAASlC,EAAMc,MAAMqB,GAAGC,iBAAiBN,KACxC,CACP,CACD,CAED,MAAMO,EAAa3B,EACjB4B,MAAM,MACNC,KAAKC,GACL3B,EAAO4B,KAAK,YAAa,KAAMD,EAAO,CAAC3B,EAAOH,KAAK8B,IAAS,MAExDV,EAAQ,IAAIC,EAAMW,EAASC,UAAUN,GAAa,EAAG,GAE3D,OADArC,EAAMkC,SAASlC,EAAMc,MAAMqB,GAAGC,iBAAiBN,KACxC,CACR"}
@@ -0,0 +1,2 @@
1
+ import{Fragment as e}from"@tiptap/pm/model";const t=new Set(["P","LI","H1","H2","H3","H4","H5","H6","TD","TH","PRE"]),r="p,div,h1,h2,h3,h4,h5,h6,ul,ol,li,blockquote,table,pre",n=new Set(["bold","italic","strike","underline","code"]);function o(e){const r=Array.from(e.querySelectorAll("br"));for(const n of r){let r=!1,o=n.parentElement;for(;o&&o!==e;){if(t.has(o.tagName)){r=!0;break}o=o.parentElement}r||n.parentElement.replaceChild(document.createElement("p"),n)}}function a(t){const r=[];let n=!1;return t.forEach((e=>{var t;if("paragraph"===e.type.name&&1===e.childCount&&"hardBreak"===(null===(t=e.firstChild)||void 0===t?void 0:t.type.name))return n||r.push(e.type.create(e.attrs)),void(n=!0);const o="paragraph"===e.type.name&&0===e.childCount;o&&n||(n=o,e.isBlock&&!e.isLeaf?r.push(e.copy(a(e.content))):r.push(e))})),e.from(r)}function l(t){const r=[];return t.forEach((e=>{if(e.isText){const t=e.marks.filter((e=>n.has(e.type.name)));r.push(t.length===e.marks.length?e:e.mark(t))}else r.push(e.copy(l(e.content)))})),e.from(r)}export{r as BLOCK_SELECTOR,t as TEXTBLOCK_TAGS,o as cleanBlockBrs,a as normalizeBlanks,l as stripRichMarks};
2
+ //# sourceMappingURL=pasteUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pasteUtils.js","sources":["../../../../../src/editor/extensions/plainClipboard/pasteUtils.ts"],"sourcesContent":["import { Fragment, Node as PMNode } from '@tiptap/pm/model';\n\nexport const TEXTBLOCK_TAGS = new Set([\n\t'P',\n\t'LI',\n\t'H1',\n\t'H2',\n\t'H3',\n\t'H4',\n\t'H5',\n\t'H6',\n\t'TD',\n\t'TH',\n\t'PRE',\n]);\n\nexport const BLOCK_SELECTOR =\n\t'p,div,h1,h2,h3,h4,h5,h6,ul,ol,li,blockquote,table,pre';\n\nconst BASIC_MARKS = new Set(['bold', 'italic', 'strike', 'underline', 'code']);\n\n/**\n * Replace `<br>` elements that sit at block level (not inside a textblock\n * like `<p>`, `<li>`, etc.) with empty `<p></p>` elements. Google Docs\n * puts standalone `<br>` tags between paragraphs to represent blank lines.\n * Without this, ProseMirror parses them as top-level hardBreak nodes.\n */\nexport function cleanBlockBrs(container: HTMLElement): void {\n\tconst brs = Array.from(container.querySelectorAll('br'));\n\tfor (const br of brs) {\n\t\tlet insideTextblock = false;\n\t\tlet el = br.parentElement;\n\t\twhile (el && el !== container) {\n\t\t\tif (TEXTBLOCK_TAGS.has(el.tagName)) {\n\t\t\t\tinsideTextblock = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tel = el.parentElement;\n\t\t}\n\t\tif (!insideTextblock) {\n\t\t\tbr.parentElement!.replaceChild(document.createElement('p'), br);\n\t\t}\n\t}\n}\n\n/**\n * 1. Convert paragraphs containing only a hard_break into empty paragraphs.\n * 2. Collapse consecutive empty paragraphs into one.\n */\nexport function normalizeBlanks(fragment: Fragment): Fragment {\n\tconst nodes: PMNode[] = [];\n\tlet prevEmpty = false;\n\tfragment.forEach((node) => {\n\t\tconst isHardBreakOnly =\n\t\t\tnode.type.name === 'paragraph' &&\n\t\t\tnode.childCount === 1 &&\n\t\t\tnode.firstChild?.type.name === 'hardBreak';\n\t\tif (isHardBreakOnly) {\n\t\t\tif (!prevEmpty) nodes.push(node.type.create(node.attrs));\n\t\t\tprevEmpty = true;\n\t\t\treturn;\n\t\t}\n\t\tconst isEmpty = node.type.name === 'paragraph' && node.childCount === 0;\n\t\tif (isEmpty && prevEmpty) return;\n\t\tprevEmpty = isEmpty;\n\t\tif (node.isBlock && !node.isLeaf) {\n\t\t\tnodes.push(node.copy(normalizeBlanks(node.content)));\n\t\t} else {\n\t\t\tnodes.push(node);\n\t\t}\n\t});\n\treturn Fragment.from(nodes);\n}\n\n/**\n * Strip only \"rich\" marks (link, textStyle, highlight, etc.) while keeping\n * basic formatting marks (bold, italic, strike, underline, code) that\n * messaging channels can represent.\n */\nexport function stripRichMarks(fragment: Fragment): Fragment {\n\tconst nodes: PMNode[] = [];\n\tfragment.forEach((node) => {\n\t\tif (node.isText) {\n\t\t\tconst kept = node.marks.filter((m) => BASIC_MARKS.has(m.type.name));\n\t\t\tnodes.push(kept.length === node.marks.length ? node : node.mark(kept));\n\t\t} else {\n\t\t\tnodes.push(node.copy(stripRichMarks(node.content)));\n\t\t}\n\t});\n\treturn Fragment.from(nodes);\n}\n"],"names":["TEXTBLOCK_TAGS","Set","BLOCK_SELECTOR","BASIC_MARKS","cleanBlockBrs","container","brs","Array","from","querySelectorAll","br","insideTextblock","el","parentElement","has","tagName","replaceChild","document","createElement","normalizeBlanks","fragment","nodes","prevEmpty","forEach","node","type","name","childCount","_a","firstChild","push","create","attrs","isEmpty","isBlock","isLeaf","copy","content","Fragment","stripRichMarks","isText","kept","marks","filter","m","length","mark"],"mappings":"4CAEaA,MAAAA,EAAiB,IAAIC,IAAI,CACrC,IACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,QAGYC,EACZ,wDAEKC,EAAc,IAAIF,IAAI,CAAC,OAAQ,SAAU,SAAU,YAAa,SAQhE,SAAUG,EAAcC,GAC7B,MAAMC,EAAMC,MAAMC,KAAKH,EAAUI,iBAAiB,OAClD,IAAK,MAAMC,KAAMJ,EAAK,CACrB,IAAIK,GAAkB,EAClBC,EAAKF,EAAGG,cACZ,KAAOD,GAAMA,IAAOP,GAAW,CAC9B,GAAIL,EAAec,IAAIF,EAAGG,SAAU,CACnCJ,GAAkB,EAClB,KACA,CACDC,EAAKA,EAAGC,aACR,CACIF,GACJD,EAAGG,cAAeG,aAAaC,SAASC,cAAc,KAAMR,EAE7D,CACF,CAMM,SAAUS,EAAgBC,GAC/B,MAAMC,EAAkB,GACxB,IAAIC,GAAY,EAoBhB,OAnBAF,EAASG,SAASC,UAKjB,GAHoB,cAAnBA,EAAKC,KAAKC,MACU,IAApBF,EAAKG,YAC0B,eAAhB,QAAfC,EAAAJ,EAAKK,kBAAU,IAAAD,OAAA,EAAAA,EAAEH,KAAKC,MAItB,OAFKJ,GAAWD,EAAMS,KAAKN,EAAKC,KAAKM,OAAOP,EAAKQ,aACjDV,GAAY,GAGb,MAAMW,EAA6B,cAAnBT,EAAKC,KAAKC,MAA4C,IAApBF,EAAKG,WACnDM,GAAWX,IACfA,EAAYW,EACRT,EAAKU,UAAYV,EAAKW,OACzBd,EAAMS,KAAKN,EAAKY,KAAKjB,EAAgBK,EAAKa,WAE1ChB,EAAMS,KAAKN,GACX,IAEKc,EAAS9B,KAAKa,EACtB,CAOM,SAAUkB,EAAenB,GAC9B,MAAMC,EAAkB,GASxB,OARAD,EAASG,SAASC,IACjB,GAAIA,EAAKgB,OAAQ,CAChB,MAAMC,EAAOjB,EAAKkB,MAAMC,QAAQC,GAAMzC,EAAYW,IAAI8B,EAAEnB,KAAKC,QAC7DL,EAAMS,KAAKW,EAAKI,SAAWrB,EAAKkB,MAAMG,OAASrB,EAAOA,EAAKsB,KAAKL,GAChE,MACApB,EAAMS,KAAKN,EAAKY,KAAKG,EAAef,EAAKa,UACzC,IAEKC,EAAS9B,KAAKa,EACtB"}
@@ -1,2 +1,2 @@
1
- import{Extension as e}from"../../../node_modules/@tiptap/core/dist/index.js";import{ReactRenderer as r}from"@tiptap/react";import t from"@tiptap/suggestion";import{createSuggestionPopup as o}from"../suggestionPopup.js";import{SlashCommandMenu as n}from"./SlashCommandMenu.js";function i(i,s,d,a){return e.create({name:"slashCommand",addProseMirrorPlugins(){return[t({editor:this.editor,char:"/",items:e=>{let{query:r}=e;return i.current.filter((e=>e.label.toLowerCase().includes(r.toLowerCase()))).slice(0,20)},command:e=>{let{editor:r,range:t,props:o}=e;r.chain().focus().deleteRange(t).run(),null==s||s(o)},render:()=>{let e,t;return{onStart:i=>{e=new r(n,{props:Object.assign(Object.assign({},i),{renderItem:d,renderDropdown:a}),editor:i.editor}),t=o(e.element,i.clientRect)},onUpdate:r=>{var o;e.updateProps(Object.assign(Object.assign({},r),{renderItem:d,renderDropdown:a})),(null===(o=r.items)||void 0===o?void 0:o.length)?(t.show(),t.updatePosition(r.clientRect)):t.hide()},onKeyDown:r=>{var o,n;return"Escape"===r.event.key?(t.hide(),!0):null!==(n=null===(o=e.ref)||void 0===o?void 0:o.onKeyDown(r))&&void 0!==n&&n},onExit:()=>{t.destroy(),e.destroy()}}}})]}})}export{i as buildSlashCommandExtension};
1
+ import{Extension as e}from"../../../node_modules/@tiptap/core/dist/index.js";import{ReactRenderer as r}from"@tiptap/react";import t from"@tiptap/suggestion";import{createSuggestionPopup as o}from"../suggestionPopup.js";import{SlashCommandMenu as n}from"./SlashCommandMenu.js";function i(i,s,d,a){return e.create({name:"slashCommand",addProseMirrorPlugins(){return[t({editor:this.editor,char:"/",allowSpaces:!0,items:e=>{let{query:r}=e;return i.current.filter((e=>e.label.toLowerCase().includes(r.toLowerCase()))).slice(0,20)},command:e=>{let{editor:r,range:t,props:o}=e;r.chain().focus().deleteRange(t).run(),null==s||s(o)},render:()=>{let e,t;return{onStart:i=>{e=new r(n,{props:Object.assign(Object.assign({},i),{renderItem:d,renderDropdown:a}),editor:i.editor}),t=o(e.element,i.clientRect)},onUpdate:r=>{var o;e.updateProps(Object.assign(Object.assign({},r),{renderItem:d,renderDropdown:a})),(null===(o=r.items)||void 0===o?void 0:o.length)?(t.show(),t.updatePosition(r.clientRect)):t.hide()},onKeyDown:r=>{var o,n;return"Escape"===r.event.key?(t.hide(),!0):null!==(n=null===(o=e.ref)||void 0===o?void 0:o.onKeyDown(r))&&void 0!==n&&n},onExit:()=>{t.destroy(),e.destroy()}}}})]}})}export{i as buildSlashCommandExtension};
2
2
  //# sourceMappingURL=SlashCommandExtension.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SlashCommandExtension.js","sources":["../../../../../src/editor/extensions/slashCommand/SlashCommandExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport { ReactRenderer } from '@tiptap/react';\nimport Suggestion from '@tiptap/suggestion';\nimport type { ReactNode } from 'react';\nimport type {\n\tSlashCommandDropdownRenderProps,\n\tSlashCommandItem,\n} from '../../BikEditor.types';\nimport {\n\tcreateSuggestionPopup,\n\ttype SuggestionPopup,\n} from '../suggestionPopup';\nimport { SlashCommandMenu } from './SlashCommandMenu';\n\nexport function buildSlashCommandExtension(\n\tcommandsRef: { current: SlashCommandItem[] },\n\tonSelect?: (command: SlashCommandItem) => void,\n\trenderItem?: (item: SlashCommandItem, isActive: boolean) => ReactNode,\n\trenderDropdown?: (props: SlashCommandDropdownRenderProps) => ReactNode,\n) {\n\treturn Extension.create({\n\t\tname: 'slashCommand',\n\t\taddProseMirrorPlugins() {\n\t\t\treturn [\n\t\t\t\tSuggestion({\n\t\t\t\t\teditor: this.editor,\n\t\t\t\t\tchar: '/',\n\t\t\t\t\titems: ({ query }: any) =>\n\t\t\t\t\t\tcommandsRef.current\n\t\t\t\t\t\t\t.filter((c) =>\n\t\t\t\t\t\t\t\tc.label.toLowerCase().includes(query.toLowerCase()),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.slice(0, 20),\n\t\t\t\t\tcommand: ({ editor, range, props }: any) => {\n\t\t\t\t\t\teditor.chain().focus().deleteRange(range).run();\n\t\t\t\t\t\tonSelect?.(props);\n\t\t\t\t\t},\n\t\t\t\t\trender: () => {\n\t\t\t\t\t\tlet component: ReactRenderer;\n\t\t\t\t\t\tlet popup: SuggestionPopup;\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tonStart: (props: any) => {\n\t\t\t\t\t\t\t\tcomponent = new ReactRenderer(SlashCommandMenu, {\n\t\t\t\t\t\t\t\t\tprops: { ...props, renderItem, renderDropdown },\n\t\t\t\t\t\t\t\t\teditor: props.editor,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tpopup = createSuggestionPopup(\n\t\t\t\t\t\t\t\t\tcomponent.element,\n\t\t\t\t\t\t\t\t\tprops.clientRect,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tonUpdate: (props: any) => {\n\t\t\t\t\t\t\t\tcomponent.updateProps({ ...props, renderItem, renderDropdown });\n\t\t\t\t\t\t\t\tif (!props.items?.length) {\n\t\t\t\t\t\t\t\t\tpopup.hide();\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tpopup.show();\n\t\t\t\t\t\t\t\tpopup.updatePosition(props.clientRect);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tonKeyDown: (props: any) => {\n\t\t\t\t\t\t\t\tif (props.event.key === 'Escape') {\n\t\t\t\t\t\t\t\t\tpopup.hide();\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn (component.ref as any)?.onKeyDown(props) ?? false;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tonExit: () => {\n\t\t\t\t\t\t\t\tpopup.destroy();\n\t\t\t\t\t\t\t\tcomponent.destroy();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t];\n\t\t},\n\t});\n}\n"],"names":["buildSlashCommandExtension","commandsRef","onSelect","renderItem","renderDropdown","Extension","create","name","addProseMirrorPlugins","Suggestion","editor","this","char","items","_ref","query","current","filter","c","label","toLowerCase","includes","slice","command","_ref2","range","props","chain","focus","deleteRange","run","render","component","popup","onStart","ReactRenderer","SlashCommandMenu","createSuggestionPopup","element","clientRect","onUpdate","updateProps","Object","assign","_a","length","show","updatePosition","hide","onKeyDown","event","key","_b","ref","onExit","destroy"],"mappings":"oRAcM,SAAUA,EACfC,EACAC,EACAC,EACAC,GAEA,OAAOC,EAAUC,OAAO,CACvBC,KAAM,eACNC,wBACC,MAAO,CACNC,EAAW,CACVC,OAAQC,KAAKD,OACbE,KAAM,IACNC,MAAOC,IAAA,IAACC,MAAEA,GAAYD,EAAA,OACrBb,EAAYe,QACVC,QAAQC,GACRA,EAAEC,MAAMC,cAAcC,SAASN,EAAMK,iBAErCE,MAAM,EAAG,GAAG,EACfC,QAASC,IAAkC,IAAjCd,OAAEA,EAAMe,MAAEA,EAAKC,MAAEA,GAAYF,EACtCd,EAAOiB,QAAQC,QAAQC,YAAYJ,GAAOK,MAC1C5B,SAAAA,EAAWwB,EAAM,EAElBK,OAAQA,KACP,IAAIC,EACAC,EAEJ,MAAO,CACNC,QAAUR,IACTM,EAAY,IAAIG,EAAcC,EAAkB,CAC/CV,qCAAYA,GAAK,CAAEvB,aAAYC,mBAC/BM,OAAQgB,EAAMhB,SAEfuB,EAAQI,EACPL,EAAUM,QACVZ,EAAMa,WACN,EAEFC,SAAWd,UACVM,EAAUS,YAAiBC,OAAAC,OAAAD,OAAAC,OAAA,CAAA,EAAAjB,IAAOvB,aAAYC,qBAC9B,QAAXwC,EAAAlB,EAAMb,aAAK,IAAA+B,OAAA,EAAAA,EAAEC,SAIlBZ,EAAMa,OACNb,EAAMc,eAAerB,EAAMa,aAJ1BN,EAAMe,MAI+B,EAEvCC,UAAYvB,YACX,MAAwB,WAApBA,EAAMwB,MAAMC,KACflB,EAAMe,QACC,GAE2C,QAA5CI,EAAsB,QAAtBR,EAACZ,EAAUqB,WAAW,IAAAT,OAAA,EAAAA,EAAEK,UAAUvB,UAAU,IAAA0B,GAAAA,CAAK,EAEzDE,OAAQA,KACPrB,EAAMsB,UACNvB,EAAUuB,SAAS,EAEpB,IAIL,GAEF"}
1
+ {"version":3,"file":"SlashCommandExtension.js","sources":["../../../../../src/editor/extensions/slashCommand/SlashCommandExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport { ReactRenderer } from '@tiptap/react';\nimport Suggestion from '@tiptap/suggestion';\nimport type { ReactNode } from 'react';\nimport type {\n\tSlashCommandDropdownRenderProps,\n\tSlashCommandItem,\n} from '../../BikEditor.types';\nimport {\n\tcreateSuggestionPopup,\n\ttype SuggestionPopup,\n} from '../suggestionPopup';\nimport { SlashCommandMenu } from './SlashCommandMenu';\n\nexport function buildSlashCommandExtension(\n\tcommandsRef: { current: SlashCommandItem[] },\n\tonSelect?: (command: SlashCommandItem) => void,\n\trenderItem?: (item: SlashCommandItem, isActive: boolean) => ReactNode,\n\trenderDropdown?: (props: SlashCommandDropdownRenderProps) => ReactNode,\n) {\n\treturn Extension.create({\n\t\tname: 'slashCommand',\n\t\taddProseMirrorPlugins() {\n\t\t\treturn [\n\t\t\t\tSuggestion({\n\t\t\t\t\teditor: this.editor,\n\t\t\t\t\tchar: '/',\n\t\t\t\t\tallowSpaces: true,\n\t\t\t\t\titems: ({ query }: any) =>\n\t\t\t\t\t\tcommandsRef.current\n\t\t\t\t\t\t\t.filter((c) =>\n\t\t\t\t\t\t\t\tc.label.toLowerCase().includes(query.toLowerCase()),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.slice(0, 20),\n\t\t\t\t\tcommand: ({ editor, range, props }: any) => {\n\t\t\t\t\t\teditor.chain().focus().deleteRange(range).run();\n\t\t\t\t\t\tonSelect?.(props);\n\t\t\t\t\t},\n\t\t\t\t\trender: () => {\n\t\t\t\t\t\tlet component: ReactRenderer;\n\t\t\t\t\t\tlet popup: SuggestionPopup;\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tonStart: (props: any) => {\n\t\t\t\t\t\t\t\tcomponent = new ReactRenderer(SlashCommandMenu, {\n\t\t\t\t\t\t\t\t\tprops: { ...props, renderItem, renderDropdown },\n\t\t\t\t\t\t\t\t\teditor: props.editor,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tpopup = createSuggestionPopup(\n\t\t\t\t\t\t\t\t\tcomponent.element,\n\t\t\t\t\t\t\t\t\tprops.clientRect,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tonUpdate: (props: any) => {\n\t\t\t\t\t\t\t\tcomponent.updateProps({ ...props, renderItem, renderDropdown });\n\t\t\t\t\t\t\t\tif (!props.items?.length) {\n\t\t\t\t\t\t\t\t\tpopup.hide();\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tpopup.show();\n\t\t\t\t\t\t\t\tpopup.updatePosition(props.clientRect);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tonKeyDown: (props: any) => {\n\t\t\t\t\t\t\t\tif (props.event.key === 'Escape') {\n\t\t\t\t\t\t\t\t\tpopup.hide();\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn (component.ref as any)?.onKeyDown(props) ?? false;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tonExit: () => {\n\t\t\t\t\t\t\t\tpopup.destroy();\n\t\t\t\t\t\t\t\tcomponent.destroy();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t];\n\t\t},\n\t});\n}\n"],"names":["buildSlashCommandExtension","commandsRef","onSelect","renderItem","renderDropdown","Extension","create","name","addProseMirrorPlugins","Suggestion","editor","this","char","allowSpaces","items","_ref","query","current","filter","c","label","toLowerCase","includes","slice","command","_ref2","range","props","chain","focus","deleteRange","run","render","component","popup","onStart","ReactRenderer","SlashCommandMenu","createSuggestionPopup","element","clientRect","onUpdate","updateProps","Object","assign","_a","length","show","updatePosition","hide","onKeyDown","event","key","_b","ref","onExit","destroy"],"mappings":"oRAcM,SAAUA,EACfC,EACAC,EACAC,EACAC,GAEA,OAAOC,EAAUC,OAAO,CACvBC,KAAM,eACNC,wBACC,MAAO,CACNC,EAAW,CACVC,OAAQC,KAAKD,OACbE,KAAM,IACNC,aAAa,EACbC,MAAOC,IAAA,IAACC,MAAEA,GAAYD,EAAA,OACrBd,EAAYgB,QACVC,QAAQC,GACRA,EAAEC,MAAMC,cAAcC,SAASN,EAAMK,iBAErCE,MAAM,EAAG,GAAG,EACfC,QAASC,IAAkC,IAAjCf,OAAEA,EAAMgB,MAAEA,EAAKC,MAAEA,GAAYF,EACtCf,EAAOkB,QAAQC,QAAQC,YAAYJ,GAAOK,MAC1C7B,SAAAA,EAAWyB,EAAM,EAElBK,OAAQA,KACP,IAAIC,EACAC,EAEJ,MAAO,CACNC,QAAUR,IACTM,EAAY,IAAIG,EAAcC,EAAkB,CAC/CV,qCAAYA,GAAK,CAAExB,aAAYC,mBAC/BM,OAAQiB,EAAMjB,SAEfwB,EAAQI,EACPL,EAAUM,QACVZ,EAAMa,WACN,EAEFC,SAAWd,UACVM,EAAUS,YAAiBC,OAAAC,OAAAD,OAAAC,OAAA,CAAA,EAAAjB,IAAOxB,aAAYC,qBAC9B,QAAXyC,EAAAlB,EAAMb,aAAK,IAAA+B,OAAA,EAAAA,EAAEC,SAIlBZ,EAAMa,OACNb,EAAMc,eAAerB,EAAMa,aAJ1BN,EAAMe,MAI+B,EAEvCC,UAAYvB,YACX,MAAwB,WAApBA,EAAMwB,MAAMC,KACflB,EAAMe,QACC,GAE2C,QAA5CI,EAAsB,QAAtBR,EAACZ,EAAUqB,WAAW,IAAAT,OAAA,EAAAA,EAAEK,UAAUvB,UAAU,IAAA0B,GAAAA,CAAK,EAEzDE,OAAQA,KACPrB,EAAMsB,UACNvB,EAAUuB,SAAS,EAEpB,IAIL,GAEF"}
@@ -1,2 +1,2 @@
1
- function e(e){if(!e)return"";if("undefined"!=typeof document){return r((new DOMParser).parseFromString(e,"text/html").body).replace(/\n{3,}/g,"\n\n").trim()}return function(e){return e.replace(/<strong[^>]*>([\s\S]*?)<\/strong>/gi,"*$1*").replace(/<b[^>]*>([\s\S]*?)<\/b>/gi,"*$1*").replace(/<em[^>]*>([\s\S]*?)<\/em>/gi,"$1").replace(/<i[^>]*>([\s\S]*?)<\/i>/gi,"$1").replace(/<s[^>]*>([\s\S]*?)<\/s>/gi,"$1").replace(/<del[^>]*>([\s\S]*?)<\/del>/gi,"$1").replace(/<a[^>]*>([\s\S]*?)<\/a>/gi,"$1").replace(/<br\s*\/?>/gi,"\n").replace(/<\/p>/gi,"\n").replace(/<\/div>/gi,"\n").replace(/<\/h[1-6]>/gi,"\n").replace(/<li[^>]*>/gi,"• ").replace(/<\/li>/gi,"\n").replace(/<[^>]+>/g,"").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&nbsp;/g," ").replace(/\n{3,}/g,"\n\n").trim()}(e)}function r(e){var a;if(e.nodeType===Node.TEXT_NODE)return null!==(a=e.textContent)&&void 0!==a?a:"";if(e.nodeType!==Node.ELEMENT_NODE)return"";const n=e,c=n.tagName.toLowerCase(),s=function(e){return Array.from(e.childNodes).map(r).join("")}(n);switch(c){case"strong":case"b":return s?`*${s}*`:"";case"em":case"i":case"s":case"del":case"strike":case"code":case"pre":case"a":case"ul":case"ol":case"body":default:return s;case"br":return"\n";case"p":case"div":return s?`${s}\n`:"\n";case"h1":case"h2":case"h3":case"h4":case"h5":case"h6":return s?`*${s}*\n`:"\n";case"li":return`• ${s.trimEnd()}\n`;case"blockquote":return s+"\n"}}export{e as toLiveChatText};
1
+ function e(e){if(!e)return"";if("undefined"!=typeof document){return r((new DOMParser).parseFromString(e,"text/html").body).trim()}return function(e){return e.replace(/<strong[^>]*>([\s\S]*?)<\/strong>/gi,"*$1*").replace(/<b[^>]*>([\s\S]*?)<\/b>/gi,"*$1*").replace(/<em[^>]*>([\s\S]*?)<\/em>/gi,"$1").replace(/<i[^>]*>([\s\S]*?)<\/i>/gi,"$1").replace(/<s[^>]*>([\s\S]*?)<\/s>/gi,"$1").replace(/<del[^>]*>([\s\S]*?)<\/del>/gi,"$1").replace(/<a[^>]*>([\s\S]*?)<\/a>/gi,"$1").replace(/<p[^>]*>\s*<br\s*\/?>\s*<\/p>/gi,"\n").replace(/<br\s*\/?>/gi,"\n").replace(/<\/p>/gi,"\n").replace(/<\/div>/gi,"\n").replace(/<\/h[1-6]>/gi,"\n").replace(/<li[^>]*>/gi,"• ").replace(/<\/li>/gi,"\n").replace(/<[^>]+>/g,"").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&nbsp;/g," ").trim()}(e)}function r(e){var a,n,c;if(e.nodeType===Node.TEXT_NODE)return null!==(a=e.textContent)&&void 0!==a?a:"";if(e.nodeType!==Node.ELEMENT_NODE)return"";const s=e,t=s.tagName.toLowerCase(),i=function(e){return Array.from(e.childNodes).map(r).join("")}(s);switch(t){case"strong":case"b":return i?`*${i}*`:"";case"em":case"i":case"s":case"del":case"strike":case"code":case"pre":case"a":case"ul":case"ol":case"body":default:return i;case"br":return"\n";case"p":case"div":return 1===s.childNodes.length&&"br"===(null===(c=null===(n=s.firstChild)||void 0===n?void 0:n.tagName)||void 0===c?void 0:c.toLowerCase())?"\n":i?`${i}\n`:"\n";case"h1":case"h2":case"h3":case"h4":case"h5":case"h6":return i?`*${i}*\n`:"\n";case"li":return`• ${i.trimEnd()}\n`;case"blockquote":return i+"\n"}}export{e as toLiveChatText};
2
2
  //# sourceMappingURL=toLiveChatText.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"toLiveChatText.js","sources":["../../../../src/editor/serializers/toLiveChatText.ts"],"sourcesContent":["/**\n * Converts TipTap HTML to LiveChat plain text.\n *\n * LiveChat supports **bold** (`*text*`) but NOT italic or strikethrough.\n * Italic and strikethrough marks are stripped — the inner text is preserved.\n * Links emit only the display text (href is dropped).\n *\n * @example\n * const { html } = ref.current?.getContent();\n * const lcText = toLiveChatText(html);\n * sendLiveChat({ text: lcText });\n */\nexport function toLiveChatText(html: string): string {\n\tif (!html) return '';\n\n\tif (typeof document !== 'undefined') {\n\t\tconst doc = new DOMParser().parseFromString(html, 'text/html');\n\t\treturn serializeNode(doc.body)\n\t\t\t.replace(/\\n{3,}/g, '\\n\\n')\n\t\t\t.trim();\n\t}\n\n\treturn ssrFallback(html);\n}\n\n// ---------------------------------------------------------------------------\n// Browser path — DOM-based, handles nested marks correctly\n// ---------------------------------------------------------------------------\n\nfunction serializeNode(node: Node): string {\n\tif (node.nodeType === Node.TEXT_NODE) return node.textContent ?? '';\n\tif (node.nodeType !== Node.ELEMENT_NODE) return '';\n\n\tconst el = node as Element;\n\tconst tag = el.tagName.toLowerCase();\n\tconst inner = serializeChildren(el);\n\n\tswitch (tag) {\n\t\tcase 'strong':\n\t\tcase 'b':\n\t\t\treturn inner ? `*${inner}*` : '';\n\n\t\t// Italic and strike: strip marks, keep inner text\n\t\tcase 'em':\n\t\tcase 'i':\n\t\tcase 's':\n\t\tcase 'del':\n\t\tcase 'strike':\n\t\t\treturn inner;\n\n\t\tcase 'code':\n\t\tcase 'pre':\n\t\t\treturn inner;\n\n\t\tcase 'a':\n\t\t\t// LiveChat does not support hyperlinks — emit display text only\n\t\t\treturn inner;\n\n\t\tcase 'br':\n\t\t\treturn '\\n';\n\n\t\tcase 'p':\n\t\tcase 'div':\n\t\t\treturn inner ? `${inner}\\n` : '\\n';\n\n\t\tcase 'h1':\n\t\tcase 'h2':\n\t\tcase 'h3':\n\t\tcase 'h4':\n\t\tcase 'h5':\n\t\tcase 'h6':\n\t\t\treturn inner ? `*${inner}*\\n` : '\\n';\n\n\t\tcase 'ul':\n\t\tcase 'ol':\n\t\t\treturn inner;\n\n\t\tcase 'li':\n\t\t\treturn `• ${inner.trimEnd()}\\n`;\n\n\t\tcase 'blockquote':\n\t\t\treturn inner + '\\n';\n\n\t\tcase 'body':\n\t\tdefault:\n\t\t\treturn inner;\n\t}\n}\n\nfunction serializeChildren(el: Element): string {\n\treturn Array.from(el.childNodes).map(serializeNode).join('');\n}\n\n// ---------------------------------------------------------------------------\n// SSR / Node.js fallback — regex-based, best-effort for simple markup\n// ---------------------------------------------------------------------------\n\nfunction ssrFallback(html: string): string {\n\treturn html\n\t\t.replace(/<strong[^>]*>([\\s\\S]*?)<\\/strong>/gi, '*$1*')\n\t\t.replace(/<b[^>]*>([\\s\\S]*?)<\\/b>/gi, '*$1*')\n\t\t.replace(/<em[^>]*>([\\s\\S]*?)<\\/em>/gi, '$1')\n\t\t.replace(/<i[^>]*>([\\s\\S]*?)<\\/i>/gi, '$1')\n\t\t.replace(/<s[^>]*>([\\s\\S]*?)<\\/s>/gi, '$1')\n\t\t.replace(/<del[^>]*>([\\s\\S]*?)<\\/del>/gi, '$1')\n\t\t.replace(/<a[^>]*>([\\s\\S]*?)<\\/a>/gi, '$1')\n\t\t.replace(/<br\\s*\\/?>/gi, '\\n')\n\t\t.replace(/<\\/p>/gi, '\\n')\n\t\t.replace(/<\\/div>/gi, '\\n')\n\t\t.replace(/<\\/h[1-6]>/gi, '\\n')\n\t\t.replace(/<li[^>]*>/gi, '• ')\n\t\t.replace(/<\\/li>/gi, '\\n')\n\t\t.replace(/<[^>]+>/g, '')\n\t\t.replace(/&amp;/g, '&')\n\t\t.replace(/&lt;/g, '<')\n\t\t.replace(/&gt;/g, '>')\n\t\t.replace(/&nbsp;/g, ' ')\n\t\t.replace(/\\n{3,}/g, '\\n\\n')\n\t\t.trim();\n}\n"],"names":["toLiveChatText","html","document","serializeNode","DOMParser","parseFromString","body","replace","trim","ssrFallback","node","nodeType","Node","TEXT_NODE","textContent","_a","ELEMENT_NODE","el","tag","tagName","toLowerCase","inner","Array","from","childNodes","map","join","serializeChildren","trimEnd"],"mappings":"AAYM,SAAUA,EAAeC,GAC9B,IAAKA,EAAM,MAAO,GAElB,GAAwB,oBAAbC,SAA0B,CAEpC,OAAOC,GADK,IAAIC,WAAYC,gBAAgBJ,EAAM,aACzBK,MACvBC,QAAQ,UAAW,QACnBC,MACF,CAED,OA2ED,SAAqBP,GACpB,OAAOA,EACLM,QAAQ,sCAAuC,QAC/CA,QAAQ,4BAA6B,QACrCA,QAAQ,8BAA+B,MACvCA,QAAQ,4BAA6B,MACrCA,QAAQ,4BAA6B,MACrCA,QAAQ,gCAAiC,MACzCA,QAAQ,4BAA6B,MACrCA,QAAQ,eAAgB,MACxBA,QAAQ,UAAW,MACnBA,QAAQ,YAAa,MACrBA,QAAQ,eAAgB,MACxBA,QAAQ,cAAe,MACvBA,QAAQ,WAAY,MACpBA,QAAQ,WAAY,IACpBA,QAAQ,SAAU,KAClBA,QAAQ,QAAS,KACjBA,QAAQ,QAAS,KACjBA,QAAQ,UAAW,KACnBA,QAAQ,UAAW,QACnBC,MACH,CAjGQC,CAAYR,EACpB,CAMA,SAASE,EAAcO,SACtB,GAAIA,EAAKC,WAAaC,KAAKC,UAAW,OAAuB,UAAhBH,EAAKI,mBAAW,IAAAC,EAAAA,EAAI,GACjE,GAAIL,EAAKC,WAAaC,KAAKI,aAAc,MAAO,GAEhD,MAAMC,EAAKP,EACLQ,EAAMD,EAAGE,QAAQC,cACjBC,EAsDP,SAA2BJ,GAC1B,OAAOK,MAAMC,KAAKN,EAAGO,YAAYC,IAAItB,GAAeuB,KAAK,GAC1D,CAxDeC,CAAkBV,GAEhC,OAAQC,GACP,IAAK,SACL,IAAK,IACJ,OAAOG,EAAQ,IAAIA,KAAW,GAG/B,IAAK,KACL,IAAK,IACL,IAAK,IACL,IAAK,MACL,IAAK,SAGL,IAAK,OACL,IAAK,MAGL,IAAK,IAmBL,IAAK,KACL,IAAK,KASL,IAAK,OACL,QACC,OAAOA,EA3BR,IAAK,KACJ,MAAO,KAER,IAAK,IACL,IAAK,MACJ,OAAOA,EAAQ,GAAGA,MAAY,KAE/B,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACJ,OAAOA,EAAQ,IAAIA,OAAa,KAMjC,IAAK,KACJ,WAAYA,EAAMO,cAEnB,IAAK,aACJ,OAAOP,EAAQ,KAMlB"}
1
+ {"version":3,"file":"toLiveChatText.js","sources":["../../../../src/editor/serializers/toLiveChatText.ts"],"sourcesContent":["/**\n * Converts TipTap HTML to LiveChat plain text.\n *\n * LiveChat supports **bold** (`*text*`) but NOT italic or strikethrough.\n * Italic and strikethrough marks are stripped — the inner text is preserved.\n * Links emit only the display text (href is dropped).\n *\n * @example\n * const { html } = ref.current?.getContent();\n * const lcText = toLiveChatText(html);\n * sendLiveChat({ text: lcText });\n */\nexport function toLiveChatText(html: string): string {\n\tif (!html) return '';\n\n\tif (typeof document !== 'undefined') {\n\t\tconst doc = new DOMParser().parseFromString(html, 'text/html');\n\t\treturn serializeNode(doc.body).trim();\n\t}\n\n\treturn ssrFallback(html);\n}\n\n// ---------------------------------------------------------------------------\n// Browser path — DOM-based, handles nested marks correctly\n// ---------------------------------------------------------------------------\n\nfunction serializeNode(node: Node): string {\n\tif (node.nodeType === Node.TEXT_NODE) return node.textContent ?? '';\n\tif (node.nodeType !== Node.ELEMENT_NODE) return '';\n\n\tconst el = node as Element;\n\tconst tag = el.tagName.toLowerCase();\n\tconst inner = serializeChildren(el);\n\n\tswitch (tag) {\n\t\tcase 'strong':\n\t\tcase 'b':\n\t\t\treturn inner ? `*${inner}*` : '';\n\n\t\t// Italic and strike: strip marks, keep inner text\n\t\tcase 'em':\n\t\tcase 'i':\n\t\tcase 's':\n\t\tcase 'del':\n\t\tcase 'strike':\n\t\t\treturn inner;\n\n\t\tcase 'code':\n\t\tcase 'pre':\n\t\t\treturn inner;\n\n\t\tcase 'a':\n\t\t\t// LiveChat does not support hyperlinks — emit display text only\n\t\t\treturn inner;\n\n\t\tcase 'br':\n\t\t\treturn '\\n';\n\n\t\tcase 'p':\n\t\tcase 'div': {\n\t\t\tconst isBlankLine =\n\t\t\t\tel.childNodes.length === 1 &&\n\t\t\t\t(el.firstChild as Element)?.tagName?.toLowerCase() === 'br';\n\t\t\treturn isBlankLine ? '\\n' : inner ? `${inner}\\n` : '\\n';\n\t\t}\n\n\t\tcase 'h1':\n\t\tcase 'h2':\n\t\tcase 'h3':\n\t\tcase 'h4':\n\t\tcase 'h5':\n\t\tcase 'h6':\n\t\t\treturn inner ? `*${inner}*\\n` : '\\n';\n\n\t\tcase 'ul':\n\t\tcase 'ol':\n\t\t\treturn inner;\n\n\t\tcase 'li':\n\t\t\treturn `• ${inner.trimEnd()}\\n`;\n\n\t\tcase 'blockquote':\n\t\t\treturn inner + '\\n';\n\n\t\tcase 'body':\n\t\tdefault:\n\t\t\treturn inner;\n\t}\n}\n\nfunction serializeChildren(el: Element): string {\n\treturn Array.from(el.childNodes).map(serializeNode).join('');\n}\n\n// ---------------------------------------------------------------------------\n// SSR / Node.js fallback — regex-based, best-effort for simple markup\n// ---------------------------------------------------------------------------\n\nfunction ssrFallback(html: string): string {\n\treturn html\n\t\t.replace(/<strong[^>]*>([\\s\\S]*?)<\\/strong>/gi, '*$1*')\n\t\t.replace(/<b[^>]*>([\\s\\S]*?)<\\/b>/gi, '*$1*')\n\t\t.replace(/<em[^>]*>([\\s\\S]*?)<\\/em>/gi, '$1')\n\t\t.replace(/<i[^>]*>([\\s\\S]*?)<\\/i>/gi, '$1')\n\t\t.replace(/<s[^>]*>([\\s\\S]*?)<\\/s>/gi, '$1')\n\t\t.replace(/<del[^>]*>([\\s\\S]*?)<\\/del>/gi, '$1')\n\t\t.replace(/<a[^>]*>([\\s\\S]*?)<\\/a>/gi, '$1')\n\t\t.replace(/<p[^>]*>\\s*<br\\s*\\/?>\\s*<\\/p>/gi, '\\n')\n\t\t.replace(/<br\\s*\\/?>/gi, '\\n')\n\t\t.replace(/<\\/p>/gi, '\\n')\n\t\t.replace(/<\\/div>/gi, '\\n')\n\t\t.replace(/<\\/h[1-6]>/gi, '\\n')\n\t\t.replace(/<li[^>]*>/gi, '• ')\n\t\t.replace(/<\\/li>/gi, '\\n')\n\t\t.replace(/<[^>]+>/g, '')\n\t\t.replace(/&amp;/g, '&')\n\t\t.replace(/&lt;/g, '<')\n\t\t.replace(/&gt;/g, '>')\n\t\t.replace(/&nbsp;/g, ' ')\n\t\t.trim();\n}\n"],"names":["toLiveChatText","html","document","serializeNode","DOMParser","parseFromString","body","trim","replace","ssrFallback","node","nodeType","Node","TEXT_NODE","textContent","_a","ELEMENT_NODE","el","tag","tagName","toLowerCase","inner","Array","from","childNodes","map","join","serializeChildren","length","_c","_b","firstChild","trimEnd"],"mappings":"AAYM,SAAUA,EAAeC,GAC9B,IAAKA,EAAM,MAAO,GAElB,GAAwB,oBAAbC,SAA0B,CAEpC,OAAOC,GADK,IAAIC,WAAYC,gBAAgBJ,EAAM,aACzBK,MAAMC,MAC/B,CAED,OA+ED,SAAqBN,GACpB,OAAOA,EACLO,QAAQ,sCAAuC,QAC/CA,QAAQ,4BAA6B,QACrCA,QAAQ,8BAA+B,MACvCA,QAAQ,4BAA6B,MACrCA,QAAQ,4BAA6B,MACrCA,QAAQ,gCAAiC,MACzCA,QAAQ,4BAA6B,MACrCA,QAAQ,kCAAmC,MAC3CA,QAAQ,eAAgB,MACxBA,QAAQ,UAAW,MACnBA,QAAQ,YAAa,MACrBA,QAAQ,eAAgB,MACxBA,QAAQ,cAAe,MACvBA,QAAQ,WAAY,MACpBA,QAAQ,WAAY,IACpBA,QAAQ,SAAU,KAClBA,QAAQ,QAAS,KACjBA,QAAQ,QAAS,KACjBA,QAAQ,UAAW,KACnBD,MACH,CArGQE,CAAYR,EACpB,CAMA,SAASE,EAAcO,aACtB,GAAIA,EAAKC,WAAaC,KAAKC,UAAW,OAAuB,UAAhBH,EAAKI,mBAAW,IAAAC,EAAAA,EAAI,GACjE,GAAIL,EAAKC,WAAaC,KAAKI,aAAc,MAAO,GAEhD,MAAMC,EAAKP,EACLQ,EAAMD,EAAGE,QAAQC,cACjBC,EA0DP,SAA2BJ,GAC1B,OAAOK,MAAMC,KAAKN,EAAGO,YAAYC,IAAItB,GAAeuB,KAAK,GAC1D,CA5DeC,CAAkBV,GAEhC,OAAQC,GACP,IAAK,SACL,IAAK,IACJ,OAAOG,EAAQ,IAAIA,KAAW,GAG/B,IAAK,KACL,IAAK,IACL,IAAK,IACL,IAAK,MACL,IAAK,SAGL,IAAK,OACL,IAAK,MAGL,IAAK,IAuBL,IAAK,KACL,IAAK,KASL,IAAK,OACL,QACC,OAAOA,EA/BR,IAAK,KACJ,MAAO,KAER,IAAK,IACL,IAAK,MAIJ,OAF0B,IAAzBJ,EAAGO,WAAWI,QACyC,QAApB,QAAnCC,EAA0B,QAA1BC,EAACb,EAAGc,kBAAsB,IAAAD,OAAA,EAAAA,EAAEX,eAAO,IAAAU,OAAA,EAAAA,EAAET,eACjB,KAAOC,KAAWA,MAAY,KAGpD,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACJ,OAAOA,EAAQ,IAAIA,OAAa,KAMjC,IAAK,KACJ,WAAYA,EAAMW,cAEnB,IAAK,aACJ,OAAOX,EAAQ,KAMlB"}
@@ -1,2 +1,2 @@
1
- function e(e){if(!e)return"";if("undefined"!=typeof document){return r((new DOMParser).parseFromString(e,"text/html").body).replace(/\n{3,}/g,"\n\n").trim()}return function(e){return e.replace(/<strong[^>]*>([\s\S]*?)<\/strong>/gi,"*$1*").replace(/<b[^>]*>([\s\S]*?)<\/b>/gi,"*$1*").replace(/<em[^>]*>([\s\S]*?)<\/em>/gi,"_$1_").replace(/<i[^>]*>([\s\S]*?)<\/i>/gi,"_$1_").replace(/<s[^>]*>([\s\S]*?)<\/s>/gi,"~$1~").replace(/<del[^>]*>([\s\S]*?)<\/del>/gi,"~$1~").replace(/<code[^>]*>([\s\S]*?)<\/code>/gi,"`$1`").replace(/<a[^>]*href="([^"]*)"[^>]*>[\s\S]*?<\/a>/gi,"$1").replace(/<br\s*\/?>/gi,"\n").replace(/<\/p>/gi,"\n").replace(/<\/div>/gi,"\n").replace(/<\/h[1-6]>/gi,"\n").replace(/<li[^>]*>/gi,"• ").replace(/<\/li>/gi,"\n").replace(/<[^>]+>/g,"").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&nbsp;/g," ").replace(/\n{3,}/g,"\n\n").trim()}(e)}function r(e){var n,a;if(e.nodeType===Node.TEXT_NODE)return null!==(n=e.textContent)&&void 0!==n?n:"";if(e.nodeType!==Node.ELEMENT_NODE)return"";const c=e,t=c.tagName.toLowerCase(),s=function(e){return Array.from(e.childNodes).map(r).join("")}(c);switch(t){case"strong":case"b":return s?`*${s}*`:"";case"em":case"i":return s?`_${s}_`:"";case"s":case"del":case"strike":return s?`~${s}~`:"";case"code":return s?`\`${s}\``:"";case"pre":return s?`\`\`\`${s}\`\`\``:"";case"a":return(null!==(a=c.getAttribute("href"))&&void 0!==a?a:"")||s;case"br":return"\n";case"p":case"div":return s?`${s}\n`:"\n";case"h1":case"h2":case"h3":case"h4":case"h5":case"h6":return s?`*${s}*\n`:"\n";case"ul":case"ol":case"body":default:return s;case"li":return`• ${s.trimEnd()}\n`;case"blockquote":return s.split("\n").map((e=>e?`> ${e}`:"")).join("\n")+"\n"}}export{e as toWhatsAppText};
1
+ function e(e){if(!e)return"";if("undefined"!=typeof document){return r((new DOMParser).parseFromString(e,"text/html").body).trim()}return function(e){return e.replace(/<strong[^>]*>([\s\S]*?)<\/strong>/gi,"*$1*").replace(/<b[^>]*>([\s\S]*?)<\/b>/gi,"*$1*").replace(/<em[^>]*>([\s\S]*?)<\/em>/gi,"_$1_").replace(/<i[^>]*>([\s\S]*?)<\/i>/gi,"_$1_").replace(/<s[^>]*>([\s\S]*?)<\/s>/gi,"~$1~").replace(/<del[^>]*>([\s\S]*?)<\/del>/gi,"~$1~").replace(/<code[^>]*>([\s\S]*?)<\/code>/gi,"`$1`").replace(/<a[^>]*>([\s\S]*?)<\/a>/gi,"$1").replace(/<p[^>]*>\s*<br\s*\/?>\s*<\/p>/gi,"\n").replace(/<br\s*\/?>/gi,"\n").replace(/<\/p>/gi,"\n").replace(/<\/div>/gi,"\n").replace(/<\/h[1-6]>/gi,"\n").replace(/<li[^>]*>/gi,"• ").replace(/<\/li>/gi,"\n").replace(/<[^>]+>/g,"").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&nbsp;/g," ").trim()}(e)}function r(e){var n,a,c;if(e.nodeType===Node.TEXT_NODE)return null!==(n=e.textContent)&&void 0!==n?n:"";if(e.nodeType!==Node.ELEMENT_NODE)return"";const s=e,t=s.tagName.toLowerCase(),i=function(e){return Array.from(e.childNodes).map(r).join("")}(s);switch(t){case"strong":case"b":return i?`*${i}*`:"";case"em":case"i":return i?`_${i}_`:"";case"s":case"del":case"strike":return i?`~${i}~`:"";case"code":return i?`\`${i}\``:"";case"pre":return i?`\`\`\`${i}\`\`\``:"";case"a":case"ul":case"ol":case"body":default:return i;case"br":return"\n";case"p":case"div":return 1===s.childNodes.length&&"br"===(null===(c=null===(a=s.firstChild)||void 0===a?void 0:a.tagName)||void 0===c?void 0:c.toLowerCase())?"\n":i?`${i}\n`:"\n";case"h1":case"h2":case"h3":case"h4":case"h5":case"h6":return i?`*${i}*\n`:"\n";case"li":return`• ${i.trimEnd()}\n`;case"blockquote":return i.split("\n").map((e=>e?`> ${e}`:"")).join("\n")+"\n"}}export{e as toWhatsAppText};
2
2
  //# sourceMappingURL=toWhatsAppText.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"toWhatsAppText.js","sources":["../../../../src/editor/serializers/toWhatsAppText.ts"],"sourcesContent":["/**\n * Converts TipTap HTML to WhatsApp-flavoured markdown text.\n *\n * WhatsApp formatting:\n * *bold* _italic_ ~strikethrough~ ```monospace```\n *\n * Links: WhatsApp does not support custom display text for hyperlinks.\n * <a href=\"https://…\">Visit us</a> → https://… (href wins, display text dropped)\n *\n * @example\n * const { html } = ref.current?.getContent();\n * const waText = toWhatsAppText(html);\n * sendWhatsApp({ text: waText });\n */\nexport function toWhatsAppText(html: string): string {\n\tif (!html) return '';\n\n\tif (typeof document !== 'undefined') {\n\t\tconst doc = new DOMParser().parseFromString(html, 'text/html');\n\t\treturn serializeNode(doc.body)\n\t\t\t.replace(/\\n{3,}/g, '\\n\\n')\n\t\t\t.trim();\n\t}\n\n\t// SSR / Node.js fallback — handles simple non-nested markup\n\treturn ssrFallback(html);\n}\n\n// ---------------------------------------------------------------------------\n// Browser path — DOM-based, handles nested marks correctly\n// ---------------------------------------------------------------------------\n\nfunction serializeNode(node: Node): string {\n\tif (node.nodeType === Node.TEXT_NODE) {\n\t\treturn node.textContent ?? '';\n\t}\n\tif (node.nodeType !== Node.ELEMENT_NODE) return '';\n\n\tconst el = node as Element;\n\tconst tag = el.tagName.toLowerCase();\n\tconst inner = serializeChildren(el);\n\n\tswitch (tag) {\n\t\tcase 'strong':\n\t\tcase 'b':\n\t\t\treturn inner ? `*${inner}*` : '';\n\n\t\tcase 'em':\n\t\tcase 'i':\n\t\t\treturn inner ? `_${inner}_` : '';\n\n\t\tcase 's':\n\t\tcase 'del':\n\t\tcase 'strike':\n\t\t\treturn inner ? `~${inner}~` : '';\n\n\t\tcase 'code':\n\t\t\treturn inner ? `\\`${inner}\\`` : '';\n\n\t\tcase 'pre':\n\t\t\treturn inner ? `\\`\\`\\`${inner}\\`\\`\\`` : '';\n\n\t\tcase 'a': {\n\t\t\t// WhatsApp doesn't support custom link text — just emit the URL.\n\t\t\tconst href = el.getAttribute('href') ?? '';\n\t\t\treturn href || inner;\n\t\t}\n\n\t\tcase 'br':\n\t\t\treturn '\\n';\n\n\t\tcase 'p':\n\t\tcase 'div':\n\t\t\treturn inner ? `${inner}\\n` : '\\n';\n\n\t\tcase 'h1':\n\t\tcase 'h2':\n\t\tcase 'h3':\n\t\tcase 'h4':\n\t\tcase 'h5':\n\t\tcase 'h6':\n\t\t\treturn inner ? `*${inner}*\\n` : '\\n';\n\n\t\tcase 'ul':\n\t\tcase 'ol':\n\t\t\treturn inner;\n\n\t\tcase 'li':\n\t\t\treturn `• ${inner.trimEnd()}\\n`;\n\n\t\tcase 'blockquote':\n\t\t\treturn (\n\t\t\t\tinner\n\t\t\t\t\t.split('\\n')\n\t\t\t\t\t.map((l) => (l ? `> ${l}` : ''))\n\t\t\t\t\t.join('\\n') + '\\n'\n\t\t\t);\n\n\t\tcase 'body':\n\t\tdefault:\n\t\t\treturn inner;\n\t}\n}\n\nfunction serializeChildren(el: Element): string {\n\treturn Array.from(el.childNodes).map(serializeNode).join('');\n}\n\n// ---------------------------------------------------------------------------\n// SSR fallback — regex-based, best-effort for simple markup\n// ---------------------------------------------------------------------------\n\nfunction ssrFallback(html: string): string {\n\treturn html\n\t\t.replace(/<strong[^>]*>([\\s\\S]*?)<\\/strong>/gi, '*$1*')\n\t\t.replace(/<b[^>]*>([\\s\\S]*?)<\\/b>/gi, '*$1*')\n\t\t.replace(/<em[^>]*>([\\s\\S]*?)<\\/em>/gi, '_$1_')\n\t\t.replace(/<i[^>]*>([\\s\\S]*?)<\\/i>/gi, '_$1_')\n\t\t.replace(/<s[^>]*>([\\s\\S]*?)<\\/s>/gi, '~$1~')\n\t\t.replace(/<del[^>]*>([\\s\\S]*?)<\\/del>/gi, '~$1~')\n\t\t.replace(/<code[^>]*>([\\s\\S]*?)<\\/code>/gi, '`$1`')\n\t\t.replace(/<a[^>]*href=\"([^\"]*)\"[^>]*>[\\s\\S]*?<\\/a>/gi, '$1')\n\t\t.replace(/<br\\s*\\/?>/gi, '\\n')\n\t\t.replace(/<\\/p>/gi, '\\n')\n\t\t.replace(/<\\/div>/gi, '\\n')\n\t\t.replace(/<\\/h[1-6]>/gi, '\\n')\n\t\t.replace(/<li[^>]*>/gi, '• ')\n\t\t.replace(/<\\/li>/gi, '\\n')\n\t\t.replace(/<[^>]+>/g, '')\n\t\t.replace(/&amp;/g, '&')\n\t\t.replace(/&lt;/g, '<')\n\t\t.replace(/&gt;/g, '>')\n\t\t.replace(/&nbsp;/g, ' ')\n\t\t.replace(/\\n{3,}/g, '\\n\\n')\n\t\t.trim();\n}\n"],"names":["toWhatsAppText","html","document","serializeNode","DOMParser","parseFromString","body","replace","trim","ssrFallback","node","nodeType","Node","TEXT_NODE","textContent","_a","ELEMENT_NODE","el","tag","tagName","toLowerCase","inner","Array","from","childNodes","map","join","serializeChildren","_b","getAttribute","trimEnd","split","l"],"mappings":"AAcM,SAAUA,EAAeC,GAC9B,IAAKA,EAAM,MAAO,GAElB,GAAwB,oBAAbC,SAA0B,CAEpC,OAAOC,GADK,IAAIC,WAAYC,gBAAgBJ,EAAM,aACzBK,MACvBC,QAAQ,UAAW,QACnBC,MACF,CAGD,OAuFD,SAAqBP,GACpB,OAAOA,EACLM,QAAQ,sCAAuC,QAC/CA,QAAQ,4BAA6B,QACrCA,QAAQ,8BAA+B,QACvCA,QAAQ,4BAA6B,QACrCA,QAAQ,4BAA6B,QACrCA,QAAQ,gCAAiC,QACzCA,QAAQ,kCAAmC,QAC3CA,QAAQ,6CAA8C,MACtDA,QAAQ,eAAgB,MACxBA,QAAQ,UAAW,MACnBA,QAAQ,YAAa,MACrBA,QAAQ,eAAgB,MACxBA,QAAQ,cAAe,MACvBA,QAAQ,WAAY,MACpBA,QAAQ,WAAY,IACpBA,QAAQ,SAAU,KAClBA,QAAQ,QAAS,KACjBA,QAAQ,QAAS,KACjBA,QAAQ,UAAW,KACnBA,QAAQ,UAAW,QACnBC,MACH,CA9GQC,CAAYR,EACpB,CAMA,SAASE,EAAcO,WACtB,GAAIA,EAAKC,WAAaC,KAAKC,UAC1B,OAAuB,UAAhBH,EAAKI,mBAAW,IAAAC,EAAAA,EAAI,GAE5B,GAAIL,EAAKC,WAAaC,KAAKI,aAAc,MAAO,GAEhD,MAAMC,EAAKP,EACLQ,EAAMD,EAAGE,QAAQC,cACjBC,EAgEP,SAA2BJ,GAC1B,OAAOK,MAAMC,KAAKN,EAAGO,YAAYC,IAAItB,GAAeuB,KAAK,GAC1D,CAlEeC,CAAkBV,GAEhC,OAAQC,GACP,IAAK,SACL,IAAK,IACJ,OAAOG,EAAQ,IAAIA,KAAW,GAE/B,IAAK,KACL,IAAK,IACJ,OAAOA,EAAQ,IAAIA,KAAW,GAE/B,IAAK,IACL,IAAK,MACL,IAAK,SACJ,OAAOA,EAAQ,IAAIA,KAAW,GAE/B,IAAK,OACJ,OAAOA,EAAQ,KAAKA,MAAY,GAEjC,IAAK,MACJ,OAAOA,EAAQ,SAASA,UAAgB,GAEzC,IAAK,IAGJ,OADwC,QAA3BO,EAAAX,EAAGY,aAAa,eAAW,IAAAD,EAAAA,EAAA,KACzBP,EAGhB,IAAK,KACJ,MAAO,KAER,IAAK,IACL,IAAK,MACJ,OAAOA,EAAQ,GAAGA,MAAY,KAE/B,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACJ,OAAOA,EAAQ,IAAIA,OAAa,KAEjC,IAAK,KACL,IAAK,KAcL,IAAK,OACL,QACC,OAAOA,EAbR,IAAK,KACJ,WAAYA,EAAMS,cAEnB,IAAK,aACJ,OACCT,EACEU,MAAM,MACNN,KAAKO,GAAOA,EAAI,KAAKA,IAAM,KAC3BN,KAAK,MAAQ,KAOnB"}
1
+ {"version":3,"file":"toWhatsAppText.js","sources":["../../../../src/editor/serializers/toWhatsAppText.ts"],"sourcesContent":["/**\n * Converts TipTap HTML to WhatsApp-flavoured markdown text.\n *\n * WhatsApp formatting:\n * *bold* _italic_ ~strikethrough~ ```monospace```\n *\n * Links: WhatsApp does not support hyperlinks.\n * <a href=\"https://…\">Visit us</a> → Visit us (display text kept, href dropped)\n *\n * @example\n * const { html } = ref.current?.getContent();\n * const waText = toWhatsAppText(html);\n * sendWhatsApp({ text: waText });\n */\nexport function toWhatsAppText(html: string): string {\n\tif (!html) return '';\n\n\tif (typeof document !== 'undefined') {\n\t\tconst doc = new DOMParser().parseFromString(html, 'text/html');\n\t\treturn serializeNode(doc.body).trim();\n\t}\n\n\t// SSR / Node.js fallback — handles simple non-nested markup\n\treturn ssrFallback(html);\n}\n\n// ---------------------------------------------------------------------------\n// Browser path — DOM-based, handles nested marks correctly\n// ---------------------------------------------------------------------------\n\nfunction serializeNode(node: Node): string {\n\tif (node.nodeType === Node.TEXT_NODE) {\n\t\treturn node.textContent ?? '';\n\t}\n\tif (node.nodeType !== Node.ELEMENT_NODE) return '';\n\n\tconst el = node as Element;\n\tconst tag = el.tagName.toLowerCase();\n\tconst inner = serializeChildren(el);\n\n\tswitch (tag) {\n\t\tcase 'strong':\n\t\tcase 'b':\n\t\t\treturn inner ? `*${inner}*` : '';\n\n\t\tcase 'em':\n\t\tcase 'i':\n\t\t\treturn inner ? `_${inner}_` : '';\n\n\t\tcase 's':\n\t\tcase 'del':\n\t\tcase 'strike':\n\t\t\treturn inner ? `~${inner}~` : '';\n\n\t\tcase 'code':\n\t\t\treturn inner ? `\\`${inner}\\`` : '';\n\n\t\tcase 'pre':\n\t\t\treturn inner ? `\\`\\`\\`${inner}\\`\\`\\`` : '';\n\n\t\tcase 'a':\n\t\t\treturn inner;\n\n\t\tcase 'br':\n\t\t\treturn '\\n';\n\n\t\tcase 'p':\n\t\tcase 'div': {\n\t\t\tconst isBlankLine =\n\t\t\t\tel.childNodes.length === 1 &&\n\t\t\t\t(el.firstChild as Element)?.tagName?.toLowerCase() === 'br';\n\t\t\treturn isBlankLine ? '\\n' : inner ? `${inner}\\n` : '\\n';\n\t\t}\n\n\t\tcase 'h1':\n\t\tcase 'h2':\n\t\tcase 'h3':\n\t\tcase 'h4':\n\t\tcase 'h5':\n\t\tcase 'h6':\n\t\t\treturn inner ? `*${inner}*\\n` : '\\n';\n\n\t\tcase 'ul':\n\t\tcase 'ol':\n\t\t\treturn inner;\n\n\t\tcase 'li':\n\t\t\treturn `• ${inner.trimEnd()}\\n`;\n\n\t\tcase 'blockquote':\n\t\t\treturn (\n\t\t\t\tinner\n\t\t\t\t\t.split('\\n')\n\t\t\t\t\t.map((l) => (l ? `> ${l}` : ''))\n\t\t\t\t\t.join('\\n') + '\\n'\n\t\t\t);\n\n\t\tcase 'body':\n\t\tdefault:\n\t\t\treturn inner;\n\t}\n}\n\nfunction serializeChildren(el: Element): string {\n\treturn Array.from(el.childNodes).map(serializeNode).join('');\n}\n\n// ---------------------------------------------------------------------------\n// SSR fallback — regex-based, best-effort for simple markup\n// ---------------------------------------------------------------------------\n\nfunction ssrFallback(html: string): string {\n\treturn html\n\t\t.replace(/<strong[^>]*>([\\s\\S]*?)<\\/strong>/gi, '*$1*')\n\t\t.replace(/<b[^>]*>([\\s\\S]*?)<\\/b>/gi, '*$1*')\n\t\t.replace(/<em[^>]*>([\\s\\S]*?)<\\/em>/gi, '_$1_')\n\t\t.replace(/<i[^>]*>([\\s\\S]*?)<\\/i>/gi, '_$1_')\n\t\t.replace(/<s[^>]*>([\\s\\S]*?)<\\/s>/gi, '~$1~')\n\t\t.replace(/<del[^>]*>([\\s\\S]*?)<\\/del>/gi, '~$1~')\n\t\t.replace(/<code[^>]*>([\\s\\S]*?)<\\/code>/gi, '`$1`')\n\t\t.replace(/<a[^>]*>([\\s\\S]*?)<\\/a>/gi, '$1')\n\t\t.replace(/<p[^>]*>\\s*<br\\s*\\/?>\\s*<\\/p>/gi, '\\n')\n\t\t.replace(/<br\\s*\\/?>/gi, '\\n')\n\t\t.replace(/<\\/p>/gi, '\\n')\n\t\t.replace(/<\\/div>/gi, '\\n')\n\t\t.replace(/<\\/h[1-6]>/gi, '\\n')\n\t\t.replace(/<li[^>]*>/gi, '• ')\n\t\t.replace(/<\\/li>/gi, '\\n')\n\t\t.replace(/<[^>]+>/g, '')\n\t\t.replace(/&amp;/g, '&')\n\t\t.replace(/&lt;/g, '<')\n\t\t.replace(/&gt;/g, '>')\n\t\t.replace(/&nbsp;/g, ' ')\n\t\t.trim();\n}\n"],"names":["toWhatsAppText","html","document","serializeNode","DOMParser","parseFromString","body","trim","replace","ssrFallback","node","nodeType","Node","TEXT_NODE","textContent","_a","ELEMENT_NODE","el","tag","tagName","toLowerCase","inner","Array","from","childNodes","map","join","serializeChildren","length","_c","_b","firstChild","trimEnd","split","l"],"mappings":"AAcM,SAAUA,EAAeC,GAC9B,IAAKA,EAAM,MAAO,GAElB,GAAwB,oBAAbC,SAA0B,CAEpC,OAAOC,GADK,IAAIC,WAAYC,gBAAgBJ,EAAM,aACzBK,MAAMC,MAC/B,CAGD,OAwFD,SAAqBN,GACpB,OAAOA,EACLO,QAAQ,sCAAuC,QAC/CA,QAAQ,4BAA6B,QACrCA,QAAQ,8BAA+B,QACvCA,QAAQ,4BAA6B,QACrCA,QAAQ,4BAA6B,QACrCA,QAAQ,gCAAiC,QACzCA,QAAQ,kCAAmC,QAC3CA,QAAQ,4BAA6B,MACrCA,QAAQ,kCAAmC,MAC3CA,QAAQ,eAAgB,MACxBA,QAAQ,UAAW,MACnBA,QAAQ,YAAa,MACrBA,QAAQ,eAAgB,MACxBA,QAAQ,cAAe,MACvBA,QAAQ,WAAY,MACpBA,QAAQ,WAAY,IACpBA,QAAQ,SAAU,KAClBA,QAAQ,QAAS,KACjBA,QAAQ,QAAS,KACjBA,QAAQ,UAAW,KACnBD,MACH,CA/GQE,CAAYR,EACpB,CAMA,SAASE,EAAcO,aACtB,GAAIA,EAAKC,WAAaC,KAAKC,UAC1B,OAAuB,UAAhBH,EAAKI,mBAAW,IAAAC,EAAAA,EAAI,GAE5B,GAAIL,EAAKC,WAAaC,KAAKI,aAAc,MAAO,GAEhD,MAAMC,EAAKP,EACLQ,EAAMD,EAAGE,QAAQC,cACjBC,EAiEP,SAA2BJ,GAC1B,OAAOK,MAAMC,KAAKN,EAAGO,YAAYC,IAAItB,GAAeuB,KAAK,GAC1D,CAnEeC,CAAkBV,GAEhC,OAAQC,GACP,IAAK,SACL,IAAK,IACJ,OAAOG,EAAQ,IAAIA,KAAW,GAE/B,IAAK,KACL,IAAK,IACJ,OAAOA,EAAQ,IAAIA,KAAW,GAE/B,IAAK,IACL,IAAK,MACL,IAAK,SACJ,OAAOA,EAAQ,IAAIA,KAAW,GAE/B,IAAK,OACJ,OAAOA,EAAQ,KAAKA,MAAY,GAEjC,IAAK,MACJ,OAAOA,EAAQ,SAASA,UAAgB,GAEzC,IAAK,IAsBL,IAAK,KACL,IAAK,KAcL,IAAK,OACL,QACC,OAAOA,EApCR,IAAK,KACJ,MAAO,KAER,IAAK,IACL,IAAK,MAIJ,OAF0B,IAAzBJ,EAAGO,WAAWI,QACyC,QAApB,QAAnCC,EAA0B,QAA1BC,EAACb,EAAGc,kBAAsB,IAAAD,OAAA,EAAAA,EAAEX,eAAO,IAAAU,OAAA,EAAAA,EAAET,eACjB,KAAOC,KAAWA,MAAY,KAGpD,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACJ,OAAOA,EAAQ,IAAIA,OAAa,KAMjC,IAAK,KACJ,WAAYA,EAAMW,cAEnB,IAAK,aACJ,OACCX,EACEY,MAAM,MACNR,KAAKS,GAAOA,EAAI,KAAKA,IAAM,KAC3BR,KAAK,MAAQ,KAOnB"}
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
- import { QueryBuilderNodeProps } from "../../../types/QueryBuilderNodeProps.type";
2
+ import { QueryBuilderNodeProps } from "../../../Types/QueryBuilderNodeProps.type";
3
3
  declare const EventsTrigger: React.FC<QueryBuilderNodeProps>;
4
4
  export default EventsTrigger;
@@ -1,2 +1,2 @@
1
- import { QueryBuilderAPIData } from "../../../types/QueryBuilderAPI.type";
1
+ import { QueryBuilderAPIData } from "../../../Types/QueryBuilderAPI.type";
2
2
  export declare const useIGTriggerNameCacheSelector: () => QueryBuilderAPIData[];
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
- import { QueryBuilderNodeProps } from "../../../types/QueryBuilderNodeProps.type";
2
+ import { QueryBuilderNodeProps } from "../../../Types/QueryBuilderNodeProps.type";
3
3
  declare const IGTrigger: React.FC<QueryBuilderNodeProps>;
4
4
  export default IGTrigger;
@@ -1,2 +1,2 @@
1
- import { QueryBuilderAPIData } from "../../../types/QueryBuilderAPI.type";
1
+ import { QueryBuilderAPIData } from "../../../Types/QueryBuilderAPI.type";
2
2
  export declare const useIGTriggerNameCacheSelector: () => QueryBuilderAPIData[];
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { DropdownOption } from "../../../dropdown/type";
3
- import { QueryBuilderProperty } from "../../types/QueryBuilder.type";
4
- import { QueryBuilderNodeProps } from "../../types/QueryBuilderNodeProps.type";
3
+ import { QueryBuilderProperty } from "../../Types/QueryBuilder.type";
4
+ import { QueryBuilderNodeProps } from "../../Types/QueryBuilderNodeProps.type";
5
5
  declare const BaseTriggerQueryBuilderNode: React.FC<QueryBuilderNodeProps & {
6
6
  cacheKey: string;
7
7
  propertyAddBtnText: string;
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  export declare const Menus: ({
2
3
  displayName: string;
3
4
  key: number;
@@ -3,18 +3,23 @@ import { EditorSnapshot, FormatState } from './BikEditor.types';
3
3
  /**
4
4
  * Normalise HTML before passing it to TipTap.
5
5
  *
6
- * Problem: Quill uses `<p><br></p>` as a blank-line separator. TipTap's
7
- * HardBreak extension parses that `<br>` as a real `hard_break` node.
8
- * ProseMirror then also appends `<br class="ProseMirror-trailingBreak">` as a
9
- * cursor-position decoration, making the empty paragraph render at **2× line
10
- * height** instead of 1×.
11
- *
12
- * Fix: replace `<p><br></p>` `<p></p>` so TipTap stores a truly empty
13
- * paragraph. ProseMirror adds only the trailing decoration, giving the correct
14
- * 1× line height. The WA text output is unchanged (`\n` either way after
15
- * surrounding-newline collapse in `toWhatsAppText`).
6
+ * 1. Strip all `<span>` tags first (keeps inner content). This exposes
7
+ * bare `<br>` inside otherwise-empty paragraphs like Quill's
8
+ * `<p><span class="ql-cursor"><br></span></p>`.
9
+ * 2. Then convert `<p><br></p>` `<p></p>`. ProseMirror parses `<p></p>`
10
+ * as an empty paragraph node and adds its own DOM `<br>` for cursor
11
+ * positioning — one blank line, correct height. Leaving the `<br>`
12
+ * would create a `hard_break` child AND the cursor `<br>`, producing
13
+ * double-height blank lines.
16
14
  */
17
15
  export declare function normalizeHtml(html: string): string;
16
+ /**
17
+ * Convert ProseMirror's `<p></p>` empty paragraphs to the universally
18
+ * rendered `<p><br></p>` format before the HTML leaves the editor.
19
+ * Email clients, chat bubbles, and every renderer understand `<p><br></p>`
20
+ * as a visible blank line, whereas `<p></p>` collapses to zero height.
21
+ */
22
+ export declare function toPortableHtml(html: string): string;
18
23
  /**
19
24
  * Insert HTML at the current cursor position, merging the first paragraph
20
25
  * inline while preserving the block structure of subsequent paragraphs/lists.
@@ -0,0 +1,7 @@
1
+ import { Extension } from '@tiptap/core';
2
+ /**
3
+ * Lightweight paste normalizer for rich-paste editors (email).
4
+ * Fixes Google Docs' standalone `<br>` between paragraphs and collapses
5
+ * consecutive empty paragraphs — but keeps ALL formatting marks intact.
6
+ */
7
+ export declare const ClipboardNormalizationExtension: Extension<any, any>;
@@ -0,0 +1,21 @@
1
+ import { Fragment } from '@tiptap/pm/model';
2
+ export declare const TEXTBLOCK_TAGS: Set<string>;
3
+ export declare const BLOCK_SELECTOR = "p,div,h1,h2,h3,h4,h5,h6,ul,ol,li,blockquote,table,pre";
4
+ /**
5
+ * Replace `<br>` elements that sit at block level (not inside a textblock
6
+ * like `<p>`, `<li>`, etc.) with empty `<p></p>` elements. Google Docs
7
+ * puts standalone `<br>` tags between paragraphs to represent blank lines.
8
+ * Without this, ProseMirror parses them as top-level hardBreak nodes.
9
+ */
10
+ export declare function cleanBlockBrs(container: HTMLElement): void;
11
+ /**
12
+ * 1. Convert paragraphs containing only a hard_break into empty paragraphs.
13
+ * 2. Collapse consecutive empty paragraphs into one.
14
+ */
15
+ export declare function normalizeBlanks(fragment: Fragment): Fragment;
16
+ /**
17
+ * Strip only "rich" marks (link, textStyle, highlight, etc.) while keeping
18
+ * basic formatting marks (bold, italic, strike, underline, code) that
19
+ * messaging channels can represent.
20
+ */
21
+ export declare function stripRichMarks(fragment: Fragment): Fragment;
@@ -4,8 +4,8 @@
4
4
  * WhatsApp formatting:
5
5
  * *bold* _italic_ ~strikethrough~ ```monospace```
6
6
  *
7
- * Links: WhatsApp does not support custom display text for hyperlinks.
8
- * <a href="https://…">Visit us</a> → https://… (href wins, display text dropped)
7
+ * Links: WhatsApp does not support hyperlinks.
8
+ * <a href="https://…">Visit us</a> → Visit us (display text kept, href dropped)
9
9
  *
10
10
  * @example
11
11
  * const { html } = ref.current?.getContent();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bikdotai/bik-component-library",
3
- "version": "0.0.806",
3
+ "version": "0.0.807-beta.1",
4
4
  "description": "Bik Component Library",
5
5
  "repository": {
6
6
  "type": "git",