@pega/cosmos-react-rte 9.0.0-build.22.0 → 9.0.0-build.22.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"IframeTiptapEditor.d.ts","sourceRoot":"","sources":["../../../src/components/Editor/IframeTiptapEditor.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,cAAc,CAAC;AAO3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAE9C,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AA+BjE,MAAM,WAAW,uBAAuB;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IAC1C,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;IAC5C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACnE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;IAC5C,eAAe,CAAC,EAAE,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,gBAAgB,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,eAAe,EAAE,CAAC;IACnC,WAAW,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;CAC1C;AAGD,eAAO,MAAM,kBAAkB,GAAI,iOAmBhC,uBAAuB,4CA2RzB,CAAC"}
1
+ {"version":3,"file":"IframeTiptapEditor.d.ts","sourceRoot":"","sources":["../../../src/components/Editor/IframeTiptapEditor.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,cAAc,CAAC;AAS3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAE9C,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AA0EjE,MAAM,WAAW,uBAAuB;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IAC1C,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;IAC5C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACnE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;IAC5C,eAAe,CAAC,EAAE,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,gBAAgB,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,eAAe,EAAE,CAAC;IACnC,WAAW,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;CAC1C;AAGD,eAAO,MAAM,kBAAkB,GAAI,iOAmBhC,uBAAuB,4CAkSzB,CAAC"}
@@ -5,8 +5,54 @@ import StarterKit from '@tiptap/starter-kit';
5
5
  import Placeholder from '@tiptap/extension-placeholder';
6
6
  import Link from '@tiptap/extension-link';
7
7
  import Image from '@tiptap/extension-image';
8
+ import Blockquote from '@tiptap/extension-blockquote';
9
+ import Paragraph from '@tiptap/extension-paragraph';
8
10
  import { useEffect, useImperativeHandle, useMemo } from 'react';
9
11
  import { TextIndent } from './extensions/TextIndent';
12
+ import { PreserveDiv } from './extensions/PreserveDiv';
13
+ // Extend Blockquote to preserve inline styles (e.g., border-left from email chains)
14
+ const BlockquoteWithStyle = Blockquote.extend({
15
+ addAttributes() {
16
+ return {
17
+ ...this.parent?.(),
18
+ style: {
19
+ default: null,
20
+ parseHTML: element => element.getAttribute('style'),
21
+ renderHTML: attributes => {
22
+ if (!attributes.style)
23
+ return {};
24
+ return { style: attributes.style };
25
+ }
26
+ }
27
+ };
28
+ }
29
+ });
30
+ // Extend Paragraph to preserve class and style attributes (e.g., pega-email-reply-header)
31
+ const ParagraphWithStyle = Paragraph.extend({
32
+ addAttributes() {
33
+ return {
34
+ ...this.parent?.(),
35
+ class: {
36
+ default: null,
37
+ parseHTML: element => element.getAttribute('class'),
38
+ renderHTML: attributes => {
39
+ if (!attributes.class)
40
+ return {};
41
+ return { class: attributes.class };
42
+ }
43
+ },
44
+ style: {
45
+ default: null,
46
+ parseHTML: element => element.getAttribute('style'),
47
+ renderHTML: attributes => {
48
+ if (!attributes.style)
49
+ return {};
50
+ return { style: attributes.style };
51
+ }
52
+ }
53
+ };
54
+ }
55
+ });
10
56
  // Custom keyboard shortcuts that match the toolbar tooltips
11
57
  const CustomKeyboardShortcuts = Extension.create({
12
58
  name: 'customKeyboardShortcuts',
@@ -107,11 +153,17 @@ export const IframeTiptapEditor = ({ placeholder, defaultValue, disabled, readOn
107
153
  StarterKit.configure({
108
154
  // Exclude link from StarterKit since we're configuring it separately
109
155
  link: false,
156
+ // Exclude blockquote so we can use our extended version with style preservation
157
+ blockquote: false,
158
+ // Exclude paragraph so we can use our extended version with class/style preservation
159
+ paragraph: false,
110
160
  // Disable text patterns if specified in initOptions
111
161
  ...(initOptions?.textPatterns === false && {
112
162
  typography: false
113
163
  })
114
164
  }),
165
+ BlockquoteWithStyle,
166
+ ParagraphWithStyle,
115
167
  Placeholder.configure({
116
168
  placeholder: placeholder ?? ''
117
169
  }),
@@ -130,6 +182,7 @@ export const IframeTiptapEditor = ({ placeholder, defaultValue, disabled, readOn
130
182
  allowBase64: true
131
183
  }),
132
184
  CustomKeyboardShortcuts,
185
+ PreserveDiv,
133
186
  ...customComponentExtensions
134
187
  ],
135
188
  content: defaultValue,
@@ -1 +1 @@
1
- {"version":3,"file":"IframeTiptapEditor.js","sourceRoot":"","sources":["../../../src/components/Editor/IframeTiptapEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEditor, EditorContent } from '@tiptap/react';\nimport { Extension, Node } from '@tiptap/core';\nimport type { Editor as TiptapEditor } from '@tiptap/core';\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model';\nimport StarterKit from '@tiptap/starter-kit';\nimport Placeholder from '@tiptap/extension-placeholder';\nimport Link from '@tiptap/extension-link';\nimport Image from '@tiptap/extension-image';\nimport { useEffect, useImperativeHandle, useMemo } from 'react';\nimport type { MutableRefObject } from 'react';\n\nimport type { EditorProps, CustomComponent } from './Editor.types';\nimport type { IframeEditorHandle } from './hooks/useIframeSetup';\nimport { TextIndent } from './extensions/TextIndent';\n\n// Custom keyboard shortcuts that match the toolbar tooltips\nconst CustomKeyboardShortcuts = Extension.create({\n name: 'customKeyboardShortcuts',\n addKeyboardShortcuts() {\n return {\n 'Mod-Shift-x': () => this.editor.commands.toggleStrike(),\n 'Mod-Shift-l': () => this.editor.commands.toggleBulletList()\n };\n }\n});\n\ntype ImageInfoArray = { id: string; url: string; name: string }[];\n\nconst getFileFromUrl = async (url: string, name: string): Promise<File | null> => {\n try {\n const response = await fetch(url);\n if (!response.ok) {\n return null;\n }\n const data = await response.blob();\n return new File([data], name, {\n type: data.type\n });\n } catch {\n return null;\n }\n};\n\nexport interface IframeTiptapEditorProps {\n placeholder?: string;\n defaultValue?: string;\n disabled?: boolean;\n readOnly?: boolean;\n onChange?: (editor: TiptapEditor) => void;\n onKeyDown?: (event?: KeyboardEvent) => void;\n onFocus?: () => void;\n onBlur?: () => void;\n onInit?: (editor: TiptapEditor) => void;\n onImageAdded?: (image: File, id: string, altText?: string) => void;\n imagesEnabled?: boolean;\n imageInsertionMode?: 'file' | 'url' | 'all';\n pastedImagesRef?: MutableRefObject<File[]>;\n editorId?: string;\n editorRef: MutableRefObject<IframeEditorHandle | null>;\n spellcheck?: boolean;\n customElements?: CustomComponent[];\n initOptions?: EditorProps['initOptions'];\n}\n\n// Component that renders inside the iframe\nexport const IframeTiptapEditor = ({\n placeholder,\n defaultValue,\n disabled,\n readOnly,\n onChange,\n onKeyDown,\n onFocus,\n onBlur,\n onInit,\n editorRef,\n spellcheck = true,\n customElements = [],\n initOptions,\n onImageAdded,\n imagesEnabled = false,\n imageInsertionMode = 'all',\n pastedImagesRef,\n editorId = ''\n}: IframeTiptapEditorProps) => {\n // Process pasted image URLs and convert to File objects\n const processPastedImgUrls = async (infoArr: ImageInfoArray) => {\n const files = await Promise.all(\n infoArr.map(({ id: imgId, url }) => getFileFromUrl(url, imgId))\n );\n files.forEach((file, i) => {\n if (file) {\n onImageAdded?.(file, infoArr[i].id);\n }\n });\n };\n\n // Generate Tiptap extensions for custom components\n const customComponentExtensions = useMemo(() => {\n return customElements.map((component: CustomComponent) => {\n return Node.create({\n name: component.name,\n group: 'inline',\n inline: true,\n atom: true,\n content: 'text*', // Allow text content inside\n\n addAttributes() {\n const attrs: Record<string, { default: null }> = {};\n if (component.extensionAttributes) {\n component.extensionAttributes.forEach((attr: string) => {\n attrs[attr] = { default: null };\n });\n }\n // Add common attributes for pega-file\n attrs['data-id'] = { default: null };\n attrs['data-name'] = { default: null };\n attrs['data-url'] = { default: null };\n attrs['data-progress'] = { default: null };\n attrs['data-error'] = { default: null };\n attrs['data-alt'] = { default: null };\n // Add attributes for pega-reference\n attrs['data-rule-id'] = { default: null };\n attrs['data-rule-type'] = { default: null };\n attrs['data-rule-namespace'] = { default: null };\n attrs.role = { default: null };\n return attrs;\n },\n\n parseHTML() {\n return [\n {\n tag: component.name,\n getAttrs: (node: HTMLElement | string) => {\n if (typeof node === 'string') return null;\n const attrs: Record<string, string | null> = {};\n // Get all data attributes and role\n Array.from(node.attributes).forEach(attr => {\n if (\n attr.name.startsWith('data-') ||\n attr.name === 'role' ||\n component.extensionAttributes?.includes(attr.name)\n ) {\n attrs[attr.name] = attr.value;\n }\n });\n return attrs;\n }\n }\n ];\n },\n\n renderHTML({\n HTMLAttributes,\n node\n }: {\n HTMLAttributes: Record<string, string | null>;\n node: ProseMirrorNode;\n }) {\n // Get text content from the node\n const textContent = node.textContent || '';\n return [component.name, HTMLAttributes, textContent];\n }\n });\n });\n }, [customElements]);\n\n const editor = useEditor({\n extensions: [\n StarterKit.configure({\n // Exclude link from StarterKit since we're configuring it separately\n link: false,\n // Disable text patterns if specified in initOptions\n ...(initOptions?.textPatterns === false && {\n typography: false\n })\n }),\n Placeholder.configure({\n placeholder: placeholder ?? ''\n }),\n TextIndent.configure({\n types: ['paragraph', 'heading']\n }),\n Link.configure({\n openOnClick: false,\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer'\n }\n }),\n Image.configure({\n inline: true,\n allowBase64: true\n }),\n CustomKeyboardShortcuts,\n ...customComponentExtensions\n ],\n content: defaultValue,\n editable: !disabled && !readOnly,\n editorProps: {\n attributes: {\n class: 'ProseMirror',\n spellcheck: spellcheck ? 'true' : 'false'\n },\n handleDOMEvents: {\n keydown: (view, event) => {\n onKeyDown?.(event);\n return false; // Allow other handlers to process\n },\n paste: (view, event) => {\n // Track pasted files for later processing\n if (\n event.clipboardData?.files &&\n event.clipboardData.files.length > 0 &&\n pastedImagesRef\n ) {\n pastedImagesRef.current = Array.from(event.clipboardData.files);\n }\n return false; // Let handlePaste process\n }\n },\n // Handle paste behavior based on initOptions\n handlePaste: (view, event) => {\n // If pasteAsText is enabled, convert to plain text\n if (initOptions?.pasteAsText) {\n event.preventDefault();\n const text = event.clipboardData?.getData('text/plain');\n if (text) {\n view.dispatch(view.state.tr.insertText(text));\n }\n return true;\n }\n\n const html = event.clipboardData?.getData('text/html');\n const isImg = html && html.includes('<img');\n\n // If images are disabled or mode is url-only, strip images from pasted content\n if ((!imagesEnabled || imageInsertionMode === 'url') && isImg) {\n event.preventDefault();\n const cleanedHtml = html.replace(/<img[^>]*\\/?>/g, '');\n const tempDiv = document.createElement('div');\n tempDiv.innerHTML = cleanedHtml;\n view.dispatch(\n view.state.tr.replaceSelectionWith(\n view.state.schema.nodes.paragraph.create(\n null,\n view.state.schema.text(tempDiv.textContent || '')\n )\n )\n );\n return true;\n }\n\n // If pasteDataImages is disabled, strip images from pasted content\n if (initOptions?.pasteDataImages === false && isImg) {\n event.preventDefault();\n const cleanedHtml = html.replace(/<img[^>]*>/g, '');\n const tempDiv = document.createElement('div');\n tempDiv.innerHTML = cleanedHtml;\n view.dispatch(\n view.state.tr.replaceSelectionWith(\n view.state.schema.nodes.paragraph.create(\n null,\n view.state.schema.text(tempDiv.textContent || '')\n )\n )\n );\n return true;\n }\n\n // Process pasted images and convert to pega-file elements\n if (imagesEnabled && isImg && html) {\n event.preventDefault();\n\n const pastedHtml = new DOMParser().parseFromString(html, 'text/html').body;\n const imgInfo: ImageInfoArray = [];\n\n pastedHtml.querySelectorAll('img').forEach(imgEl => {\n const imgId = `img-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const url = imgEl.src;\n const name = pastedImagesRef?.current.shift()?.name || editorId || 'pasted-image';\n\n imgInfo.push({ id: imgId, url, name });\n\n // Create pega-file element to show upload progress\n const uploadEl = document.createElement('pega-file');\n uploadEl.setAttribute('data-id', imgId);\n uploadEl.setAttribute('data-name', name);\n uploadEl.setAttribute('data-url', url);\n uploadEl.setAttribute('data-progress', '0');\n uploadEl.setAttribute('contenteditable', 'false');\n\n const uploadElString = `<br/>${uploadEl.outerHTML}<br/>`;\n const uploadElHtml = new DOMParser().parseFromString(uploadElString, 'text/html').body;\n\n imgEl.replaceWith(uploadElHtml);\n });\n\n // Insert the modified HTML\n const modifiedHtml = pastedHtml.innerHTML;\n view.dispatch(view.state.tr.insertText(''));\n\n // Use setTimeout to ensure the DOM is ready\n setTimeout(() => {\n const currentEditor = editorRef.current?.getEditor();\n if (currentEditor) {\n currentEditor.chain().focus().insertContent(modifiedHtml).run();\n }\n }, 0);\n\n // Process the pasted image URLs\n processPastedImgUrls(imgInfo).catch(() => {\n // Errors are handled inside processPastedImgUrls\n });\n\n return true;\n }\n\n return false;\n }\n },\n onUpdate: ({ editor: currentEditor }) => {\n onChange?.(currentEditor);\n },\n onFocus: () => {\n onFocus?.();\n },\n onBlur: () => {\n onBlur?.();\n }\n });\n\n useEffect(() => {\n if (editor && onInit) {\n // Call initInstanceCallback if provided\n if (initOptions?.initInstanceCallback) {\n initOptions.initInstanceCallback(editor);\n }\n\n onInit(editor);\n }\n }, [editor, onInit, initOptions]);\n\n useImperativeHandle(\n editorRef,\n () => ({\n focus: () => editor?.chain().focus().run(),\n getPlainText: () => editor?.getText() ?? '',\n getRichText: () => (editor ? JSON.stringify(editor.getJSON()) : ''),\n getHtml: () => editor?.getHTML() ?? '',\n clear: () => editor?.chain().clearContent().run(),\n insertText: (text: string) => editor?.chain().insertContent(text).run(),\n setCursorLocationToStart: () => editor?.chain().focus('start').run(),\n insertHtml: (html: string, overwrite: boolean = false) => {\n if (overwrite) {\n editor?.chain().setContent(html).run();\n } else {\n editor?.chain().insertContent(html).run();\n }\n },\n getEditor: () => editor,\n setEditable: (editable: boolean) => editor?.setEditable(editable)\n }),\n [editor]\n );\n\n return <EditorContent editor={editor} />;\n};\n"]}
1
+ {"version":3,"file":"IframeTiptapEditor.js","sourceRoot":"","sources":["../../../src/components/Editor/IframeTiptapEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEditor, EditorContent } from '@tiptap/react';\nimport { Extension, Node } from '@tiptap/core';\nimport type { Editor as TiptapEditor } from '@tiptap/core';\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model';\nimport StarterKit from '@tiptap/starter-kit';\nimport Placeholder from '@tiptap/extension-placeholder';\nimport Link from '@tiptap/extension-link';\nimport Image from '@tiptap/extension-image';\nimport Blockquote from '@tiptap/extension-blockquote';\nimport Paragraph from '@tiptap/extension-paragraph';\nimport { useEffect, useImperativeHandle, useMemo } from 'react';\nimport type { MutableRefObject } from 'react';\n\nimport type { EditorProps, CustomComponent } from './Editor.types';\nimport type { IframeEditorHandle } from './hooks/useIframeSetup';\nimport { TextIndent } from './extensions/TextIndent';\nimport { PreserveDiv } from './extensions/PreserveDiv';\n\n// Extend Blockquote to preserve inline styles (e.g., border-left from email chains)\nconst BlockquoteWithStyle = Blockquote.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n style: {\n default: null,\n parseHTML: element => element.getAttribute('style'),\n renderHTML: attributes => {\n if (!attributes.style) return {};\n return { style: attributes.style };\n }\n }\n };\n }\n});\n\n// Extend Paragraph to preserve class and style attributes (e.g., pega-email-reply-header)\nconst ParagraphWithStyle = Paragraph.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n class: {\n default: null,\n parseHTML: element => element.getAttribute('class'),\n renderHTML: attributes => {\n if (!attributes.class) return {};\n return { class: attributes.class };\n }\n },\n style: {\n default: null,\n parseHTML: element => element.getAttribute('style'),\n renderHTML: attributes => {\n if (!attributes.style) return {};\n return { style: attributes.style };\n }\n }\n };\n }\n});\n\n// Custom keyboard shortcuts that match the toolbar tooltips\nconst CustomKeyboardShortcuts = Extension.create({\n name: 'customKeyboardShortcuts',\n addKeyboardShortcuts() {\n return {\n 'Mod-Shift-x': () => this.editor.commands.toggleStrike(),\n 'Mod-Shift-l': () => this.editor.commands.toggleBulletList()\n };\n }\n});\n\ntype ImageInfoArray = { id: string; url: string; name: string }[];\n\nconst getFileFromUrl = async (url: string, name: string): Promise<File | null> => {\n try {\n const response = await fetch(url);\n if (!response.ok) {\n return null;\n }\n const data = await response.blob();\n return new File([data], name, {\n type: data.type\n });\n } catch {\n return null;\n }\n};\n\nexport interface IframeTiptapEditorProps {\n placeholder?: string;\n defaultValue?: string;\n disabled?: boolean;\n readOnly?: boolean;\n onChange?: (editor: TiptapEditor) => void;\n onKeyDown?: (event?: KeyboardEvent) => void;\n onFocus?: () => void;\n onBlur?: () => void;\n onInit?: (editor: TiptapEditor) => void;\n onImageAdded?: (image: File, id: string, altText?: string) => void;\n imagesEnabled?: boolean;\n imageInsertionMode?: 'file' | 'url' | 'all';\n pastedImagesRef?: MutableRefObject<File[]>;\n editorId?: string;\n editorRef: MutableRefObject<IframeEditorHandle | null>;\n spellcheck?: boolean;\n customElements?: CustomComponent[];\n initOptions?: EditorProps['initOptions'];\n}\n\n// Component that renders inside the iframe\nexport const IframeTiptapEditor = ({\n placeholder,\n defaultValue,\n disabled,\n readOnly,\n onChange,\n onKeyDown,\n onFocus,\n onBlur,\n onInit,\n editorRef,\n spellcheck = true,\n customElements = [],\n initOptions,\n onImageAdded,\n imagesEnabled = false,\n imageInsertionMode = 'all',\n pastedImagesRef,\n editorId = ''\n}: IframeTiptapEditorProps) => {\n // Process pasted image URLs and convert to File objects\n const processPastedImgUrls = async (infoArr: ImageInfoArray) => {\n const files = await Promise.all(\n infoArr.map(({ id: imgId, url }) => getFileFromUrl(url, imgId))\n );\n files.forEach((file, i) => {\n if (file) {\n onImageAdded?.(file, infoArr[i].id);\n }\n });\n };\n\n // Generate Tiptap extensions for custom components\n const customComponentExtensions = useMemo(() => {\n return customElements.map((component: CustomComponent) => {\n return Node.create({\n name: component.name,\n group: 'inline',\n inline: true,\n atom: true,\n content: 'text*', // Allow text content inside\n\n addAttributes() {\n const attrs: Record<string, { default: null }> = {};\n if (component.extensionAttributes) {\n component.extensionAttributes.forEach((attr: string) => {\n attrs[attr] = { default: null };\n });\n }\n // Add common attributes for pega-file\n attrs['data-id'] = { default: null };\n attrs['data-name'] = { default: null };\n attrs['data-url'] = { default: null };\n attrs['data-progress'] = { default: null };\n attrs['data-error'] = { default: null };\n attrs['data-alt'] = { default: null };\n // Add attributes for pega-reference\n attrs['data-rule-id'] = { default: null };\n attrs['data-rule-type'] = { default: null };\n attrs['data-rule-namespace'] = { default: null };\n attrs.role = { default: null };\n return attrs;\n },\n\n parseHTML() {\n return [\n {\n tag: component.name,\n getAttrs: (node: HTMLElement | string) => {\n if (typeof node === 'string') return null;\n const attrs: Record<string, string | null> = {};\n // Get all data attributes and role\n Array.from(node.attributes).forEach(attr => {\n if (\n attr.name.startsWith('data-') ||\n attr.name === 'role' ||\n component.extensionAttributes?.includes(attr.name)\n ) {\n attrs[attr.name] = attr.value;\n }\n });\n return attrs;\n }\n }\n ];\n },\n\n renderHTML({\n HTMLAttributes,\n node\n }: {\n HTMLAttributes: Record<string, string | null>;\n node: ProseMirrorNode;\n }) {\n // Get text content from the node\n const textContent = node.textContent || '';\n return [component.name, HTMLAttributes, textContent];\n }\n });\n });\n }, [customElements]);\n\n const editor = useEditor({\n extensions: [\n StarterKit.configure({\n // Exclude link from StarterKit since we're configuring it separately\n link: false,\n // Exclude blockquote so we can use our extended version with style preservation\n blockquote: false,\n // Exclude paragraph so we can use our extended version with class/style preservation\n paragraph: false,\n // Disable text patterns if specified in initOptions\n ...(initOptions?.textPatterns === false && {\n typography: false\n })\n }),\n BlockquoteWithStyle,\n ParagraphWithStyle,\n Placeholder.configure({\n placeholder: placeholder ?? ''\n }),\n TextIndent.configure({\n types: ['paragraph', 'heading']\n }),\n Link.configure({\n openOnClick: false,\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer'\n }\n }),\n Image.configure({\n inline: true,\n allowBase64: true\n }),\n CustomKeyboardShortcuts,\n PreserveDiv,\n ...customComponentExtensions\n ],\n content: defaultValue,\n editable: !disabled && !readOnly,\n editorProps: {\n attributes: {\n class: 'ProseMirror',\n spellcheck: spellcheck ? 'true' : 'false'\n },\n handleDOMEvents: {\n keydown: (view, event) => {\n onKeyDown?.(event);\n return false; // Allow other handlers to process\n },\n paste: (view, event) => {\n // Track pasted files for later processing\n if (\n event.clipboardData?.files &&\n event.clipboardData.files.length > 0 &&\n pastedImagesRef\n ) {\n pastedImagesRef.current = Array.from(event.clipboardData.files);\n }\n return false; // Let handlePaste process\n }\n },\n // Handle paste behavior based on initOptions\n handlePaste: (view, event) => {\n // If pasteAsText is enabled, convert to plain text\n if (initOptions?.pasteAsText) {\n event.preventDefault();\n const text = event.clipboardData?.getData('text/plain');\n if (text) {\n view.dispatch(view.state.tr.insertText(text));\n }\n return true;\n }\n\n const html = event.clipboardData?.getData('text/html');\n const isImg = html && html.includes('<img');\n\n // If images are disabled or mode is url-only, strip images from pasted content\n if ((!imagesEnabled || imageInsertionMode === 'url') && isImg) {\n event.preventDefault();\n const cleanedHtml = html.replace(/<img[^>]*\\/?>/g, '');\n const tempDiv = document.createElement('div');\n tempDiv.innerHTML = cleanedHtml;\n view.dispatch(\n view.state.tr.replaceSelectionWith(\n view.state.schema.nodes.paragraph.create(\n null,\n view.state.schema.text(tempDiv.textContent || '')\n )\n )\n );\n return true;\n }\n\n // If pasteDataImages is disabled, strip images from pasted content\n if (initOptions?.pasteDataImages === false && isImg) {\n event.preventDefault();\n const cleanedHtml = html.replace(/<img[^>]*>/g, '');\n const tempDiv = document.createElement('div');\n tempDiv.innerHTML = cleanedHtml;\n view.dispatch(\n view.state.tr.replaceSelectionWith(\n view.state.schema.nodes.paragraph.create(\n null,\n view.state.schema.text(tempDiv.textContent || '')\n )\n )\n );\n return true;\n }\n\n // Process pasted images and convert to pega-file elements\n if (imagesEnabled && isImg && html) {\n event.preventDefault();\n\n const pastedHtml = new DOMParser().parseFromString(html, 'text/html').body;\n const imgInfo: ImageInfoArray = [];\n\n pastedHtml.querySelectorAll('img').forEach(imgEl => {\n const imgId = `img-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const url = imgEl.src;\n const name = pastedImagesRef?.current.shift()?.name || editorId || 'pasted-image';\n\n imgInfo.push({ id: imgId, url, name });\n\n // Create pega-file element to show upload progress\n const uploadEl = document.createElement('pega-file');\n uploadEl.setAttribute('data-id', imgId);\n uploadEl.setAttribute('data-name', name);\n uploadEl.setAttribute('data-url', url);\n uploadEl.setAttribute('data-progress', '0');\n uploadEl.setAttribute('contenteditable', 'false');\n\n const uploadElString = `<br/>${uploadEl.outerHTML}<br/>`;\n const uploadElHtml = new DOMParser().parseFromString(uploadElString, 'text/html').body;\n\n imgEl.replaceWith(uploadElHtml);\n });\n\n // Insert the modified HTML\n const modifiedHtml = pastedHtml.innerHTML;\n view.dispatch(view.state.tr.insertText(''));\n\n // Use setTimeout to ensure the DOM is ready\n setTimeout(() => {\n const currentEditor = editorRef.current?.getEditor();\n if (currentEditor) {\n currentEditor.chain().focus().insertContent(modifiedHtml).run();\n }\n }, 0);\n\n // Process the pasted image URLs\n processPastedImgUrls(imgInfo).catch(() => {\n // Errors are handled inside processPastedImgUrls\n });\n\n return true;\n }\n\n return false;\n }\n },\n onUpdate: ({ editor: currentEditor }) => {\n onChange?.(currentEditor);\n },\n onFocus: () => {\n onFocus?.();\n },\n onBlur: () => {\n onBlur?.();\n }\n });\n\n useEffect(() => {\n if (editor && onInit) {\n // Call initInstanceCallback if provided\n if (initOptions?.initInstanceCallback) {\n initOptions.initInstanceCallback(editor);\n }\n\n onInit(editor);\n }\n }, [editor, onInit, initOptions]);\n\n useImperativeHandle(\n editorRef,\n () => ({\n focus: () => editor?.chain().focus().run(),\n getPlainText: () => editor?.getText() ?? '',\n getRichText: () => (editor ? JSON.stringify(editor.getJSON()) : ''),\n getHtml: () => editor?.getHTML() ?? '',\n clear: () => editor?.chain().clearContent().run(),\n insertText: (text: string) => editor?.chain().insertContent(text).run(),\n setCursorLocationToStart: () => editor?.chain().focus('start').run(),\n insertHtml: (html: string, overwrite: boolean = false) => {\n if (overwrite) {\n editor?.chain().setContent(html).run();\n } else {\n editor?.chain().insertContent(html).run();\n }\n },\n getEditor: () => editor,\n setEditable: (editable: boolean) => editor?.setEditable(editable)\n }),\n [editor]\n );\n\n return <EditorContent editor={editor} />;\n};\n"]}
@@ -0,0 +1,13 @@
1
+ import { Node } from '@tiptap/core';
2
+ export interface PreserveDivOptions {
3
+ HTMLAttributes: Record<string, string>;
4
+ }
5
+ /**
6
+ * PreserveDiv extension for Tiptap
7
+ *
8
+ * Preserves div elements with id, class, or style attributes that contain other blocks.
9
+ * This allows styled container elements from external sources (like email chains) to pass
10
+ * through without being stripped.
11
+ */
12
+ export declare const PreserveDiv: Node<PreserveDivOptions, any>;
13
+ //# sourceMappingURL=PreserveDiv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PreserveDiv.d.ts","sourceRoot":"","sources":["../../../../src/components/Editor/extensions/PreserveDiv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,cAAc,CAAC;AA8BrD,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,+BAgDtB,CAAC"}
@@ -0,0 +1,73 @@
1
+ import { Node, mergeAttributes } from '@tiptap/core';
2
+ /**
3
+ * Attributes to preserve on div elements
4
+ */
5
+ const PRESERVED_ATTRIBUTES = ['id', 'class', 'style', 'title', 'lang', 'dir'];
6
+ /**
7
+ * Get attributes from an element
8
+ */
9
+ const getPreservedAttributes = (element) => {
10
+ const attrs = {};
11
+ PRESERVED_ATTRIBUTES.forEach(attr => {
12
+ const value = element.getAttribute(attr);
13
+ if (value !== null) {
14
+ attrs[attr] = value;
15
+ }
16
+ });
17
+ // Get data-* attributes
18
+ Array.from(element.attributes).forEach(attr => {
19
+ if (attr.name.startsWith('data-')) {
20
+ attrs[attr.name] = attr.value;
21
+ }
22
+ });
23
+ return attrs;
24
+ };
25
+ /**
26
+ * PreserveDiv extension for Tiptap
27
+ *
28
+ * Preserves div elements with id, class, or style attributes that contain other blocks.
29
+ * This allows styled container elements from external sources (like email chains) to pass
30
+ * through without being stripped.
31
+ */
32
+ export const PreserveDiv = Node.create({
33
+ name: 'preserveDiv',
34
+ group: 'block',
35
+ content: 'block*',
36
+ isolating: true,
37
+ addOptions() {
38
+ return {
39
+ HTMLAttributes: {}
40
+ };
41
+ },
42
+ addAttributes() {
43
+ return {
44
+ preservedAttrs: {
45
+ default: {},
46
+ parseHTML: element => getPreservedAttributes(element),
47
+ renderHTML: attributes => attributes.preservedAttrs || {}
48
+ }
49
+ };
50
+ },
51
+ parseHTML() {
52
+ return [
53
+ {
54
+ tag: 'div',
55
+ priority: 30,
56
+ getAttrs: element => {
57
+ if (typeof element === 'string')
58
+ return false;
59
+ if (!element.getAttribute('id') &&
60
+ !element.getAttribute('class') &&
61
+ !element.getAttribute('style')) {
62
+ return false;
63
+ }
64
+ return null;
65
+ }
66
+ }
67
+ ];
68
+ },
69
+ renderHTML({ HTMLAttributes }) {
70
+ return ['div', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
71
+ }
72
+ });
73
+ //# sourceMappingURL=PreserveDiv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PreserveDiv.js","sourceRoot":"","sources":["../../../../src/components/Editor/extensions/PreserveDiv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAErD;;GAEG;AACH,MAAM,oBAAoB,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAE9E;;GAEG;AACH,MAAM,sBAAsB,GAAG,CAAC,OAAoB,EAA0B,EAAE;IAC9E,MAAM,KAAK,GAA2B,EAAE,CAAC;IAEzC,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QAClC,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,wBAAwB;IACxB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QAC5C,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;QAChC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAMF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAqB;IACzD,IAAI,EAAE,aAAa;IAEnB,KAAK,EAAE,OAAO;IAEd,OAAO,EAAE,QAAQ;IAEjB,SAAS,EAAE,IAAI;IAEf,UAAU;QACR,OAAO;YACL,cAAc,EAAE,EAAE;SACnB,CAAC;IACJ,CAAC;IAED,aAAa;QACX,OAAO;YACL,cAAc,EAAE;gBACd,OAAO,EAAE,EAAE;gBACX,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,sBAAsB,CAAC,OAAO,CAAC;gBACrD,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,cAAc,IAAI,EAAE;aAC1D;SACF,CAAC;IACJ,CAAC;IAED,SAAS;QACP,OAAO;YACL;gBACE,GAAG,EAAE,KAAK;gBACV,QAAQ,EAAE,EAAE;gBACZ,QAAQ,EAAE,OAAO,CAAC,EAAE;oBAClB,IAAI,OAAO,OAAO,KAAK,QAAQ;wBAAE,OAAO,KAAK,CAAC;oBAC9C,IACE,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC;wBAC3B,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC;wBAC9B,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,EAC9B,CAAC;wBACD,OAAO,KAAK,CAAC;oBACf,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC;aACF;SACF,CAAC;IACJ,CAAC;IAED,UAAU,CAAC,EAAE,cAAc,EAAE;QAC3B,OAAO,CAAC,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC;IAClF,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { Node, mergeAttributes } from '@tiptap/core';\n\n/**\n * Attributes to preserve on div elements\n */\nconst PRESERVED_ATTRIBUTES = ['id', 'class', 'style', 'title', 'lang', 'dir'];\n\n/**\n * Get attributes from an element\n */\nconst getPreservedAttributes = (element: HTMLElement): Record<string, string> => {\n const attrs: Record<string, string> = {};\n\n PRESERVED_ATTRIBUTES.forEach(attr => {\n const value = element.getAttribute(attr);\n if (value !== null) {\n attrs[attr] = value;\n }\n });\n\n // Get data-* attributes\n Array.from(element.attributes).forEach(attr => {\n if (attr.name.startsWith('data-')) {\n attrs[attr.name] = attr.value;\n }\n });\n\n return attrs;\n};\n\nexport interface PreserveDivOptions {\n HTMLAttributes: Record<string, string>;\n}\n\n/**\n * PreserveDiv extension for Tiptap\n *\n * Preserves div elements with id, class, or style attributes that contain other blocks.\n * This allows styled container elements from external sources (like email chains) to pass\n * through without being stripped.\n */\nexport const PreserveDiv = Node.create<PreserveDivOptions>({\n name: 'preserveDiv',\n\n group: 'block',\n\n content: 'block*',\n\n isolating: true,\n\n addOptions() {\n return {\n HTMLAttributes: {}\n };\n },\n\n addAttributes() {\n return {\n preservedAttrs: {\n default: {},\n parseHTML: element => getPreservedAttributes(element),\n renderHTML: attributes => attributes.preservedAttrs || {}\n }\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'div',\n priority: 30,\n getAttrs: element => {\n if (typeof element === 'string') return false;\n if (\n !element.getAttribute('id') &&\n !element.getAttribute('class') &&\n !element.getAttribute('style')\n ) {\n return false;\n }\n return null;\n }\n }\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['div', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];\n }\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pega/cosmos-react-rte",
3
- "version": "9.0.0-build.22.0",
3
+ "version": "9.0.0-build.22.2",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "author": "Pegasystems",
6
6
  "sideEffects": false,
@@ -14,11 +14,13 @@
14
14
  "build": "tsc -b tsconfig.build.json"
15
15
  },
16
16
  "dependencies": {
17
- "@pega/cosmos-react-core": "9.0.0-build.22.0",
17
+ "@pega/cosmos-react-core": "9.0.0-build.22.2",
18
18
  "@popperjs/core": "^2.11.6",
19
19
  "@tiptap/core": "^3.12.1",
20
+ "@tiptap/extension-blockquote": "^3.12.1",
20
21
  "@tiptap/extension-image": "^3.12.1",
21
22
  "@tiptap/extension-link": "^3.12.1",
23
+ "@tiptap/extension-paragraph": "^3.12.1",
22
24
  "@tiptap/extension-placeholder": "^3.12.1",
23
25
  "@tiptap/react": "^3.12.1",
24
26
  "@tiptap/starter-kit": "^3.12.1",