add paste rules
This commit is contained in:
@@ -23,6 +23,7 @@
|
|||||||
"prosemirror-commands": "^1.0.7",
|
"prosemirror-commands": "^1.0.7",
|
||||||
"prosemirror-inputrules": "^1.0.1",
|
"prosemirror-inputrules": "^1.0.1",
|
||||||
"prosemirror-schema-list": "^1.0.1",
|
"prosemirror-schema-list": "^1.0.1",
|
||||||
|
"prosemirror-state": "^1.2.2",
|
||||||
"tiptap-utils": "^1.0.1"
|
"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 toggleList from './commands/toggleList'
|
||||||
import toggleWrap from './commands/toggleWrap'
|
import toggleWrap from './commands/toggleWrap'
|
||||||
import updateMark from './commands/updateMark'
|
import updateMark from './commands/updateMark'
|
||||||
|
import wrappingPasteRule from './commands/wrappingPasteRule'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
// prosemirror-commands
|
// prosemirror-commands
|
||||||
@@ -98,4 +99,5 @@ export {
|
|||||||
toggleList,
|
toggleList,
|
||||||
toggleWrap,
|
toggleWrap,
|
||||||
updateMark,
|
updateMark,
|
||||||
|
wrappingPasteRule,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Mark, Plugin, TextSelection } from 'tiptap'
|
import { Mark, Plugin, TextSelection } from 'tiptap'
|
||||||
import { updateMark, removeMark } from 'tiptap-commands'
|
import { updateMark, removeMark, wrappingPasteRule } from 'tiptap-commands'
|
||||||
import { getMarkRange } from 'tiptap-utils'
|
import { getMarkRange } from 'tiptap-utils'
|
||||||
|
|
||||||
export default class Link extends Mark {
|
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() {
|
get plugins() {
|
||||||
return [
|
return [
|
||||||
new Plugin({
|
new Plugin({
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export default class Editor {
|
|||||||
this.plugins = this.createPlugins()
|
this.plugins = this.createPlugins()
|
||||||
this.keymaps = this.createKeymaps()
|
this.keymaps = this.createKeymaps()
|
||||||
this.inputRules = this.createInputRules()
|
this.inputRules = this.createInputRules()
|
||||||
|
this.pasteRules = this.createPasteRules()
|
||||||
this.state = this.createState()
|
this.state = this.createState()
|
||||||
this.view = this.createView()
|
this.view = this.createView()
|
||||||
this.commands = this.createCommands()
|
this.commands = this.createCommands()
|
||||||
@@ -94,6 +95,12 @@ export default class Editor {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createPasteRules() {
|
||||||
|
return this.extensions.pasteRules({
|
||||||
|
schema: this.schema,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
createCommands() {
|
createCommands() {
|
||||||
return this.extensions.commands({
|
return this.extensions.commands({
|
||||||
schema: this.schema,
|
schema: this.schema,
|
||||||
@@ -126,6 +133,7 @@ export default class Editor {
|
|||||||
inputRules({
|
inputRules({
|
||||||
rules: this.inputRules,
|
rules: this.inputRules,
|
||||||
}),
|
}),
|
||||||
|
...this.pasteRules,
|
||||||
...this.keymaps,
|
...this.keymaps,
|
||||||
keymap({
|
keymap({
|
||||||
Backspace: undoInputRule,
|
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 }) {
|
commands({ schema, view, editable }) {
|
||||||
return this.extensions
|
return this.extensions
|
||||||
.filter(extension => extension.commands)
|
.filter(extension => extension.commands)
|
||||||
|
|||||||
Reference in New Issue
Block a user