@tiptap/extension-link 2.0.0-beta.20 → 2.0.0-beta.24
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/packages/extension-link/src/link.d.ts +1 -9
- package/dist/tiptap-extension-link.cjs.js +31 -21
- package/dist/tiptap-extension-link.cjs.js.map +1 -1
- package/dist/tiptap-extension-link.esm.js +31 -19
- package/dist/tiptap-extension-link.esm.js.map +1 -1
- package/dist/tiptap-extension-link.umd.js +35 -26
- package/dist/tiptap-extension-link.umd.js.map +1 -1
- package/package.json +3 -2
- package/src/link.ts +28 -20
- package/CHANGELOG.md +0 -292
|
@@ -37,12 +37,4 @@ declare module '@tiptap/core' {
|
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
-
|
|
41
|
-
* A regex that matches any string that contains a link
|
|
42
|
-
*/
|
|
43
|
-
export declare const pasteRegex: RegExp;
|
|
44
|
-
/**
|
|
45
|
-
* A regex that matches an url
|
|
46
|
-
*/
|
|
47
|
-
export declare const pasteRegexExact: RegExp;
|
|
48
|
-
export declare const Link: Mark<LinkOptions>;
|
|
40
|
+
export declare const Link: Mark<LinkOptions, any>;
|
|
@@ -4,26 +4,21 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var core = require('@tiptap/core');
|
|
6
6
|
var prosemirrorState = require('prosemirror-state');
|
|
7
|
+
var linkifyjs = require('linkifyjs');
|
|
7
8
|
|
|
8
|
-
/**
|
|
9
|
-
* A regex that matches any string that contains a link
|
|
10
|
-
*/
|
|
11
|
-
const pasteRegex = /https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)/gi;
|
|
12
|
-
/**
|
|
13
|
-
* A regex that matches an url
|
|
14
|
-
*/
|
|
15
|
-
const pasteRegexExact = /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)$/gi;
|
|
16
9
|
const Link = core.Mark.create({
|
|
17
10
|
name: 'link',
|
|
18
11
|
priority: 1000,
|
|
19
12
|
inclusive: false,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
13
|
+
addOptions() {
|
|
14
|
+
return {
|
|
15
|
+
openOnClick: true,
|
|
16
|
+
linkOnPaste: true,
|
|
17
|
+
HTMLAttributes: {
|
|
18
|
+
target: '_blank',
|
|
19
|
+
rel: 'noopener noreferrer nofollow',
|
|
20
|
+
},
|
|
21
|
+
};
|
|
27
22
|
},
|
|
28
23
|
addAttributes() {
|
|
29
24
|
return {
|
|
@@ -58,7 +53,22 @@ const Link = core.Mark.create({
|
|
|
58
53
|
},
|
|
59
54
|
addPasteRules() {
|
|
60
55
|
return [
|
|
61
|
-
core.markPasteRule(
|
|
56
|
+
core.markPasteRule({
|
|
57
|
+
find: text => linkifyjs.find(text)
|
|
58
|
+
.filter(link => link.isLink)
|
|
59
|
+
.map(link => ({
|
|
60
|
+
text: link.value,
|
|
61
|
+
index: link.start,
|
|
62
|
+
data: link,
|
|
63
|
+
})),
|
|
64
|
+
type: this.type,
|
|
65
|
+
getAttributes: match => {
|
|
66
|
+
var _a;
|
|
67
|
+
return ({
|
|
68
|
+
href: (_a = match.data) === null || _a === void 0 ? void 0 : _a.href,
|
|
69
|
+
});
|
|
70
|
+
},
|
|
71
|
+
}),
|
|
62
72
|
];
|
|
63
73
|
},
|
|
64
74
|
addProseMirrorPlugins() {
|
|
@@ -95,11 +105,13 @@ const Link = core.Mark.create({
|
|
|
95
105
|
slice.content.forEach(node => {
|
|
96
106
|
textContent += node.textContent;
|
|
97
107
|
});
|
|
98
|
-
|
|
108
|
+
const link = linkifyjs.find(textContent)
|
|
109
|
+
.find(item => item.isLink && item.value === textContent);
|
|
110
|
+
if (!textContent || !link) {
|
|
99
111
|
return false;
|
|
100
112
|
}
|
|
101
113
|
this.editor.commands.setMark(this.type, {
|
|
102
|
-
href:
|
|
114
|
+
href: link.href,
|
|
103
115
|
});
|
|
104
116
|
return true;
|
|
105
117
|
},
|
|
@@ -111,7 +123,5 @@ const Link = core.Mark.create({
|
|
|
111
123
|
});
|
|
112
124
|
|
|
113
125
|
exports.Link = Link;
|
|
114
|
-
exports[
|
|
115
|
-
exports.pasteRegex = pasteRegex;
|
|
116
|
-
exports.pasteRegexExact = pasteRegexExact;
|
|
126
|
+
exports["default"] = Link;
|
|
117
127
|
//# sourceMappingURL=tiptap-extension-link.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tiptap-extension-link.cjs.js","sources":["../src/link.ts"],"sourcesContent":["import {\n Mark,\n markPasteRule,\n mergeAttributes,\n} from '@tiptap/core'\nimport { Plugin, PluginKey } from 'prosemirror-state'\n\nexport interface LinkOptions {\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\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string, target?: string }) => ReturnType,\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string, target?: string }) => ReturnType,\n /**\n * Unset a link mark\n */\n unsetLink: () => ReturnType,\n }\n }\n}\n\
|
|
1
|
+
{"version":3,"file":"tiptap-extension-link.cjs.js","sources":["../src/link.ts"],"sourcesContent":["import {\n Mark,\n markPasteRule,\n mergeAttributes,\n} from '@tiptap/core'\nimport { Plugin, PluginKey } from 'prosemirror-state'\nimport { find } from 'linkifyjs'\n\nexport interface LinkOptions {\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\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string, target?: string }) => ReturnType,\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string, target?: string }) => 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 inclusive: false,\n\n addOptions() {\n return {\n openOnClick: true,\n linkOnPaste: true,\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n },\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n }\n },\n\n parseHTML() {\n return [\n { tag: 'a[href]' },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setLink: attributes => ({ commands }) => {\n return commands.setMark('link', attributes)\n },\n toggleLink: attributes => ({ commands }) => {\n return commands.toggleMark('link', attributes, { extendEmptyMarkRange: true })\n },\n unsetLink: () => ({ commands }) => {\n return commands.unsetMark('link', { extendEmptyMarkRange: true })\n },\n }\n },\n\n addPasteRules() {\n return [\n markPasteRule({\n find: text => find(text)\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 = []\n\n if (this.options.openOnClick) {\n plugins.push(\n new Plugin({\n key: new PluginKey('handleClickLink'),\n props: {\n handleClick: (view, pos, event) => {\n const attrs = this.editor.getAttributes('link')\n const link = (event.target as HTMLElement)?.closest('a')\n\n if (link && attrs.href) {\n window.open(attrs.href, attrs.target)\n\n return true\n }\n\n return false\n },\n },\n }),\n )\n }\n\n if (this.options.linkOnPaste) {\n plugins.push(\n 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)\n .find(item => item.isLink && item.value === textContent)\n\n if (!textContent || !link) {\n return false\n }\n\n this.editor.commands.setMark(this.type, {\n href: link.href,\n })\n\n return true\n },\n },\n }),\n )\n }\n\n return plugins\n },\n})\n"],"names":["Mark","mergeAttributes","markPasteRule","find","Plugin","PluginKey"],"mappings":"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"}
|
|
@@ -1,25 +1,20 @@
|
|
|
1
1
|
import { Mark, mergeAttributes, markPasteRule } from '@tiptap/core';
|
|
2
2
|
import { Plugin, PluginKey } from 'prosemirror-state';
|
|
3
|
+
import { find } from 'linkifyjs';
|
|
3
4
|
|
|
4
|
-
/**
|
|
5
|
-
* A regex that matches any string that contains a link
|
|
6
|
-
*/
|
|
7
|
-
const pasteRegex = /https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)/gi;
|
|
8
|
-
/**
|
|
9
|
-
* A regex that matches an url
|
|
10
|
-
*/
|
|
11
|
-
const pasteRegexExact = /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)$/gi;
|
|
12
5
|
const Link = Mark.create({
|
|
13
6
|
name: 'link',
|
|
14
7
|
priority: 1000,
|
|
15
8
|
inclusive: false,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
9
|
+
addOptions() {
|
|
10
|
+
return {
|
|
11
|
+
openOnClick: true,
|
|
12
|
+
linkOnPaste: true,
|
|
13
|
+
HTMLAttributes: {
|
|
14
|
+
target: '_blank',
|
|
15
|
+
rel: 'noopener noreferrer nofollow',
|
|
16
|
+
},
|
|
17
|
+
};
|
|
23
18
|
},
|
|
24
19
|
addAttributes() {
|
|
25
20
|
return {
|
|
@@ -54,7 +49,22 @@ const Link = Mark.create({
|
|
|
54
49
|
},
|
|
55
50
|
addPasteRules() {
|
|
56
51
|
return [
|
|
57
|
-
markPasteRule(
|
|
52
|
+
markPasteRule({
|
|
53
|
+
find: text => find(text)
|
|
54
|
+
.filter(link => link.isLink)
|
|
55
|
+
.map(link => ({
|
|
56
|
+
text: link.value,
|
|
57
|
+
index: link.start,
|
|
58
|
+
data: link,
|
|
59
|
+
})),
|
|
60
|
+
type: this.type,
|
|
61
|
+
getAttributes: match => {
|
|
62
|
+
var _a;
|
|
63
|
+
return ({
|
|
64
|
+
href: (_a = match.data) === null || _a === void 0 ? void 0 : _a.href,
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
}),
|
|
58
68
|
];
|
|
59
69
|
},
|
|
60
70
|
addProseMirrorPlugins() {
|
|
@@ -91,11 +101,13 @@ const Link = Mark.create({
|
|
|
91
101
|
slice.content.forEach(node => {
|
|
92
102
|
textContent += node.textContent;
|
|
93
103
|
});
|
|
94
|
-
|
|
104
|
+
const link = find(textContent)
|
|
105
|
+
.find(item => item.isLink && item.value === textContent);
|
|
106
|
+
if (!textContent || !link) {
|
|
95
107
|
return false;
|
|
96
108
|
}
|
|
97
109
|
this.editor.commands.setMark(this.type, {
|
|
98
|
-
href:
|
|
110
|
+
href: link.href,
|
|
99
111
|
});
|
|
100
112
|
return true;
|
|
101
113
|
},
|
|
@@ -106,5 +118,5 @@ const Link = Mark.create({
|
|
|
106
118
|
},
|
|
107
119
|
});
|
|
108
120
|
|
|
109
|
-
export { Link, Link as default
|
|
121
|
+
export { Link, Link as default };
|
|
110
122
|
//# sourceMappingURL=tiptap-extension-link.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tiptap-extension-link.esm.js","sources":["../src/link.ts"],"sourcesContent":["import {\n Mark,\n markPasteRule,\n mergeAttributes,\n} from '@tiptap/core'\nimport { Plugin, PluginKey } from 'prosemirror-state'\n\nexport interface LinkOptions {\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\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string, target?: string }) => ReturnType,\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string, target?: string }) => ReturnType,\n /**\n * Unset a link mark\n */\n unsetLink: () => ReturnType,\n }\n }\n}\n\
|
|
1
|
+
{"version":3,"file":"tiptap-extension-link.esm.js","sources":["../src/link.ts"],"sourcesContent":["import {\n Mark,\n markPasteRule,\n mergeAttributes,\n} from '@tiptap/core'\nimport { Plugin, PluginKey } from 'prosemirror-state'\nimport { find } from 'linkifyjs'\n\nexport interface LinkOptions {\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\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string, target?: string }) => ReturnType,\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string, target?: string }) => 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 inclusive: false,\n\n addOptions() {\n return {\n openOnClick: true,\n linkOnPaste: true,\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n },\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n }\n },\n\n parseHTML() {\n return [\n { tag: 'a[href]' },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setLink: attributes => ({ commands }) => {\n return commands.setMark('link', attributes)\n },\n toggleLink: attributes => ({ commands }) => {\n return commands.toggleMark('link', attributes, { extendEmptyMarkRange: true })\n },\n unsetLink: () => ({ commands }) => {\n return commands.unsetMark('link', { extendEmptyMarkRange: true })\n },\n }\n },\n\n addPasteRules() {\n return [\n markPasteRule({\n find: text => find(text)\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 = []\n\n if (this.options.openOnClick) {\n plugins.push(\n new Plugin({\n key: new PluginKey('handleClickLink'),\n props: {\n handleClick: (view, pos, event) => {\n const attrs = this.editor.getAttributes('link')\n const link = (event.target as HTMLElement)?.closest('a')\n\n if (link && attrs.href) {\n window.open(attrs.href, attrs.target)\n\n return true\n }\n\n return false\n },\n },\n }),\n )\n }\n\n if (this.options.linkOnPaste) {\n plugins.push(\n 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)\n .find(item => item.isLink && item.value === textContent)\n\n if (!textContent || !link) {\n return false\n }\n\n this.editor.commands.setMark(this.type, {\n href: link.href,\n })\n\n return true\n },\n },\n }),\n )\n }\n\n return plugins\n },\n})\n"],"names":[],"mappings":"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"}
|
|
@@ -1,28 +1,22 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tiptap/core'), require('prosemirror-state')) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', '@tiptap/core', 'prosemirror-state'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global[
|
|
5
|
-
}(this, (function (exports, core, prosemirrorState) { 'use strict';
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tiptap/core'), require('prosemirror-state'), require('linkifyjs')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', '@tiptap/core', 'prosemirror-state', 'linkifyjs'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@tiptap/extension-link"] = {}, global.core, global.prosemirrorState, global.linkifyjs));
|
|
5
|
+
})(this, (function (exports, core, prosemirrorState, linkifyjs) { 'use strict';
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
* A regex that matches any string that contains a link
|
|
9
|
-
*/
|
|
10
|
-
const pasteRegex = /https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)/gi;
|
|
11
|
-
/**
|
|
12
|
-
* A regex that matches an url
|
|
13
|
-
*/
|
|
14
|
-
const pasteRegexExact = /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)$/gi;
|
|
15
7
|
const Link = core.Mark.create({
|
|
16
8
|
name: 'link',
|
|
17
9
|
priority: 1000,
|
|
18
10
|
inclusive: false,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
11
|
+
addOptions() {
|
|
12
|
+
return {
|
|
13
|
+
openOnClick: true,
|
|
14
|
+
linkOnPaste: true,
|
|
15
|
+
HTMLAttributes: {
|
|
16
|
+
target: '_blank',
|
|
17
|
+
rel: 'noopener noreferrer nofollow',
|
|
18
|
+
},
|
|
19
|
+
};
|
|
26
20
|
},
|
|
27
21
|
addAttributes() {
|
|
28
22
|
return {
|
|
@@ -57,7 +51,22 @@
|
|
|
57
51
|
},
|
|
58
52
|
addPasteRules() {
|
|
59
53
|
return [
|
|
60
|
-
core.markPasteRule(
|
|
54
|
+
core.markPasteRule({
|
|
55
|
+
find: text => linkifyjs.find(text)
|
|
56
|
+
.filter(link => link.isLink)
|
|
57
|
+
.map(link => ({
|
|
58
|
+
text: link.value,
|
|
59
|
+
index: link.start,
|
|
60
|
+
data: link,
|
|
61
|
+
})),
|
|
62
|
+
type: this.type,
|
|
63
|
+
getAttributes: match => {
|
|
64
|
+
var _a;
|
|
65
|
+
return ({
|
|
66
|
+
href: (_a = match.data) === null || _a === void 0 ? void 0 : _a.href,
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
}),
|
|
61
70
|
];
|
|
62
71
|
},
|
|
63
72
|
addProseMirrorPlugins() {
|
|
@@ -94,11 +103,13 @@
|
|
|
94
103
|
slice.content.forEach(node => {
|
|
95
104
|
textContent += node.textContent;
|
|
96
105
|
});
|
|
97
|
-
|
|
106
|
+
const link = linkifyjs.find(textContent)
|
|
107
|
+
.find(item => item.isLink && item.value === textContent);
|
|
108
|
+
if (!textContent || !link) {
|
|
98
109
|
return false;
|
|
99
110
|
}
|
|
100
111
|
this.editor.commands.setMark(this.type, {
|
|
101
|
-
href:
|
|
112
|
+
href: link.href,
|
|
102
113
|
});
|
|
103
114
|
return true;
|
|
104
115
|
},
|
|
@@ -110,11 +121,9 @@
|
|
|
110
121
|
});
|
|
111
122
|
|
|
112
123
|
exports.Link = Link;
|
|
113
|
-
exports[
|
|
114
|
-
exports.pasteRegex = pasteRegex;
|
|
115
|
-
exports.pasteRegexExact = pasteRegexExact;
|
|
124
|
+
exports["default"] = Link;
|
|
116
125
|
|
|
117
126
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
118
127
|
|
|
119
|
-
}))
|
|
128
|
+
}));
|
|
120
129
|
//# sourceMappingURL=tiptap-extension-link.umd.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tiptap-extension-link.umd.js","sources":["../src/link.ts"],"sourcesContent":["import {\n Mark,\n markPasteRule,\n mergeAttributes,\n} from '@tiptap/core'\nimport { Plugin, PluginKey } from 'prosemirror-state'\n\nexport interface LinkOptions {\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\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string, target?: string }) => ReturnType,\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string, target?: string }) => ReturnType,\n /**\n * Unset a link mark\n */\n unsetLink: () => ReturnType,\n }\n }\n}\n\
|
|
1
|
+
{"version":3,"file":"tiptap-extension-link.umd.js","sources":["../src/link.ts"],"sourcesContent":["import {\n Mark,\n markPasteRule,\n mergeAttributes,\n} from '@tiptap/core'\nimport { Plugin, PluginKey } from 'prosemirror-state'\nimport { find } from 'linkifyjs'\n\nexport interface LinkOptions {\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\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n link: {\n /**\n * Set a link mark\n */\n setLink: (attributes: { href: string, target?: string }) => ReturnType,\n /**\n * Toggle a link mark\n */\n toggleLink: (attributes: { href: string, target?: string }) => 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 inclusive: false,\n\n addOptions() {\n return {\n openOnClick: true,\n linkOnPaste: true,\n HTMLAttributes: {\n target: '_blank',\n rel: 'noopener noreferrer nofollow',\n },\n }\n },\n\n addAttributes() {\n return {\n href: {\n default: null,\n },\n target: {\n default: this.options.HTMLAttributes.target,\n },\n }\n },\n\n parseHTML() {\n return [\n { tag: 'a[href]' },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setLink: attributes => ({ commands }) => {\n return commands.setMark('link', attributes)\n },\n toggleLink: attributes => ({ commands }) => {\n return commands.toggleMark('link', attributes, { extendEmptyMarkRange: true })\n },\n unsetLink: () => ({ commands }) => {\n return commands.unsetMark('link', { extendEmptyMarkRange: true })\n },\n }\n },\n\n addPasteRules() {\n return [\n markPasteRule({\n find: text => find(text)\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 = []\n\n if (this.options.openOnClick) {\n plugins.push(\n new Plugin({\n key: new PluginKey('handleClickLink'),\n props: {\n handleClick: (view, pos, event) => {\n const attrs = this.editor.getAttributes('link')\n const link = (event.target as HTMLElement)?.closest('a')\n\n if (link && attrs.href) {\n window.open(attrs.href, attrs.target)\n\n return true\n }\n\n return false\n },\n },\n }),\n )\n }\n\n if (this.options.linkOnPaste) {\n plugins.push(\n 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)\n .find(item => item.isLink && item.value === textContent)\n\n if (!textContent || !link) {\n return false\n }\n\n this.editor.commands.setMark(this.type, {\n href: link.href,\n })\n\n return true\n },\n },\n }),\n )\n }\n\n return plugins\n },\n})\n"],"names":["Mark","mergeAttributes","markPasteRule","find","Plugin","PluginKey"],"mappings":"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"}
|
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.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.24",
|
|
5
5
|
"homepage": "https://tiptap.dev",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"tiptap",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"@tiptap/core": "^2.0.0-beta.1"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
+
"linkifyjs": "^3.0.3",
|
|
27
28
|
"prosemirror-state": "^1.3.4"
|
|
28
29
|
},
|
|
29
30
|
"repository": {
|
|
@@ -31,5 +32,5 @@
|
|
|
31
32
|
"url": "https://github.com/ueberdosis/tiptap",
|
|
32
33
|
"directory": "packages/extension-link"
|
|
33
34
|
},
|
|
34
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "642627ec3635a1d8fa851887d75bee5f193ec63b"
|
|
35
36
|
}
|
package/src/link.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
mergeAttributes,
|
|
5
5
|
} from '@tiptap/core'
|
|
6
6
|
import { Plugin, PluginKey } from 'prosemirror-state'
|
|
7
|
+
import { find } from 'linkifyjs'
|
|
7
8
|
|
|
8
9
|
export interface LinkOptions {
|
|
9
10
|
/**
|
|
@@ -39,16 +40,6 @@ declare module '@tiptap/core' {
|
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
/**
|
|
43
|
-
* A regex that matches any string that contains a link
|
|
44
|
-
*/
|
|
45
|
-
export const pasteRegex = /https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)/gi
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* A regex that matches an url
|
|
49
|
-
*/
|
|
50
|
-
export const pasteRegexExact = /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)$/gi
|
|
51
|
-
|
|
52
43
|
export const Link = Mark.create<LinkOptions>({
|
|
53
44
|
name: 'link',
|
|
54
45
|
|
|
@@ -56,13 +47,15 @@ export const Link = Mark.create<LinkOptions>({
|
|
|
56
47
|
|
|
57
48
|
inclusive: false,
|
|
58
49
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
50
|
+
addOptions() {
|
|
51
|
+
return {
|
|
52
|
+
openOnClick: true,
|
|
53
|
+
linkOnPaste: true,
|
|
54
|
+
HTMLAttributes: {
|
|
55
|
+
target: '_blank',
|
|
56
|
+
rel: 'noopener noreferrer nofollow',
|
|
57
|
+
},
|
|
58
|
+
}
|
|
66
59
|
},
|
|
67
60
|
|
|
68
61
|
addAttributes() {
|
|
@@ -102,7 +95,19 @@ export const Link = Mark.create<LinkOptions>({
|
|
|
102
95
|
|
|
103
96
|
addPasteRules() {
|
|
104
97
|
return [
|
|
105
|
-
markPasteRule(
|
|
98
|
+
markPasteRule({
|
|
99
|
+
find: text => find(text)
|
|
100
|
+
.filter(link => link.isLink)
|
|
101
|
+
.map(link => ({
|
|
102
|
+
text: link.value,
|
|
103
|
+
index: link.start,
|
|
104
|
+
data: link,
|
|
105
|
+
})),
|
|
106
|
+
type: this.type,
|
|
107
|
+
getAttributes: match => ({
|
|
108
|
+
href: match.data?.href,
|
|
109
|
+
}),
|
|
110
|
+
}),
|
|
106
111
|
]
|
|
107
112
|
},
|
|
108
113
|
|
|
@@ -151,12 +156,15 @@ export const Link = Mark.create<LinkOptions>({
|
|
|
151
156
|
textContent += node.textContent
|
|
152
157
|
})
|
|
153
158
|
|
|
154
|
-
|
|
159
|
+
const link = find(textContent)
|
|
160
|
+
.find(item => item.isLink && item.value === textContent)
|
|
161
|
+
|
|
162
|
+
if (!textContent || !link) {
|
|
155
163
|
return false
|
|
156
164
|
}
|
|
157
165
|
|
|
158
166
|
this.editor.commands.setMark(this.type, {
|
|
159
|
-
href:
|
|
167
|
+
href: link.href,
|
|
160
168
|
})
|
|
161
169
|
|
|
162
170
|
return true
|
package/CHANGELOG.md
DELETED
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
# Change Log
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file.
|
|
4
|
-
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
|
-
|
|
6
|
-
# [2.0.0-beta.20](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.19...@tiptap/extension-link@2.0.0-beta.20) (2021-09-08)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
### Features
|
|
10
|
-
|
|
11
|
-
* add extendEmptyMarkRange option to mark commands ([#1859](https://github.com/ueberdosis/tiptap/issues/1859)) ([14e458e](https://github.com/ueberdosis/tiptap/commit/14e458ea7d7475a51ac00d6f67509dc769919d0b))
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
# [2.0.0-beta.19](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.18...@tiptap/extension-link@2.0.0-beta.19) (2021-07-26)
|
|
18
|
-
|
|
19
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
# [2.0.0-beta.18](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.17...@tiptap/extension-link@2.0.0-beta.18) (2021-06-07)
|
|
26
|
-
|
|
27
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
# [2.0.0-beta.17](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.16...@tiptap/extension-link@2.0.0-beta.17) (2021-05-18)
|
|
34
|
-
|
|
35
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
# [2.0.0-beta.16](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.15...@tiptap/extension-link@2.0.0-beta.16) (2021-05-13)
|
|
42
|
-
|
|
43
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
# [2.0.0-beta.15](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.14...@tiptap/extension-link@2.0.0-beta.15) (2021-05-07)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
### Features
|
|
53
|
-
|
|
54
|
-
* add editor.getAttributes, deprecate editor.getNodeAttributes and editor.getMarkAttributes ([072905c](https://github.com/ueberdosis/tiptap/commit/072905cb95e022a37f5bc937889999bfbb33ad88))
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
# [2.0.0-beta.14](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.13...@tiptap/extension-link@2.0.0-beta.14) (2021-05-07)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
### Bug Fixes
|
|
64
|
-
|
|
65
|
-
* fix a bug that messed up pasted link attributes, fix [#1284](https://github.com/ueberdosis/tiptap/issues/1284) ([7da647d](https://github.com/ueberdosis/tiptap/commit/7da647d99f1dcefabc653347a8e2abfae3bb972e))
|
|
66
|
-
* revert adding exports ([bc320d0](https://github.com/ueberdosis/tiptap/commit/bc320d0b4b80b0e37a7e47a56e0f6daec6e65d98))
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
# [2.0.0-beta.13](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.12...@tiptap/extension-link@2.0.0-beta.13) (2021-05-06)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
### Bug Fixes
|
|
76
|
-
|
|
77
|
-
* revert adding type: module ([f8d6475](https://github.com/ueberdosis/tiptap/commit/f8d6475e2151faea6f96baecdd6bd75880d50d2c))
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
# [2.0.0-beta.12](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.11...@tiptap/extension-link@2.0.0-beta.12) (2021-05-06)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
### Bug Fixes
|
|
87
|
-
|
|
88
|
-
* add exports to package.json ([1277fa4](https://github.com/ueberdosis/tiptap/commit/1277fa47151e9c039508cdb219bdd0ffe647f4ee))
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
# [2.0.0-beta.11](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.10...@tiptap/extension-link@2.0.0-beta.11) (2021-05-06)
|
|
95
|
-
|
|
96
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
# [2.0.0-beta.10](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.9...@tiptap/extension-link@2.0.0-beta.10) (2021-05-05)
|
|
103
|
-
|
|
104
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
# [2.0.0-beta.9](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.8...@tiptap/extension-link@2.0.0-beta.9) (2021-05-05)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
### Features
|
|
114
|
-
|
|
115
|
-
* add linkOnPaste option for adding a link to the current selection if the pasted content only contains an url, fix [#1210](https://github.com/ueberdosis/tiptap/issues/1210) ([9e9401e](https://github.com/ueberdosis/tiptap/commit/9e9401e68b79d34070fb79c4f356841fa19fe436))
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
# [2.0.0-beta.8](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.7...@tiptap/extension-link@2.0.0-beta.8) (2021-04-23)
|
|
122
|
-
|
|
123
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
# [2.0.0-beta.7](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.6...@tiptap/extension-link@2.0.0-beta.7) (2021-04-22)
|
|
130
|
-
|
|
131
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
# [2.0.0-beta.6](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.5...@tiptap/extension-link@2.0.0-beta.6) (2021-04-21)
|
|
138
|
-
|
|
139
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
# [2.0.0-beta.5](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.4...@tiptap/extension-link@2.0.0-beta.5) (2021-04-16)
|
|
146
|
-
|
|
147
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
# [2.0.0-beta.4](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.3...@tiptap/extension-link@2.0.0-beta.4) (2021-04-15)
|
|
154
|
-
|
|
155
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
# [2.0.0-beta.3](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.2...@tiptap/extension-link@2.0.0-beta.3) (2021-04-11)
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
### Bug Fixes
|
|
165
|
-
|
|
166
|
-
* fix a bug in link click handler, where we can’t click on text selections. fix [#263](https://github.com/ueberdosis/tiptap/issues/263) ([33c30c0](https://github.com/ueberdosis/tiptap/commit/33c30c0d6df66190fd1d5073ccc43b1020b517f9))
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
# [2.0.0-beta.2](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-beta.1...@tiptap/extension-link@2.0.0-beta.2) (2021-04-07)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
### Features
|
|
176
|
-
|
|
177
|
-
* add priority option to extensions ([bb1ae65](https://github.com/ueberdosis/tiptap/commit/bb1ae659a463e97a7ada15af711347b5c004897a))
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
# [2.0.0-beta.1](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-alpha.11...@tiptap/extension-link@2.0.0-beta.1) (2021-03-05)
|
|
184
|
-
|
|
185
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
# [2.0.0-alpha.11](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-alpha.10...@tiptap/extension-link@2.0.0-alpha.11) (2021-02-16)
|
|
192
|
-
|
|
193
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
# [2.0.0-alpha.10](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-alpha.9...@tiptap/extension-link@2.0.0-alpha.10) (2021-02-07)
|
|
200
|
-
|
|
201
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
# [2.0.0-alpha.9](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-alpha.8...@tiptap/extension-link@2.0.0-alpha.9) (2021-02-05)
|
|
208
|
-
|
|
209
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
# [2.0.0-alpha.8](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-alpha.7...@tiptap/extension-link@2.0.0-alpha.8) (2021-01-29)
|
|
216
|
-
|
|
217
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
# [2.0.0-alpha.7](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-alpha.6...@tiptap/extension-link@2.0.0-alpha.7) (2021-01-29)
|
|
224
|
-
|
|
225
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
# [2.0.0-alpha.6](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-alpha.5...@tiptap/extension-link@2.0.0-alpha.6) (2021-01-28)
|
|
232
|
-
|
|
233
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
# [2.0.0-alpha.5](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-alpha.4...@tiptap/extension-link@2.0.0-alpha.5) (2020-12-18)
|
|
240
|
-
|
|
241
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
# [2.0.0-alpha.4](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-alpha.3...@tiptap/extension-link@2.0.0-alpha.4) (2020-12-02)
|
|
248
|
-
|
|
249
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
# [2.0.0-alpha.3](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-alpha.2...@tiptap/extension-link@2.0.0-alpha.3) (2020-11-19)
|
|
256
|
-
|
|
257
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
# [2.0.0-alpha.2](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@2.0.0-alpha.1...@tiptap/extension-link@2.0.0-alpha.2) (2020-11-19)
|
|
264
|
-
|
|
265
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
# [2.0.0-alpha.1](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@1.0.0-alpha.2...@tiptap/extension-link@2.0.0-alpha.1) (2020-11-18)
|
|
272
|
-
|
|
273
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
# [1.0.0-alpha.2](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-link@1.0.0-alpha.1...@tiptap/extension-link@1.0.0-alpha.2) (2020-11-16)
|
|
280
|
-
|
|
281
|
-
**Note:** Version bump only for package @tiptap/extension-link
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
# 1.0.0-alpha.1 (2020-11-16)
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
### Reverts
|
|
291
|
-
|
|
292
|
-
* Revert "use global namespace" ([0c9ce26](https://github.com/ueberdosis/tiptap/commit/0c9ce26c02c07d88a757c01b0a9d7f9e2b0b7502))
|