@bikdotai/bik-component-library 0.0.809-beta.18 → 0.0.809-beta.19
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.
- package/dist/cjs/components/list-item/themes.js +1 -1
- package/dist/cjs/components/list-item/themes.js.map +1 -1
- package/dist/cjs/components/variable-picker-v3/Content.js +1 -1
- package/dist/cjs/components/variable-picker-v3/Content.js.map +1 -1
- package/dist/cjs/components/variable-picker-v3/SubHeaderItems.js +1 -1
- package/dist/cjs/components/variable-picker-v3/SubHeaderItems.js.map +1 -1
- package/dist/cjs/components/variable-picker-v3/context.js +1 -1
- package/dist/cjs/components/variable-picker-v3/context.js.map +1 -1
- package/dist/cjs/editor/BikEditor.js +1 -1
- package/dist/cjs/editor/BikEditor.js.map +1 -1
- package/dist/cjs/editor/BikEditor.styles.js +3 -13
- package/dist/cjs/editor/BikEditor.styles.js.map +1 -1
- package/dist/cjs/editor/BikEditor.types.js.map +1 -1
- package/dist/cjs/editor/extensions/buildExtensions.js +1 -1
- package/dist/cjs/editor/extensions/buildExtensions.js.map +1 -1
- package/dist/cjs/editor/extensions/plainClipboard/ClipboardNormalizationExtension.js +2 -0
- package/dist/cjs/editor/extensions/plainClipboard/ClipboardNormalizationExtension.js.map +1 -0
- package/dist/cjs/editor/extensions/plainClipboard/PlainClipboardExtension.js +2 -0
- package/dist/cjs/editor/extensions/plainClipboard/PlainClipboardExtension.js.map +1 -0
- package/dist/cjs/editor/extensions/plainClipboard/pasteUtils.js +1 -1
- package/dist/cjs/editor/extensions/plainClipboard/pasteUtils.js.map +1 -1
- package/dist/cjs/src/components/variable-picker-v3/context.d.ts +4 -0
- package/dist/cjs/src/editor/BikEditor.styles.d.ts +0 -1
- package/dist/cjs/src/editor/BikEditor.types.d.ts +0 -2
- package/dist/cjs/src/editor/extensions/plainClipboard/ClipboardNormalizationExtension.d.ts +7 -0
- package/dist/cjs/src/editor/extensions/plainClipboard/PlainClipboardExtension.d.ts +2 -0
- package/dist/cjs/src/editor/extensions/plainClipboard/pasteUtils.d.ts +8 -40
- package/dist/cjs/src/icons/Actions/Common actions/SendAirplane2.d.ts +7 -0
- package/dist/cjs/src/icons/BIK AI specific/AiAgent.d.ts +7 -0
- package/dist/cjs/src/icons/Informational/Communication/AtSymbol.d.ts +7 -0
- package/dist/cjs/src/icons/Informational/Communication/Hangup.d.ts +7 -0
- package/dist/cjs/src/icons/Informational/Communication/IncomingCall.d.ts +7 -0
- package/dist/cjs/src/icons/Informational/Communication/OutgoingCall.d.ts +7 -0
- package/dist/cjs/src/icons/Informational/Communication/PhoneCall.d.ts +7 -0
- package/dist/cjs/src/icons/Informational/Communication/Transcript.d.ts +7 -0
- package/dist/cjs/src/icons/Informational/Files and folders/BookOpen.d.ts +7 -0
- package/dist/cjs/src/icons/Informational/Identity/AiVoiceAgent.d.ts +7 -0
- package/dist/cjs/src/icons/Social/Channels/Subdued/FbCommentTicket.d.ts +6 -0
- package/dist/cjs/src/icons/Social/Channels/Subdued/FbTicket.d.ts +6 -0
- package/dist/cjs/src/icons/Social/Channels/Subdued/IgCommentTicket.d.ts +6 -0
- package/dist/cjs/src/icons/Social/Channels/Subdued/IgTicket.d.ts +6 -0
- package/dist/cjs/src/icons/Social/Channels/Subdued/MailTicket.d.ts +6 -0
- package/dist/cjs/src/icons/Social/Channels/Subdued/PhoneTicket.d.ts +6 -0
- package/dist/cjs/src/icons/Social/Channels/Subdued/TaskTicket.d.ts +6 -0
- package/dist/cjs/src/icons/Social/Channels/Subdued/WhatsappTicket.d.ts +6 -0
- package/dist/cjs/src/icons/Social/Channels/Subdued/index.d.ts +8 -0
- package/dist/esm/components/list-item/themes.js +1 -1
- package/dist/esm/components/list-item/themes.js.map +1 -1
- package/dist/esm/components/variable-picker-v3/Content.js +1 -1
- package/dist/esm/components/variable-picker-v3/Content.js.map +1 -1
- package/dist/esm/components/variable-picker-v3/SubHeaderItems.js +1 -1
- package/dist/esm/components/variable-picker-v3/SubHeaderItems.js.map +1 -1
- package/dist/esm/components/variable-picker-v3/context.js +1 -1
- package/dist/esm/components/variable-picker-v3/context.js.map +1 -1
- package/dist/esm/editor/BikEditor.js +1 -1
- package/dist/esm/editor/BikEditor.js.map +1 -1
- package/dist/esm/editor/BikEditor.styles.js +7 -17
- package/dist/esm/editor/BikEditor.styles.js.map +1 -1
- package/dist/esm/editor/BikEditor.types.js.map +1 -1
- package/dist/esm/editor/extensions/buildExtensions.js +1 -1
- package/dist/esm/editor/extensions/buildExtensions.js.map +1 -1
- package/dist/esm/editor/extensions/plainClipboard/ClipboardNormalizationExtension.js +2 -0
- package/dist/esm/editor/extensions/plainClipboard/ClipboardNormalizationExtension.js.map +1 -0
- package/dist/esm/editor/extensions/plainClipboard/PlainClipboardExtension.js +2 -0
- package/dist/esm/editor/extensions/plainClipboard/PlainClipboardExtension.js.map +1 -0
- package/dist/esm/editor/extensions/plainClipboard/pasteUtils.js +1 -1
- package/dist/esm/editor/extensions/plainClipboard/pasteUtils.js.map +1 -1
- package/dist/esm/src/components/variable-picker-v3/context.d.ts +4 -0
- package/dist/esm/src/editor/BikEditor.styles.d.ts +0 -1
- package/dist/esm/src/editor/BikEditor.types.d.ts +0 -2
- package/dist/esm/src/editor/extensions/plainClipboard/ClipboardNormalizationExtension.d.ts +7 -0
- package/dist/esm/src/editor/extensions/plainClipboard/PlainClipboardExtension.d.ts +2 -0
- package/dist/esm/src/editor/extensions/plainClipboard/pasteUtils.d.ts +8 -40
- package/dist/esm/src/icons/Actions/Common actions/SendAirplane2.d.ts +7 -0
- package/dist/esm/src/icons/BIK AI specific/AiAgent.d.ts +7 -0
- package/dist/esm/src/icons/Informational/Communication/AtSymbol.d.ts +7 -0
- package/dist/esm/src/icons/Informational/Communication/Hangup.d.ts +7 -0
- package/dist/esm/src/icons/Informational/Communication/IncomingCall.d.ts +7 -0
- package/dist/esm/src/icons/Informational/Communication/OutgoingCall.d.ts +7 -0
- package/dist/esm/src/icons/Informational/Communication/PhoneCall.d.ts +7 -0
- package/dist/esm/src/icons/Informational/Communication/Transcript.d.ts +7 -0
- package/dist/esm/src/icons/Informational/Files and folders/BookOpen.d.ts +7 -0
- package/dist/esm/src/icons/Informational/Identity/AiVoiceAgent.d.ts +7 -0
- package/dist/esm/src/icons/Social/Channels/Subdued/FbCommentTicket.d.ts +6 -0
- package/dist/esm/src/icons/Social/Channels/Subdued/FbTicket.d.ts +6 -0
- package/dist/esm/src/icons/Social/Channels/Subdued/IgCommentTicket.d.ts +6 -0
- package/dist/esm/src/icons/Social/Channels/Subdued/IgTicket.d.ts +6 -0
- package/dist/esm/src/icons/Social/Channels/Subdued/MailTicket.d.ts +6 -0
- package/dist/esm/src/icons/Social/Channels/Subdued/PhoneTicket.d.ts +6 -0
- package/dist/esm/src/icons/Social/Channels/Subdued/TaskTicket.d.ts +6 -0
- package/dist/esm/src/icons/Social/Channels/Subdued/WhatsappTicket.d.ts +6 -0
- package/dist/esm/src/icons/Social/Channels/Subdued/index.d.ts +8 -0
- package/package.json +1 -1
- package/dist/cjs/editor/extensions/plainClipboard/PasteNormalizationExtension.js +0 -2
- package/dist/cjs/editor/extensions/plainClipboard/PasteNormalizationExtension.js.map +0 -1
- package/dist/cjs/src/editor/extensions/plainClipboard/PasteNormalizationExtension.d.ts +0 -13
- package/dist/esm/editor/extensions/plainClipboard/PasteNormalizationExtension.js +0 -2
- package/dist/esm/editor/extensions/plainClipboard/PasteNormalizationExtension.js.map +0 -1
- package/dist/esm/src/editor/extensions/plainClipboard/PasteNormalizationExtension.d.ts +0 -13
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
1
|
+
import o from"@tiptap/extension-character-count";import e from"@tiptap/extension-color";import t from"@tiptap/extension-font-family";import n from"@tiptap/extension-highlight";import i from"@tiptap/extension-image";import r from"@tiptap/extension-link";import a from"@tiptap/extension-placeholder";import s from"@tiptap/extension-subscript";import m from"@tiptap/extension-superscript";import p from"@tiptap/extension-text-align";import{TextStyle as l}from"@tiptap/extension-text-style";import d from"@tiptap/extension-underline";import c from"@tiptap/starter-kit";import{FontSizeExtension as u}from"./FontSizeExtension.js";import{buildAgentMentionExtension as f,buildTeamMentionExtension as h}from"./mention/MentionExtension.js";import{PasteExtension as x}from"./paste/PasteExtension.js";import{ClipboardNormalizationExtension as g}from"./plainClipboard/ClipboardNormalizationExtension.js";import{PlainClipboardExtension as v}from"./plainClipboard/PlainClipboardExtension.js";import{SectionDividerNode as S}from"./sectionDivider/SectionDividerNode.js";import{SendShortcutExtension as C}from"./sendShortcut/SendShortcutExtension.js";import{buildSlashCommandExtension as b}from"./slashCommand/SlashCommandExtension.js";import{VariableDecorationExtension as k}from"./variable/VariableDecorationExtension.js";function j(j){var M,E,P,y,D,w,I,T,z;const N=null!==(E=null===(M=j.features)||void 0===M?void 0:M.richPaste)&&void 0!==E&&E,O=null!==(y=null===(P=j.features)||void 0===P?void 0:P.richTypography)&&void 0!==y&&y,R=null===(D=j.features)||void 0===D?void 0:D.allowedMarks,A=o=>!R||R.includes(o);return[...[c.configure({link:!1,underline:!1,bold:!!A("bold")&&{},italic:!!A("italic")&&{},strike:!!A("strike")&&{},code:!!A("code")&&{}}),...A("underline")?[d]:[],r.extend({addPasteRules:()=>[],addInputRules:()=>[]}).configure({openOnClick:!1,autolink:!1,linkOnPaste:!1,HTMLAttributes:{rel:"noopener noreferrer",class:"bik-link"}}),l,a.configure({placeholder:null!==(w=j.placeholder)&&void 0!==w?w:"Type a message..."}),...j.onPaste?[x.configure({onPaste:j.onPaste})]:[],...N?[g]:[v],C.configure({onSend:j.onSend,sendShortcut:j.sendShortcut,extraShortcuts:null!==(I=j.shortcuts)&&void 0!==I?I:[]}),k,...j.maxCharacters?[o.configure({limit:j.maxCharacters})]:[],S],...[...(null===(T=j.mentions)||void 0===T?void 0:T.agents)?[f(j.mentions.agents,j.onMentionSelected,j.renderMentionItem,j.renderMentionDropdown)]:[],...(null===(z=j.mentions)||void 0===z?void 0:z.teams)?[h(j.mentions.teams,j.onMentionSelected,j.renderMentionItem,j.renderMentionDropdown)]:[],...j.slashCommands?[b(j.slashCommands,j.onSlashCommandSelected,j.renderSlashCommandItem,j.renderSlashCommandDropdown)]:[]],...O?[e,n.configure({multicolor:!0}),t,u,p.configure({types:["heading","paragraph"]}),s,m,i]:[e]]}export{j as buildExtensions};
|
|
2
2
|
//# sourceMappingURL=buildExtensions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildExtensions.js","sources":["../../../../src/editor/extensions/buildExtensions.ts"],"sourcesContent":["import CharacterCount from '@tiptap/extension-character-count';\nimport Color from '@tiptap/extension-color';\nimport FontFamily from '@tiptap/extension-font-family';\nimport Highlight from '@tiptap/extension-highlight';\nimport Image from '@tiptap/extension-image';\nimport Link from '@tiptap/extension-link';\nimport Placeholder from '@tiptap/extension-placeholder';\nimport Subscript from '@tiptap/extension-subscript';\nimport Superscript from '@tiptap/extension-superscript';\nimport TextAlign from '@tiptap/extension-text-align';\nimport { TextStyle } from '@tiptap/extension-text-style';\nimport Underline from '@tiptap/extension-underline';\nimport StarterKit from '@tiptap/starter-kit';\nimport type { ReactNode } from 'react';\nimport type {\n\tEditorFeatures,\n\tEditorSnapshot,\n\tKeyboardShortcut,\n\tMentionDropdownRenderProps,\n\tMentionItem,\n\tPasteData,\n\tSlashCommandDropdownRenderProps,\n\tSlashCommandItem,\n} from '../BikEditor.types';\nimport { FontSizeExtension } from './FontSizeExtension';\nimport {\n\tbuildAgentMentionExtension,\n\tbuildTeamMentionExtension,\n} from './mention/MentionExtension';\nimport { PasteExtension } from './paste/PasteExtension';\nimport {
|
|
1
|
+
{"version":3,"file":"buildExtensions.js","sources":["../../../../src/editor/extensions/buildExtensions.ts"],"sourcesContent":["import CharacterCount from '@tiptap/extension-character-count';\nimport Color from '@tiptap/extension-color';\nimport FontFamily from '@tiptap/extension-font-family';\nimport Highlight from '@tiptap/extension-highlight';\nimport Image from '@tiptap/extension-image';\nimport Link from '@tiptap/extension-link';\nimport Placeholder from '@tiptap/extension-placeholder';\nimport Subscript from '@tiptap/extension-subscript';\nimport Superscript from '@tiptap/extension-superscript';\nimport TextAlign from '@tiptap/extension-text-align';\nimport { TextStyle } from '@tiptap/extension-text-style';\nimport Underline from '@tiptap/extension-underline';\nimport StarterKit from '@tiptap/starter-kit';\nimport type { ReactNode } from 'react';\nimport type {\n\tEditorFeatures,\n\tEditorSnapshot,\n\tKeyboardShortcut,\n\tMentionDropdownRenderProps,\n\tMentionItem,\n\tPasteData,\n\tSlashCommandDropdownRenderProps,\n\tSlashCommandItem,\n} from '../BikEditor.types';\nimport { FontSizeExtension } from './FontSizeExtension';\nimport {\n\tbuildAgentMentionExtension,\n\tbuildTeamMentionExtension,\n} from './mention/MentionExtension';\nimport { PasteExtension } from './paste/PasteExtension';\nimport { ClipboardNormalizationExtension } from './plainClipboard/ClipboardNormalizationExtension';\nimport { PlainClipboardExtension } from './plainClipboard/PlainClipboardExtension';\nimport { SectionDividerNode } from './sectionDivider/SectionDividerNode';\nimport { SendShortcutExtension } from './sendShortcut/SendShortcutExtension';\nimport { buildSlashCommandExtension } from './slashCommand/SlashCommandExtension';\nimport { VariableDecorationExtension } from './variable/VariableDecorationExtension';\n\ninterface ExtensionConfig {\n\tfeatures?: EditorFeatures;\n\tplaceholder?: string;\n\tmaxCharacters?: number;\n\thasSections?: boolean;\n\tmentions?: {\n\t\tagents?: { current: MentionItem[] };\n\t\tteams?: { current: MentionItem[] };\n\t};\n\tslashCommands?: { current: SlashCommandItem[] };\n\tonPaste?: (data: PasteData) => boolean | void;\n\tonSend?: (content: EditorSnapshot) => void;\n\tsendShortcut?:\n\t\t| { key: string; modifiers?: Array<'mod' | 'ctrl' | 'shift' | 'alt'> }\n\t\t| Array<{\n\t\t\t\tkey: string;\n\t\t\t\tmodifiers?: Array<'mod' | 'ctrl' | 'shift' | 'alt'>;\n\t\t }>;\n\tshortcuts?: KeyboardShortcut[];\n\tonMentionSelected?: (item: MentionItem, char: '@' | '#') => void;\n\tonSlashCommandSelected?: (command: SlashCommandItem) => void;\n\trenderMentionItem?: (item: MentionItem, isActive: boolean) => ReactNode;\n\trenderMentionDropdown?: (props: MentionDropdownRenderProps) => ReactNode;\n\trenderSlashCommandItem?: (\n\t\titem: SlashCommandItem,\n\t\tisActive: boolean,\n\t) => ReactNode;\n\trenderSlashCommandDropdown?: (\n\t\tprops: SlashCommandDropdownRenderProps,\n\t) => ReactNode;\n}\n\nexport function buildExtensions(config: ExtensionConfig) {\n\tconst hasRichPaste = config.features?.richPaste ?? false;\n\tconst hasRichTypography = config.features?.richTypography ?? false;\n\n\t// When allowedMarks is specified only those marks are registered in the schema.\n\t// This disables rendering, keyboard shortcuts AND paste-preservation for the\n\t// excluded marks — all three come for free when the extension is absent.\n\tconst allowedMarks = config.features?.allowedMarks;\n\tconst isMark = (m: 'bold' | 'italic' | 'strike' | 'underline' | 'code') =>\n\t\t!allowedMarks || allowedMarks.includes(m);\n\n\tconst base = [\n\t\t// Exclude Link and Underline from StarterKit — TipTap v3 bundles both.\n\t\t// Without this, two copies of each are registered and the StarterKit copy's\n\t\t// click handler calls window.open even when openOnClick: false is set.\n\t\tStarterKit.configure({\n\t\t\tlink: false,\n\t\t\tunderline: false,\n\t\t\tbold: isMark('bold') ? {} : false,\n\t\t\titalic: isMark('italic') ? {} : false,\n\t\t\tstrike: isMark('strike') ? {} : false,\n\t\t\tcode: isMark('code') ? {} : false,\n\t\t}),\n\t\t...(isMark('underline') ? [Underline] : []),\n\t\t// Extend Link to strip addPasteRules() and addInputRules() so pasting a\n\t\t// URL never creates a hyperlink regardless of autolink/linkOnPaste values.\n\t\tLink.extend({\n\t\t\taddPasteRules: () => [],\n\t\t\taddInputRules: () => [],\n\t\t}).configure({\n\t\t\topenOnClick: false,\n\t\t\tautolink: false,\n\t\t\tlinkOnPaste: false,\n\t\t\tHTMLAttributes: {\n\t\t\t\trel: 'noopener noreferrer',\n\t\t\t\tclass: 'bik-link',\n\t\t\t},\n\t\t}),\n\t\tTextStyle,\n\t\tPlaceholder.configure({\n\t\t\tplaceholder: config.placeholder ?? 'Type a message...',\n\t\t}),\n\t\t// Consumer paste callback runs first. If it returns true the event is\n\t\t// consumed and neither PlainClipboardExtension nor the editor's default\n\t\t// paste handling will run for that event.\n\t\t...(config.onPaste\n\t\t\t? [PasteExtension.configure({ onPaste: config.onPaste })]\n\t\t\t: []),\n\t\t// Non-rich editors: strip rich marks + normalize blanks on paste.\n\t\t// Rich editors (email): only normalize blanks (fix Google Docs spacing).\n\t\t...(!hasRichPaste\n\t\t\t? [PlainClipboardExtension]\n\t\t\t: [ClipboardNormalizationExtension]),\n\t\tSendShortcutExtension.configure({\n\t\t\tonSend: config.onSend,\n\t\t\tsendShortcut: config.sendShortcut,\n\t\t\textraShortcuts: config.shortcuts ?? [],\n\t\t}),\n\t\tVariableDecorationExtension,\n\t\t...(config.maxCharacters\n\t\t\t? [CharacterCount.configure({ limit: config.maxCharacters })]\n\t\t\t: []),\n\t\t// Always register SectionDividerNode so the custom <div data-section-divider>\n\t\t// node is part of the schema in every editor instance. This means imperative\n\t\t// callers (setBodyAndSections / setSectionContent) work even when no\n\t\t// `sections` prop was provided at mount time.\n\t\tSectionDividerNode,\n\t];\n\n\tconst mentionExtensions = [\n\t\t...(config.mentions?.agents\n\t\t\t? [\n\t\t\t\t\tbuildAgentMentionExtension(\n\t\t\t\t\t\tconfig.mentions.agents,\n\t\t\t\t\t\tconfig.onMentionSelected,\n\t\t\t\t\t\tconfig.renderMentionItem,\n\t\t\t\t\t\tconfig.renderMentionDropdown,\n\t\t\t\t\t),\n\t\t\t ]\n\t\t\t: []),\n\t\t...(config.mentions?.teams\n\t\t\t? [\n\t\t\t\t\tbuildTeamMentionExtension(\n\t\t\t\t\t\tconfig.mentions.teams,\n\t\t\t\t\t\tconfig.onMentionSelected,\n\t\t\t\t\t\tconfig.renderMentionItem,\n\t\t\t\t\t\tconfig.renderMentionDropdown,\n\t\t\t\t\t),\n\t\t\t ]\n\t\t\t: []),\n\t\t...(config.slashCommands\n\t\t\t? [\n\t\t\t\t\tbuildSlashCommandExtension(\n\t\t\t\t\t\tconfig.slashCommands,\n\t\t\t\t\t\tconfig.onSlashCommandSelected,\n\t\t\t\t\t\tconfig.renderSlashCommandItem,\n\t\t\t\t\t\tconfig.renderSlashCommandDropdown,\n\t\t\t\t\t),\n\t\t\t ]\n\t\t\t: []),\n\t];\n\n\tconst richExtensions = hasRichTypography\n\t\t? [\n\t\t\t\tColor,\n\t\t\t\tHighlight.configure({ multicolor: true }),\n\t\t\t\tFontFamily,\n\t\t\t\tFontSizeExtension,\n\t\t\t\tTextAlign.configure({ types: ['heading', 'paragraph'] }),\n\t\t\t\tSubscript,\n\t\t\t\tSuperscript,\n\t\t\t\tImage,\n\t\t ]\n\t\t: [Color];\n\n\treturn [...base, ...mentionExtensions, ...richExtensions];\n}\n"],"names":["buildExtensions","config","hasRichPaste","_b","_a","features","richPaste","hasRichTypography","_d","_c","richTypography","allowedMarks","_e","isMark","m","includes","StarterKit","configure","link","underline","bold","italic","strike","code","Underline","Link","extend","addPasteRules","addInputRules","openOnClick","autolink","linkOnPaste","HTMLAttributes","rel","class","TextStyle","Placeholder","placeholder","_f","onPaste","PasteExtension","ClipboardNormalizationExtension","PlainClipboardExtension","SendShortcutExtension","onSend","sendShortcut","extraShortcuts","_g","shortcuts","VariableDecorationExtension","maxCharacters","CharacterCount","limit","SectionDividerNode","_h","mentions","agents","buildAgentMentionExtension","onMentionSelected","renderMentionItem","renderMentionDropdown","_j","teams","buildTeamMentionExtension","slashCommands","buildSlashCommandExtension","onSlashCommandSelected","renderSlashCommandItem","renderSlashCommandDropdown","Color","Highlight","multicolor","FontFamily","FontSizeExtension","TextAlign","types","Subscript","Superscript","Image"],"mappings":"0xCAqEM,SAAUA,EAAgBC,yBAC/B,MAAMC,EAA6C,QAA9BC,EAAiB,QAAjBC,EAAAH,EAAOI,gBAAU,IAAAD,OAAA,EAAAA,EAAAE,iBAAa,IAAAH,GAAAA,EAC7CI,EAAuD,QAAnCC,EAAiB,QAAjBC,EAAAR,EAAOI,gBAAU,IAAAI,OAAA,EAAAA,EAAAC,sBAAkB,IAAAF,GAAAA,EAKvDG,EAA8B,QAAfC,EAAAX,EAAOI,gBAAQ,IAAAO,OAAA,EAAAA,EAAED,aAChCE,EAAUC,IACdH,GAAgBA,EAAaI,SAASD,GA0GxC,MAAO,IAxGM,CAIZE,EAAWC,UAAU,CACpBC,MAAM,EACNC,WAAW,EACXC,OAAMP,EAAO,SAAU,CAAE,EACzBQ,SAAQR,EAAO,WAAY,CAAE,EAC7BS,SAAQT,EAAO,WAAY,CAAE,EAC7BU,OAAMV,EAAO,SAAU,CAAE,OAEtBA,EAAO,aAAe,CAACW,GAAa,GAGxCC,EAAKC,OAAO,CACXC,cAAeA,IAAM,GACrBC,cAAeA,IAAM,KACnBX,UAAU,CACZY,aAAa,EACbC,UAAU,EACVC,aAAa,EACbC,eAAgB,CACfC,IAAK,sBACLC,MAAO,cAGTC,EACAC,EAAYnB,UAAU,CACrBoB,oBAAaC,EAAArC,EAAOoC,2BAAe,yBAKhCpC,EAAOsC,QACR,CAACC,EAAevB,UAAU,CAAEsB,QAAStC,EAAOsC,WAC5C,MAGErC,EAEF,CAACuC,GADD,CAACC,GAEJC,EAAsB1B,UAAU,CAC/B2B,OAAQ3C,EAAO2C,OACfC,aAAc5C,EAAO4C,aACrBC,uBAAgBC,EAAA9C,EAAO+C,yBAAa,KAErCC,KACIhD,EAAOiD,cACR,CAACC,EAAelC,UAAU,CAAEmC,MAAOnD,EAAOiD,iBAC1C,GAKHG,MAGyB,aACrBC,EAAArD,EAAOsD,+BAAUC,QAClB,CACAC,EACCxD,EAAOsD,SAASC,OAChBvD,EAAOyD,kBACPzD,EAAO0D,kBACP1D,EAAO2D,wBAGR,eACCC,EAAA5D,EAAOsD,+BAAUO,OAClB,CACAC,EACC9D,EAAOsD,SAASO,MAChB7D,EAAOyD,kBACPzD,EAAO0D,kBACP1D,EAAO2D,wBAGR,MACC3D,EAAO+D,cACR,CACAC,EACChE,EAAO+D,cACP/D,EAAOiE,uBACPjE,EAAOkE,uBACPlE,EAAOmE,6BAGR,OAGmB7D,EACpB,CACA8D,EACAC,EAAUrD,UAAU,CAAEsD,YAAY,IAClCC,EACAC,EACAC,EAAUzD,UAAU,CAAE0D,MAAO,CAAC,UAAW,eACzCC,EACAC,EACAC,GAEA,CAACT,GAGL"}
|
|
@@ -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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
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
|
+
//# sourceMappingURL=PlainClipboardExtension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Fragment as e
|
|
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
2
|
//# sourceMappingURL=pasteUtils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pasteUtils.js","sources":["../../../../../src/editor/extensions/plainClipboard/pasteUtils.ts"],"sourcesContent":["import { Fragment, Node as PMNode
|
|
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"}
|
|
@@ -8,6 +8,8 @@ export declare const VariablePickerContext: React.Context<{
|
|
|
8
8
|
setVariables: React.Dispatch<React.SetStateAction<any[]>>;
|
|
9
9
|
showRecommended: boolean;
|
|
10
10
|
setShowRecommended: React.Dispatch<React.SetStateAction<boolean>>;
|
|
11
|
+
containerRef: React.RefObject<HTMLDivElement | null>;
|
|
12
|
+
scrollPositionStack: React.MutableRefObject<number[]>;
|
|
11
13
|
}>;
|
|
12
14
|
export declare const useVariablePickerContext: () => {
|
|
13
15
|
searchText: string;
|
|
@@ -18,4 +20,6 @@ export declare const useVariablePickerContext: () => {
|
|
|
18
20
|
setVariables: React.Dispatch<React.SetStateAction<any[]>>;
|
|
19
21
|
showRecommended: boolean;
|
|
20
22
|
setShowRecommended: React.Dispatch<React.SetStateAction<boolean>>;
|
|
23
|
+
containerRef: React.RefObject<HTMLDivElement | null>;
|
|
24
|
+
scrollPositionStack: React.MutableRefObject<number[]>;
|
|
21
25
|
};
|
|
@@ -728,6 +728,4 @@ export interface BikEditorProps {
|
|
|
728
728
|
minHeight?: string;
|
|
729
729
|
/** Maximum height. The editor scrolls internally when exceeded. CSS value, e.g. `'400px'`. */
|
|
730
730
|
maxHeight?: string;
|
|
731
|
-
/** Gap between consecutive paragraphs. CSS value, defaults to `'4px'`. */
|
|
732
|
-
paragraphGap?: string;
|
|
733
731
|
}
|
|
@@ -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>;
|
|
@@ -1,53 +1,21 @@
|
|
|
1
|
-
import { Fragment
|
|
1
|
+
import { Fragment } from '@tiptap/pm/model';
|
|
2
2
|
export declare const TEXTBLOCK_TAGS: Set<string>;
|
|
3
3
|
export declare const BLOCK_SELECTOR = "p,div,h1,h2,h3,h4,h5,h6,ul,ol,li,blockquote,table,pre";
|
|
4
|
-
/**
|
|
5
|
-
* When pasted HTML is entirely inline (no block elements), split at
|
|
6
|
-
* `<br><br>` boundaries into `<p>` elements. Single `<br>` stays as a
|
|
7
|
-
* line break inside the paragraph.
|
|
8
|
-
*/
|
|
9
|
-
export declare function wrapInlineContent(container: HTMLElement): void;
|
|
10
4
|
/**
|
|
11
5
|
* Replace `<br>` elements that sit at block level (not inside a textblock
|
|
12
6
|
* like `<p>`, `<li>`, etc.) with empty `<p></p>` elements. Google Docs
|
|
13
7
|
* puts standalone `<br>` tags between paragraphs to represent blank lines.
|
|
8
|
+
* Without this, ProseMirror parses them as top-level hardBreak nodes.
|
|
14
9
|
*/
|
|
15
10
|
export declare function cleanBlockBrs(container: HTMLElement): void;
|
|
16
11
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* placeholder. Without this, ProseMirror creates a trailing hardBreak that
|
|
20
|
-
* adds a visual blank line at the bottom of the paragraph.
|
|
21
|
-
*/
|
|
22
|
-
export declare function stripTrailingBrs(container: HTMLElement): void;
|
|
23
|
-
/**
|
|
24
|
-
* Convert paragraphs containing only a hardBreak into truly empty paragraphs.
|
|
25
|
-
* Google Docs represents blank lines as `<p><br></p>` — ProseMirror parses
|
|
26
|
-
* the `<br>` as a hardBreak node, which renders double-height. Converting to
|
|
27
|
-
* an empty paragraph (childCount 0) gives a single-height blank line.
|
|
28
|
-
*
|
|
29
|
-
* Does NOT collapse consecutive empties — that would destroy user intent.
|
|
12
|
+
* 1. Convert paragraphs containing only a hard_break into empty paragraphs.
|
|
13
|
+
* 2. Collapse consecutive empty paragraphs into one.
|
|
30
14
|
*/
|
|
31
|
-
export declare function
|
|
15
|
+
export declare function normalizeBlanks(fragment: Fragment): Fragment;
|
|
32
16
|
/**
|
|
33
|
-
* Strip "rich" marks (link, textStyle, highlight, etc.) while keeping
|
|
34
|
-
* basic marks (bold, italic, strike, underline, code) that
|
|
35
|
-
* channels can represent.
|
|
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.
|
|
36
20
|
*/
|
|
37
21
|
export declare function stripRichMarks(fragment: Fragment): Fragment;
|
|
38
|
-
/**
|
|
39
|
-
* Parse plain clipboard text into a ProseMirror Slice, preserving blank
|
|
40
|
-
* lines as empty paragraphs. This replaces ProseMirror's default text
|
|
41
|
-
* parser which uses `\n+` and loses all blank lines.
|
|
42
|
-
*
|
|
43
|
-
* Best for channels with compact paragraph gaps (e.g. WhatsApp) where
|
|
44
|
-
* blank lines need structural representation as empty paragraphs.
|
|
45
|
-
*/
|
|
46
|
-
export declare function parseClipboardText(text: string, schema: Schema): Slice;
|
|
47
|
-
/**
|
|
48
|
-
* Parse plain clipboard text into a single paragraph with hardBreaks for
|
|
49
|
-
* every `\n`. Produces the same structure as Gmail's Cmd+Shift+V output:
|
|
50
|
-
* one block element with `<br>` for line breaks and `<br><br>` for blank
|
|
51
|
-
* lines. This gives identical html and text output to Gmail.
|
|
52
|
-
*/
|
|
53
|
-
export declare function parseClipboardTextAsBreaks(text: string, schema: Schema): Slice;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SVGProps } from 'react';
|
|
2
|
+
interface Props extends SVGProps<SVGSVGElement> {
|
|
3
|
+
size?: number | string;
|
|
4
|
+
color?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const SvgSendAirplane2: ({ size, color, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SvgSendAirplane2;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SVGProps } from 'react';
|
|
2
|
+
interface Props extends SVGProps<SVGSVGElement> {
|
|
3
|
+
size?: number | string;
|
|
4
|
+
color?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const SvgAiAgent: ({ size, color, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SvgAiAgent;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SVGProps } from 'react';
|
|
2
|
+
interface Props extends SVGProps<SVGSVGElement> {
|
|
3
|
+
size?: number | string;
|
|
4
|
+
color?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const SvgAtSymbol: ({ size, color, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SvgAtSymbol;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SVGProps } from 'react';
|
|
2
|
+
interface Props extends SVGProps<SVGSVGElement> {
|
|
3
|
+
size?: number | string;
|
|
4
|
+
color?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const SvgHangup: ({ size, color, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SvgHangup;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SVGProps } from 'react';
|
|
2
|
+
interface Props extends SVGProps<SVGSVGElement> {
|
|
3
|
+
size?: number | string;
|
|
4
|
+
color?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const SvgIncomingCall: ({ size, color, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SvgIncomingCall;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SVGProps } from 'react';
|
|
2
|
+
interface Props extends SVGProps<SVGSVGElement> {
|
|
3
|
+
size?: number | string;
|
|
4
|
+
color?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const SvgOutgoingCall: ({ size, color, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SvgOutgoingCall;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SVGProps } from 'react';
|
|
2
|
+
interface Props extends SVGProps<SVGSVGElement> {
|
|
3
|
+
size?: number | string;
|
|
4
|
+
color?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const SvgPhoneCall: ({ size, color, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SvgPhoneCall;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SVGProps } from 'react';
|
|
2
|
+
interface Props extends SVGProps<SVGSVGElement> {
|
|
3
|
+
size?: number | string;
|
|
4
|
+
color?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const SvgTranscript: ({ size, color, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SvgTranscript;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SVGProps } from 'react';
|
|
2
|
+
interface Props extends SVGProps<SVGSVGElement> {
|
|
3
|
+
size?: number | string;
|
|
4
|
+
color?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const SvgBookOpen: ({ size, color, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SvgBookOpen;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SVGProps } from 'react';
|
|
2
|
+
interface Props extends SVGProps<SVGSVGElement> {
|
|
3
|
+
size?: number | string;
|
|
4
|
+
color?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const SvgAiVoiceAgent: ({ size, color, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SvgAiVoiceAgent;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { default as FbCommentTicket } from './FbCommentTicket';
|
|
2
|
+
export { default as FbTicket } from './FbTicket';
|
|
3
|
+
export { default as IgCommentTicket } from './IgCommentTicket';
|
|
4
|
+
export { default as IgTicket } from './IgTicket';
|
|
5
|
+
export { default as MailTicket } from './MailTicket';
|
|
6
|
+
export { default as PhoneTicket } from './PhoneTicket';
|
|
7
|
+
export { default as TaskTicket } from './TaskTicket';
|
|
8
|
+
export { default as WhatsappTicket } from './WhatsappTicket';
|
package/package.json
CHANGED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../../../node_modules/@tiptap/core/dist/index.js"),t=require("@tiptap/pm/model"),r=require("@tiptap/pm/state"),a=require("@tiptap/pm/view"),n=require("./pasteUtils.js");const s=e.Extension.create({name:"pasteNormalization",addOptions:()=>({preserveMarks:!1}),addProseMirrorPlugins(){const e=this.options.preserveMarks;return[new r.Plugin({props:{decorations(e){const t=[];return e.doc.descendants(((e,r)=>{"paragraph"===e.type.name&&0===e.childCount&&t.push(a.Decoration.node(r,r+e.nodeSize,{class:"is-blank"}))})),a.DecorationSet.create(e.doc,t)},handlePaste(t,r){var a;if(e)return!1;const s=null===(a=r.clipboardData)||void 0===a?void 0:a.getData("text/plain");if(!s)return!1;const i=n.parseClipboardText(s,t.state.schema);return t.dispatch(t.state.tr.replaceSelection(i)),!0},clipboardTextParser:(t,r,a,s)=>(e?n.parseClipboardTextAsBreaks:n.parseClipboardText)(t,s.state.schema),transformPastedHTML(e){if(e.includes("data-pm-slice"))return e;const t=document.createElement("div");return t.innerHTML=e,n.wrapInlineContent(t),n.cleanBlockBrs(t),n.stripTrailingBrs(t),t.innerHTML},transformPasted(r){let a=n.normalizeHardBreaks(r.content);return e||(a=n.stripRichMarks(a)),new t.Slice(a,r.openStart,r.openEnd)}}})]}});exports.PasteNormalizationExtension=s;
|
|
2
|
-
//# sourceMappingURL=PasteNormalizationExtension.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PasteNormalizationExtension.js","sources":["../../../../../src/editor/extensions/plainClipboard/PasteNormalizationExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport { Slice } from '@tiptap/pm/model';\nimport { Plugin } from '@tiptap/pm/state';\nimport { Decoration, DecorationSet } from '@tiptap/pm/view';\nimport {\n\tcleanBlockBrs,\n\tnormalizeHardBreaks,\n\tparseClipboardText,\n\tparseClipboardTextAsBreaks,\n\tstripRichMarks,\n\tstripTrailingBrs,\n\twrapInlineContent,\n} from './pasteUtils';\n\n/**\n * Unified paste normalizer for all editor channels.\n *\n * Uses ProseMirror's recommended hooks instead of overriding handlePaste:\n * - clipboardTextParser: plain text → Slice (preserves blank lines)\n * - transformPastedHTML: HTML → HTML (cleans Google Docs / Word artifacts)\n * - transformPasted: Slice → Slice (normalizes hardBreaks, strips marks)\n *\n * Also decorates empty paragraphs with an `is-blank` CSS class so the\n * editor stylesheet can give blank lines precise height without extra margins.\n */\nexport const PasteNormalizationExtension = Extension.create({\n\tname: 'pasteNormalization',\n\taddOptions() {\n\t\treturn {\n\t\t\tpreserveMarks: false,\n\t\t};\n\t},\n\taddProseMirrorPlugins() {\n\t\tconst preserveMarks = this.options.preserveMarks;\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tprops: {\n\t\t\t\t\tdecorations(state) {\n\t\t\t\t\t\tconst decorations: Decoration[] = [];\n\t\t\t\t\t\tstate.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (node.type.name === 'paragraph' && node.childCount === 0) {\n\t\t\t\t\t\t\t\tdecorations.push(\n\t\t\t\t\t\t\t\t\tDecoration.node(pos, pos + node.nodeSize, {\n\t\t\t\t\t\t\t\t\t\tclass: 'is-blank',\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn DecorationSet.create(state.doc, decorations);\n\t\t\t\t\t},\n\n\t\t\t\t\thandlePaste(view, event) {\n\t\t\t\t\t\tif (preserveMarks) return false;\n\t\t\t\t\t\tconst text = event.clipboardData?.getData('text/plain');\n\t\t\t\t\t\tif (!text) return false;\n\t\t\t\t\t\tconst slice = parseClipboardText(text, view.state.schema);\n\t\t\t\t\t\tview.dispatch(view.state.tr.replaceSelection(slice));\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\n\t\t\t\t\tclipboardTextParser(text, _$context, _plain, view) {\n\t\t\t\t\t\tconst parse = preserveMarks\n\t\t\t\t\t\t\t? parseClipboardTextAsBreaks\n\t\t\t\t\t\t\t: parseClipboardText;\n\t\t\t\t\t\treturn parse(text, view.state.schema);\n\t\t\t\t\t},\n\n\t\t\t\t\ttransformPastedHTML(html) {\n\t\t\t\t\t\tif (html.includes('data-pm-slice')) return html;\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\twrapInlineContent(container);\n\t\t\t\t\t\tcleanBlockBrs(container);\n\t\t\t\t\t\tstripTrailingBrs(container);\n\t\t\t\t\t\treturn container.innerHTML;\n\t\t\t\t\t},\n\n\t\t\t\t\ttransformPasted(slice) {\n\t\t\t\t\t\tlet content = normalizeHardBreaks(slice.content);\n\t\t\t\t\t\tif (!preserveMarks) {\n\t\t\t\t\t\t\tcontent = stripRichMarks(content);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn new Slice(content, slice.openStart, slice.openEnd);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["PasteNormalizationExtension","Extension","create","name","addOptions","preserveMarks","addProseMirrorPlugins","this","options","Plugin","props","decorations","state","doc","descendants","node","pos","type","childCount","push","Decoration","nodeSize","class","DecorationSet","handlePaste","view","event","text","_a","clipboardData","getData","slice","parseClipboardText","schema","dispatch","tr","replaceSelection","clipboardTextParser","_$context","_plain","parseClipboardTextAsBreaks","transformPastedHTML","html","includes","container","document","createElement","innerHTML","wrapInlineContent","cleanBlockBrs","stripTrailingBrs","transformPasted","content","normalizeHardBreaks","stripRichMarks","Slice","openStart","openEnd"],"mappings":"kQAyBaA,EAA8BC,EAASA,UAACC,OAAO,CAC3DC,KAAM,qBACNC,WAAUA,KACF,CACNC,eAAe,IAGjBC,wBACC,MAAMD,EAAgBE,KAAKC,QAAQH,cACnC,MAAO,CACN,IAAII,EAAAA,OAAO,CACVC,MAAO,CACNC,YAAYC,GACX,MAAMD,EAA4B,GAUlC,OATAC,EAAMC,IAAIC,aAAY,CAACC,EAAMC,KACL,cAAnBD,EAAKE,KAAKd,MAA4C,IAApBY,EAAKG,YAC1CP,EAAYQ,KACXC,aAAWL,KAAKC,EAAKA,EAAMD,EAAKM,SAAU,CACzCC,MAAO,aAGT,IAEKC,EAAaA,cAACrB,OAAOU,EAAMC,IAAKF,EACvC,EAEDa,YAAYC,EAAMC,SACjB,GAAIrB,EAAe,OAAO,EAC1B,MAAMsB,EAA0B,QAAnBC,EAAAF,EAAMG,qBAAa,IAAAD,OAAA,EAAAA,EAAEE,QAAQ,cAC1C,IAAKH,EAAM,OAAO,EAClB,MAAMI,EAAQC,EAAAA,mBAAmBL,EAAMF,EAAKb,MAAMqB,QAElD,OADAR,EAAKS,SAAST,EAAKb,MAAMuB,GAAGC,iBAAiBL,KACtC,CACP,EAEDM,oBAAmBA,CAACV,EAAMW,EAAWC,EAAQd,KAC9BpB,EACXmC,EAA0BA,2BAC1BR,sBACUL,EAAMF,EAAKb,MAAMqB,QAG/BQ,oBAAoBC,GACnB,GAAIA,EAAKC,SAAS,iBAAkB,OAAOD,EAC3C,MAAME,EAAYC,SAASC,cAAc,OAKzC,OAJAF,EAAUG,UAAYL,EACtBM,EAAiBA,kBAACJ,GAClBK,EAAaA,cAACL,GACdM,EAAgBA,iBAACN,GACVA,EAAUG,SACjB,EAEDI,gBAAgBpB,GACf,IAAIqB,EAAUC,EAAAA,oBAAoBtB,EAAMqB,SAIxC,OAHK/C,IACJ+C,EAAUE,EAAAA,eAAeF,IAEnB,IAAIG,EAAKA,MAACH,EAASrB,EAAMyB,UAAWzB,EAAM0B,QAClD,KAIJ"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Extension } from '@tiptap/core';
|
|
2
|
-
/**
|
|
3
|
-
* Unified paste normalizer for all editor channels.
|
|
4
|
-
*
|
|
5
|
-
* Uses ProseMirror's recommended hooks instead of overriding handlePaste:
|
|
6
|
-
* - clipboardTextParser: plain text → Slice (preserves blank lines)
|
|
7
|
-
* - transformPastedHTML: HTML → HTML (cleans Google Docs / Word artifacts)
|
|
8
|
-
* - transformPasted: Slice → Slice (normalizes hardBreaks, strips marks)
|
|
9
|
-
*
|
|
10
|
-
* Also decorates empty paragraphs with an `is-blank` CSS class so the
|
|
11
|
-
* editor stylesheet can give blank lines precise height without extra margins.
|
|
12
|
-
*/
|
|
13
|
-
export declare const PasteNormalizationExtension: Extension<any, any>;
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{Extension as t}from"../../../node_modules/@tiptap/core/dist/index.js";import{Slice as e}from"@tiptap/pm/model";import{Plugin as r}from"@tiptap/pm/state";import{Decoration as a,DecorationSet as n}from"@tiptap/pm/view";import{parseClipboardText as o,wrapInlineContent as s,cleanBlockBrs as i,stripTrailingBrs as p,normalizeHardBreaks as d,stripRichMarks as c,parseClipboardTextAsBreaks as m}from"./pasteUtils.js";const l=t.create({name:"pasteNormalization",addOptions:()=>({preserveMarks:!1}),addProseMirrorPlugins(){const t=this.options.preserveMarks;return[new r({props:{decorations(t){const e=[];return t.doc.descendants(((t,r)=>{"paragraph"===t.type.name&&0===t.childCount&&e.push(a.node(r,r+t.nodeSize,{class:"is-blank"}))})),n.create(t.doc,e)},handlePaste(e,r){var a;if(t)return!1;const n=null===(a=r.clipboardData)||void 0===a?void 0:a.getData("text/plain");if(!n)return!1;const s=o(n,e.state.schema);return e.dispatch(e.state.tr.replaceSelection(s)),!0},clipboardTextParser:(e,r,a,n)=>(t?m:o)(e,n.state.schema),transformPastedHTML(t){if(t.includes("data-pm-slice"))return t;const e=document.createElement("div");return e.innerHTML=t,s(e),i(e),p(e),e.innerHTML},transformPasted(r){let a=d(r.content);return t||(a=c(a)),new e(a,r.openStart,r.openEnd)}}})]}});export{l as PasteNormalizationExtension};
|
|
2
|
-
//# sourceMappingURL=PasteNormalizationExtension.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PasteNormalizationExtension.js","sources":["../../../../../src/editor/extensions/plainClipboard/PasteNormalizationExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport { Slice } from '@tiptap/pm/model';\nimport { Plugin } from '@tiptap/pm/state';\nimport { Decoration, DecorationSet } from '@tiptap/pm/view';\nimport {\n\tcleanBlockBrs,\n\tnormalizeHardBreaks,\n\tparseClipboardText,\n\tparseClipboardTextAsBreaks,\n\tstripRichMarks,\n\tstripTrailingBrs,\n\twrapInlineContent,\n} from './pasteUtils';\n\n/**\n * Unified paste normalizer for all editor channels.\n *\n * Uses ProseMirror's recommended hooks instead of overriding handlePaste:\n * - clipboardTextParser: plain text → Slice (preserves blank lines)\n * - transformPastedHTML: HTML → HTML (cleans Google Docs / Word artifacts)\n * - transformPasted: Slice → Slice (normalizes hardBreaks, strips marks)\n *\n * Also decorates empty paragraphs with an `is-blank` CSS class so the\n * editor stylesheet can give blank lines precise height without extra margins.\n */\nexport const PasteNormalizationExtension = Extension.create({\n\tname: 'pasteNormalization',\n\taddOptions() {\n\t\treturn {\n\t\t\tpreserveMarks: false,\n\t\t};\n\t},\n\taddProseMirrorPlugins() {\n\t\tconst preserveMarks = this.options.preserveMarks;\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tprops: {\n\t\t\t\t\tdecorations(state) {\n\t\t\t\t\t\tconst decorations: Decoration[] = [];\n\t\t\t\t\t\tstate.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (node.type.name === 'paragraph' && node.childCount === 0) {\n\t\t\t\t\t\t\t\tdecorations.push(\n\t\t\t\t\t\t\t\t\tDecoration.node(pos, pos + node.nodeSize, {\n\t\t\t\t\t\t\t\t\t\tclass: 'is-blank',\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn DecorationSet.create(state.doc, decorations);\n\t\t\t\t\t},\n\n\t\t\t\t\thandlePaste(view, event) {\n\t\t\t\t\t\tif (preserveMarks) return false;\n\t\t\t\t\t\tconst text = event.clipboardData?.getData('text/plain');\n\t\t\t\t\t\tif (!text) return false;\n\t\t\t\t\t\tconst slice = parseClipboardText(text, view.state.schema);\n\t\t\t\t\t\tview.dispatch(view.state.tr.replaceSelection(slice));\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\n\t\t\t\t\tclipboardTextParser(text, _$context, _plain, view) {\n\t\t\t\t\t\tconst parse = preserveMarks\n\t\t\t\t\t\t\t? parseClipboardTextAsBreaks\n\t\t\t\t\t\t\t: parseClipboardText;\n\t\t\t\t\t\treturn parse(text, view.state.schema);\n\t\t\t\t\t},\n\n\t\t\t\t\ttransformPastedHTML(html) {\n\t\t\t\t\t\tif (html.includes('data-pm-slice')) return html;\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\twrapInlineContent(container);\n\t\t\t\t\t\tcleanBlockBrs(container);\n\t\t\t\t\t\tstripTrailingBrs(container);\n\t\t\t\t\t\treturn container.innerHTML;\n\t\t\t\t\t},\n\n\t\t\t\t\ttransformPasted(slice) {\n\t\t\t\t\t\tlet content = normalizeHardBreaks(slice.content);\n\t\t\t\t\t\tif (!preserveMarks) {\n\t\t\t\t\t\t\tcontent = stripRichMarks(content);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn new Slice(content, slice.openStart, slice.openEnd);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["PasteNormalizationExtension","Extension","create","name","addOptions","preserveMarks","addProseMirrorPlugins","this","options","Plugin","props","decorations","state","doc","descendants","node","pos","type","childCount","push","Decoration","nodeSize","class","DecorationSet","handlePaste","view","event","text","_a","clipboardData","getData","slice","parseClipboardText","schema","dispatch","tr","replaceSelection","clipboardTextParser","_$context","_plain","parseClipboardTextAsBreaks","transformPastedHTML","html","includes","container","document","createElement","innerHTML","wrapInlineContent","cleanBlockBrs","stripTrailingBrs","transformPasted","content","normalizeHardBreaks","stripRichMarks","Slice","openStart","openEnd"],"mappings":"waAyBaA,EAA8BC,EAAUC,OAAO,CAC3DC,KAAM,qBACNC,WAAUA,KACF,CACNC,eAAe,IAGjBC,wBACC,MAAMD,EAAgBE,KAAKC,QAAQH,cACnC,MAAO,CACN,IAAII,EAAO,CACVC,MAAO,CACNC,YAAYC,GACX,MAAMD,EAA4B,GAUlC,OATAC,EAAMC,IAAIC,aAAY,CAACC,EAAMC,KACL,cAAnBD,EAAKE,KAAKd,MAA4C,IAApBY,EAAKG,YAC1CP,EAAYQ,KACXC,EAAWL,KAAKC,EAAKA,EAAMD,EAAKM,SAAU,CACzCC,MAAO,aAGT,IAEKC,EAAcrB,OAAOU,EAAMC,IAAKF,EACvC,EAEDa,YAAYC,EAAMC,SACjB,GAAIrB,EAAe,OAAO,EAC1B,MAAMsB,EAA0B,QAAnBC,EAAAF,EAAMG,qBAAa,IAAAD,OAAA,EAAAA,EAAEE,QAAQ,cAC1C,IAAKH,EAAM,OAAO,EAClB,MAAMI,EAAQC,EAAmBL,EAAMF,EAAKb,MAAMqB,QAElD,OADAR,EAAKS,SAAST,EAAKb,MAAMuB,GAAGC,iBAAiBL,KACtC,CACP,EAEDM,oBAAmBA,CAACV,EAAMW,EAAWC,EAAQd,KAC9BpB,EACXmC,EACAR,GACUL,EAAMF,EAAKb,MAAMqB,QAG/BQ,oBAAoBC,GACnB,GAAIA,EAAKC,SAAS,iBAAkB,OAAOD,EAC3C,MAAME,EAAYC,SAASC,cAAc,OAKzC,OAJAF,EAAUG,UAAYL,EACtBM,EAAkBJ,GAClBK,EAAcL,GACdM,EAAiBN,GACVA,EAAUG,SACjB,EAEDI,gBAAgBpB,GACf,IAAIqB,EAAUC,EAAoBtB,EAAMqB,SAIxC,OAHK/C,IACJ+C,EAAUE,EAAeF,IAEnB,IAAIG,EAAMH,EAASrB,EAAMyB,UAAWzB,EAAM0B,QAClD,KAIJ"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Extension } from '@tiptap/core';
|
|
2
|
-
/**
|
|
3
|
-
* Unified paste normalizer for all editor channels.
|
|
4
|
-
*
|
|
5
|
-
* Uses ProseMirror's recommended hooks instead of overriding handlePaste:
|
|
6
|
-
* - clipboardTextParser: plain text → Slice (preserves blank lines)
|
|
7
|
-
* - transformPastedHTML: HTML → HTML (cleans Google Docs / Word artifacts)
|
|
8
|
-
* - transformPasted: Slice → Slice (normalizes hardBreaks, strips marks)
|
|
9
|
-
*
|
|
10
|
-
* Also decorates empty paragraphs with an `is-blank` CSS class so the
|
|
11
|
-
* editor stylesheet can give blank lines precise height without extra margins.
|
|
12
|
-
*/
|
|
13
|
-
export declare const PasteNormalizationExtension: Extension<any, any>;
|