@tiptap/extension-link 2.1.0-rc.0 → 2.1.0-rc.10
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 +94 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +95 -58
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +94 -57
- package/dist/index.umd.js.map +1 -1
- package/dist/packages/extension-link/src/helpers/pasteHandler.d.ts +1 -0
- package/dist/packages/extension-link/src/index.d.ts +2 -2
- package/package.json +3 -3
- package/src/helpers/autolink.ts +32 -14
- package/src/helpers/clickHandler.ts +4 -2
- package/src/helpers/pasteHandler.ts +73 -7
- package/src/index.ts +2 -2
- package/src/link.ts +15 -38
package/dist/index.cjs
CHANGED
|
@@ -19,8 +19,9 @@ function autolink(options) {
|
|
|
19
19
|
const transform = core.combineTransactionSteps(oldState.doc, [...transactions]);
|
|
20
20
|
const { mapping } = transform;
|
|
21
21
|
const changes = core.getChangedRanges(transform);
|
|
22
|
+
let needsAutolink = true;
|
|
22
23
|
changes.forEach(({ oldRange, newRange }) => {
|
|
23
|
-
//
|
|
24
|
+
// At first we check if we have to remove links.
|
|
24
25
|
core.getMarksBetween(oldRange.from, oldRange.to, oldState.doc)
|
|
25
26
|
.filter(item => item.mark.type === options.type)
|
|
26
27
|
.forEach(oldMark => {
|
|
@@ -35,23 +36,26 @@ function autolink(options) {
|
|
|
35
36
|
const newLinkText = newState.doc.textBetween(newMark.from, newMark.to, undefined, ' ');
|
|
36
37
|
const wasLink = linkifyjs.test(oldLinkText);
|
|
37
38
|
const isLink = linkifyjs.test(newLinkText);
|
|
38
|
-
|
|
39
|
-
|
|
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.
|
|
40
44
|
if (wasLink && !isLink) {
|
|
41
|
-
tr.removeMark(newMark.from, newMark.to, options.type);
|
|
45
|
+
tr.removeMark(needsAutolink ? newMark.from : newMark.to - 1, newMark.to, options.type);
|
|
42
46
|
}
|
|
43
47
|
});
|
|
44
|
-
//
|
|
48
|
+
// Now let’s see if we can add new links.
|
|
45
49
|
const nodesInChangedRanges = core.findChildrenInRange(newState.doc, newRange, node => node.isTextblock);
|
|
46
50
|
let textBlock;
|
|
47
51
|
let textBeforeWhitespace;
|
|
48
52
|
if (nodesInChangedRanges.length > 1) {
|
|
49
|
-
// Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter)
|
|
53
|
+
// Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).
|
|
50
54
|
textBlock = nodesInChangedRanges[0];
|
|
51
55
|
textBeforeWhitespace = newState.doc.textBetween(textBlock.pos, textBlock.pos + textBlock.node.nodeSize, undefined, ' ');
|
|
52
56
|
}
|
|
53
57
|
else if (nodesInChangedRanges.length
|
|
54
|
-
// We want to make sure to include the block seperator argument to treat hard breaks like spaces
|
|
58
|
+
// We want to make sure to include the block seperator argument to treat hard breaks like spaces.
|
|
55
59
|
&& newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')) {
|
|
56
60
|
textBlock = nodesInChangedRanges[0];
|
|
57
61
|
textBeforeWhitespace = newState.doc.textBetween(textBlock.pos, newRange.to, undefined, ' ');
|
|
@@ -68,20 +72,28 @@ function autolink(options) {
|
|
|
68
72
|
}
|
|
69
73
|
linkifyjs.find(lastWordBeforeSpace)
|
|
70
74
|
.filter(link => link.isLink)
|
|
75
|
+
// Calculate link position.
|
|
76
|
+
.map(link => ({
|
|
77
|
+
...link,
|
|
78
|
+
from: lastWordAndBlockOffset + link.start + 1,
|
|
79
|
+
to: lastWordAndBlockOffset + link.end + 1,
|
|
80
|
+
}))
|
|
81
|
+
// ignore link inside code mark
|
|
82
|
+
.filter(link => {
|
|
83
|
+
return !newState.doc.rangeHasMark(link.from, link.to, newState.schema.marks.code);
|
|
84
|
+
})
|
|
85
|
+
// validate link
|
|
71
86
|
.filter(link => {
|
|
72
87
|
if (options.validate) {
|
|
73
88
|
return options.validate(link.value);
|
|
74
89
|
}
|
|
75
90
|
return true;
|
|
76
91
|
})
|
|
77
|
-
//
|
|
78
|
-
.map(link => ({
|
|
79
|
-
...link,
|
|
80
|
-
from: lastWordAndBlockOffset + link.start + 1,
|
|
81
|
-
to: lastWordAndBlockOffset + link.end + 1,
|
|
82
|
-
}))
|
|
83
|
-
// add link mark
|
|
92
|
+
// Add link mark.
|
|
84
93
|
.forEach(link => {
|
|
94
|
+
if (core.getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
85
97
|
tr.addMark(link.from, link.to, options.type.create({
|
|
86
98
|
href: link.href,
|
|
87
99
|
}));
|
|
@@ -101,16 +113,18 @@ function clickHandler(options) {
|
|
|
101
113
|
key: new state.PluginKey('handleClickLink'),
|
|
102
114
|
props: {
|
|
103
115
|
handleClick: (view, pos, event) => {
|
|
104
|
-
var _a, _b
|
|
116
|
+
var _a, _b;
|
|
105
117
|
if (event.button !== 0) {
|
|
106
118
|
return false;
|
|
107
119
|
}
|
|
108
120
|
const attrs = core.getAttributes(view.state, options.type.name);
|
|
109
|
-
const link =
|
|
110
|
-
const href = (
|
|
111
|
-
const target = (
|
|
121
|
+
const link = event.target;
|
|
122
|
+
const href = (_a = link === null || link === void 0 ? void 0 : link.href) !== null && _a !== void 0 ? _a : attrs.href;
|
|
123
|
+
const target = (_b = link === null || link === void 0 ? void 0 : link.target) !== null && _b !== void 0 ? _b : attrs.target;
|
|
112
124
|
if (link && href) {
|
|
113
|
-
|
|
125
|
+
if (view.editable) {
|
|
126
|
+
window.open(href, target);
|
|
127
|
+
}
|
|
114
128
|
return true;
|
|
115
129
|
}
|
|
116
130
|
return false;
|
|
@@ -124,24 +138,71 @@ function pasteHandler(options) {
|
|
|
124
138
|
key: new state.PluginKey('handlePasteLink'),
|
|
125
139
|
props: {
|
|
126
140
|
handlePaste: (view, event, slice) => {
|
|
141
|
+
var _a, _b;
|
|
127
142
|
const { state } = view;
|
|
128
143
|
const { selection } = state;
|
|
129
|
-
|
|
130
|
-
if (
|
|
144
|
+
// Do not proceed if in code block.
|
|
145
|
+
if (state.doc.resolve(selection.from).parent.type.spec.code) {
|
|
131
146
|
return false;
|
|
132
147
|
}
|
|
148
|
+
const pastedLinkMarks = [];
|
|
133
149
|
let textContent = '';
|
|
134
150
|
slice.content.forEach(node => {
|
|
135
151
|
textContent += node.textContent;
|
|
152
|
+
node.marks.forEach(mark => {
|
|
153
|
+
if (mark.type.name === options.type.name) {
|
|
154
|
+
pastedLinkMarks.push(mark);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
136
157
|
});
|
|
158
|
+
const hasPastedLink = pastedLinkMarks.length > 0;
|
|
137
159
|
const link = linkifyjs.find(textContent).find(item => item.isLink && item.value === textContent);
|
|
138
|
-
if (!
|
|
160
|
+
if (!selection.empty && options.linkOnPaste) {
|
|
161
|
+
const pastedLink = hasPastedLink ? pastedLinkMarks[0].attrs.href : (link === null || link === void 0 ? void 0 : link.href) || null;
|
|
162
|
+
if (pastedLink) {
|
|
163
|
+
options.editor.commands.setMark(options.type, { href: pastedLink });
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const firstChildIsText = ((_a = slice.content.firstChild) === null || _a === void 0 ? void 0 : _a.type.name) === 'text';
|
|
168
|
+
const firstChildContainsLinkMark = (_b = slice.content.firstChild) === null || _b === void 0 ? void 0 : _b.marks.some(mark => mark.type.name === options.type.name);
|
|
169
|
+
if (firstChildIsText && firstChildContainsLinkMark) {
|
|
139
170
|
return false;
|
|
140
171
|
}
|
|
141
|
-
|
|
142
|
-
href
|
|
172
|
+
if (link && selection.empty) {
|
|
173
|
+
options.editor.commands.insertContent(`<a href="${link.href}">${link.href}</a>`);
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
const { tr } = state;
|
|
177
|
+
let deleteOnly = false;
|
|
178
|
+
if (!selection.empty) {
|
|
179
|
+
deleteOnly = true;
|
|
180
|
+
tr.delete(selection.from, selection.to);
|
|
181
|
+
}
|
|
182
|
+
let currentPos = selection.from;
|
|
183
|
+
let fragmentLinks = [];
|
|
184
|
+
slice.content.forEach(node => {
|
|
185
|
+
fragmentLinks = linkifyjs.find(node.textContent);
|
|
186
|
+
tr.insert(currentPos - 1, node);
|
|
187
|
+
if (fragmentLinks.length > 0) {
|
|
188
|
+
deleteOnly = false;
|
|
189
|
+
fragmentLinks.forEach(fragmentLink => {
|
|
190
|
+
const linkStart = currentPos + fragmentLink.start;
|
|
191
|
+
const linkEnd = currentPos + fragmentLink.end;
|
|
192
|
+
const hasMark = tr.doc.rangeHasMark(linkStart, linkEnd, options.type);
|
|
193
|
+
if (!hasMark) {
|
|
194
|
+
tr.addMark(linkStart, linkEnd, options.type.create({ href: fragmentLink.href }));
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
currentPos += node.nodeSize;
|
|
143
199
|
});
|
|
144
|
-
|
|
200
|
+
const hasFragmentLinks = fragmentLinks.length > 0;
|
|
201
|
+
if (tr.docChanged && !deleteOnly && hasFragmentLinks) {
|
|
202
|
+
options.editor.view.dispatch(tr);
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
return false;
|
|
145
206
|
},
|
|
146
207
|
},
|
|
147
208
|
});
|
|
@@ -188,6 +249,9 @@ const Link = core.Mark.create({
|
|
|
188
249
|
target: {
|
|
189
250
|
default: this.options.HTMLAttributes.target,
|
|
190
251
|
},
|
|
252
|
+
rel: {
|
|
253
|
+
default: this.options.HTMLAttributes.rel,
|
|
254
|
+
},
|
|
191
255
|
class: {
|
|
192
256
|
default: this.options.HTMLAttributes.class,
|
|
193
257
|
},
|
|
@@ -218,32 +282,6 @@ const Link = core.Mark.create({
|
|
|
218
282
|
},
|
|
219
283
|
};
|
|
220
284
|
},
|
|
221
|
-
addPasteRules() {
|
|
222
|
-
return [
|
|
223
|
-
core.markPasteRule({
|
|
224
|
-
find: text => linkifyjs.find(text)
|
|
225
|
-
.filter(link => {
|
|
226
|
-
if (this.options.validate) {
|
|
227
|
-
return this.options.validate(link.value);
|
|
228
|
-
}
|
|
229
|
-
return true;
|
|
230
|
-
})
|
|
231
|
-
.filter(link => link.isLink)
|
|
232
|
-
.map(link => ({
|
|
233
|
-
text: link.value,
|
|
234
|
-
index: link.start,
|
|
235
|
-
data: link,
|
|
236
|
-
})),
|
|
237
|
-
type: this.type,
|
|
238
|
-
getAttributes: match => {
|
|
239
|
-
var _a;
|
|
240
|
-
return ({
|
|
241
|
-
href: (_a = match.data) === null || _a === void 0 ? void 0 : _a.href,
|
|
242
|
-
});
|
|
243
|
-
},
|
|
244
|
-
}),
|
|
245
|
-
];
|
|
246
|
-
},
|
|
247
285
|
addProseMirrorPlugins() {
|
|
248
286
|
const plugins = [];
|
|
249
287
|
if (this.options.autolink) {
|
|
@@ -257,12 +295,11 @@ const Link = core.Mark.create({
|
|
|
257
295
|
type: this.type,
|
|
258
296
|
}));
|
|
259
297
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
}
|
|
298
|
+
plugins.push(pasteHandler({
|
|
299
|
+
editor: this.editor,
|
|
300
|
+
type: this.type,
|
|
301
|
+
linkOnPaste: this.options.linkOnPaste,
|
|
302
|
+
}));
|
|
266
303
|
return plugins;
|
|
267
304
|
},
|
|
268
305
|
});
|
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\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 // 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(newMark.from, 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 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 { 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}\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 const { empty } = selection\n\n if (empty) {\n return false\n }\n\n let textContent = ''\n\n slice.content.forEach(node => {\n textContent += node.textContent\n })\n\n const link = find(textContent).find(item => item.isLink && item.value === textContent)\n\n if (!textContent || !link) {\n return false\n }\n\n options.editor.commands.setMark(options.type, {\n href: link.href,\n })\n\n return true\n },\n },\n })\n}\n","import { Mark, markPasteRule, mergeAttributes } from '@tiptap/core'\nimport { Plugin } from '@tiptap/pm/state'\nimport { find, 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 addPasteRules() {\n return [\n markPasteRule({\n find: text => find(text)\n .filter(link => {\n if (this.options.validate) {\n return this.options.validate(link.value)\n }\n\n return true\n })\n .filter(link => link.isLink)\n .map(link => ({\n text: link.value,\n index: link.start,\n data: link,\n })),\n type: this.type,\n getAttributes: match => ({\n href: match.data?.href,\n }),\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 if (this.options.linkOnPaste) {\n plugins.push(\n pasteHandler({\n editor: this.editor,\n type: this.type,\n }),\n )\n }\n\n return plugins\n },\n})\n"],"names":["Plugin","PluginKey","combineTransactionSteps","getChangedRanges","getMarksBetween","test","findChildrenInRange","find","getAttributes","Mark","registerCustomProtocol","reset","mergeAttributes","markPasteRule"],"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, 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 // 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 { 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.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","getMarksBetween","test","findChildrenInRange","find","getAttributes","Mark","registerCustomProtocol","reset","mergeAttributes"],"mappings":";;;;;;;;AAgBM,SAAU,QAAQ,CAAC,OAAwB,EAAA;IAC/C,OAAO,IAAIA,YAAM,CAAC;AAChB,QAAA,GAAG,EAAE,IAAIC,eAAS,CAAC,UAAU,CAAC;QAC9B,iBAAiB,EAAE,CAAC,YAAY,EAAE,QAAQ,EAAE,QAAQ,KAAI;YACtD,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;AAC7G,YAAA,MAAM,eAAe,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAA;AAEhG,YAAA,IAAI,CAAC,UAAU,IAAI,eAAe,EAAE;gBAClC,OAAM;AACP,aAAA;AAED,YAAA,MAAM,EAAE,EAAE,EAAE,GAAG,QAAQ,CAAA;AACvB,YAAA,MAAM,SAAS,GAAGC,4BAAuB,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAA;AAC1E,YAAA,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,CAAA;AAC7B,YAAA,MAAM,OAAO,GAAGC,qBAAgB,CAAC,SAAS,CAAC,CAAA;YAC3C,IAAI,aAAa,GAAG,IAAI,CAAA;YAExB,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAI;;AAEzC,gBAAAC,oBAAe,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,GAAG,CAAC;AACtD,qBAAA,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC;qBAC/C,OAAO,CAAC,OAAO,IAAG;oBACjB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;oBACzC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AACrC,oBAAA,MAAM,QAAQ,GAAGA,oBAAe,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,CACnE,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CACxC,CAAA;AAED,oBAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;wBACpB,OAAM;AACP,qBAAA;AAED,oBAAA,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;oBAC3B,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,CAAA;oBACtF,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,CAAA;AACtF,oBAAA,MAAM,OAAO,GAAGC,cAAI,CAAC,WAAW,CAAC,CAAA;AACjC,oBAAA,MAAM,MAAM,GAAGA,cAAI,CAAC,WAAW,CAAC,CAAA;AAEhC,oBAAA,IAAI,OAAO,EAAE;wBACX,aAAa,GAAG,KAAK,CAAA;AACtB,qBAAA;;;AAID,oBAAA,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE;wBACtB,EAAE,CAAC,UAAU,CAAC,aAAa,GAAG,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;AACvF,qBAAA;AACH,iBAAC,CAAC,CAAA;;AAGJ,gBAAA,MAAM,oBAAoB,GAAGC,wBAAmB,CAC9C,QAAQ,CAAC,GAAG,EACZ,QAAQ,EACR,IAAI,IAAI,IAAI,CAAC,WAAW,CACzB,CAAA;AAED,gBAAA,IAAI,SAAkC,CAAA;AACtC,gBAAA,IAAI,oBAAwC,CAAA;AAE5C,gBAAA,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE;;AAEnC,oBAAA,SAAS,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAA;oBACnC,oBAAoB,GAAG,QAAQ,CAAC,GAAG,CAAC,WAAW,CAC7C,SAAS,CAAC,GAAG,EACb,SAAS,CAAC,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,QAAQ,EACvC,SAAS,EACT,GAAG,CACJ,CAAA;AACF,iBAAA;qBAAM,IACL,oBAAoB,CAAC,MAAM;;uBAExB,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAC/E;AACA,oBAAA,SAAS,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAA;AACnC,oBAAA,oBAAoB,GAAG,QAAQ,CAAC,GAAG,CAAC,WAAW,CAC7C,SAAS,CAAC,GAAG,EACb,QAAQ,CAAC,EAAE,EACX,SAAS,EACT,GAAG,CACJ,CAAA;AACF,iBAAA;gBAED,IAAI,SAAS,IAAI,oBAAoB,EAAE;AACrC,oBAAA,MAAM,qBAAqB,GAAG,oBAAoB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;AAEnF,oBAAA,IAAI,qBAAqB,CAAC,MAAM,IAAI,CAAC,EAAE;AACrC,wBAAA,OAAO,KAAK,CAAA;AACb,qBAAA;oBAED,MAAM,mBAAmB,GAAG,qBAAqB,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AACnF,oBAAA,MAAM,sBAAsB,GAAG,SAAS,CAAC,GAAG,GAAG,oBAAoB,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAA;oBAEpG,IAAI,CAAC,mBAAmB,EAAE;AACxB,wBAAA,OAAO,KAAK,CAAA;AACb,qBAAA;oBAEDC,cAAI,CAAC,mBAAmB,CAAC;yBACtB,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC;;AAE3B,yBAAA,GAAG,CAAC,IAAI,KAAK;AACZ,wBAAA,GAAG,IAAI;AACP,wBAAA,IAAI,EAAE,sBAAsB,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;AAC7C,wBAAA,EAAE,EAAE,sBAAsB,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;AAC1C,qBAAA,CAAC,CAAC;;yBAEF,MAAM,CAAC,IAAI,IAAG;wBACb,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAC/B,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,EAAE,EACP,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAC3B,CAAA;AACH,qBAAC,CAAC;;yBAED,MAAM,CAAC,IAAI,IAAG;wBACb,IAAI,OAAO,CAAC,QAAQ,EAAE;4BACpB,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACpC,yBAAA;AACD,wBAAA,OAAO,IAAI,CAAA;AACb,qBAAC,CAAC;;yBAED,OAAO,CAAC,IAAI,IAAG;AACd,wBAAA,IAAIH,oBAAe,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE;4BACnG,OAAM;AACP,yBAAA;AAED,wBAAA,EAAE,CAAC,OAAO,CACR,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,EAAE,EACP,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;4BAClB,IAAI,EAAE,IAAI,CAAC,IAAI;AAChB,yBAAA,CAAC,CACH,CAAA;AACH,qBAAC,CAAC,CAAA;AACL,iBAAA;AACH,aAAC,CAAC,CAAA;AAEF,YAAA,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE;gBACpB,OAAM;AACP,aAAA;AAED,YAAA,OAAO,EAAE,CAAA;SACV;AACF,KAAA,CAAC,CAAA;AACJ;;ACvJM,SAAU,YAAY,CAAC,OAA4B,EAAA;IACvD,OAAO,IAAIJ,YAAM,CAAC;AAChB,QAAA,GAAG,EAAE,IAAIC,eAAS,CAAC,iBAAiB,CAAC;AACrC,QAAA,KAAK,EAAE;YACL,WAAW,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,KAAI;;AAChC,gBAAA,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;AACtB,oBAAA,OAAO,KAAK,CAAA;AACb,iBAAA;AAED,gBAAA,MAAM,KAAK,GAAGO,kBAAa,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC1D,gBAAA,MAAM,IAAI,GAAI,KAAK,CAAC,MAA0B,CAAA;AAE9C,gBAAA,MAAM,IAAI,GAAG,CAAA,EAAA,GAAA,IAAI,aAAJ,IAAI,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAJ,IAAI,CAAE,IAAI,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAI,KAAK,CAAC,IAAI,CAAA;AACrC,gBAAA,MAAM,MAAM,GAAG,CAAA,EAAA,GAAA,IAAI,aAAJ,IAAI,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAJ,IAAI,CAAE,MAAM,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAI,KAAK,CAAC,MAAM,CAAA;gBAE3C,IAAI,IAAI,IAAI,IAAI,EAAE;oBAChB,IAAI,IAAI,CAAC,QAAQ,EAAE;AACjB,wBAAA,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;AAC1B,qBAAA;AAED,oBAAA,OAAO,IAAI,CAAA;AACZ,iBAAA;AAED,gBAAA,OAAO,KAAK,CAAA;aACb;AACF,SAAA;AACF,KAAA,CAAC,CAAA;AACJ;;ACxBM,SAAU,YAAY,CAAC,OAA4B,EAAA;IACvD,OAAO,IAAIR,YAAM,CAAC;AAChB,QAAA,GAAG,EAAE,IAAIC,eAAS,CAAC,iBAAiB,CAAC;AACrC,QAAA,KAAK,EAAE;YACL,WAAW,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,KAAI;;AAClC,gBAAA,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;AACtB,gBAAA,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAA;;AAG3B,gBAAA,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;AAC3D,oBAAA,OAAO,KAAK,CAAA;AACb,iBAAA;gBAED,MAAM,eAAe,GAAW,EAAE,CAAA;gBAClC,IAAI,WAAW,GAAG,EAAE,CAAA;AAEpB,gBAAA,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,IAAG;AAC3B,oBAAA,WAAW,IAAI,IAAI,CAAC,WAAW,CAAA;AAE/B,oBAAA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,IAAG;wBACxB,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE;AACxC,4BAAA,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC3B,yBAAA;AACH,qBAAC,CAAC,CAAA;AACJ,iBAAC,CAAC,CAAA;AAEF,gBAAA,MAAM,aAAa,GAAG,eAAe,CAAC,MAAM,GAAG,CAAC,CAAA;gBAChD,MAAM,IAAI,GAAGM,cAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,CAAC,CAAA;gBAEtF,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,OAAO,CAAC,WAAW,EAAE;oBAC3C,MAAM,UAAU,GAAG,aAAa,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,GAAG,CAAA,IAAI,KAAJ,IAAA,IAAA,IAAI,KAAJ,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,IAAI,CAAE,IAAI,KAAI,IAAI,CAAA;AAErF,oBAAA,IAAI,UAAU,EAAE;AACd,wBAAA,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAA;AAEnE,wBAAA,OAAO,IAAI,CAAA;AACZ,qBAAA;AACF,iBAAA;AAED,gBAAA,MAAM,gBAAgB,GAAG,CAAA,CAAA,EAAA,GAAA,KAAK,CAAC,OAAO,CAAC,UAAU,0CAAE,IAAI,CAAC,IAAI,MAAK,MAAM,CAAA;AACvE,gBAAA,MAAM,0BAA0B,GAAG,CAAA,EAAA,GAAA,KAAK,CAAC,OAAO,CAAC,UAAU,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBAErH,IAAI,gBAAgB,IAAI,0BAA0B,EAAE;AAClD,oBAAA,OAAO,KAAK,CAAA;AACb,iBAAA;AAED,gBAAA,IAAI,IAAI,IAAI,SAAS,CAAC,KAAK,EAAE;AAC3B,oBAAA,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAA,SAAA,EAAY,IAAI,CAAC,IAAI,CAAK,EAAA,EAAA,IAAI,CAAC,IAAI,CAAA,IAAA,CAAM,CAAC,CAAA;AAEhF,oBAAA,OAAO,IAAI,CAAA;AACZ,iBAAA;AAED,gBAAA,MAAM,EAAE,EAAE,EAAE,GAAG,KAAK,CAAA;gBACpB,IAAI,UAAU,GAAG,KAAK,CAAA;AAEtB,gBAAA,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE;oBACpB,UAAU,GAAG,IAAI,CAAA;oBAEjB,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC,CAAA;AACxC,iBAAA;AAED,gBAAA,IAAI,UAAU,GAAG,SAAS,CAAC,IAAI,CAAA;gBAC/B,IAAI,aAAa,GAAG,EAAE,CAAA;AAEtB,gBAAA,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,IAAG;AAC3B,oBAAA,aAAa,GAAGA,cAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;oBAEtC,EAAE,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,EAAE,IAAI,CAAC,CAAA;AAE/B,oBAAA,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;wBAC5B,UAAU,GAAG,KAAK,CAAA;AAElB,wBAAA,aAAa,CAAC,OAAO,CAAC,YAAY,IAAG;AACnC,4BAAA,MAAM,SAAS,GAAG,UAAU,GAAG,YAAY,CAAC,KAAK,CAAA;AACjD,4BAAA,MAAM,OAAO,GAAG,UAAU,GAAG,YAAY,CAAC,GAAG,CAAA;AAC7C,4BAAA,MAAM,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;4BAErE,IAAI,CAAC,OAAO,EAAE;gCACZ,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;AACjF,6BAAA;AACH,yBAAC,CAAC,CAAA;AAEH,qBAAA;AACD,oBAAA,UAAU,IAAI,IAAI,CAAC,QAAQ,CAAA;AAC7B,iBAAC,CAAC,CAAA;AAEF,gBAAA,MAAM,gBAAgB,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,CAAA;gBAEjD,IAAI,EAAE,CAAC,UAAU,IAAI,CAAC,UAAU,IAAI,gBAAgB,EAAE;oBACpD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;AAEhC,oBAAA,OAAO,IAAI,CAAA;AACZ,iBAAA;AAED,gBAAA,OAAO,KAAK,CAAA;aACb;AACF,SAAA;AACF,KAAA,CAAC,CAAA;AACJ;;AChDa,MAAA,IAAI,GAAGE,SAAI,CAAC,MAAM,CAAc;AAC3C,IAAA,IAAI,EAAE,MAAM;AAEZ,IAAA,QAAQ,EAAE,IAAI;AAEd,IAAA,WAAW,EAAE,KAAK;IAElB,QAAQ,GAAA;QACN,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,IAAG;AACxC,YAAA,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;gBAChCC,gCAAsB,CAAC,QAAQ,CAAC,CAAA;gBAChC,OAAM;AACP,aAAA;YACDA,gCAAsB,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAA;AACnE,SAAC,CAAC,CAAA;KACH;IAED,SAAS,GAAA;AACP,QAAAC,eAAK,EAAE,CAAA;KACR;IAED,SAAS,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAA;KAC7B;IAED,UAAU,GAAA;QACR,OAAO;AACL,YAAA,WAAW,EAAE,IAAI;AACjB,YAAA,WAAW,EAAE,IAAI;AACjB,YAAA,QAAQ,EAAE,IAAI;AACd,YAAA,SAAS,EAAE,EAAE;AACb,YAAA,cAAc,EAAE;AACd,gBAAA,MAAM,EAAE,QAAQ;AAChB,gBAAA,GAAG,EAAE,8BAA8B;AACnC,gBAAA,KAAK,EAAE,IAAI;AACZ,aAAA;AACD,YAAA,QAAQ,EAAE,SAAS;SACpB,CAAA;KACF;IAED,aAAa,GAAA;QACX,OAAO;AACL,YAAA,IAAI,EAAE;AACJ,gBAAA,OAAO,EAAE,IAAI;AACd,aAAA;AACD,YAAA,MAAM,EAAE;AACN,gBAAA,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM;AAC5C,aAAA;AACD,YAAA,GAAG,EAAE;AACH,gBAAA,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG;AACzC,aAAA;AACD,YAAA,KAAK,EAAE;AACL,gBAAA,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK;AAC3C,aAAA;SACF,CAAA;KACF;IAED,SAAS,GAAA;AACP,QAAA,OAAO,CAAC,EAAE,GAAG,EAAE,wCAAwC,EAAE,CAAC,CAAA;KAC3D;IAED,UAAU,CAAC,EAAE,cAAc,EAAE,EAAA;AAC3B,QAAA,OAAO,CAAC,GAAG,EAAEC,oBAAe,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC,CAAA;KAC9E;IAED,WAAW,GAAA;QACT,OAAO;YACL,OAAO,EACL,UAAU,IAAI,CAAC,EAAE,KAAK,EAAE,KAAI;gBAC1B,OAAO,KAAK,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,CAAA;aACrF;YAEH,UAAU,EACR,UAAU,IAAI,CAAC,EAAE,KAAK,EAAE,KAAI;AAC1B,gBAAA,OAAO,KAAK,EAAE;AACX,qBAAA,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;AACjE,qBAAA,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC;AAChC,qBAAA,GAAG,EAAE,CAAA;aACT;YAEH,SAAS,EACP,MAAM,CAAC,EAAE,KAAK,EAAE,KAAI;AAClB,gBAAA,OAAO,KAAK,EAAE;qBACX,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;AACpD,qBAAA,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC;AAChC,qBAAA,GAAG,EAAE,CAAA;aACT;SACJ,CAAA;KACF;IAED,qBAAqB,GAAA;QACnB,MAAM,OAAO,GAAa,EAAE,CAAA;AAE5B,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE;AACzB,YAAA,OAAO,CAAC,IAAI,CACV,QAAQ,CAAC;gBACP,IAAI,EAAE,IAAI,CAAC,IAAI;AACf,gBAAA,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;AAChC,aAAA,CAAC,CACH,CAAA;AACF,SAAA;AAED,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;AAC5B,YAAA,OAAO,CAAC,IAAI,CACV,YAAY,CAAC;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI;AAChB,aAAA,CAAC,CACH,CAAA;AACF,SAAA;AAED,QAAA,OAAO,CAAC,IAAI,CACV,YAAY,CAAC;YACX,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,IAAI,EAAE,IAAI,CAAC,IAAI;AACf,YAAA,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;AACtC,SAAA,CAAC,CACH,CAAA;AAED,QAAA,OAAO,OAAO,CAAA;KACf;AACF,CAAA;;;;;"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { combineTransactionSteps, getChangedRanges, getMarksBetween, findChildrenInRange, getAttributes, Mark, mergeAttributes
|
|
1
|
+
import { combineTransactionSteps, getChangedRanges, getMarksBetween, findChildrenInRange, getAttributes, Mark, mergeAttributes } from '@tiptap/core';
|
|
2
2
|
import { test, find, registerCustomProtocol, reset } from 'linkifyjs';
|
|
3
3
|
import { Plugin, PluginKey } from '@tiptap/pm/state';
|
|
4
4
|
|
|
@@ -15,8 +15,9 @@ function autolink(options) {
|
|
|
15
15
|
const transform = combineTransactionSteps(oldState.doc, [...transactions]);
|
|
16
16
|
const { mapping } = transform;
|
|
17
17
|
const changes = getChangedRanges(transform);
|
|
18
|
+
let needsAutolink = true;
|
|
18
19
|
changes.forEach(({ oldRange, newRange }) => {
|
|
19
|
-
//
|
|
20
|
+
// At first we check if we have to remove links.
|
|
20
21
|
getMarksBetween(oldRange.from, oldRange.to, oldState.doc)
|
|
21
22
|
.filter(item => item.mark.type === options.type)
|
|
22
23
|
.forEach(oldMark => {
|
|
@@ -31,23 +32,26 @@ function autolink(options) {
|
|
|
31
32
|
const newLinkText = newState.doc.textBetween(newMark.from, newMark.to, undefined, ' ');
|
|
32
33
|
const wasLink = test(oldLinkText);
|
|
33
34
|
const isLink = test(newLinkText);
|
|
34
|
-
|
|
35
|
-
|
|
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.
|
|
36
40
|
if (wasLink && !isLink) {
|
|
37
|
-
tr.removeMark(newMark.from, newMark.to, options.type);
|
|
41
|
+
tr.removeMark(needsAutolink ? newMark.from : newMark.to - 1, newMark.to, options.type);
|
|
38
42
|
}
|
|
39
43
|
});
|
|
40
|
-
//
|
|
44
|
+
// Now let’s see if we can add new links.
|
|
41
45
|
const nodesInChangedRanges = findChildrenInRange(newState.doc, newRange, node => node.isTextblock);
|
|
42
46
|
let textBlock;
|
|
43
47
|
let textBeforeWhitespace;
|
|
44
48
|
if (nodesInChangedRanges.length > 1) {
|
|
45
|
-
// Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter)
|
|
49
|
+
// Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).
|
|
46
50
|
textBlock = nodesInChangedRanges[0];
|
|
47
51
|
textBeforeWhitespace = newState.doc.textBetween(textBlock.pos, textBlock.pos + textBlock.node.nodeSize, undefined, ' ');
|
|
48
52
|
}
|
|
49
53
|
else if (nodesInChangedRanges.length
|
|
50
|
-
// We want to make sure to include the block seperator argument to treat hard breaks like spaces
|
|
54
|
+
// We want to make sure to include the block seperator argument to treat hard breaks like spaces.
|
|
51
55
|
&& newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')) {
|
|
52
56
|
textBlock = nodesInChangedRanges[0];
|
|
53
57
|
textBeforeWhitespace = newState.doc.textBetween(textBlock.pos, newRange.to, undefined, ' ');
|
|
@@ -64,20 +68,28 @@ function autolink(options) {
|
|
|
64
68
|
}
|
|
65
69
|
find(lastWordBeforeSpace)
|
|
66
70
|
.filter(link => link.isLink)
|
|
71
|
+
// Calculate link position.
|
|
72
|
+
.map(link => ({
|
|
73
|
+
...link,
|
|
74
|
+
from: lastWordAndBlockOffset + link.start + 1,
|
|
75
|
+
to: lastWordAndBlockOffset + link.end + 1,
|
|
76
|
+
}))
|
|
77
|
+
// ignore link inside code mark
|
|
78
|
+
.filter(link => {
|
|
79
|
+
return !newState.doc.rangeHasMark(link.from, link.to, newState.schema.marks.code);
|
|
80
|
+
})
|
|
81
|
+
// validate link
|
|
67
82
|
.filter(link => {
|
|
68
83
|
if (options.validate) {
|
|
69
84
|
return options.validate(link.value);
|
|
70
85
|
}
|
|
71
86
|
return true;
|
|
72
87
|
})
|
|
73
|
-
//
|
|
74
|
-
.map(link => ({
|
|
75
|
-
...link,
|
|
76
|
-
from: lastWordAndBlockOffset + link.start + 1,
|
|
77
|
-
to: lastWordAndBlockOffset + link.end + 1,
|
|
78
|
-
}))
|
|
79
|
-
// add link mark
|
|
88
|
+
// Add link mark.
|
|
80
89
|
.forEach(link => {
|
|
90
|
+
if (getMarksBetween(link.from, link.to, newState.doc).some(item => item.mark.type === options.type)) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
81
93
|
tr.addMark(link.from, link.to, options.type.create({
|
|
82
94
|
href: link.href,
|
|
83
95
|
}));
|
|
@@ -97,16 +109,18 @@ function clickHandler(options) {
|
|
|
97
109
|
key: new PluginKey('handleClickLink'),
|
|
98
110
|
props: {
|
|
99
111
|
handleClick: (view, pos, event) => {
|
|
100
|
-
var _a, _b
|
|
112
|
+
var _a, _b;
|
|
101
113
|
if (event.button !== 0) {
|
|
102
114
|
return false;
|
|
103
115
|
}
|
|
104
116
|
const attrs = getAttributes(view.state, options.type.name);
|
|
105
|
-
const link =
|
|
106
|
-
const href = (
|
|
107
|
-
const target = (
|
|
117
|
+
const link = event.target;
|
|
118
|
+
const href = (_a = link === null || link === void 0 ? void 0 : link.href) !== null && _a !== void 0 ? _a : attrs.href;
|
|
119
|
+
const target = (_b = link === null || link === void 0 ? void 0 : link.target) !== null && _b !== void 0 ? _b : attrs.target;
|
|
108
120
|
if (link && href) {
|
|
109
|
-
|
|
121
|
+
if (view.editable) {
|
|
122
|
+
window.open(href, target);
|
|
123
|
+
}
|
|
110
124
|
return true;
|
|
111
125
|
}
|
|
112
126
|
return false;
|
|
@@ -120,24 +134,71 @@ function pasteHandler(options) {
|
|
|
120
134
|
key: new PluginKey('handlePasteLink'),
|
|
121
135
|
props: {
|
|
122
136
|
handlePaste: (view, event, slice) => {
|
|
137
|
+
var _a, _b;
|
|
123
138
|
const { state } = view;
|
|
124
139
|
const { selection } = state;
|
|
125
|
-
|
|
126
|
-
if (
|
|
140
|
+
// Do not proceed if in code block.
|
|
141
|
+
if (state.doc.resolve(selection.from).parent.type.spec.code) {
|
|
127
142
|
return false;
|
|
128
143
|
}
|
|
144
|
+
const pastedLinkMarks = [];
|
|
129
145
|
let textContent = '';
|
|
130
146
|
slice.content.forEach(node => {
|
|
131
147
|
textContent += node.textContent;
|
|
148
|
+
node.marks.forEach(mark => {
|
|
149
|
+
if (mark.type.name === options.type.name) {
|
|
150
|
+
pastedLinkMarks.push(mark);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
132
153
|
});
|
|
154
|
+
const hasPastedLink = pastedLinkMarks.length > 0;
|
|
133
155
|
const link = find(textContent).find(item => item.isLink && item.value === textContent);
|
|
134
|
-
if (!
|
|
156
|
+
if (!selection.empty && options.linkOnPaste) {
|
|
157
|
+
const pastedLink = hasPastedLink ? pastedLinkMarks[0].attrs.href : (link === null || link === void 0 ? void 0 : link.href) || null;
|
|
158
|
+
if (pastedLink) {
|
|
159
|
+
options.editor.commands.setMark(options.type, { href: pastedLink });
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
const firstChildIsText = ((_a = slice.content.firstChild) === null || _a === void 0 ? void 0 : _a.type.name) === 'text';
|
|
164
|
+
const firstChildContainsLinkMark = (_b = slice.content.firstChild) === null || _b === void 0 ? void 0 : _b.marks.some(mark => mark.type.name === options.type.name);
|
|
165
|
+
if (firstChildIsText && firstChildContainsLinkMark) {
|
|
135
166
|
return false;
|
|
136
167
|
}
|
|
137
|
-
|
|
138
|
-
href
|
|
168
|
+
if (link && selection.empty) {
|
|
169
|
+
options.editor.commands.insertContent(`<a href="${link.href}">${link.href}</a>`);
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
const { tr } = state;
|
|
173
|
+
let deleteOnly = false;
|
|
174
|
+
if (!selection.empty) {
|
|
175
|
+
deleteOnly = true;
|
|
176
|
+
tr.delete(selection.from, selection.to);
|
|
177
|
+
}
|
|
178
|
+
let currentPos = selection.from;
|
|
179
|
+
let fragmentLinks = [];
|
|
180
|
+
slice.content.forEach(node => {
|
|
181
|
+
fragmentLinks = find(node.textContent);
|
|
182
|
+
tr.insert(currentPos - 1, node);
|
|
183
|
+
if (fragmentLinks.length > 0) {
|
|
184
|
+
deleteOnly = false;
|
|
185
|
+
fragmentLinks.forEach(fragmentLink => {
|
|
186
|
+
const linkStart = currentPos + fragmentLink.start;
|
|
187
|
+
const linkEnd = currentPos + fragmentLink.end;
|
|
188
|
+
const hasMark = tr.doc.rangeHasMark(linkStart, linkEnd, options.type);
|
|
189
|
+
if (!hasMark) {
|
|
190
|
+
tr.addMark(linkStart, linkEnd, options.type.create({ href: fragmentLink.href }));
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
currentPos += node.nodeSize;
|
|
139
195
|
});
|
|
140
|
-
|
|
196
|
+
const hasFragmentLinks = fragmentLinks.length > 0;
|
|
197
|
+
if (tr.docChanged && !deleteOnly && hasFragmentLinks) {
|
|
198
|
+
options.editor.view.dispatch(tr);
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
return false;
|
|
141
202
|
},
|
|
142
203
|
},
|
|
143
204
|
});
|
|
@@ -184,6 +245,9 @@ const Link = Mark.create({
|
|
|
184
245
|
target: {
|
|
185
246
|
default: this.options.HTMLAttributes.target,
|
|
186
247
|
},
|
|
248
|
+
rel: {
|
|
249
|
+
default: this.options.HTMLAttributes.rel,
|
|
250
|
+
},
|
|
187
251
|
class: {
|
|
188
252
|
default: this.options.HTMLAttributes.class,
|
|
189
253
|
},
|
|
@@ -214,32 +278,6 @@ const Link = Mark.create({
|
|
|
214
278
|
},
|
|
215
279
|
};
|
|
216
280
|
},
|
|
217
|
-
addPasteRules() {
|
|
218
|
-
return [
|
|
219
|
-
markPasteRule({
|
|
220
|
-
find: text => find(text)
|
|
221
|
-
.filter(link => {
|
|
222
|
-
if (this.options.validate) {
|
|
223
|
-
return this.options.validate(link.value);
|
|
224
|
-
}
|
|
225
|
-
return true;
|
|
226
|
-
})
|
|
227
|
-
.filter(link => link.isLink)
|
|
228
|
-
.map(link => ({
|
|
229
|
-
text: link.value,
|
|
230
|
-
index: link.start,
|
|
231
|
-
data: link,
|
|
232
|
-
})),
|
|
233
|
-
type: this.type,
|
|
234
|
-
getAttributes: match => {
|
|
235
|
-
var _a;
|
|
236
|
-
return ({
|
|
237
|
-
href: (_a = match.data) === null || _a === void 0 ? void 0 : _a.href,
|
|
238
|
-
});
|
|
239
|
-
},
|
|
240
|
-
}),
|
|
241
|
-
];
|
|
242
|
-
},
|
|
243
281
|
addProseMirrorPlugins() {
|
|
244
282
|
const plugins = [];
|
|
245
283
|
if (this.options.autolink) {
|
|
@@ -253,12 +291,11 @@ const Link = Mark.create({
|
|
|
253
291
|
type: this.type,
|
|
254
292
|
}));
|
|
255
293
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
294
|
+
plugins.push(pasteHandler({
|
|
295
|
+
editor: this.editor,
|
|
296
|
+
type: this.type,
|
|
297
|
+
linkOnPaste: this.options.linkOnPaste,
|
|
298
|
+
}));
|
|
262
299
|
return plugins;
|
|
263
300
|
},
|
|
264
301
|
});
|