Skip to content

Commit

Permalink
feature(core): pass through paste event to pasteHandler `getAttribute…
Browse files Browse the repository at this point in the history
…s` (#4354)

* add pass through of paste event for paste handlers

* remove unused pasteHandler.ts

* remove link extension from youtube demo

* added missing prop for handler
  • Loading branch information
bdbch authored Sep 20, 2023
1 parent 8b89b97 commit 361a821
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 139 deletions.
34 changes: 26 additions & 8 deletions packages/core/src/PasteRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,21 @@ export class PasteRule {
commands: SingleCommands
chain: () => ChainedCommands
can: () => CanCommands
pasteEvent: ClipboardEvent
dropEvent: DragEvent
}) => void | null

constructor(config: {
find: PasteRuleFinder
handler: (props: {
state: EditorState
range: Range
match: ExtendedRegExpMatchArray
commands: SingleCommands
chain: () => ChainedCommands
can: () => CanCommands
chain: () => ChainedCommands
commands: SingleCommands
dropEvent: DragEvent
match: ExtendedRegExpMatchArray
pasteEvent: ClipboardEvent
range: Range
state: EditorState
}) => void | null
}) {
this.find = config.find
Expand Down Expand Up @@ -92,9 +96,11 @@ function run(config: {
from: number
to: number
rule: PasteRule
pasteEvent: ClipboardEvent
dropEvent: DragEvent
}): boolean {
const {
editor, state, from, to, rule,
editor, state, from, to, rule, pasteEvent, dropEvent,
} = config

const { commands, chain, can } = new CommandManager({
Expand Down Expand Up @@ -134,6 +140,8 @@ function run(config: {
commands,
chain,
can,
pasteEvent,
dropEvent,
})

handlers.push(handler)
Expand All @@ -155,6 +163,8 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }):
let dragSourceElement: Element | null = null
let isPastedFromProseMirror = false
let isDroppedFromProseMirror = false
let pasteEvent = new ClipboardEvent('paste')
let dropEvent = new DragEvent('drop')

const plugins = rules.map(rule => {
return new Plugin({
Expand All @@ -177,15 +187,18 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }):

props: {
handleDOMEvents: {
drop: view => {
drop: (view, event: Event) => {
isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement
dropEvent = event as DragEvent

return false
},

paste: (view, event: Event) => {
paste: (_view, event: Event) => {
const html = (event as ClipboardEvent).clipboardData?.getData('text/html')

pasteEvent = event as ClipboardEvent

isPastedFromProseMirror = !!html?.includes('data-pm-slice')

return false
Expand Down Expand Up @@ -224,13 +237,18 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }):
from: Math.max(from - 1, 0),
to: to.b - 1,
rule,
pasteEvent,
dropEvent,
})

// stop if there are no changes
if (!handler || !tr.steps.length) {
return
}

dropEvent = new DragEvent('drop')
pasteEvent = new ClipboardEvent('paste')

return tr
},
})
Expand Down
8 changes: 5 additions & 3 deletions packages/core/src/pasteRules/markPasteRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ export function markPasteRule(config: {
type: MarkType
getAttributes?:
| Record<string, any>
| ((match: ExtendedRegExpMatchArray) => Record<string, any>)
| ((match: ExtendedRegExpMatchArray, event: ClipboardEvent) => Record<string, any>)
| false
| null
}) {
return new PasteRule({
find: config.find,
handler: ({ state, range, match }) => {
const attributes = callOrReturn(config.getAttributes, undefined, match)
handler: ({
state, range, match, pasteEvent,
}) => {
const attributes = callOrReturn(config.getAttributes, undefined, match, pasteEvent)

if (attributes === false || attributes === null) {
return null
Expand Down
8 changes: 5 additions & 3 deletions packages/core/src/pasteRules/nodePasteRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ export function nodePasteRule(config: {
type: NodeType
getAttributes?:
| Record<string, any>
| ((match: ExtendedRegExpMatchArray) => Record<string, any>)
| ((match: ExtendedRegExpMatchArray, event: ClipboardEvent) => Record<string, any>)
| false
| null
}) {
return new PasteRule({
find: config.find,
handler({ match, chain, range }) {
const attributes = callOrReturn(config.getAttributes, undefined, match)
handler({
match, chain, range, pasteEvent,
}) {
const attributes = callOrReturn(config.getAttributes, undefined, match, pasteEvent)

if (attributes === false || attributes === null) {
return null
Expand Down
114 changes: 0 additions & 114 deletions packages/extension-link/src/helpers/pasteHandler.ts

This file was deleted.

51 changes: 40 additions & 11 deletions packages/extension-link/src/link.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { Mark, mergeAttributes } from '@tiptap/core'
import { Mark, markPasteRule, mergeAttributes } from '@tiptap/core'
import { Plugin } from '@tiptap/pm/state'
import { registerCustomProtocol, reset } from 'linkifyjs'
import { find, registerCustomProtocol, reset } from 'linkifyjs'

import { autolink } from './helpers/autolink.js'
import { clickHandler } from './helpers/clickHandler.js'
import { pasteHandler } from './helpers/pasteHandler.js'

export interface LinkProtocolOptions {
scheme: string;
Expand Down Expand Up @@ -149,6 +148,44 @@ export const Link = Mark.create<LinkOptions>({
}
},

addPasteRules() {
return [
markPasteRule({
find: text => find(text)
.filter(link => {
if (this.options.validate) {
return this.options.validate(link.value)
}

return true
})
.filter(link => link.isLink)
.map(link => ({
text: link.value,
index: link.start,
data: link,
})),
type: this.type,
getAttributes: (match, pasteEvent) => {
const html = pasteEvent.clipboardData?.getData('text/html')
const hrefRegex = /href="([^"]*)"/

const existingLink = html?.match(hrefRegex)

if (existingLink) {
return {
href: existingLink[1],
}
}

return {
href: match.data?.href,
}
},
}),
]
},

addProseMirrorPlugins() {
const plugins: Plugin[] = []

Expand All @@ -169,14 +206,6 @@ export const Link = Mark.create<LinkOptions>({
)
}

plugins.push(
pasteHandler({
editor: this.editor,
type: this.type,
linkOnPaste: this.options.linkOnPaste,
}),
)

return plugins
},
})

0 comments on commit 361a821

Please sign in to comment.