@tiptap/extension-link 2.1.0-rc.9 → 2.1.0
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.
- package/dist/index.cjs +33 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +35 -49
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +33 -47
- package/dist/index.umd.js.map +1 -1
- package/dist/packages/extension-link/src/index.d.ts +2 -2
- package/package.json +3 -3
- package/src/helpers/autolink.ts +17 -41
- package/src/helpers/clickHandler.ts +4 -2
- package/src/helpers/pasteHandler.ts +14 -10
- package/src/index.ts +2 -2
- package/src/link.ts +6 -3
package/dist/index.cjs
CHANGED
|
@@ -17,34 +17,8 @@ function autolink(options) {
|
|
|
17
17
|
}
|
|
18
18
|
const { tr } = newState;
|
|
19
19
|
const transform = core.combineTransactionSteps(oldState.doc, [...transactions]);
|
|
20
|
-
const { mapping } = transform;
|
|
21
20
|
const changes = core.getChangedRanges(transform);
|
|
22
|
-
|
|
23
|
-
changes.forEach(({ oldRange, newRange }) => {
|
|
24
|
-
// At first we check if we have to remove links.
|
|
25
|
-
core.getMarksBetween(oldRange.from, oldRange.to, oldState.doc)
|
|
26
|
-
.filter(item => item.mark.type === options.type)
|
|
27
|
-
.forEach(oldMark => {
|
|
28
|
-
const newFrom = mapping.map(oldMark.from);
|
|
29
|
-
const newTo = mapping.map(oldMark.to);
|
|
30
|
-
const newMarks = core.getMarksBetween(newFrom, newTo, newState.doc).filter(item => item.mark.type === options.type);
|
|
31
|
-
if (!newMarks.length) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
const newMark = newMarks[0];
|
|
35
|
-
const oldLinkText = oldState.doc.textBetween(oldMark.from, oldMark.to, undefined, ' ');
|
|
36
|
-
const newLinkText = newState.doc.textBetween(newMark.from, newMark.to, undefined, ' ');
|
|
37
|
-
const wasLink = linkifyjs.test(oldLinkText);
|
|
38
|
-
const isLink = linkifyjs.test(newLinkText);
|
|
39
|
-
if (wasLink) {
|
|
40
|
-
needsAutolink = false;
|
|
41
|
-
}
|
|
42
|
-
// Remove only the link, if it was a link before too.
|
|
43
|
-
// Because we don’t want to remove links that were set manually.
|
|
44
|
-
if (wasLink && !isLink) {
|
|
45
|
-
tr.removeMark(needsAutolink ? newMark.from : newMark.to - 1, newMark.to, options.type);
|
|
46
|
-
}
|
|
47
|
-
});
|
|
21
|
+
changes.forEach(({ newRange }) => {
|
|
48
22
|
// Now let’s see if we can add new links.
|
|
49
23
|
const nodesInChangedRanges = core.findChildrenInRange(newState.doc, newRange, node => node.isTextblock);
|
|
50
24
|
let textBlock;
|
|
@@ -72,18 +46,23 @@ function autolink(options) {
|
|
|
72
46
|
}
|
|
73
47
|
linkifyjs.find(lastWordBeforeSpace)
|
|
74
48
|
.filter(link => link.isLink)
|
|
75
|
-
.filter(link => {
|
|
76
|
-
if (options.validate) {
|
|
77
|
-
return options.validate(link.value);
|
|
78
|
-
}
|
|
79
|
-
return true;
|
|
80
|
-
})
|
|
81
49
|
// Calculate link position.
|
|
82
50
|
.map(link => ({
|
|
83
51
|
...link,
|
|
84
52
|
from: lastWordAndBlockOffset + link.start + 1,
|
|
85
53
|
to: lastWordAndBlockOffset + link.end + 1,
|
|
86
54
|
}))
|
|
55
|
+
// ignore link inside code mark
|
|
56
|
+
.filter(link => {
|
|
57
|
+
return !newState.doc.rangeHasMark(link.from, link.to, newState.schema.marks.code);
|
|
58
|
+
})
|
|
59
|
+
// validate link
|
|
60
|
+
.filter(link => {
|
|
61
|
+
if (options.validate) {
|
|
62
|
+
return options.validate(link.value);
|
|
63
|
+
}
|
|
64
|
+
return true;
|
|
65
|
+
})
|
|
87
66
|
// Add link mark.
|
|
88
67
|
.forEach(link => {
|
|
89
68
|
if (core.getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {
|
|
@@ -108,16 +87,18 @@ function clickHandler(options) {
|
|
|
108
87
|
key: new state.PluginKey('handleClickLink'),
|
|
109
88
|
props: {
|
|
110
89
|
handleClick: (view, pos, event) => {
|
|
111
|
-
var _a, _b
|
|
90
|
+
var _a, _b;
|
|
112
91
|
if (event.button !== 0) {
|
|
113
92
|
return false;
|
|
114
93
|
}
|
|
115
94
|
const attrs = core.getAttributes(view.state, options.type.name);
|
|
116
|
-
const link =
|
|
117
|
-
const href = (
|
|
118
|
-
const target = (
|
|
95
|
+
const link = event.target;
|
|
96
|
+
const href = (_a = link === null || link === void 0 ? void 0 : link.href) !== null && _a !== void 0 ? _a : attrs.href;
|
|
97
|
+
const target = (_b = link === null || link === void 0 ? void 0 : link.target) !== null && _b !== void 0 ? _b : attrs.target;
|
|
119
98
|
if (link && href) {
|
|
120
|
-
|
|
99
|
+
if (view.editable) {
|
|
100
|
+
window.open(href, target);
|
|
101
|
+
}
|
|
121
102
|
return true;
|
|
122
103
|
}
|
|
123
104
|
return false;
|
|
@@ -138,20 +119,22 @@ function pasteHandler(options) {
|
|
|
138
119
|
if (state.doc.resolve(selection.from).parent.type.spec.code) {
|
|
139
120
|
return false;
|
|
140
121
|
}
|
|
141
|
-
const pastedLinkMarks = [];
|
|
142
122
|
let textContent = '';
|
|
143
123
|
slice.content.forEach(node => {
|
|
144
124
|
textContent += node.textContent;
|
|
145
|
-
node.marks.forEach(mark => {
|
|
146
|
-
if (mark.type.name === options.type.name) {
|
|
147
|
-
pastedLinkMarks.push(mark);
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
125
|
});
|
|
151
|
-
|
|
126
|
+
let isAlreadyLink = false;
|
|
127
|
+
slice.content.descendants(node => {
|
|
128
|
+
if (node.marks.some(mark => mark.type.name === options.type.name)) {
|
|
129
|
+
isAlreadyLink = true;
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
if (isAlreadyLink) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
152
135
|
const link = linkifyjs.find(textContent).find(item => item.isLink && item.value === textContent);
|
|
153
136
|
if (!selection.empty && options.linkOnPaste) {
|
|
154
|
-
const pastedLink =
|
|
137
|
+
const pastedLink = (link === null || link === void 0 ? void 0 : link.href) || null;
|
|
155
138
|
if (pastedLink) {
|
|
156
139
|
options.editor.commands.setMark(options.type, { href: pastedLink });
|
|
157
140
|
return true;
|
|
@@ -159,7 +142,7 @@ function pasteHandler(options) {
|
|
|
159
142
|
}
|
|
160
143
|
const firstChildIsText = ((_a = slice.content.firstChild) === null || _a === void 0 ? void 0 : _a.type.name) === 'text';
|
|
161
144
|
const firstChildContainsLinkMark = (_b = slice.content.firstChild) === null || _b === void 0 ? void 0 : _b.marks.some(mark => mark.type.name === options.type.name);
|
|
162
|
-
if (firstChildIsText && firstChildContainsLinkMark) {
|
|
145
|
+
if ((firstChildIsText && firstChildContainsLinkMark) || !options.linkOnPaste) {
|
|
163
146
|
return false;
|
|
164
147
|
}
|
|
165
148
|
if (link && selection.empty) {
|
|
@@ -242,6 +225,9 @@ const Link = core.Mark.create({
|
|
|
242
225
|
target: {
|
|
243
226
|
default: this.options.HTMLAttributes.target,
|
|
244
227
|
},
|
|
228
|
+
rel: {
|
|
229
|
+
default: this.options.HTMLAttributes.rel,
|
|
230
|
+
},
|
|
245
231
|
class: {
|
|
246
232
|
default: this.options.HTMLAttributes.class,
|
|
247
233
|
},
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/helpers/autolink.ts","../src/helpers/clickHandler.ts","../src/helpers/pasteHandler.ts","../src/link.ts"],"sourcesContent":["import {\n combineTransactionSteps,\n findChildrenInRange,\n getChangedRanges,\n getMarksBetween,\n NodeWithPos,\n} from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find, test } from 'linkifyjs'\n\ntype AutolinkOptions = {\n type: MarkType\n validate?: (url: string) => boolean\n}\n\nexport function autolink(options: AutolinkOptions): Plugin {\n return new Plugin({\n key: new PluginKey('autolink'),\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges = transactions.some(transaction => transaction.docChanged) && !oldState.doc.eq(newState.doc)\n const preventAutolink = transactions.some(transaction => transaction.getMeta('preventAutolink'))\n\n if (!docChanges || preventAutolink) {\n return\n }\n\n const { tr } = newState\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n const { mapping } = transform\n const changes = getChangedRanges(transform)\n let needsAutolink = true\n\n changes.forEach(({ oldRange, newRange }) => {\n // At first we check if we have to remove links.\n getMarksBetween(oldRange.from, oldRange.to, oldState.doc)\n .filter(item => item.mark.type === options.type)\n .forEach(oldMark => {\n const newFrom = mapping.map(oldMark.from)\n const newTo = mapping.map(oldMark.to)\n const newMarks = getMarksBetween(newFrom, newTo, newState.doc).filter(\n item => item.mark.type === options.type,\n )\n\n if (!newMarks.length) {\n return\n }\n\n const newMark = newMarks[0]\n const oldLinkText = oldState.doc.textBetween(oldMark.from, oldMark.to, undefined, ' ')\n const newLinkText = newState.doc.textBetween(newMark.from, newMark.to, undefined, ' ')\n const wasLink = test(oldLinkText)\n const isLink = test(newLinkText)\n\n if (wasLink) {\n needsAutolink = false\n }\n\n // Remove only the link, if it was a link before too.\n // Because we don’t want to remove links that were set manually.\n if (wasLink && !isLink) {\n tr.removeMark(needsAutolink ? newMark.from : newMark.to - 1, newMark.to, options.type)\n }\n })\n\n // Now let’s see if we can add new links.\n const nodesInChangedRanges = findChildrenInRange(\n newState.doc,\n newRange,\n node => node.isTextblock,\n )\n\n let textBlock: NodeWithPos | undefined\n let textBeforeWhitespace: string | undefined\n\n if (nodesInChangedRanges.length > 1) {\n // Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n textBlock.pos + textBlock.node.nodeSize,\n undefined,\n ' ',\n )\n } else if (\n nodesInChangedRanges.length\n // We want to make sure to include the block seperator argument to treat hard breaks like spaces.\n && newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')\n ) {\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n newRange.to,\n undefined,\n ' ',\n )\n }\n\n if (textBlock && textBeforeWhitespace) {\n const wordsBeforeWhitespace = textBeforeWhitespace.split(' ').filter(s => s !== '')\n\n if (wordsBeforeWhitespace.length <= 0) {\n return false\n }\n\n const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]\n const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace)\n\n if (!lastWordBeforeSpace) {\n return false\n }\n\n find(lastWordBeforeSpace)\n .filter(link => link.isLink)\n .filter(link => {\n if (options.validate) {\n return options.validate(link.value)\n }\n return true\n })\n // Calculate link position.\n .map(link => ({\n ...link,\n from: lastWordAndBlockOffset + link.start + 1,\n to: lastWordAndBlockOffset + link.end + 1,\n }))\n // Add link mark.\n .forEach(link => {\n if (getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {\n return\n }\n\n tr.addMark(\n link.from,\n link.to,\n options.type.create({\n href: link.href,\n }),\n )\n })\n }\n })\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n },\n })\n}\n","import { getAttributes } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\ntype ClickHandlerOptions = {\n type: MarkType\n}\n\nexport function clickHandler(options: ClickHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handleClickLink'),\n props: {\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return false\n }\n\n const attrs = getAttributes(view.state, options.type.name)\n const link = (event.target as HTMLElement)?.closest('a')\n\n const href = link?.href ?? attrs.href\n const target = link?.target ?? attrs.target\n\n if (link && href) {\n window.open(href, target)\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Editor } from '@tiptap/core'\nimport { Mark, MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype PasteHandlerOptions = {\n editor: Editor\n type: MarkType\n linkOnPaste?: boolean\n}\n\nexport function pasteHandler(options: PasteHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handlePasteLink'),\n props: {\n handlePaste: (view, event, slice) => {\n const { state } = view\n const { selection } = state\n\n // Do not proceed if in code block.\n if (state.doc.resolve(selection.from).parent.type.spec.code) {\n return false\n }\n\n const pastedLinkMarks: Mark[] = []\n let textContent = ''\n\n slice.content.forEach(node => {\n textContent += node.textContent\n\n node.marks.forEach(mark => {\n if (mark.type.name === options.type.name) {\n pastedLinkMarks.push(mark)\n }\n })\n })\n\n const hasPastedLink = pastedLinkMarks.length > 0\n const link = find(textContent).find(item => item.isLink && item.value === textContent)\n\n if (!selection.empty && options.linkOnPaste) {\n const pastedLink = hasPastedLink ? pastedLinkMarks[0].attrs.href : link?.href || null\n\n if (pastedLink) {\n options.editor.commands.setMark(options.type, { href: pastedLink })\n\n return true\n }\n }\n\n const firstChildIsText = slice.content.firstChild?.type.name === 'text'\n const firstChildContainsLinkMark = slice.content.firstChild?.marks.some(mark => mark.type.name === options.type.name)\n\n if (firstChildIsText && firstChildContainsLinkMark) {\n return false\n }\n\n if (link && selection.empty) {\n options.editor.commands.insertContent(`<a href=\"${link.href}\">${link.href}</a>`)\n\n return true\n }\n\n const { tr } = state\n let deleteOnly = false\n\n if (!selection.empty) {\n deleteOnly = true\n\n tr.delete(selection.from, selection.to)\n }\n\n let currentPos = selection.from\n let fragmentLinks = []\n\n slice.content.forEach(node => {\n fragmentLinks = find(node.textContent)\n\n tr.insert(currentPos - 1, node)\n\n if (fragmentLinks.length > 0) {\n deleteOnly = false\n\n fragmentLinks.forEach(fragmentLink => {\n const linkStart = currentPos + fragmentLink.start\n const linkEnd = currentPos + fragmentLink.end\n const hasMark = tr.doc.rangeHasMark(linkStart, linkEnd, options.type)\n\n if (!hasMark) {\n tr.addMark(linkStart, linkEnd, options.type.create({ href: fragmentLink.href }))\n }\n })\n\n }\n currentPos += node.nodeSize\n })\n\n const hasFragmentLinks = fragmentLinks.length > 0\n\n if (tr.docChanged && !deleteOnly && hasFragmentLinks) {\n options.editor.view.dispatch(tr)\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Mark, mergeAttributes } from '@tiptap/core'\nimport { Plugin } from '@tiptap/pm/state'\nimport { registerCustomProtocol, reset } from 'linkifyjs'\n\nimport { autolink } from './helpers/autolink'\nimport { clickHandler } from './helpers/clickHandler'\nimport { pasteHandler } from './helpers/pasteHandler'\n\nexport interface LinkProtocolOptions {\n scheme: string;\n optionalSlashes?: boolean;\n}\n\nexport interface LinkOptions {\n /**\n * If enabled, it adds links as you type.\n */\n autolink: boolean\n /**\n * An array of custom protocols to be registered with linkifyjs.\n */\n protocols: Array<LinkProtocolOptions | string>\n /**\n * If enabled, links will be opened on click.\n */\n openOnClick: boolean\n /**\n * Adds a link to the current selection if the pasted content only contains an url.\n */\n linkOnPaste: boolean\n /**\n * A list of HTML attributes to be rendered.\n */\n HTMLAttributes: Record<string, any>\n /**\n * A validation function that modifies link verification for the auto linker.\n * @param url - The url to be validated.\n * @returns - True if the url is valid, false otherwise.\n */\n validate?: (url: string) => boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string; target?: string | null }) => ReturnType\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string; target?: string | null }) => ReturnType\n /**\n * Unset a link mark\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\nexport const Link = Mark.create<LinkOptions>({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n onCreate() {\n this.options.protocols.forEach(protocol => {\n if (typeof protocol === 'string') {\n registerCustomProtocol(protocol)\n return\n }\n registerCustomProtocol(protocol.scheme, protocol.optionalSlashes)\n })\n },\n\n onDestroy() {\n reset()\n },\n\n inclusive() {\n return this.options.autolink\n },\n\n addOptions() {\n return {\n openOnClick: true,\n linkOnPaste: true,\n autolink: true,\n protocols: [],\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n validate: undefined,\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n class: {\n default: this.options.HTMLAttributes.class,\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'a[href]:not([href *= \"javascript:\" i])' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setLink:\n attributes => ({ chain }) => {\n return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run()\n },\n\n toggleLink:\n attributes => ({ chain }) => {\n return chain()\n .toggleMark(this.name, attributes, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n\n unsetLink:\n () => ({ chain }) => {\n return chain()\n .unsetMark(this.name, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n }\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = []\n\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n validate: this.options.validate,\n }),\n )\n }\n\n if (this.options.openOnClick) {\n plugins.push(\n clickHandler({\n type: this.type,\n }),\n )\n }\n\n plugins.push(\n pasteHandler({\n editor: this.editor,\n type: this.type,\n linkOnPaste: this.options.linkOnPaste,\n }),\n )\n\n return plugins\n },\n})\n"],"names":["Plugin","PluginKey","combineTransactionSteps","getChangedRanges","getMarksBetween","test","findChildrenInRange","find","getAttributes","Mark","registerCustomProtocol","reset","mergeAttributes"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/helpers/autolink.ts","../src/helpers/clickHandler.ts","../src/helpers/pasteHandler.ts","../src/link.ts"],"sourcesContent":["import {\n combineTransactionSteps,\n findChildrenInRange,\n getChangedRanges,\n getMarksBetween,\n NodeWithPos,\n} from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype AutolinkOptions = {\n type: MarkType\n validate?: (url: string) => boolean\n}\n\nexport function autolink(options: AutolinkOptions): Plugin {\n return new Plugin({\n key: new PluginKey('autolink'),\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges = transactions.some(transaction => transaction.docChanged) && !oldState.doc.eq(newState.doc)\n const preventAutolink = transactions.some(transaction => transaction.getMeta('preventAutolink'))\n\n if (!docChanges || preventAutolink) {\n return\n }\n\n const { tr } = newState\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n const changes = getChangedRanges(transform)\n\n changes.forEach(({ newRange }) => {\n // Now let’s see if we can add new links.\n const nodesInChangedRanges = findChildrenInRange(\n newState.doc,\n newRange,\n node => node.isTextblock,\n )\n\n let textBlock: NodeWithPos | undefined\n let textBeforeWhitespace: string | undefined\n\n if (nodesInChangedRanges.length > 1) {\n // Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n textBlock.pos + textBlock.node.nodeSize,\n undefined,\n ' ',\n )\n } else if (\n nodesInChangedRanges.length\n // We want to make sure to include the block seperator argument to treat hard breaks like spaces.\n && newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')\n ) {\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n newRange.to,\n undefined,\n ' ',\n )\n }\n\n if (textBlock && textBeforeWhitespace) {\n const wordsBeforeWhitespace = textBeforeWhitespace.split(' ').filter(s => s !== '')\n\n if (wordsBeforeWhitespace.length <= 0) {\n return false\n }\n\n const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]\n const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace)\n\n if (!lastWordBeforeSpace) {\n return false\n }\n\n find(lastWordBeforeSpace)\n .filter(link => link.isLink)\n // Calculate link position.\n .map(link => ({\n ...link,\n from: lastWordAndBlockOffset + link.start + 1,\n to: lastWordAndBlockOffset + link.end + 1,\n }))\n // ignore link inside code mark\n .filter(link => {\n return !newState.doc.rangeHasMark(\n link.from,\n link.to,\n newState.schema.marks.code,\n )\n })\n // validate link\n .filter(link => {\n if (options.validate) {\n return options.validate(link.value)\n }\n return true\n })\n // Add link mark.\n .forEach(link => {\n if (getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {\n return\n }\n\n tr.addMark(\n link.from,\n link.to,\n options.type.create({\n href: link.href,\n }),\n )\n })\n }\n })\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n },\n })\n}\n","import { getAttributes } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\ntype ClickHandlerOptions = {\n type: MarkType\n}\n\nexport function clickHandler(options: ClickHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handleClickLink'),\n props: {\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return false\n }\n\n const attrs = getAttributes(view.state, options.type.name)\n const link = (event.target as HTMLLinkElement)\n\n const href = link?.href ?? attrs.href\n const target = link?.target ?? attrs.target\n\n if (link && href) {\n if (view.editable) {\n window.open(href, target)\n }\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Editor } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype PasteHandlerOptions = {\n editor: Editor\n type: MarkType\n linkOnPaste?: boolean\n}\n\nexport function pasteHandler(options: PasteHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handlePasteLink'),\n props: {\n handlePaste: (view, event, slice) => {\n const { state } = view\n const { selection } = state\n\n // Do not proceed if in code block.\n if (state.doc.resolve(selection.from).parent.type.spec.code) {\n return false\n }\n\n let textContent = ''\n\n slice.content.forEach(node => {\n textContent += node.textContent\n })\n\n let isAlreadyLink = false\n\n slice.content.descendants(node => {\n if (node.marks.some(mark => mark.type.name === options.type.name)) {\n isAlreadyLink = true\n }\n })\n\n if (isAlreadyLink) {\n return\n }\n\n const link = find(textContent).find(item => item.isLink && item.value === textContent)\n\n if (!selection.empty && options.linkOnPaste) {\n const pastedLink = link?.href || null\n\n if (pastedLink) {\n options.editor.commands.setMark(options.type, { href: pastedLink })\n\n return true\n }\n }\n\n const firstChildIsText = slice.content.firstChild?.type.name === 'text'\n const firstChildContainsLinkMark = slice.content.firstChild?.marks.some(mark => mark.type.name === options.type.name)\n\n if ((firstChildIsText && firstChildContainsLinkMark) || !options.linkOnPaste) {\n return false\n }\n\n if (link && selection.empty) {\n options.editor.commands.insertContent(`<a href=\"${link.href}\">${link.href}</a>`)\n\n return true\n }\n\n const { tr } = state\n let deleteOnly = false\n\n if (!selection.empty) {\n deleteOnly = true\n\n tr.delete(selection.from, selection.to)\n }\n\n let currentPos = selection.from\n let fragmentLinks = []\n\n slice.content.forEach(node => {\n fragmentLinks = find(node.textContent)\n\n tr.insert(currentPos - 1, node)\n\n if (fragmentLinks.length > 0) {\n deleteOnly = false\n\n fragmentLinks.forEach(fragmentLink => {\n const linkStart = currentPos + fragmentLink.start\n const linkEnd = currentPos + fragmentLink.end\n const hasMark = tr.doc.rangeHasMark(linkStart, linkEnd, options.type)\n\n if (!hasMark) {\n tr.addMark(linkStart, linkEnd, options.type.create({ href: fragmentLink.href }))\n }\n })\n\n }\n currentPos += node.nodeSize\n })\n\n const hasFragmentLinks = fragmentLinks.length > 0\n\n if (tr.docChanged && !deleteOnly && hasFragmentLinks) {\n options.editor.view.dispatch(tr)\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Mark, mergeAttributes } from '@tiptap/core'\nimport { Plugin } from '@tiptap/pm/state'\nimport { registerCustomProtocol, reset } from 'linkifyjs'\n\nimport { autolink } from './helpers/autolink.js'\nimport { clickHandler } from './helpers/clickHandler.js'\nimport { pasteHandler } from './helpers/pasteHandler.js'\n\nexport interface LinkProtocolOptions {\n scheme: string;\n optionalSlashes?: boolean;\n}\n\nexport interface LinkOptions {\n /**\n * If enabled, it adds links as you type.\n */\n autolink: boolean\n /**\n * An array of custom protocols to be registered with linkifyjs.\n */\n protocols: Array<LinkProtocolOptions | string>\n /**\n * If enabled, links will be opened on click.\n */\n openOnClick: boolean\n /**\n * Adds a link to the current selection if the pasted content only contains an url.\n */\n linkOnPaste: boolean\n /**\n * A list of HTML attributes to be rendered.\n */\n HTMLAttributes: Record<string, any>\n /**\n * A validation function that modifies link verification for the auto linker.\n * @param url - The url to be validated.\n * @returns - True if the url is valid, false otherwise.\n */\n validate?: (url: string) => boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string; target?: string | null }) => ReturnType\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string; target?: string | null }) => ReturnType\n /**\n * Unset a link mark\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\nexport const Link = Mark.create<LinkOptions>({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n onCreate() {\n this.options.protocols.forEach(protocol => {\n if (typeof protocol === 'string') {\n registerCustomProtocol(protocol)\n return\n }\n registerCustomProtocol(protocol.scheme, protocol.optionalSlashes)\n })\n },\n\n onDestroy() {\n reset()\n },\n\n inclusive() {\n return this.options.autolink\n },\n\n addOptions() {\n return {\n openOnClick: true,\n linkOnPaste: true,\n autolink: true,\n protocols: [],\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n validate: undefined,\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n rel: {\n default: this.options.HTMLAttributes.rel,\n },\n class: {\n default: this.options.HTMLAttributes.class,\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'a[href]:not([href *= \"javascript:\" i])' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setLink:\n attributes => ({ chain }) => {\n return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run()\n },\n\n toggleLink:\n attributes => ({ chain }) => {\n return chain()\n .toggleMark(this.name, attributes, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n\n unsetLink:\n () => ({ chain }) => {\n return chain()\n .unsetMark(this.name, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n }\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = []\n\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n validate: this.options.validate,\n }),\n )\n }\n\n if (this.options.openOnClick) {\n plugins.push(\n clickHandler({\n type: this.type,\n }),\n )\n }\n\n plugins.push(\n pasteHandler({\n editor: this.editor,\n type: this.type,\n linkOnPaste: this.options.linkOnPaste,\n }),\n )\n\n return plugins\n },\n})\n"],"names":["Plugin","PluginKey","combineTransactionSteps","getChangedRanges","findChildrenInRange","find","getMarksBetween","getAttributes","Mark","registerCustomProtocol","reset","mergeAttributes"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { combineTransactionSteps, getChangedRanges,
|
|
2
|
-
import {
|
|
1
|
+
import { combineTransactionSteps, getChangedRanges, findChildrenInRange, getMarksBetween, getAttributes, Mark, mergeAttributes } from '@tiptap/core';
|
|
2
|
+
import { find, registerCustomProtocol, reset } from 'linkifyjs';
|
|
3
3
|
import { Plugin, PluginKey } from '@tiptap/pm/state';
|
|
4
4
|
|
|
5
5
|
function autolink(options) {
|
|
@@ -13,34 +13,8 @@ function autolink(options) {
|
|
|
13
13
|
}
|
|
14
14
|
const { tr } = newState;
|
|
15
15
|
const transform = combineTransactionSteps(oldState.doc, [...transactions]);
|
|
16
|
-
const { mapping } = transform;
|
|
17
16
|
const changes = getChangedRanges(transform);
|
|
18
|
-
|
|
19
|
-
changes.forEach(({ oldRange, newRange }) => {
|
|
20
|
-
// At first we check if we have to remove links.
|
|
21
|
-
getMarksBetween(oldRange.from, oldRange.to, oldState.doc)
|
|
22
|
-
.filter(item => item.mark.type === options.type)
|
|
23
|
-
.forEach(oldMark => {
|
|
24
|
-
const newFrom = mapping.map(oldMark.from);
|
|
25
|
-
const newTo = mapping.map(oldMark.to);
|
|
26
|
-
const newMarks = getMarksBetween(newFrom, newTo, newState.doc).filter(item => item.mark.type === options.type);
|
|
27
|
-
if (!newMarks.length) {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
const newMark = newMarks[0];
|
|
31
|
-
const oldLinkText = oldState.doc.textBetween(oldMark.from, oldMark.to, undefined, ' ');
|
|
32
|
-
const newLinkText = newState.doc.textBetween(newMark.from, newMark.to, undefined, ' ');
|
|
33
|
-
const wasLink = test(oldLinkText);
|
|
34
|
-
const isLink = test(newLinkText);
|
|
35
|
-
if (wasLink) {
|
|
36
|
-
needsAutolink = false;
|
|
37
|
-
}
|
|
38
|
-
// Remove only the link, if it was a link before too.
|
|
39
|
-
// Because we don’t want to remove links that were set manually.
|
|
40
|
-
if (wasLink && !isLink) {
|
|
41
|
-
tr.removeMark(needsAutolink ? newMark.from : newMark.to - 1, newMark.to, options.type);
|
|
42
|
-
}
|
|
43
|
-
});
|
|
17
|
+
changes.forEach(({ newRange }) => {
|
|
44
18
|
// Now let’s see if we can add new links.
|
|
45
19
|
const nodesInChangedRanges = findChildrenInRange(newState.doc, newRange, node => node.isTextblock);
|
|
46
20
|
let textBlock;
|
|
@@ -68,18 +42,23 @@ function autolink(options) {
|
|
|
68
42
|
}
|
|
69
43
|
find(lastWordBeforeSpace)
|
|
70
44
|
.filter(link => link.isLink)
|
|
71
|
-
.filter(link => {
|
|
72
|
-
if (options.validate) {
|
|
73
|
-
return options.validate(link.value);
|
|
74
|
-
}
|
|
75
|
-
return true;
|
|
76
|
-
})
|
|
77
45
|
// Calculate link position.
|
|
78
46
|
.map(link => ({
|
|
79
47
|
...link,
|
|
80
48
|
from: lastWordAndBlockOffset + link.start + 1,
|
|
81
49
|
to: lastWordAndBlockOffset + link.end + 1,
|
|
82
50
|
}))
|
|
51
|
+
// ignore link inside code mark
|
|
52
|
+
.filter(link => {
|
|
53
|
+
return !newState.doc.rangeHasMark(link.from, link.to, newState.schema.marks.code);
|
|
54
|
+
})
|
|
55
|
+
// validate link
|
|
56
|
+
.filter(link => {
|
|
57
|
+
if (options.validate) {
|
|
58
|
+
return options.validate(link.value);
|
|
59
|
+
}
|
|
60
|
+
return true;
|
|
61
|
+
})
|
|
83
62
|
// Add link mark.
|
|
84
63
|
.forEach(link => {
|
|
85
64
|
if (getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {
|
|
@@ -104,16 +83,18 @@ function clickHandler(options) {
|
|
|
104
83
|
key: new PluginKey('handleClickLink'),
|
|
105
84
|
props: {
|
|
106
85
|
handleClick: (view, pos, event) => {
|
|
107
|
-
var _a, _b
|
|
86
|
+
var _a, _b;
|
|
108
87
|
if (event.button !== 0) {
|
|
109
88
|
return false;
|
|
110
89
|
}
|
|
111
90
|
const attrs = getAttributes(view.state, options.type.name);
|
|
112
|
-
const link =
|
|
113
|
-
const href = (
|
|
114
|
-
const target = (
|
|
91
|
+
const link = event.target;
|
|
92
|
+
const href = (_a = link === null || link === void 0 ? void 0 : link.href) !== null && _a !== void 0 ? _a : attrs.href;
|
|
93
|
+
const target = (_b = link === null || link === void 0 ? void 0 : link.target) !== null && _b !== void 0 ? _b : attrs.target;
|
|
115
94
|
if (link && href) {
|
|
116
|
-
|
|
95
|
+
if (view.editable) {
|
|
96
|
+
window.open(href, target);
|
|
97
|
+
}
|
|
117
98
|
return true;
|
|
118
99
|
}
|
|
119
100
|
return false;
|
|
@@ -134,20 +115,22 @@ function pasteHandler(options) {
|
|
|
134
115
|
if (state.doc.resolve(selection.from).parent.type.spec.code) {
|
|
135
116
|
return false;
|
|
136
117
|
}
|
|
137
|
-
const pastedLinkMarks = [];
|
|
138
118
|
let textContent = '';
|
|
139
119
|
slice.content.forEach(node => {
|
|
140
120
|
textContent += node.textContent;
|
|
141
|
-
node.marks.forEach(mark => {
|
|
142
|
-
if (mark.type.name === options.type.name) {
|
|
143
|
-
pastedLinkMarks.push(mark);
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
121
|
});
|
|
147
|
-
|
|
122
|
+
let isAlreadyLink = false;
|
|
123
|
+
slice.content.descendants(node => {
|
|
124
|
+
if (node.marks.some(mark => mark.type.name === options.type.name)) {
|
|
125
|
+
isAlreadyLink = true;
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
if (isAlreadyLink) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
148
131
|
const link = find(textContent).find(item => item.isLink && item.value === textContent);
|
|
149
132
|
if (!selection.empty && options.linkOnPaste) {
|
|
150
|
-
const pastedLink =
|
|
133
|
+
const pastedLink = (link === null || link === void 0 ? void 0 : link.href) || null;
|
|
151
134
|
if (pastedLink) {
|
|
152
135
|
options.editor.commands.setMark(options.type, { href: pastedLink });
|
|
153
136
|
return true;
|
|
@@ -155,7 +138,7 @@ function pasteHandler(options) {
|
|
|
155
138
|
}
|
|
156
139
|
const firstChildIsText = ((_a = slice.content.firstChild) === null || _a === void 0 ? void 0 : _a.type.name) === 'text';
|
|
157
140
|
const firstChildContainsLinkMark = (_b = slice.content.firstChild) === null || _b === void 0 ? void 0 : _b.marks.some(mark => mark.type.name === options.type.name);
|
|
158
|
-
if (firstChildIsText && firstChildContainsLinkMark) {
|
|
141
|
+
if ((firstChildIsText && firstChildContainsLinkMark) || !options.linkOnPaste) {
|
|
159
142
|
return false;
|
|
160
143
|
}
|
|
161
144
|
if (link && selection.empty) {
|
|
@@ -238,6 +221,9 @@ const Link = Mark.create({
|
|
|
238
221
|
target: {
|
|
239
222
|
default: this.options.HTMLAttributes.target,
|
|
240
223
|
},
|
|
224
|
+
rel: {
|
|
225
|
+
default: this.options.HTMLAttributes.rel,
|
|
226
|
+
},
|
|
241
227
|
class: {
|
|
242
228
|
default: this.options.HTMLAttributes.class,
|
|
243
229
|
},
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/helpers/autolink.ts","../src/helpers/clickHandler.ts","../src/helpers/pasteHandler.ts","../src/link.ts"],"sourcesContent":["import {\n combineTransactionSteps,\n findChildrenInRange,\n getChangedRanges,\n getMarksBetween,\n NodeWithPos,\n} from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find, test } from 'linkifyjs'\n\ntype AutolinkOptions = {\n type: MarkType\n validate?: (url: string) => boolean\n}\n\nexport function autolink(options: AutolinkOptions): Plugin {\n return new Plugin({\n key: new PluginKey('autolink'),\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges = transactions.some(transaction => transaction.docChanged) && !oldState.doc.eq(newState.doc)\n const preventAutolink = transactions.some(transaction => transaction.getMeta('preventAutolink'))\n\n if (!docChanges || preventAutolink) {\n return\n }\n\n const { tr } = newState\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n const { mapping } = transform\n const changes = getChangedRanges(transform)\n let needsAutolink = true\n\n changes.forEach(({ oldRange, newRange }) => {\n // At first we check if we have to remove links.\n getMarksBetween(oldRange.from, oldRange.to, oldState.doc)\n .filter(item => item.mark.type === options.type)\n .forEach(oldMark => {\n const newFrom = mapping.map(oldMark.from)\n const newTo = mapping.map(oldMark.to)\n const newMarks = getMarksBetween(newFrom, newTo, newState.doc).filter(\n item => item.mark.type === options.type,\n )\n\n if (!newMarks.length) {\n return\n }\n\n const newMark = newMarks[0]\n const oldLinkText = oldState.doc.textBetween(oldMark.from, oldMark.to, undefined, ' ')\n const newLinkText = newState.doc.textBetween(newMark.from, newMark.to, undefined, ' ')\n const wasLink = test(oldLinkText)\n const isLink = test(newLinkText)\n\n if (wasLink) {\n needsAutolink = false\n }\n\n // Remove only the link, if it was a link before too.\n // Because we don’t want to remove links that were set manually.\n if (wasLink && !isLink) {\n tr.removeMark(needsAutolink ? newMark.from : newMark.to - 1, newMark.to, options.type)\n }\n })\n\n // Now let’s see if we can add new links.\n const nodesInChangedRanges = findChildrenInRange(\n newState.doc,\n newRange,\n node => node.isTextblock,\n )\n\n let textBlock: NodeWithPos | undefined\n let textBeforeWhitespace: string | undefined\n\n if (nodesInChangedRanges.length > 1) {\n // Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n textBlock.pos + textBlock.node.nodeSize,\n undefined,\n ' ',\n )\n } else if (\n nodesInChangedRanges.length\n // We want to make sure to include the block seperator argument to treat hard breaks like spaces.\n && newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')\n ) {\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n newRange.to,\n undefined,\n ' ',\n )\n }\n\n if (textBlock && textBeforeWhitespace) {\n const wordsBeforeWhitespace = textBeforeWhitespace.split(' ').filter(s => s !== '')\n\n if (wordsBeforeWhitespace.length <= 0) {\n return false\n }\n\n const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]\n const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace)\n\n if (!lastWordBeforeSpace) {\n return false\n }\n\n find(lastWordBeforeSpace)\n .filter(link => link.isLink)\n .filter(link => {\n if (options.validate) {\n return options.validate(link.value)\n }\n return true\n })\n // Calculate link position.\n .map(link => ({\n ...link,\n from: lastWordAndBlockOffset + link.start + 1,\n to: lastWordAndBlockOffset + link.end + 1,\n }))\n // Add link mark.\n .forEach(link => {\n if (getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {\n return\n }\n\n tr.addMark(\n link.from,\n link.to,\n options.type.create({\n href: link.href,\n }),\n )\n })\n }\n })\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n },\n })\n}\n","import { getAttributes } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\ntype ClickHandlerOptions = {\n type: MarkType\n}\n\nexport function clickHandler(options: ClickHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handleClickLink'),\n props: {\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return false\n }\n\n const attrs = getAttributes(view.state, options.type.name)\n const link = (event.target as HTMLElement)?.closest('a')\n\n const href = link?.href ?? attrs.href\n const target = link?.target ?? attrs.target\n\n if (link && href) {\n window.open(href, target)\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Editor } from '@tiptap/core'\nimport { Mark, MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype PasteHandlerOptions = {\n editor: Editor\n type: MarkType\n linkOnPaste?: boolean\n}\n\nexport function pasteHandler(options: PasteHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handlePasteLink'),\n props: {\n handlePaste: (view, event, slice) => {\n const { state } = view\n const { selection } = state\n\n // Do not proceed if in code block.\n if (state.doc.resolve(selection.from).parent.type.spec.code) {\n return false\n }\n\n const pastedLinkMarks: Mark[] = []\n let textContent = ''\n\n slice.content.forEach(node => {\n textContent += node.textContent\n\n node.marks.forEach(mark => {\n if (mark.type.name === options.type.name) {\n pastedLinkMarks.push(mark)\n }\n })\n })\n\n const hasPastedLink = pastedLinkMarks.length > 0\n const link = find(textContent).find(item => item.isLink && item.value === textContent)\n\n if (!selection.empty && options.linkOnPaste) {\n const pastedLink = hasPastedLink ? pastedLinkMarks[0].attrs.href : link?.href || null\n\n if (pastedLink) {\n options.editor.commands.setMark(options.type, { href: pastedLink })\n\n return true\n }\n }\n\n const firstChildIsText = slice.content.firstChild?.type.name === 'text'\n const firstChildContainsLinkMark = slice.content.firstChild?.marks.some(mark => mark.type.name === options.type.name)\n\n if (firstChildIsText && firstChildContainsLinkMark) {\n return false\n }\n\n if (link && selection.empty) {\n options.editor.commands.insertContent(`<a href=\"${link.href}\">${link.href}</a>`)\n\n return true\n }\n\n const { tr } = state\n let deleteOnly = false\n\n if (!selection.empty) {\n deleteOnly = true\n\n tr.delete(selection.from, selection.to)\n }\n\n let currentPos = selection.from\n let fragmentLinks = []\n\n slice.content.forEach(node => {\n fragmentLinks = find(node.textContent)\n\n tr.insert(currentPos - 1, node)\n\n if (fragmentLinks.length > 0) {\n deleteOnly = false\n\n fragmentLinks.forEach(fragmentLink => {\n const linkStart = currentPos + fragmentLink.start\n const linkEnd = currentPos + fragmentLink.end\n const hasMark = tr.doc.rangeHasMark(linkStart, linkEnd, options.type)\n\n if (!hasMark) {\n tr.addMark(linkStart, linkEnd, options.type.create({ href: fragmentLink.href }))\n }\n })\n\n }\n currentPos += node.nodeSize\n })\n\n const hasFragmentLinks = fragmentLinks.length > 0\n\n if (tr.docChanged && !deleteOnly && hasFragmentLinks) {\n options.editor.view.dispatch(tr)\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Mark, mergeAttributes } from '@tiptap/core'\nimport { Plugin } from '@tiptap/pm/state'\nimport { registerCustomProtocol, reset } from 'linkifyjs'\n\nimport { autolink } from './helpers/autolink'\nimport { clickHandler } from './helpers/clickHandler'\nimport { pasteHandler } from './helpers/pasteHandler'\n\nexport interface LinkProtocolOptions {\n scheme: string;\n optionalSlashes?: boolean;\n}\n\nexport interface LinkOptions {\n /**\n * If enabled, it adds links as you type.\n */\n autolink: boolean\n /**\n * An array of custom protocols to be registered with linkifyjs.\n */\n protocols: Array<LinkProtocolOptions | string>\n /**\n * If enabled, links will be opened on click.\n */\n openOnClick: boolean\n /**\n * Adds a link to the current selection if the pasted content only contains an url.\n */\n linkOnPaste: boolean\n /**\n * A list of HTML attributes to be rendered.\n */\n HTMLAttributes: Record<string, any>\n /**\n * A validation function that modifies link verification for the auto linker.\n * @param url - The url to be validated.\n * @returns - True if the url is valid, false otherwise.\n */\n validate?: (url: string) => boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string; target?: string | null }) => ReturnType\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string; target?: string | null }) => ReturnType\n /**\n * Unset a link mark\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\nexport const Link = Mark.create<LinkOptions>({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n onCreate() {\n this.options.protocols.forEach(protocol => {\n if (typeof protocol === 'string') {\n registerCustomProtocol(protocol)\n return\n }\n registerCustomProtocol(protocol.scheme, protocol.optionalSlashes)\n })\n },\n\n onDestroy() {\n reset()\n },\n\n inclusive() {\n return this.options.autolink\n },\n\n addOptions() {\n return {\n openOnClick: true,\n linkOnPaste: true,\n autolink: true,\n protocols: [],\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n validate: undefined,\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n class: {\n default: this.options.HTMLAttributes.class,\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'a[href]:not([href *= \"javascript:\" i])' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setLink:\n attributes => ({ chain }) => {\n return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run()\n },\n\n toggleLink:\n attributes => ({ chain }) => {\n return chain()\n .toggleMark(this.name, attributes, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n\n unsetLink:\n () => ({ chain }) => {\n return chain()\n .unsetMark(this.name, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n }\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = []\n\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n validate: this.options.validate,\n }),\n )\n }\n\n if (this.options.openOnClick) {\n plugins.push(\n clickHandler({\n type: this.type,\n }),\n )\n }\n\n plugins.push(\n pasteHandler({\n editor: this.editor,\n type: this.type,\n linkOnPaste: this.options.linkOnPaste,\n }),\n )\n\n return plugins\n },\n})\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/helpers/autolink.ts","../src/helpers/clickHandler.ts","../src/helpers/pasteHandler.ts","../src/link.ts"],"sourcesContent":["import {\n combineTransactionSteps,\n findChildrenInRange,\n getChangedRanges,\n getMarksBetween,\n NodeWithPos,\n} from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype AutolinkOptions = {\n type: MarkType\n validate?: (url: string) => boolean\n}\n\nexport function autolink(options: AutolinkOptions): Plugin {\n return new Plugin({\n key: new PluginKey('autolink'),\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges = transactions.some(transaction => transaction.docChanged) && !oldState.doc.eq(newState.doc)\n const preventAutolink = transactions.some(transaction => transaction.getMeta('preventAutolink'))\n\n if (!docChanges || preventAutolink) {\n return\n }\n\n const { tr } = newState\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n const changes = getChangedRanges(transform)\n\n changes.forEach(({ newRange }) => {\n // Now let’s see if we can add new links.\n const nodesInChangedRanges = findChildrenInRange(\n newState.doc,\n newRange,\n node => node.isTextblock,\n )\n\n let textBlock: NodeWithPos | undefined\n let textBeforeWhitespace: string | undefined\n\n if (nodesInChangedRanges.length > 1) {\n // Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n textBlock.pos + textBlock.node.nodeSize,\n undefined,\n ' ',\n )\n } else if (\n nodesInChangedRanges.length\n // We want to make sure to include the block seperator argument to treat hard breaks like spaces.\n && newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')\n ) {\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n newRange.to,\n undefined,\n ' ',\n )\n }\n\n if (textBlock && textBeforeWhitespace) {\n const wordsBeforeWhitespace = textBeforeWhitespace.split(' ').filter(s => s !== '')\n\n if (wordsBeforeWhitespace.length <= 0) {\n return false\n }\n\n const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]\n const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace)\n\n if (!lastWordBeforeSpace) {\n return false\n }\n\n find(lastWordBeforeSpace)\n .filter(link => link.isLink)\n // Calculate link position.\n .map(link => ({\n ...link,\n from: lastWordAndBlockOffset + link.start + 1,\n to: lastWordAndBlockOffset + link.end + 1,\n }))\n // ignore link inside code mark\n .filter(link => {\n return !newState.doc.rangeHasMark(\n link.from,\n link.to,\n newState.schema.marks.code,\n )\n })\n // validate link\n .filter(link => {\n if (options.validate) {\n return options.validate(link.value)\n }\n return true\n })\n // Add link mark.\n .forEach(link => {\n if (getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {\n return\n }\n\n tr.addMark(\n link.from,\n link.to,\n options.type.create({\n href: link.href,\n }),\n )\n })\n }\n })\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n },\n })\n}\n","import { getAttributes } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\ntype ClickHandlerOptions = {\n type: MarkType\n}\n\nexport function clickHandler(options: ClickHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handleClickLink'),\n props: {\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return false\n }\n\n const attrs = getAttributes(view.state, options.type.name)\n const link = (event.target as HTMLLinkElement)\n\n const href = link?.href ?? attrs.href\n const target = link?.target ?? attrs.target\n\n if (link && href) {\n if (view.editable) {\n window.open(href, target)\n }\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Editor } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype PasteHandlerOptions = {\n editor: Editor\n type: MarkType\n linkOnPaste?: boolean\n}\n\nexport function pasteHandler(options: PasteHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handlePasteLink'),\n props: {\n handlePaste: (view, event, slice) => {\n const { state } = view\n const { selection } = state\n\n // Do not proceed if in code block.\n if (state.doc.resolve(selection.from).parent.type.spec.code) {\n return false\n }\n\n let textContent = ''\n\n slice.content.forEach(node => {\n textContent += node.textContent\n })\n\n let isAlreadyLink = false\n\n slice.content.descendants(node => {\n if (node.marks.some(mark => mark.type.name === options.type.name)) {\n isAlreadyLink = true\n }\n })\n\n if (isAlreadyLink) {\n return\n }\n\n const link = find(textContent).find(item => item.isLink && item.value === textContent)\n\n if (!selection.empty && options.linkOnPaste) {\n const pastedLink = link?.href || null\n\n if (pastedLink) {\n options.editor.commands.setMark(options.type, { href: pastedLink })\n\n return true\n }\n }\n\n const firstChildIsText = slice.content.firstChild?.type.name === 'text'\n const firstChildContainsLinkMark = slice.content.firstChild?.marks.some(mark => mark.type.name === options.type.name)\n\n if ((firstChildIsText && firstChildContainsLinkMark) || !options.linkOnPaste) {\n return false\n }\n\n if (link && selection.empty) {\n options.editor.commands.insertContent(`<a href=\"${link.href}\">${link.href}</a>`)\n\n return true\n }\n\n const { tr } = state\n let deleteOnly = false\n\n if (!selection.empty) {\n deleteOnly = true\n\n tr.delete(selection.from, selection.to)\n }\n\n let currentPos = selection.from\n let fragmentLinks = []\n\n slice.content.forEach(node => {\n fragmentLinks = find(node.textContent)\n\n tr.insert(currentPos - 1, node)\n\n if (fragmentLinks.length > 0) {\n deleteOnly = false\n\n fragmentLinks.forEach(fragmentLink => {\n const linkStart = currentPos + fragmentLink.start\n const linkEnd = currentPos + fragmentLink.end\n const hasMark = tr.doc.rangeHasMark(linkStart, linkEnd, options.type)\n\n if (!hasMark) {\n tr.addMark(linkStart, linkEnd, options.type.create({ href: fragmentLink.href }))\n }\n })\n\n }\n currentPos += node.nodeSize\n })\n\n const hasFragmentLinks = fragmentLinks.length > 0\n\n if (tr.docChanged && !deleteOnly && hasFragmentLinks) {\n options.editor.view.dispatch(tr)\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Mark, mergeAttributes } from '@tiptap/core'\nimport { Plugin } from '@tiptap/pm/state'\nimport { registerCustomProtocol, reset } from 'linkifyjs'\n\nimport { autolink } from './helpers/autolink.js'\nimport { clickHandler } from './helpers/clickHandler.js'\nimport { pasteHandler } from './helpers/pasteHandler.js'\n\nexport interface LinkProtocolOptions {\n scheme: string;\n optionalSlashes?: boolean;\n}\n\nexport interface LinkOptions {\n /**\n * If enabled, it adds links as you type.\n */\n autolink: boolean\n /**\n * An array of custom protocols to be registered with linkifyjs.\n */\n protocols: Array<LinkProtocolOptions | string>\n /**\n * If enabled, links will be opened on click.\n */\n openOnClick: boolean\n /**\n * Adds a link to the current selection if the pasted content only contains an url.\n */\n linkOnPaste: boolean\n /**\n * A list of HTML attributes to be rendered.\n */\n HTMLAttributes: Record<string, any>\n /**\n * A validation function that modifies link verification for the auto linker.\n * @param url - The url to be validated.\n * @returns - True if the url is valid, false otherwise.\n */\n validate?: (url: string) => boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string; target?: string | null }) => ReturnType\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string; target?: string | null }) => ReturnType\n /**\n * Unset a link mark\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\nexport const Link = Mark.create<LinkOptions>({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n onCreate() {\n this.options.protocols.forEach(protocol => {\n if (typeof protocol === 'string') {\n registerCustomProtocol(protocol)\n return\n }\n registerCustomProtocol(protocol.scheme, protocol.optionalSlashes)\n })\n },\n\n onDestroy() {\n reset()\n },\n\n inclusive() {\n return this.options.autolink\n },\n\n addOptions() {\n return {\n openOnClick: true,\n linkOnPaste: true,\n autolink: true,\n protocols: [],\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n validate: undefined,\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n rel: {\n default: this.options.HTMLAttributes.rel,\n },\n class: {\n default: this.options.HTMLAttributes.class,\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'a[href]:not([href *= \"javascript:\" i])' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setLink:\n attributes => ({ chain }) => {\n return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run()\n },\n\n toggleLink:\n attributes => ({ chain }) => {\n return chain()\n .toggleMark(this.name, attributes, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n\n unsetLink:\n () => ({ chain }) => {\n return chain()\n .unsetMark(this.name, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n }\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = []\n\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n validate: this.options.validate,\n }),\n )\n }\n\n if (this.options.openOnClick) {\n plugins.push(\n clickHandler({\n type: this.type,\n }),\n )\n }\n\n plugins.push(\n pasteHandler({\n editor: this.editor,\n type: this.type,\n linkOnPaste: this.options.linkOnPaste,\n }),\n )\n\n return plugins\n },\n})\n"],"names":[],"mappings":"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"}
|
package/dist/index.umd.js
CHANGED
|
@@ -15,34 +15,8 @@
|
|
|
15
15
|
}
|
|
16
16
|
const { tr } = newState;
|
|
17
17
|
const transform = core.combineTransactionSteps(oldState.doc, [...transactions]);
|
|
18
|
-
const { mapping } = transform;
|
|
19
18
|
const changes = core.getChangedRanges(transform);
|
|
20
|
-
|
|
21
|
-
changes.forEach(({ oldRange, newRange }) => {
|
|
22
|
-
// At first we check if we have to remove links.
|
|
23
|
-
core.getMarksBetween(oldRange.from, oldRange.to, oldState.doc)
|
|
24
|
-
.filter(item => item.mark.type === options.type)
|
|
25
|
-
.forEach(oldMark => {
|
|
26
|
-
const newFrom = mapping.map(oldMark.from);
|
|
27
|
-
const newTo = mapping.map(oldMark.to);
|
|
28
|
-
const newMarks = core.getMarksBetween(newFrom, newTo, newState.doc).filter(item => item.mark.type === options.type);
|
|
29
|
-
if (!newMarks.length) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
const newMark = newMarks[0];
|
|
33
|
-
const oldLinkText = oldState.doc.textBetween(oldMark.from, oldMark.to, undefined, ' ');
|
|
34
|
-
const newLinkText = newState.doc.textBetween(newMark.from, newMark.to, undefined, ' ');
|
|
35
|
-
const wasLink = linkifyjs.test(oldLinkText);
|
|
36
|
-
const isLink = linkifyjs.test(newLinkText);
|
|
37
|
-
if (wasLink) {
|
|
38
|
-
needsAutolink = false;
|
|
39
|
-
}
|
|
40
|
-
// Remove only the link, if it was a link before too.
|
|
41
|
-
// Because we don’t want to remove links that were set manually.
|
|
42
|
-
if (wasLink && !isLink) {
|
|
43
|
-
tr.removeMark(needsAutolink ? newMark.from : newMark.to - 1, newMark.to, options.type);
|
|
44
|
-
}
|
|
45
|
-
});
|
|
19
|
+
changes.forEach(({ newRange }) => {
|
|
46
20
|
// Now let’s see if we can add new links.
|
|
47
21
|
const nodesInChangedRanges = core.findChildrenInRange(newState.doc, newRange, node => node.isTextblock);
|
|
48
22
|
let textBlock;
|
|
@@ -70,18 +44,23 @@
|
|
|
70
44
|
}
|
|
71
45
|
linkifyjs.find(lastWordBeforeSpace)
|
|
72
46
|
.filter(link => link.isLink)
|
|
73
|
-
.filter(link => {
|
|
74
|
-
if (options.validate) {
|
|
75
|
-
return options.validate(link.value);
|
|
76
|
-
}
|
|
77
|
-
return true;
|
|
78
|
-
})
|
|
79
47
|
// Calculate link position.
|
|
80
48
|
.map(link => ({
|
|
81
49
|
...link,
|
|
82
50
|
from: lastWordAndBlockOffset + link.start + 1,
|
|
83
51
|
to: lastWordAndBlockOffset + link.end + 1,
|
|
84
52
|
}))
|
|
53
|
+
// ignore link inside code mark
|
|
54
|
+
.filter(link => {
|
|
55
|
+
return !newState.doc.rangeHasMark(link.from, link.to, newState.schema.marks.code);
|
|
56
|
+
})
|
|
57
|
+
// validate link
|
|
58
|
+
.filter(link => {
|
|
59
|
+
if (options.validate) {
|
|
60
|
+
return options.validate(link.value);
|
|
61
|
+
}
|
|
62
|
+
return true;
|
|
63
|
+
})
|
|
85
64
|
// Add link mark.
|
|
86
65
|
.forEach(link => {
|
|
87
66
|
if (core.getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {
|
|
@@ -106,16 +85,18 @@
|
|
|
106
85
|
key: new state.PluginKey('handleClickLink'),
|
|
107
86
|
props: {
|
|
108
87
|
handleClick: (view, pos, event) => {
|
|
109
|
-
var _a, _b
|
|
88
|
+
var _a, _b;
|
|
110
89
|
if (event.button !== 0) {
|
|
111
90
|
return false;
|
|
112
91
|
}
|
|
113
92
|
const attrs = core.getAttributes(view.state, options.type.name);
|
|
114
|
-
const link =
|
|
115
|
-
const href = (
|
|
116
|
-
const target = (
|
|
93
|
+
const link = event.target;
|
|
94
|
+
const href = (_a = link === null || link === void 0 ? void 0 : link.href) !== null && _a !== void 0 ? _a : attrs.href;
|
|
95
|
+
const target = (_b = link === null || link === void 0 ? void 0 : link.target) !== null && _b !== void 0 ? _b : attrs.target;
|
|
117
96
|
if (link && href) {
|
|
118
|
-
|
|
97
|
+
if (view.editable) {
|
|
98
|
+
window.open(href, target);
|
|
99
|
+
}
|
|
119
100
|
return true;
|
|
120
101
|
}
|
|
121
102
|
return false;
|
|
@@ -136,20 +117,22 @@
|
|
|
136
117
|
if (state.doc.resolve(selection.from).parent.type.spec.code) {
|
|
137
118
|
return false;
|
|
138
119
|
}
|
|
139
|
-
const pastedLinkMarks = [];
|
|
140
120
|
let textContent = '';
|
|
141
121
|
slice.content.forEach(node => {
|
|
142
122
|
textContent += node.textContent;
|
|
143
|
-
node.marks.forEach(mark => {
|
|
144
|
-
if (mark.type.name === options.type.name) {
|
|
145
|
-
pastedLinkMarks.push(mark);
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
123
|
});
|
|
149
|
-
|
|
124
|
+
let isAlreadyLink = false;
|
|
125
|
+
slice.content.descendants(node => {
|
|
126
|
+
if (node.marks.some(mark => mark.type.name === options.type.name)) {
|
|
127
|
+
isAlreadyLink = true;
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
if (isAlreadyLink) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
150
133
|
const link = linkifyjs.find(textContent).find(item => item.isLink && item.value === textContent);
|
|
151
134
|
if (!selection.empty && options.linkOnPaste) {
|
|
152
|
-
const pastedLink =
|
|
135
|
+
const pastedLink = (link === null || link === void 0 ? void 0 : link.href) || null;
|
|
153
136
|
if (pastedLink) {
|
|
154
137
|
options.editor.commands.setMark(options.type, { href: pastedLink });
|
|
155
138
|
return true;
|
|
@@ -157,7 +140,7 @@
|
|
|
157
140
|
}
|
|
158
141
|
const firstChildIsText = ((_a = slice.content.firstChild) === null || _a === void 0 ? void 0 : _a.type.name) === 'text';
|
|
159
142
|
const firstChildContainsLinkMark = (_b = slice.content.firstChild) === null || _b === void 0 ? void 0 : _b.marks.some(mark => mark.type.name === options.type.name);
|
|
160
|
-
if (firstChildIsText && firstChildContainsLinkMark) {
|
|
143
|
+
if ((firstChildIsText && firstChildContainsLinkMark) || !options.linkOnPaste) {
|
|
161
144
|
return false;
|
|
162
145
|
}
|
|
163
146
|
if (link && selection.empty) {
|
|
@@ -240,6 +223,9 @@
|
|
|
240
223
|
target: {
|
|
241
224
|
default: this.options.HTMLAttributes.target,
|
|
242
225
|
},
|
|
226
|
+
rel: {
|
|
227
|
+
default: this.options.HTMLAttributes.rel,
|
|
228
|
+
},
|
|
243
229
|
class: {
|
|
244
230
|
default: this.options.HTMLAttributes.class,
|
|
245
231
|
},
|
package/dist/index.umd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.umd.js","sources":["../src/helpers/autolink.ts","../src/helpers/clickHandler.ts","../src/helpers/pasteHandler.ts","../src/link.ts"],"sourcesContent":["import {\n combineTransactionSteps,\n findChildrenInRange,\n getChangedRanges,\n getMarksBetween,\n NodeWithPos,\n} from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find, test } from 'linkifyjs'\n\ntype AutolinkOptions = {\n type: MarkType\n validate?: (url: string) => boolean\n}\n\nexport function autolink(options: AutolinkOptions): Plugin {\n return new Plugin({\n key: new PluginKey('autolink'),\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges = transactions.some(transaction => transaction.docChanged) && !oldState.doc.eq(newState.doc)\n const preventAutolink = transactions.some(transaction => transaction.getMeta('preventAutolink'))\n\n if (!docChanges || preventAutolink) {\n return\n }\n\n const { tr } = newState\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n const { mapping } = transform\n const changes = getChangedRanges(transform)\n let needsAutolink = true\n\n changes.forEach(({ oldRange, newRange }) => {\n // At first we check if we have to remove links.\n getMarksBetween(oldRange.from, oldRange.to, oldState.doc)\n .filter(item => item.mark.type === options.type)\n .forEach(oldMark => {\n const newFrom = mapping.map(oldMark.from)\n const newTo = mapping.map(oldMark.to)\n const newMarks = getMarksBetween(newFrom, newTo, newState.doc).filter(\n item => item.mark.type === options.type,\n )\n\n if (!newMarks.length) {\n return\n }\n\n const newMark = newMarks[0]\n const oldLinkText = oldState.doc.textBetween(oldMark.from, oldMark.to, undefined, ' ')\n const newLinkText = newState.doc.textBetween(newMark.from, newMark.to, undefined, ' ')\n const wasLink = test(oldLinkText)\n const isLink = test(newLinkText)\n\n if (wasLink) {\n needsAutolink = false\n }\n\n // Remove only the link, if it was a link before too.\n // Because we don’t want to remove links that were set manually.\n if (wasLink && !isLink) {\n tr.removeMark(needsAutolink ? newMark.from : newMark.to - 1, newMark.to, options.type)\n }\n })\n\n // Now let’s see if we can add new links.\n const nodesInChangedRanges = findChildrenInRange(\n newState.doc,\n newRange,\n node => node.isTextblock,\n )\n\n let textBlock: NodeWithPos | undefined\n let textBeforeWhitespace: string | undefined\n\n if (nodesInChangedRanges.length > 1) {\n // Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n textBlock.pos + textBlock.node.nodeSize,\n undefined,\n ' ',\n )\n } else if (\n nodesInChangedRanges.length\n // We want to make sure to include the block seperator argument to treat hard breaks like spaces.\n && newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')\n ) {\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n newRange.to,\n undefined,\n ' ',\n )\n }\n\n if (textBlock && textBeforeWhitespace) {\n const wordsBeforeWhitespace = textBeforeWhitespace.split(' ').filter(s => s !== '')\n\n if (wordsBeforeWhitespace.length <= 0) {\n return false\n }\n\n const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]\n const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace)\n\n if (!lastWordBeforeSpace) {\n return false\n }\n\n find(lastWordBeforeSpace)\n .filter(link => link.isLink)\n .filter(link => {\n if (options.validate) {\n return options.validate(link.value)\n }\n return true\n })\n // Calculate link position.\n .map(link => ({\n ...link,\n from: lastWordAndBlockOffset + link.start + 1,\n to: lastWordAndBlockOffset + link.end + 1,\n }))\n // Add link mark.\n .forEach(link => {\n if (getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {\n return\n }\n\n tr.addMark(\n link.from,\n link.to,\n options.type.create({\n href: link.href,\n }),\n )\n })\n }\n })\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n },\n })\n}\n","import { getAttributes } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\ntype ClickHandlerOptions = {\n type: MarkType\n}\n\nexport function clickHandler(options: ClickHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handleClickLink'),\n props: {\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return false\n }\n\n const attrs = getAttributes(view.state, options.type.name)\n const link = (event.target as HTMLElement)?.closest('a')\n\n const href = link?.href ?? attrs.href\n const target = link?.target ?? attrs.target\n\n if (link && href) {\n window.open(href, target)\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Editor } from '@tiptap/core'\nimport { Mark, MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype PasteHandlerOptions = {\n editor: Editor\n type: MarkType\n linkOnPaste?: boolean\n}\n\nexport function pasteHandler(options: PasteHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handlePasteLink'),\n props: {\n handlePaste: (view, event, slice) => {\n const { state } = view\n const { selection } = state\n\n // Do not proceed if in code block.\n if (state.doc.resolve(selection.from).parent.type.spec.code) {\n return false\n }\n\n const pastedLinkMarks: Mark[] = []\n let textContent = ''\n\n slice.content.forEach(node => {\n textContent += node.textContent\n\n node.marks.forEach(mark => {\n if (mark.type.name === options.type.name) {\n pastedLinkMarks.push(mark)\n }\n })\n })\n\n const hasPastedLink = pastedLinkMarks.length > 0\n const link = find(textContent).find(item => item.isLink && item.value === textContent)\n\n if (!selection.empty && options.linkOnPaste) {\n const pastedLink = hasPastedLink ? pastedLinkMarks[0].attrs.href : link?.href || null\n\n if (pastedLink) {\n options.editor.commands.setMark(options.type, { href: pastedLink })\n\n return true\n }\n }\n\n const firstChildIsText = slice.content.firstChild?.type.name === 'text'\n const firstChildContainsLinkMark = slice.content.firstChild?.marks.some(mark => mark.type.name === options.type.name)\n\n if (firstChildIsText && firstChildContainsLinkMark) {\n return false\n }\n\n if (link && selection.empty) {\n options.editor.commands.insertContent(`<a href=\"${link.href}\">${link.href}</a>`)\n\n return true\n }\n\n const { tr } = state\n let deleteOnly = false\n\n if (!selection.empty) {\n deleteOnly = true\n\n tr.delete(selection.from, selection.to)\n }\n\n let currentPos = selection.from\n let fragmentLinks = []\n\n slice.content.forEach(node => {\n fragmentLinks = find(node.textContent)\n\n tr.insert(currentPos - 1, node)\n\n if (fragmentLinks.length > 0) {\n deleteOnly = false\n\n fragmentLinks.forEach(fragmentLink => {\n const linkStart = currentPos + fragmentLink.start\n const linkEnd = currentPos + fragmentLink.end\n const hasMark = tr.doc.rangeHasMark(linkStart, linkEnd, options.type)\n\n if (!hasMark) {\n tr.addMark(linkStart, linkEnd, options.type.create({ href: fragmentLink.href }))\n }\n })\n\n }\n currentPos += node.nodeSize\n })\n\n const hasFragmentLinks = fragmentLinks.length > 0\n\n if (tr.docChanged && !deleteOnly && hasFragmentLinks) {\n options.editor.view.dispatch(tr)\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Mark, mergeAttributes } from '@tiptap/core'\nimport { Plugin } from '@tiptap/pm/state'\nimport { registerCustomProtocol, reset } from 'linkifyjs'\n\nimport { autolink } from './helpers/autolink'\nimport { clickHandler } from './helpers/clickHandler'\nimport { pasteHandler } from './helpers/pasteHandler'\n\nexport interface LinkProtocolOptions {\n scheme: string;\n optionalSlashes?: boolean;\n}\n\nexport interface LinkOptions {\n /**\n * If enabled, it adds links as you type.\n */\n autolink: boolean\n /**\n * An array of custom protocols to be registered with linkifyjs.\n */\n protocols: Array<LinkProtocolOptions | string>\n /**\n * If enabled, links will be opened on click.\n */\n openOnClick: boolean\n /**\n * Adds a link to the current selection if the pasted content only contains an url.\n */\n linkOnPaste: boolean\n /**\n * A list of HTML attributes to be rendered.\n */\n HTMLAttributes: Record<string, any>\n /**\n * A validation function that modifies link verification for the auto linker.\n * @param url - The url to be validated.\n * @returns - True if the url is valid, false otherwise.\n */\n validate?: (url: string) => boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string; target?: string | null }) => ReturnType\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string; target?: string | null }) => ReturnType\n /**\n * Unset a link mark\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\nexport const Link = Mark.create<LinkOptions>({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n onCreate() {\n this.options.protocols.forEach(protocol => {\n if (typeof protocol === 'string') {\n registerCustomProtocol(protocol)\n return\n }\n registerCustomProtocol(protocol.scheme, protocol.optionalSlashes)\n })\n },\n\n onDestroy() {\n reset()\n },\n\n inclusive() {\n return this.options.autolink\n },\n\n addOptions() {\n return {\n openOnClick: true,\n linkOnPaste: true,\n autolink: true,\n protocols: [],\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n validate: undefined,\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n class: {\n default: this.options.HTMLAttributes.class,\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'a[href]:not([href *= \"javascript:\" i])' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setLink:\n attributes => ({ chain }) => {\n return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run()\n },\n\n toggleLink:\n attributes => ({ chain }) => {\n return chain()\n .toggleMark(this.name, attributes, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n\n unsetLink:\n () => ({ chain }) => {\n return chain()\n .unsetMark(this.name, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n }\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = []\n\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n validate: this.options.validate,\n }),\n )\n }\n\n if (this.options.openOnClick) {\n plugins.push(\n clickHandler({\n type: this.type,\n }),\n )\n }\n\n plugins.push(\n pasteHandler({\n editor: this.editor,\n type: this.type,\n linkOnPaste: this.options.linkOnPaste,\n }),\n )\n\n return plugins\n },\n})\n"],"names":["Plugin","PluginKey","combineTransactionSteps","getChangedRanges","getMarksBetween","test","findChildrenInRange","find","getAttributes","Mark","registerCustomProtocol","reset","mergeAttributes"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.umd.js","sources":["../src/helpers/autolink.ts","../src/helpers/clickHandler.ts","../src/helpers/pasteHandler.ts","../src/link.ts"],"sourcesContent":["import {\n combineTransactionSteps,\n findChildrenInRange,\n getChangedRanges,\n getMarksBetween,\n NodeWithPos,\n} from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype AutolinkOptions = {\n type: MarkType\n validate?: (url: string) => boolean\n}\n\nexport function autolink(options: AutolinkOptions): Plugin {\n return new Plugin({\n key: new PluginKey('autolink'),\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges = transactions.some(transaction => transaction.docChanged) && !oldState.doc.eq(newState.doc)\n const preventAutolink = transactions.some(transaction => transaction.getMeta('preventAutolink'))\n\n if (!docChanges || preventAutolink) {\n return\n }\n\n const { tr } = newState\n const transform = combineTransactionSteps(oldState.doc, [...transactions])\n const changes = getChangedRanges(transform)\n\n changes.forEach(({ newRange }) => {\n // Now let’s see if we can add new links.\n const nodesInChangedRanges = findChildrenInRange(\n newState.doc,\n newRange,\n node => node.isTextblock,\n )\n\n let textBlock: NodeWithPos | undefined\n let textBeforeWhitespace: string | undefined\n\n if (nodesInChangedRanges.length > 1) {\n // Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n textBlock.pos + textBlock.node.nodeSize,\n undefined,\n ' ',\n )\n } else if (\n nodesInChangedRanges.length\n // We want to make sure to include the block seperator argument to treat hard breaks like spaces.\n && newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')\n ) {\n textBlock = nodesInChangedRanges[0]\n textBeforeWhitespace = newState.doc.textBetween(\n textBlock.pos,\n newRange.to,\n undefined,\n ' ',\n )\n }\n\n if (textBlock && textBeforeWhitespace) {\n const wordsBeforeWhitespace = textBeforeWhitespace.split(' ').filter(s => s !== '')\n\n if (wordsBeforeWhitespace.length <= 0) {\n return false\n }\n\n const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]\n const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace)\n\n if (!lastWordBeforeSpace) {\n return false\n }\n\n find(lastWordBeforeSpace)\n .filter(link => link.isLink)\n // Calculate link position.\n .map(link => ({\n ...link,\n from: lastWordAndBlockOffset + link.start + 1,\n to: lastWordAndBlockOffset + link.end + 1,\n }))\n // ignore link inside code mark\n .filter(link => {\n return !newState.doc.rangeHasMark(\n link.from,\n link.to,\n newState.schema.marks.code,\n )\n })\n // validate link\n .filter(link => {\n if (options.validate) {\n return options.validate(link.value)\n }\n return true\n })\n // Add link mark.\n .forEach(link => {\n if (getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {\n return\n }\n\n tr.addMark(\n link.from,\n link.to,\n options.type.create({\n href: link.href,\n }),\n )\n })\n }\n })\n\n if (!tr.steps.length) {\n return\n }\n\n return tr\n },\n })\n}\n","import { getAttributes } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\ntype ClickHandlerOptions = {\n type: MarkType\n}\n\nexport function clickHandler(options: ClickHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handleClickLink'),\n props: {\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return false\n }\n\n const attrs = getAttributes(view.state, options.type.name)\n const link = (event.target as HTMLLinkElement)\n\n const href = link?.href ?? attrs.href\n const target = link?.target ?? attrs.target\n\n if (link && href) {\n if (view.editable) {\n window.open(href, target)\n }\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Editor } from '@tiptap/core'\nimport { MarkType } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { find } from 'linkifyjs'\n\ntype PasteHandlerOptions = {\n editor: Editor\n type: MarkType\n linkOnPaste?: boolean\n}\n\nexport function pasteHandler(options: PasteHandlerOptions): Plugin {\n return new Plugin({\n key: new PluginKey('handlePasteLink'),\n props: {\n handlePaste: (view, event, slice) => {\n const { state } = view\n const { selection } = state\n\n // Do not proceed if in code block.\n if (state.doc.resolve(selection.from).parent.type.spec.code) {\n return false\n }\n\n let textContent = ''\n\n slice.content.forEach(node => {\n textContent += node.textContent\n })\n\n let isAlreadyLink = false\n\n slice.content.descendants(node => {\n if (node.marks.some(mark => mark.type.name === options.type.name)) {\n isAlreadyLink = true\n }\n })\n\n if (isAlreadyLink) {\n return\n }\n\n const link = find(textContent).find(item => item.isLink && item.value === textContent)\n\n if (!selection.empty && options.linkOnPaste) {\n const pastedLink = link?.href || null\n\n if (pastedLink) {\n options.editor.commands.setMark(options.type, { href: pastedLink })\n\n return true\n }\n }\n\n const firstChildIsText = slice.content.firstChild?.type.name === 'text'\n const firstChildContainsLinkMark = slice.content.firstChild?.marks.some(mark => mark.type.name === options.type.name)\n\n if ((firstChildIsText && firstChildContainsLinkMark) || !options.linkOnPaste) {\n return false\n }\n\n if (link && selection.empty) {\n options.editor.commands.insertContent(`<a href=\"${link.href}\">${link.href}</a>`)\n\n return true\n }\n\n const { tr } = state\n let deleteOnly = false\n\n if (!selection.empty) {\n deleteOnly = true\n\n tr.delete(selection.from, selection.to)\n }\n\n let currentPos = selection.from\n let fragmentLinks = []\n\n slice.content.forEach(node => {\n fragmentLinks = find(node.textContent)\n\n tr.insert(currentPos - 1, node)\n\n if (fragmentLinks.length > 0) {\n deleteOnly = false\n\n fragmentLinks.forEach(fragmentLink => {\n const linkStart = currentPos + fragmentLink.start\n const linkEnd = currentPos + fragmentLink.end\n const hasMark = tr.doc.rangeHasMark(linkStart, linkEnd, options.type)\n\n if (!hasMark) {\n tr.addMark(linkStart, linkEnd, options.type.create({ href: fragmentLink.href }))\n }\n })\n\n }\n currentPos += node.nodeSize\n })\n\n const hasFragmentLinks = fragmentLinks.length > 0\n\n if (tr.docChanged && !deleteOnly && hasFragmentLinks) {\n options.editor.view.dispatch(tr)\n\n return true\n }\n\n return false\n },\n },\n })\n}\n","import { Mark, mergeAttributes } from '@tiptap/core'\nimport { Plugin } from '@tiptap/pm/state'\nimport { registerCustomProtocol, reset } from 'linkifyjs'\n\nimport { autolink } from './helpers/autolink.js'\nimport { clickHandler } from './helpers/clickHandler.js'\nimport { pasteHandler } from './helpers/pasteHandler.js'\n\nexport interface LinkProtocolOptions {\n scheme: string;\n optionalSlashes?: boolean;\n}\n\nexport interface LinkOptions {\n /**\n * If enabled, it adds links as you type.\n */\n autolink: boolean\n /**\n * An array of custom protocols to be registered with linkifyjs.\n */\n protocols: Array<LinkProtocolOptions | string>\n /**\n * If enabled, links will be opened on click.\n */\n openOnClick: boolean\n /**\n * Adds a link to the current selection if the pasted content only contains an url.\n */\n linkOnPaste: boolean\n /**\n * A list of HTML attributes to be rendered.\n */\n HTMLAttributes: Record<string, any>\n /**\n * A validation function that modifies link verification for the auto linker.\n * @param url - The url to be validated.\n * @returns - True if the url is valid, false otherwise.\n */\n validate?: (url: string) => boolean\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string; target?: string | null }) => ReturnType\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string; target?: string | null }) => ReturnType\n /**\n * Unset a link mark\n */\n unsetLink: () => ReturnType\n }\n }\n}\n\nexport const Link = Mark.create<LinkOptions>({\n name: 'link',\n\n priority: 1000,\n\n keepOnSplit: false,\n\n onCreate() {\n this.options.protocols.forEach(protocol => {\n if (typeof protocol === 'string') {\n registerCustomProtocol(protocol)\n return\n }\n registerCustomProtocol(protocol.scheme, protocol.optionalSlashes)\n })\n },\n\n onDestroy() {\n reset()\n },\n\n inclusive() {\n return this.options.autolink\n },\n\n addOptions() {\n return {\n openOnClick: true,\n linkOnPaste: true,\n autolink: true,\n protocols: [],\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n class: null,\n },\n validate: undefined,\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n rel: {\n default: this.options.HTMLAttributes.rel,\n },\n class: {\n default: this.options.HTMLAttributes.class,\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'a[href]:not([href *= \"javascript:\" i])' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setLink:\n attributes => ({ chain }) => {\n return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run()\n },\n\n toggleLink:\n attributes => ({ chain }) => {\n return chain()\n .toggleMark(this.name, attributes, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n\n unsetLink:\n () => ({ chain }) => {\n return chain()\n .unsetMark(this.name, { extendEmptyMarkRange: true })\n .setMeta('preventAutolink', true)\n .run()\n },\n }\n },\n\n addProseMirrorPlugins() {\n const plugins: Plugin[] = []\n\n if (this.options.autolink) {\n plugins.push(\n autolink({\n type: this.type,\n validate: this.options.validate,\n }),\n )\n }\n\n if (this.options.openOnClick) {\n plugins.push(\n clickHandler({\n type: this.type,\n }),\n )\n }\n\n plugins.push(\n pasteHandler({\n editor: this.editor,\n type: this.type,\n linkOnPaste: this.options.linkOnPaste,\n }),\n )\n\n return plugins\n },\n})\n"],"names":["Plugin","PluginKey","combineTransactionSteps","getChangedRanges","findChildrenInRange","find","getMarksBetween","getAttributes","Mark","registerCustomProtocol","reset","mergeAttributes"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { Link } from './link';
|
|
2
|
-
export * from './link';
|
|
1
|
+
import { Link } from './link.js';
|
|
2
|
+
export * from './link.js';
|
|
3
3
|
export default Link;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiptap/extension-link",
|
|
3
3
|
"description": "link extension for tiptap",
|
|
4
|
-
"version": "2.1.0
|
|
4
|
+
"version": "2.1.0",
|
|
5
5
|
"homepage": "https://tiptap.dev",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"tiptap",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"linkifyjs": "^4.1.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@tiptap/core": "^2.1.0
|
|
36
|
-
"@tiptap/pm": "^2.1.0
|
|
35
|
+
"@tiptap/core": "^2.1.0",
|
|
36
|
+
"@tiptap/pm": "^2.1.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@tiptap/core": "^2.0.0",
|
package/src/helpers/autolink.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from '@tiptap/core'
|
|
8
8
|
import { MarkType } from '@tiptap/pm/model'
|
|
9
9
|
import { Plugin, PluginKey } from '@tiptap/pm/state'
|
|
10
|
-
import { find
|
|
10
|
+
import { find } from 'linkifyjs'
|
|
11
11
|
|
|
12
12
|
type AutolinkOptions = {
|
|
13
13
|
type: MarkType
|
|
@@ -27,42 +27,9 @@ export function autolink(options: AutolinkOptions): Plugin {
|
|
|
27
27
|
|
|
28
28
|
const { tr } = newState
|
|
29
29
|
const transform = combineTransactionSteps(oldState.doc, [...transactions])
|
|
30
|
-
const { mapping } = transform
|
|
31
30
|
const changes = getChangedRanges(transform)
|
|
32
|
-
let needsAutolink = true
|
|
33
|
-
|
|
34
|
-
changes.forEach(({ oldRange, newRange }) => {
|
|
35
|
-
// At first we check if we have to remove links.
|
|
36
|
-
getMarksBetween(oldRange.from, oldRange.to, oldState.doc)
|
|
37
|
-
.filter(item => item.mark.type === options.type)
|
|
38
|
-
.forEach(oldMark => {
|
|
39
|
-
const newFrom = mapping.map(oldMark.from)
|
|
40
|
-
const newTo = mapping.map(oldMark.to)
|
|
41
|
-
const newMarks = getMarksBetween(newFrom, newTo, newState.doc).filter(
|
|
42
|
-
item => item.mark.type === options.type,
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
if (!newMarks.length) {
|
|
46
|
-
return
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const newMark = newMarks[0]
|
|
50
|
-
const oldLinkText = oldState.doc.textBetween(oldMark.from, oldMark.to, undefined, ' ')
|
|
51
|
-
const newLinkText = newState.doc.textBetween(newMark.from, newMark.to, undefined, ' ')
|
|
52
|
-
const wasLink = test(oldLinkText)
|
|
53
|
-
const isLink = test(newLinkText)
|
|
54
|
-
|
|
55
|
-
if (wasLink) {
|
|
56
|
-
needsAutolink = false
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Remove only the link, if it was a link before too.
|
|
60
|
-
// Because we don’t want to remove links that were set manually.
|
|
61
|
-
if (wasLink && !isLink) {
|
|
62
|
-
tr.removeMark(needsAutolink ? newMark.from : newMark.to - 1, newMark.to, options.type)
|
|
63
|
-
}
|
|
64
|
-
})
|
|
65
31
|
|
|
32
|
+
changes.forEach(({ newRange }) => {
|
|
66
33
|
// Now let’s see if we can add new links.
|
|
67
34
|
const nodesInChangedRanges = findChildrenInRange(
|
|
68
35
|
newState.doc,
|
|
@@ -112,18 +79,27 @@ export function autolink(options: AutolinkOptions): Plugin {
|
|
|
112
79
|
|
|
113
80
|
find(lastWordBeforeSpace)
|
|
114
81
|
.filter(link => link.isLink)
|
|
115
|
-
.filter(link => {
|
|
116
|
-
if (options.validate) {
|
|
117
|
-
return options.validate(link.value)
|
|
118
|
-
}
|
|
119
|
-
return true
|
|
120
|
-
})
|
|
121
82
|
// Calculate link position.
|
|
122
83
|
.map(link => ({
|
|
123
84
|
...link,
|
|
124
85
|
from: lastWordAndBlockOffset + link.start + 1,
|
|
125
86
|
to: lastWordAndBlockOffset + link.end + 1,
|
|
126
87
|
}))
|
|
88
|
+
// ignore link inside code mark
|
|
89
|
+
.filter(link => {
|
|
90
|
+
return !newState.doc.rangeHasMark(
|
|
91
|
+
link.from,
|
|
92
|
+
link.to,
|
|
93
|
+
newState.schema.marks.code,
|
|
94
|
+
)
|
|
95
|
+
})
|
|
96
|
+
// validate link
|
|
97
|
+
.filter(link => {
|
|
98
|
+
if (options.validate) {
|
|
99
|
+
return options.validate(link.value)
|
|
100
|
+
}
|
|
101
|
+
return true
|
|
102
|
+
})
|
|
127
103
|
// Add link mark.
|
|
128
104
|
.forEach(link => {
|
|
129
105
|
if (getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {
|
|
@@ -16,13 +16,15 @@ export function clickHandler(options: ClickHandlerOptions): Plugin {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
const attrs = getAttributes(view.state, options.type.name)
|
|
19
|
-
const link = (event.target as
|
|
19
|
+
const link = (event.target as HTMLLinkElement)
|
|
20
20
|
|
|
21
21
|
const href = link?.href ?? attrs.href
|
|
22
22
|
const target = link?.target ?? attrs.target
|
|
23
23
|
|
|
24
24
|
if (link && href) {
|
|
25
|
-
|
|
25
|
+
if (view.editable) {
|
|
26
|
+
window.open(href, target)
|
|
27
|
+
}
|
|
26
28
|
|
|
27
29
|
return true
|
|
28
30
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Editor } from '@tiptap/core'
|
|
2
|
-
import {
|
|
2
|
+
import { MarkType } from '@tiptap/pm/model'
|
|
3
3
|
import { Plugin, PluginKey } from '@tiptap/pm/state'
|
|
4
4
|
import { find } from 'linkifyjs'
|
|
5
5
|
|
|
@@ -22,24 +22,28 @@ export function pasteHandler(options: PasteHandlerOptions): Plugin {
|
|
|
22
22
|
return false
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
const pastedLinkMarks: Mark[] = []
|
|
26
25
|
let textContent = ''
|
|
27
26
|
|
|
28
27
|
slice.content.forEach(node => {
|
|
29
28
|
textContent += node.textContent
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
let isAlreadyLink = false
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
})
|
|
33
|
+
slice.content.descendants(node => {
|
|
34
|
+
if (node.marks.some(mark => mark.type.name === options.type.name)) {
|
|
35
|
+
isAlreadyLink = true
|
|
36
|
+
}
|
|
36
37
|
})
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
if (isAlreadyLink) {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
39
43
|
const link = find(textContent).find(item => item.isLink && item.value === textContent)
|
|
40
44
|
|
|
41
45
|
if (!selection.empty && options.linkOnPaste) {
|
|
42
|
-
const pastedLink =
|
|
46
|
+
const pastedLink = link?.href || null
|
|
43
47
|
|
|
44
48
|
if (pastedLink) {
|
|
45
49
|
options.editor.commands.setMark(options.type, { href: pastedLink })
|
|
@@ -51,7 +55,7 @@ export function pasteHandler(options: PasteHandlerOptions): Plugin {
|
|
|
51
55
|
const firstChildIsText = slice.content.firstChild?.type.name === 'text'
|
|
52
56
|
const firstChildContainsLinkMark = slice.content.firstChild?.marks.some(mark => mark.type.name === options.type.name)
|
|
53
57
|
|
|
54
|
-
if (firstChildIsText && firstChildContainsLinkMark) {
|
|
58
|
+
if ((firstChildIsText && firstChildContainsLinkMark) || !options.linkOnPaste) {
|
|
55
59
|
return false
|
|
56
60
|
}
|
|
57
61
|
|
package/src/index.ts
CHANGED
package/src/link.ts
CHANGED
|
@@ -2,9 +2,9 @@ import { Mark, mergeAttributes } from '@tiptap/core'
|
|
|
2
2
|
import { Plugin } from '@tiptap/pm/state'
|
|
3
3
|
import { registerCustomProtocol, reset } from 'linkifyjs'
|
|
4
4
|
|
|
5
|
-
import { autolink } from './helpers/autolink'
|
|
6
|
-
import { clickHandler } from './helpers/clickHandler'
|
|
7
|
-
import { pasteHandler } from './helpers/pasteHandler'
|
|
5
|
+
import { autolink } from './helpers/autolink.js'
|
|
6
|
+
import { clickHandler } from './helpers/clickHandler.js'
|
|
7
|
+
import { pasteHandler } from './helpers/pasteHandler.js'
|
|
8
8
|
|
|
9
9
|
export interface LinkProtocolOptions {
|
|
10
10
|
scheme: string;
|
|
@@ -107,6 +107,9 @@ export const Link = Mark.create<LinkOptions>({
|
|
|
107
107
|
target: {
|
|
108
108
|
default: this.options.HTMLAttributes.target,
|
|
109
109
|
},
|
|
110
|
+
rel: {
|
|
111
|
+
default: this.options.HTMLAttributes.rel,
|
|
112
|
+
},
|
|
110
113
|
class: {
|
|
111
114
|
default: this.options.HTMLAttributes.class,
|
|
112
115
|
},
|