add paste rules
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
"prosemirror-commands": "^1.0.7",
|
||||
"prosemirror-inputrules": "^1.0.1",
|
||||
"prosemirror-schema-list": "^1.0.1",
|
||||
"prosemirror-state": "^1.2.2",
|
||||
"tiptap-utils": "^1.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
52
packages/tiptap-commands/src/commands/wrappingPasteRule.js
Normal file
52
packages/tiptap-commands/src/commands/wrappingPasteRule.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import { Plugin } from 'prosemirror-state'
|
||||
import { Slice, Fragment } from 'prosemirror-model'
|
||||
|
||||
export default function (regexp, type, getAttrs) {
|
||||
|
||||
const handler = fragment => {
|
||||
const nodes = []
|
||||
|
||||
fragment.forEach(child => {
|
||||
if (child.isText) {
|
||||
const { text } = child
|
||||
let pos = 0
|
||||
let match
|
||||
|
||||
do {
|
||||
match = regexp.exec(text)
|
||||
if (match) {
|
||||
const start = match.index
|
||||
const end = start + match[0].length
|
||||
const attrs = getAttrs instanceof Function ? getAttrs(match[0]) : getAttrs
|
||||
|
||||
if (start > 0) {
|
||||
nodes.push(child.cut(pos, start))
|
||||
}
|
||||
|
||||
nodes.push(child
|
||||
.cut(start, end)
|
||||
.mark(type.create(attrs)
|
||||
.addToSet(child.marks)))
|
||||
|
||||
pos = end
|
||||
}
|
||||
} while (match)
|
||||
|
||||
if (pos < text.length) {
|
||||
nodes.push(child.cut(pos))
|
||||
}
|
||||
} else {
|
||||
nodes.push(child.copy(handler(child.content)))
|
||||
}
|
||||
})
|
||||
|
||||
return Fragment.fromArray(nodes)
|
||||
}
|
||||
|
||||
return new Plugin({
|
||||
props: {
|
||||
transformPasted: slice => new Slice(handler(slice.content), slice.openStart, slice.openEnd),
|
||||
},
|
||||
})
|
||||
|
||||
}
|
||||
@@ -48,6 +48,7 @@ import toggleBlockType from './commands/toggleBlockType'
|
||||
import toggleList from './commands/toggleList'
|
||||
import toggleWrap from './commands/toggleWrap'
|
||||
import updateMark from './commands/updateMark'
|
||||
import wrappingPasteRule from './commands/wrappingPasteRule'
|
||||
|
||||
export {
|
||||
// prosemirror-commands
|
||||
@@ -98,4 +99,5 @@ export {
|
||||
toggleList,
|
||||
toggleWrap,
|
||||
updateMark,
|
||||
wrappingPasteRule,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Mark, Plugin, TextSelection } from 'tiptap'
|
||||
import { updateMark, removeMark } from 'tiptap-commands'
|
||||
import { updateMark, removeMark, wrappingPasteRule } from 'tiptap-commands'
|
||||
import { getMarkRange } from 'tiptap-utils'
|
||||
|
||||
export default class Link extends Mark {
|
||||
@@ -41,6 +41,16 @@ export default class Link extends Mark {
|
||||
}
|
||||
}
|
||||
|
||||
pasteRules({ type }) {
|
||||
return [
|
||||
wrappingPasteRule(
|
||||
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)/g,
|
||||
type,
|
||||
url => ({ href: url }),
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
get plugins() {
|
||||
return [
|
||||
new Plugin({
|
||||
|
||||
@@ -25,6 +25,7 @@ export default class Editor {
|
||||
this.plugins = this.createPlugins()
|
||||
this.keymaps = this.createKeymaps()
|
||||
this.inputRules = this.createInputRules()
|
||||
this.pasteRules = this.createPasteRules()
|
||||
this.state = this.createState()
|
||||
this.view = this.createView()
|
||||
this.commands = this.createCommands()
|
||||
@@ -94,6 +95,12 @@ export default class Editor {
|
||||
})
|
||||
}
|
||||
|
||||
createPasteRules() {
|
||||
return this.extensions.pasteRules({
|
||||
schema: this.schema,
|
||||
})
|
||||
}
|
||||
|
||||
createCommands() {
|
||||
return this.extensions.commands({
|
||||
schema: this.schema,
|
||||
@@ -126,6 +133,7 @@ export default class Editor {
|
||||
inputRules({
|
||||
rules: this.inputRules,
|
||||
}),
|
||||
...this.pasteRules,
|
||||
...this.keymaps,
|
||||
keymap({
|
||||
Backspace: undoInputRule,
|
||||
|
||||
@@ -76,6 +76,29 @@ export default class ExtensionManager {
|
||||
]), [])
|
||||
}
|
||||
|
||||
pasteRules({ schema }) {
|
||||
const extensionPasteRules = this.extensions
|
||||
.filter(extension => ['extension'].includes(extension.type))
|
||||
.filter(extension => extension.pasteRules)
|
||||
.map(extension => extension.pasteRules({ schema }))
|
||||
|
||||
const nodeMarkPasteRules = this.extensions
|
||||
.filter(extension => ['node', 'mark'].includes(extension.type))
|
||||
.filter(extension => extension.pasteRules)
|
||||
.map(extension => extension.pasteRules({
|
||||
type: schema[`${extension.type}s`][extension.name],
|
||||
schema,
|
||||
}))
|
||||
|
||||
return [
|
||||
...extensionPasteRules,
|
||||
...nodeMarkPasteRules,
|
||||
].reduce((allPasteRules, pasteRules) => ([
|
||||
...allPasteRules,
|
||||
...pasteRules,
|
||||
]), [])
|
||||
}
|
||||
|
||||
commands({ schema, view, editable }) {
|
||||
return this.extensions
|
||||
.filter(extension => extension.commands)
|
||||
|
||||
Reference in New Issue
Block a user