From 421d9a97f832a0de30bc97c4e7dd65df759746ce Mon Sep 17 00:00:00 2001 From: Gabe Magee Date: Tue, 14 May 2024 15:15:37 -0700 Subject: [PATCH 1/2] fix(insertcontentat.ts): ensure content passed during a simulated paste / input event is string #5150 --- packages/core/src/PasteRule.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/src/PasteRule.ts b/packages/core/src/PasteRule.ts index a0969673476..574e9d61578 100644 --- a/packages/core/src/PasteRule.ts +++ b/packages/core/src/PasteRule.ts @@ -277,6 +277,7 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }): if (isSimulatedPaste) { const { from, text } = simulatedPasteMeta const to = from + text.length + // const to = from + (typeof text === 'string' ? text.length : text.size) const pasteEvt = createClipboardPasteEvent(text) return processEvent({ From 12a46e494f00d9b83cee5e7e9a328616fd5bc630 Mon Sep 17 00:00:00 2001 From: Gabe Magee Date: Wed, 15 May 2024 15:25:00 -0700 Subject: [PATCH 2/2] fix: test tests --- .../React/index.jsx | 15 ++++ .../React/index.spec.js | 10 +++ packages/core/src/PasteRule.ts | 81 ++++++++++++++++--- 3 files changed, 96 insertions(+), 10 deletions(-) diff --git a/demos/src/Commands/InsertContentApplyingRules/React/index.jsx b/demos/src/Commands/InsertContentApplyingRules/React/index.jsx index 1f803605370..5093bff3266 100644 --- a/demos/src/Commands/InsertContentApplyingRules/React/index.jsx +++ b/demos/src/Commands/InsertContentApplyingRules/React/index.jsx @@ -161,6 +161,21 @@ const MenuBar = () => { > Insert "*this is a test*" + ) } diff --git a/demos/src/Commands/InsertContentApplyingRules/React/index.spec.js b/demos/src/Commands/InsertContentApplyingRules/React/index.spec.js index 0cda50ace55..4b36653cb00 100644 --- a/demos/src/Commands/InsertContentApplyingRules/React/index.spec.js +++ b/demos/src/Commands/InsertContentApplyingRules/React/index.spec.js @@ -32,4 +32,14 @@ context('/src/Commands/InsertContentApplyingRules/React/', () => { cy.get('.tiptap').should('contain.html', '

This is an italic text

') }) }) + + it('should apply paste rules to html', () => { // todo: naming + cy.get('.tiptap').then(([{ editor }]) => { + const content = '

*This is an italic text*

' // TODO: create special case here + + editor.commands.insertContent(content, { applyPasteRules: true }) + cy.get('.tiptap').should('contain.html', '

This is an italic text

') // TODO: check if paste rules applied. + }) + }) + }) diff --git a/packages/core/src/PasteRule.ts b/packages/core/src/PasteRule.ts index 574e9d61578..479c88944a5 100644 --- a/packages/core/src/PasteRule.ts +++ b/packages/core/src/PasteRule.ts @@ -125,6 +125,11 @@ function run(config: { const textToMatch = node.textBetween(resolvedFrom - pos, resolvedTo - pos, undefined, '\ufffc') const matches = pasteRuleMatcherHandler(textToMatch, rule.find, pasteEvent) + const toCompare = /(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))/g + + if (rule.find.toString() === toCompare.toString()) { + console.log(resolvedFrom, resolvedTo, pos, node.content.size) + } matches.forEach(match => { if (match.index === undefined) { @@ -220,6 +225,45 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }): return tr } + const processEventv2 = ({ + state, + from, + to, + rule, + pasteEvt, + }: { + state: EditorState + from: number + to: { b: number } + rule: PasteRule + pasteEvt: ClipboardEvent | null + }) => { + const tr = state.tr + const chainableState = createChainableState({ + state, + transaction: tr, + }) + + const handler = run({ + editor, + state: chainableState, + from: Math.max(from - 1, 0), + to: to.b - 1, + rule, + pasteEvent: pasteEvt, + dropEvent, + }) + + if (!handler || !tr.steps.length) { + return tr + } + + dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null + pasteEvent = typeof ClipboardEvent !== 'undefined' ? new ClipboardEvent('paste') : null + + return tr + } + const plugins = rules.map(rule => { return new Plugin({ // we register a global drag handler to track the current drag source element @@ -275,18 +319,35 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }): // Handle simulated paste if (isSimulatedPaste) { - const { from, text } = simulatedPasteMeta - const to = from + text.length - // const to = from + (typeof text === 'string' ? text.length : text.size) + const text = simulatedPasteMeta.text + let from = simulatedPasteMeta.from const pasteEvt = createClipboardPasteEvent(text) - return processEvent({ - rule, - state, - from, - to: { b: to }, - pasteEvt, - }) + if (typeof text === 'string') { + const to = from + text.length + + return processEvent({ + rule, + state, + from, + to: { b: to }, + pasteEvt, + }) + } + let tr = state.tr + + for (let i = 0; i < text.content.length; i += 1) { + console.log(from, from + text.content[i].content.size) + tr = processEventv2({ + rule, + state, + from, + to: { b: text.content[i].content.size + 1 }, + pasteEvt, + }) + from += text.content[i].content.size + } + return tr } // handle actual paste/drop