@tiptap/extension-mention 2.0.0-beta.19 → 2.0.0-beta.194
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/README.md +2 -2
- package/dist/packages/extension-mention/src/mention.d.ts +9 -4
- package/dist/tiptap-extension-mention.cjs.js +72 -24
- package/dist/tiptap-extension-mention.cjs.js.map +1 -1
- package/dist/tiptap-extension-mention.esm.js +70 -24
- package/dist/tiptap-extension-mention.esm.js.map +1 -1
- package/dist/tiptap-extension-mention.umd.js +76 -29
- package/dist/tiptap-extension-mention.umd.js.map +1 -1
- package/package.json +10 -5
- package/src/mention.ts +81 -26
- package/CHANGELOG.md +0 -251
- package/LICENSE.md +0 -21
- package/dist/tiptap-extension-mention.bundle.umd.min.js +0 -2
- package/dist/tiptap-extension-mention.bundle.umd.min.js.map +0 -1
package/README.md
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
## Introduction
|
|
8
8
|
tiptap is a headless wrapper around [ProseMirror](https://ProseMirror.net) – a toolkit for building rich text WYSIWYG editors, which is already in use at many well-known companies such as *New York Times*, *The Guardian* or *Atlassian*.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Official Documentation
|
|
11
11
|
Documentation can be found on the [tiptap website](https://tiptap.dev).
|
|
12
12
|
|
|
13
13
|
## License
|
|
14
|
-
tiptap is open
|
|
14
|
+
tiptap is open sourced software licensed under the [MIT license](https://github.com/ueberdosis/tiptap/blob/main/LICENSE.md).
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { Node } from '@tiptap/core';
|
|
2
2
|
import { SuggestionOptions } from '@tiptap/suggestion';
|
|
3
|
+
import { Node as ProseMirrorNode } from 'prosemirror-model';
|
|
4
|
+
import { PluginKey } from 'prosemirror-state';
|
|
3
5
|
export declare type MentionOptions = {
|
|
4
|
-
HTMLAttributes:
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
HTMLAttributes: Record<string, any>;
|
|
7
|
+
renderLabel: (props: {
|
|
8
|
+
options: MentionOptions;
|
|
9
|
+
node: ProseMirrorNode;
|
|
10
|
+
}) => string;
|
|
7
11
|
suggestion: Omit<SuggestionOptions, 'editor'>;
|
|
8
12
|
};
|
|
9
|
-
export declare const
|
|
13
|
+
export declare const MentionPluginKey: PluginKey<any>;
|
|
14
|
+
export declare const Mention: Node<MentionOptions, any>;
|
|
@@ -4,29 +4,58 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var core = require('@tiptap/core');
|
|
6
6
|
var Suggestion = require('@tiptap/suggestion');
|
|
7
|
+
var prosemirrorState = require('prosemirror-state');
|
|
7
8
|
|
|
8
9
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
9
10
|
|
|
10
11
|
var Suggestion__default = /*#__PURE__*/_interopDefaultLegacy(Suggestion);
|
|
11
12
|
|
|
13
|
+
const MentionPluginKey = new prosemirrorState.PluginKey('mention');
|
|
12
14
|
const Mention = core.Node.create({
|
|
13
15
|
name: 'mention',
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
.chain()
|
|
21
|
-
.focus()
|
|
22
|
-
.replaceRange(range, 'mention', props)
|
|
23
|
-
.insertContent(' ')
|
|
24
|
-
.run();
|
|
16
|
+
addOptions() {
|
|
17
|
+
return {
|
|
18
|
+
HTMLAttributes: {},
|
|
19
|
+
renderLabel({ options, node }) {
|
|
20
|
+
var _a;
|
|
21
|
+
return `${options.suggestion.char}${(_a = node.attrs.label) !== null && _a !== void 0 ? _a : node.attrs.id}`;
|
|
25
22
|
},
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
suggestion: {
|
|
24
|
+
char: '@',
|
|
25
|
+
pluginKey: MentionPluginKey,
|
|
26
|
+
command: ({ editor, range, props }) => {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
// increase range.to by one when the next node is of type "text"
|
|
29
|
+
// and starts with a space character
|
|
30
|
+
const nodeAfter = editor.view.state.selection.$to.nodeAfter;
|
|
31
|
+
const overrideSpace = (_a = nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.text) === null || _a === void 0 ? void 0 : _a.startsWith(' ');
|
|
32
|
+
if (overrideSpace) {
|
|
33
|
+
range.to += 1;
|
|
34
|
+
}
|
|
35
|
+
editor
|
|
36
|
+
.chain()
|
|
37
|
+
.focus()
|
|
38
|
+
.insertContentAt(range, [
|
|
39
|
+
{
|
|
40
|
+
type: this.name,
|
|
41
|
+
attrs: props,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
type: 'text',
|
|
45
|
+
text: ' ',
|
|
46
|
+
},
|
|
47
|
+
])
|
|
48
|
+
.run();
|
|
49
|
+
(_b = window.getSelection()) === null || _b === void 0 ? void 0 : _b.collapseToEnd();
|
|
50
|
+
},
|
|
51
|
+
allow: ({ state, range }) => {
|
|
52
|
+
const $from = state.doc.resolve(range.from);
|
|
53
|
+
const type = state.schema.nodes[this.name];
|
|
54
|
+
const allow = !!$from.parent.type.contentMatch.matchType(type);
|
|
55
|
+
return allow;
|
|
56
|
+
},
|
|
28
57
|
},
|
|
29
|
-
}
|
|
58
|
+
};
|
|
30
59
|
},
|
|
31
60
|
group: 'inline',
|
|
32
61
|
inline: true,
|
|
@@ -36,17 +65,25 @@ const Mention = core.Node.create({
|
|
|
36
65
|
return {
|
|
37
66
|
id: {
|
|
38
67
|
default: null,
|
|
39
|
-
parseHTML: element =>
|
|
68
|
+
parseHTML: element => element.getAttribute('data-id'),
|
|
69
|
+
renderHTML: attributes => {
|
|
70
|
+
if (!attributes.id) {
|
|
71
|
+
return {};
|
|
72
|
+
}
|
|
40
73
|
return {
|
|
41
|
-
id:
|
|
74
|
+
'data-id': attributes.id,
|
|
42
75
|
};
|
|
43
76
|
},
|
|
77
|
+
},
|
|
78
|
+
label: {
|
|
79
|
+
default: null,
|
|
80
|
+
parseHTML: element => element.getAttribute('data-label'),
|
|
44
81
|
renderHTML: attributes => {
|
|
45
|
-
if (!attributes.
|
|
82
|
+
if (!attributes.label) {
|
|
46
83
|
return {};
|
|
47
84
|
}
|
|
48
85
|
return {
|
|
49
|
-
'data-
|
|
86
|
+
'data-label': attributes.label,
|
|
50
87
|
};
|
|
51
88
|
},
|
|
52
89
|
},
|
|
@@ -55,15 +92,25 @@ const Mention = core.Node.create({
|
|
|
55
92
|
parseHTML() {
|
|
56
93
|
return [
|
|
57
94
|
{
|
|
58
|
-
tag:
|
|
95
|
+
tag: `span[data-type="${this.name}"]`,
|
|
59
96
|
},
|
|
60
97
|
];
|
|
61
98
|
},
|
|
62
99
|
renderHTML({ node, HTMLAttributes }) {
|
|
63
|
-
return [
|
|
100
|
+
return [
|
|
101
|
+
'span',
|
|
102
|
+
core.mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),
|
|
103
|
+
this.options.renderLabel({
|
|
104
|
+
options: this.options,
|
|
105
|
+
node,
|
|
106
|
+
}),
|
|
107
|
+
];
|
|
64
108
|
},
|
|
65
109
|
renderText({ node }) {
|
|
66
|
-
return
|
|
110
|
+
return this.options.renderLabel({
|
|
111
|
+
options: this.options,
|
|
112
|
+
node,
|
|
113
|
+
});
|
|
67
114
|
},
|
|
68
115
|
addKeyboardShortcuts() {
|
|
69
116
|
return {
|
|
@@ -75,7 +122,7 @@ const Mention = core.Node.create({
|
|
|
75
122
|
return false;
|
|
76
123
|
}
|
|
77
124
|
state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
|
|
78
|
-
if (node.type.name ===
|
|
125
|
+
if (node.type.name === this.name) {
|
|
79
126
|
isMention = true;
|
|
80
127
|
tr.insertText(this.options.suggestion.char || '', pos, pos + node.nodeSize);
|
|
81
128
|
return false;
|
|
@@ -87,7 +134,7 @@ const Mention = core.Node.create({
|
|
|
87
134
|
},
|
|
88
135
|
addProseMirrorPlugins() {
|
|
89
136
|
return [
|
|
90
|
-
Suggestion__default[
|
|
137
|
+
Suggestion__default["default"]({
|
|
91
138
|
editor: this.editor,
|
|
92
139
|
...this.options.suggestion,
|
|
93
140
|
}),
|
|
@@ -96,5 +143,6 @@ const Mention = core.Node.create({
|
|
|
96
143
|
});
|
|
97
144
|
|
|
98
145
|
exports.Mention = Mention;
|
|
99
|
-
exports.
|
|
146
|
+
exports.MentionPluginKey = MentionPluginKey;
|
|
147
|
+
exports["default"] = Mention;
|
|
100
148
|
//# sourceMappingURL=tiptap-extension-mention.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tiptap-extension-mention.cjs.js","sources":["../src/mention.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"tiptap-extension-mention.cjs.js","sources":["../src/mention.ts"],"sourcesContent":["import { mergeAttributes, Node } from '@tiptap/core'\nimport Suggestion, { SuggestionOptions } from '@tiptap/suggestion'\nimport { Node as ProseMirrorNode } from 'prosemirror-model'\nimport { PluginKey } from 'prosemirror-state'\n\nexport type MentionOptions = {\n HTMLAttributes: Record<string, any>,\n renderLabel: (props: {\n options: MentionOptions,\n node: ProseMirrorNode,\n }) => string,\n suggestion: Omit<SuggestionOptions, 'editor'>,\n}\n\nexport const MentionPluginKey = new PluginKey('mention')\n\nexport const Mention = Node.create<MentionOptions>({\n name: 'mention',\n\n addOptions() {\n return {\n HTMLAttributes: {},\n renderLabel({ options, node }) {\n return `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`\n },\n suggestion: {\n char: '@',\n pluginKey: MentionPluginKey,\n command: ({ editor, range, props }) => {\n // increase range.to by one when the next node is of type \"text\"\n // and starts with a space character\n const nodeAfter = editor.view.state.selection.$to.nodeAfter\n const overrideSpace = nodeAfter?.text?.startsWith(' ')\n\n if (overrideSpace) {\n range.to += 1\n }\n\n editor\n .chain()\n .focus()\n .insertContentAt(range, [\n {\n type: this.name,\n attrs: props,\n },\n {\n type: 'text',\n text: ' ',\n },\n ])\n .run()\n\n window.getSelection()?.collapseToEnd()\n },\n allow: ({ state, range }) => {\n const $from = state.doc.resolve(range.from)\n const type = state.schema.nodes[this.name]\n const allow = !!$from.parent.type.contentMatch.matchType(type)\n\n return allow\n },\n },\n }\n },\n\n group: 'inline',\n\n inline: true,\n\n selectable: false,\n\n atom: true,\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: element => element.getAttribute('data-id'),\n renderHTML: attributes => {\n if (!attributes.id) {\n return {}\n }\n\n return {\n 'data-id': attributes.id,\n }\n },\n },\n\n label: {\n default: null,\n parseHTML: element => element.getAttribute('data-label'),\n renderHTML: attributes => {\n if (!attributes.label) {\n return {}\n }\n\n return {\n 'data-label': attributes.label,\n }\n },\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `span[data-type=\"${this.name}\"]`,\n },\n ]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n return [\n 'span',\n mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),\n this.options.renderLabel({\n options: this.options,\n node,\n }),\n ]\n },\n\n renderText({ node }) {\n return this.options.renderLabel({\n options: this.options,\n node,\n })\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => this.editor.commands.command(({ tr, state }) => {\n let isMention = false\n const { selection } = state\n const { empty, anchor } = selection\n\n if (!empty) {\n return false\n }\n\n state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {\n if (node.type.name === this.name) {\n isMention = true\n tr.insertText(this.options.suggestion.char || '', pos, pos + node.nodeSize)\n\n return false\n }\n })\n\n return isMention\n }),\n }\n },\n\n addProseMirrorPlugins() {\n return [\n Suggestion({\n editor: this.editor,\n ...this.options.suggestion,\n }),\n ]\n },\n})\n"],"names":["PluginKey","Node","mergeAttributes","Suggestion"],"mappings":"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"}
|
|
@@ -1,24 +1,53 @@
|
|
|
1
1
|
import { Node, mergeAttributes } from '@tiptap/core';
|
|
2
2
|
import Suggestion from '@tiptap/suggestion';
|
|
3
|
+
import { PluginKey } from 'prosemirror-state';
|
|
3
4
|
|
|
5
|
+
const MentionPluginKey = new PluginKey('mention');
|
|
4
6
|
const Mention = Node.create({
|
|
5
7
|
name: 'mention',
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.chain()
|
|
13
|
-
.focus()
|
|
14
|
-
.replaceRange(range, 'mention', props)
|
|
15
|
-
.insertContent(' ')
|
|
16
|
-
.run();
|
|
8
|
+
addOptions() {
|
|
9
|
+
return {
|
|
10
|
+
HTMLAttributes: {},
|
|
11
|
+
renderLabel({ options, node }) {
|
|
12
|
+
var _a;
|
|
13
|
+
return `${options.suggestion.char}${(_a = node.attrs.label) !== null && _a !== void 0 ? _a : node.attrs.id}`;
|
|
17
14
|
},
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
suggestion: {
|
|
16
|
+
char: '@',
|
|
17
|
+
pluginKey: MentionPluginKey,
|
|
18
|
+
command: ({ editor, range, props }) => {
|
|
19
|
+
var _a, _b;
|
|
20
|
+
// increase range.to by one when the next node is of type "text"
|
|
21
|
+
// and starts with a space character
|
|
22
|
+
const nodeAfter = editor.view.state.selection.$to.nodeAfter;
|
|
23
|
+
const overrideSpace = (_a = nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.text) === null || _a === void 0 ? void 0 : _a.startsWith(' ');
|
|
24
|
+
if (overrideSpace) {
|
|
25
|
+
range.to += 1;
|
|
26
|
+
}
|
|
27
|
+
editor
|
|
28
|
+
.chain()
|
|
29
|
+
.focus()
|
|
30
|
+
.insertContentAt(range, [
|
|
31
|
+
{
|
|
32
|
+
type: this.name,
|
|
33
|
+
attrs: props,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
type: 'text',
|
|
37
|
+
text: ' ',
|
|
38
|
+
},
|
|
39
|
+
])
|
|
40
|
+
.run();
|
|
41
|
+
(_b = window.getSelection()) === null || _b === void 0 ? void 0 : _b.collapseToEnd();
|
|
42
|
+
},
|
|
43
|
+
allow: ({ state, range }) => {
|
|
44
|
+
const $from = state.doc.resolve(range.from);
|
|
45
|
+
const type = state.schema.nodes[this.name];
|
|
46
|
+
const allow = !!$from.parent.type.contentMatch.matchType(type);
|
|
47
|
+
return allow;
|
|
48
|
+
},
|
|
20
49
|
},
|
|
21
|
-
}
|
|
50
|
+
};
|
|
22
51
|
},
|
|
23
52
|
group: 'inline',
|
|
24
53
|
inline: true,
|
|
@@ -28,17 +57,25 @@ const Mention = Node.create({
|
|
|
28
57
|
return {
|
|
29
58
|
id: {
|
|
30
59
|
default: null,
|
|
31
|
-
parseHTML: element =>
|
|
60
|
+
parseHTML: element => element.getAttribute('data-id'),
|
|
61
|
+
renderHTML: attributes => {
|
|
62
|
+
if (!attributes.id) {
|
|
63
|
+
return {};
|
|
64
|
+
}
|
|
32
65
|
return {
|
|
33
|
-
id:
|
|
66
|
+
'data-id': attributes.id,
|
|
34
67
|
};
|
|
35
68
|
},
|
|
69
|
+
},
|
|
70
|
+
label: {
|
|
71
|
+
default: null,
|
|
72
|
+
parseHTML: element => element.getAttribute('data-label'),
|
|
36
73
|
renderHTML: attributes => {
|
|
37
|
-
if (!attributes.
|
|
74
|
+
if (!attributes.label) {
|
|
38
75
|
return {};
|
|
39
76
|
}
|
|
40
77
|
return {
|
|
41
|
-
'data-
|
|
78
|
+
'data-label': attributes.label,
|
|
42
79
|
};
|
|
43
80
|
},
|
|
44
81
|
},
|
|
@@ -47,15 +84,25 @@ const Mention = Node.create({
|
|
|
47
84
|
parseHTML() {
|
|
48
85
|
return [
|
|
49
86
|
{
|
|
50
|
-
tag:
|
|
87
|
+
tag: `span[data-type="${this.name}"]`,
|
|
51
88
|
},
|
|
52
89
|
];
|
|
53
90
|
},
|
|
54
91
|
renderHTML({ node, HTMLAttributes }) {
|
|
55
|
-
return [
|
|
92
|
+
return [
|
|
93
|
+
'span',
|
|
94
|
+
mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),
|
|
95
|
+
this.options.renderLabel({
|
|
96
|
+
options: this.options,
|
|
97
|
+
node,
|
|
98
|
+
}),
|
|
99
|
+
];
|
|
56
100
|
},
|
|
57
101
|
renderText({ node }) {
|
|
58
|
-
return
|
|
102
|
+
return this.options.renderLabel({
|
|
103
|
+
options: this.options,
|
|
104
|
+
node,
|
|
105
|
+
});
|
|
59
106
|
},
|
|
60
107
|
addKeyboardShortcuts() {
|
|
61
108
|
return {
|
|
@@ -67,7 +114,7 @@ const Mention = Node.create({
|
|
|
67
114
|
return false;
|
|
68
115
|
}
|
|
69
116
|
state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
|
|
70
|
-
if (node.type.name ===
|
|
117
|
+
if (node.type.name === this.name) {
|
|
71
118
|
isMention = true;
|
|
72
119
|
tr.insertText(this.options.suggestion.char || '', pos, pos + node.nodeSize);
|
|
73
120
|
return false;
|
|
@@ -87,6 +134,5 @@ const Mention = Node.create({
|
|
|
87
134
|
},
|
|
88
135
|
});
|
|
89
136
|
|
|
90
|
-
export default
|
|
91
|
-
export { Mention };
|
|
137
|
+
export { Mention, MentionPluginKey, Mention as default };
|
|
92
138
|
//# sourceMappingURL=tiptap-extension-mention.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tiptap-extension-mention.esm.js","sources":["../src/mention.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"tiptap-extension-mention.esm.js","sources":["../src/mention.ts"],"sourcesContent":["import { mergeAttributes, Node } from '@tiptap/core'\nimport Suggestion, { SuggestionOptions } from '@tiptap/suggestion'\nimport { Node as ProseMirrorNode } from 'prosemirror-model'\nimport { PluginKey } from 'prosemirror-state'\n\nexport type MentionOptions = {\n HTMLAttributes: Record<string, any>,\n renderLabel: (props: {\n options: MentionOptions,\n node: ProseMirrorNode,\n }) => string,\n suggestion: Omit<SuggestionOptions, 'editor'>,\n}\n\nexport const MentionPluginKey = new PluginKey('mention')\n\nexport const Mention = Node.create<MentionOptions>({\n name: 'mention',\n\n addOptions() {\n return {\n HTMLAttributes: {},\n renderLabel({ options, node }) {\n return `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`\n },\n suggestion: {\n char: '@',\n pluginKey: MentionPluginKey,\n command: ({ editor, range, props }) => {\n // increase range.to by one when the next node is of type \"text\"\n // and starts with a space character\n const nodeAfter = editor.view.state.selection.$to.nodeAfter\n const overrideSpace = nodeAfter?.text?.startsWith(' ')\n\n if (overrideSpace) {\n range.to += 1\n }\n\n editor\n .chain()\n .focus()\n .insertContentAt(range, [\n {\n type: this.name,\n attrs: props,\n },\n {\n type: 'text',\n text: ' ',\n },\n ])\n .run()\n\n window.getSelection()?.collapseToEnd()\n },\n allow: ({ state, range }) => {\n const $from = state.doc.resolve(range.from)\n const type = state.schema.nodes[this.name]\n const allow = !!$from.parent.type.contentMatch.matchType(type)\n\n return allow\n },\n },\n }\n },\n\n group: 'inline',\n\n inline: true,\n\n selectable: false,\n\n atom: true,\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: element => element.getAttribute('data-id'),\n renderHTML: attributes => {\n if (!attributes.id) {\n return {}\n }\n\n return {\n 'data-id': attributes.id,\n }\n },\n },\n\n label: {\n default: null,\n parseHTML: element => element.getAttribute('data-label'),\n renderHTML: attributes => {\n if (!attributes.label) {\n return {}\n }\n\n return {\n 'data-label': attributes.label,\n }\n },\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `span[data-type=\"${this.name}\"]`,\n },\n ]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n return [\n 'span',\n mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),\n this.options.renderLabel({\n options: this.options,\n node,\n }),\n ]\n },\n\n renderText({ node }) {\n return this.options.renderLabel({\n options: this.options,\n node,\n })\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => this.editor.commands.command(({ tr, state }) => {\n let isMention = false\n const { selection } = state\n const { empty, anchor } = selection\n\n if (!empty) {\n return false\n }\n\n state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {\n if (node.type.name === this.name) {\n isMention = true\n tr.insertText(this.options.suggestion.char || '', pos, pos + node.nodeSize)\n\n return false\n }\n })\n\n return isMention\n }),\n }\n },\n\n addProseMirrorPlugins() {\n return [\n Suggestion({\n editor: this.editor,\n ...this.options.suggestion,\n }),\n ]\n },\n})\n"],"names":[],"mappings":"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"}
|
|
@@ -1,31 +1,59 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tiptap/core'), require('@tiptap/suggestion')) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', '@tiptap/core', '@tiptap/suggestion'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global[
|
|
5
|
-
}(this, (function (exports, core, Suggestion) { 'use strict';
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tiptap/core'), require('@tiptap/suggestion'), require('prosemirror-state')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', '@tiptap/core', '@tiptap/suggestion', 'prosemirror-state'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@tiptap/extension-mention"] = {}, global.core, global.Suggestion, global.prosemirrorState));
|
|
5
|
+
})(this, (function (exports, core, Suggestion, prosemirrorState) { 'use strict';
|
|
6
6
|
|
|
7
7
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
8
8
|
|
|
9
9
|
var Suggestion__default = /*#__PURE__*/_interopDefaultLegacy(Suggestion);
|
|
10
10
|
|
|
11
|
+
const MentionPluginKey = new prosemirrorState.PluginKey('mention');
|
|
11
12
|
const Mention = core.Node.create({
|
|
12
13
|
name: 'mention',
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
.chain()
|
|
20
|
-
.focus()
|
|
21
|
-
.replaceRange(range, 'mention', props)
|
|
22
|
-
.insertContent(' ')
|
|
23
|
-
.run();
|
|
14
|
+
addOptions() {
|
|
15
|
+
return {
|
|
16
|
+
HTMLAttributes: {},
|
|
17
|
+
renderLabel({ options, node }) {
|
|
18
|
+
var _a;
|
|
19
|
+
return `${options.suggestion.char}${(_a = node.attrs.label) !== null && _a !== void 0 ? _a : node.attrs.id}`;
|
|
24
20
|
},
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
suggestion: {
|
|
22
|
+
char: '@',
|
|
23
|
+
pluginKey: MentionPluginKey,
|
|
24
|
+
command: ({ editor, range, props }) => {
|
|
25
|
+
var _a, _b;
|
|
26
|
+
// increase range.to by one when the next node is of type "text"
|
|
27
|
+
// and starts with a space character
|
|
28
|
+
const nodeAfter = editor.view.state.selection.$to.nodeAfter;
|
|
29
|
+
const overrideSpace = (_a = nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.text) === null || _a === void 0 ? void 0 : _a.startsWith(' ');
|
|
30
|
+
if (overrideSpace) {
|
|
31
|
+
range.to += 1;
|
|
32
|
+
}
|
|
33
|
+
editor
|
|
34
|
+
.chain()
|
|
35
|
+
.focus()
|
|
36
|
+
.insertContentAt(range, [
|
|
37
|
+
{
|
|
38
|
+
type: this.name,
|
|
39
|
+
attrs: props,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
type: 'text',
|
|
43
|
+
text: ' ',
|
|
44
|
+
},
|
|
45
|
+
])
|
|
46
|
+
.run();
|
|
47
|
+
(_b = window.getSelection()) === null || _b === void 0 ? void 0 : _b.collapseToEnd();
|
|
48
|
+
},
|
|
49
|
+
allow: ({ state, range }) => {
|
|
50
|
+
const $from = state.doc.resolve(range.from);
|
|
51
|
+
const type = state.schema.nodes[this.name];
|
|
52
|
+
const allow = !!$from.parent.type.contentMatch.matchType(type);
|
|
53
|
+
return allow;
|
|
54
|
+
},
|
|
27
55
|
},
|
|
28
|
-
}
|
|
56
|
+
};
|
|
29
57
|
},
|
|
30
58
|
group: 'inline',
|
|
31
59
|
inline: true,
|
|
@@ -35,17 +63,25 @@
|
|
|
35
63
|
return {
|
|
36
64
|
id: {
|
|
37
65
|
default: null,
|
|
38
|
-
parseHTML: element =>
|
|
66
|
+
parseHTML: element => element.getAttribute('data-id'),
|
|
67
|
+
renderHTML: attributes => {
|
|
68
|
+
if (!attributes.id) {
|
|
69
|
+
return {};
|
|
70
|
+
}
|
|
39
71
|
return {
|
|
40
|
-
id:
|
|
72
|
+
'data-id': attributes.id,
|
|
41
73
|
};
|
|
42
74
|
},
|
|
75
|
+
},
|
|
76
|
+
label: {
|
|
77
|
+
default: null,
|
|
78
|
+
parseHTML: element => element.getAttribute('data-label'),
|
|
43
79
|
renderHTML: attributes => {
|
|
44
|
-
if (!attributes.
|
|
80
|
+
if (!attributes.label) {
|
|
45
81
|
return {};
|
|
46
82
|
}
|
|
47
83
|
return {
|
|
48
|
-
'data-
|
|
84
|
+
'data-label': attributes.label,
|
|
49
85
|
};
|
|
50
86
|
},
|
|
51
87
|
},
|
|
@@ -54,15 +90,25 @@
|
|
|
54
90
|
parseHTML() {
|
|
55
91
|
return [
|
|
56
92
|
{
|
|
57
|
-
tag:
|
|
93
|
+
tag: `span[data-type="${this.name}"]`,
|
|
58
94
|
},
|
|
59
95
|
];
|
|
60
96
|
},
|
|
61
97
|
renderHTML({ node, HTMLAttributes }) {
|
|
62
|
-
return [
|
|
98
|
+
return [
|
|
99
|
+
'span',
|
|
100
|
+
core.mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),
|
|
101
|
+
this.options.renderLabel({
|
|
102
|
+
options: this.options,
|
|
103
|
+
node,
|
|
104
|
+
}),
|
|
105
|
+
];
|
|
63
106
|
},
|
|
64
107
|
renderText({ node }) {
|
|
65
|
-
return
|
|
108
|
+
return this.options.renderLabel({
|
|
109
|
+
options: this.options,
|
|
110
|
+
node,
|
|
111
|
+
});
|
|
66
112
|
},
|
|
67
113
|
addKeyboardShortcuts() {
|
|
68
114
|
return {
|
|
@@ -74,7 +120,7 @@
|
|
|
74
120
|
return false;
|
|
75
121
|
}
|
|
76
122
|
state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
|
|
77
|
-
if (node.type.name ===
|
|
123
|
+
if (node.type.name === this.name) {
|
|
78
124
|
isMention = true;
|
|
79
125
|
tr.insertText(this.options.suggestion.char || '', pos, pos + node.nodeSize);
|
|
80
126
|
return false;
|
|
@@ -86,7 +132,7 @@
|
|
|
86
132
|
},
|
|
87
133
|
addProseMirrorPlugins() {
|
|
88
134
|
return [
|
|
89
|
-
Suggestion__default[
|
|
135
|
+
Suggestion__default["default"]({
|
|
90
136
|
editor: this.editor,
|
|
91
137
|
...this.options.suggestion,
|
|
92
138
|
}),
|
|
@@ -95,9 +141,10 @@
|
|
|
95
141
|
});
|
|
96
142
|
|
|
97
143
|
exports.Mention = Mention;
|
|
98
|
-
exports.
|
|
144
|
+
exports.MentionPluginKey = MentionPluginKey;
|
|
145
|
+
exports["default"] = Mention;
|
|
99
146
|
|
|
100
147
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
101
148
|
|
|
102
|
-
}))
|
|
149
|
+
}));
|
|
103
150
|
//# sourceMappingURL=tiptap-extension-mention.umd.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tiptap-extension-mention.umd.js","sources":["../src/mention.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"tiptap-extension-mention.umd.js","sources":["../src/mention.ts"],"sourcesContent":["import { mergeAttributes, Node } from '@tiptap/core'\nimport Suggestion, { SuggestionOptions } from '@tiptap/suggestion'\nimport { Node as ProseMirrorNode } from 'prosemirror-model'\nimport { PluginKey } from 'prosemirror-state'\n\nexport type MentionOptions = {\n HTMLAttributes: Record<string, any>,\n renderLabel: (props: {\n options: MentionOptions,\n node: ProseMirrorNode,\n }) => string,\n suggestion: Omit<SuggestionOptions, 'editor'>,\n}\n\nexport const MentionPluginKey = new PluginKey('mention')\n\nexport const Mention = Node.create<MentionOptions>({\n name: 'mention',\n\n addOptions() {\n return {\n HTMLAttributes: {},\n renderLabel({ options, node }) {\n return `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`\n },\n suggestion: {\n char: '@',\n pluginKey: MentionPluginKey,\n command: ({ editor, range, props }) => {\n // increase range.to by one when the next node is of type \"text\"\n // and starts with a space character\n const nodeAfter = editor.view.state.selection.$to.nodeAfter\n const overrideSpace = nodeAfter?.text?.startsWith(' ')\n\n if (overrideSpace) {\n range.to += 1\n }\n\n editor\n .chain()\n .focus()\n .insertContentAt(range, [\n {\n type: this.name,\n attrs: props,\n },\n {\n type: 'text',\n text: ' ',\n },\n ])\n .run()\n\n window.getSelection()?.collapseToEnd()\n },\n allow: ({ state, range }) => {\n const $from = state.doc.resolve(range.from)\n const type = state.schema.nodes[this.name]\n const allow = !!$from.parent.type.contentMatch.matchType(type)\n\n return allow\n },\n },\n }\n },\n\n group: 'inline',\n\n inline: true,\n\n selectable: false,\n\n atom: true,\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: element => element.getAttribute('data-id'),\n renderHTML: attributes => {\n if (!attributes.id) {\n return {}\n }\n\n return {\n 'data-id': attributes.id,\n }\n },\n },\n\n label: {\n default: null,\n parseHTML: element => element.getAttribute('data-label'),\n renderHTML: attributes => {\n if (!attributes.label) {\n return {}\n }\n\n return {\n 'data-label': attributes.label,\n }\n },\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `span[data-type=\"${this.name}\"]`,\n },\n ]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n return [\n 'span',\n mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),\n this.options.renderLabel({\n options: this.options,\n node,\n }),\n ]\n },\n\n renderText({ node }) {\n return this.options.renderLabel({\n options: this.options,\n node,\n })\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => this.editor.commands.command(({ tr, state }) => {\n let isMention = false\n const { selection } = state\n const { empty, anchor } = selection\n\n if (!empty) {\n return false\n }\n\n state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {\n if (node.type.name === this.name) {\n isMention = true\n tr.insertText(this.options.suggestion.char || '', pos, pos + node.nodeSize)\n\n return false\n }\n })\n\n return isMention\n }),\n }\n },\n\n addProseMirrorPlugins() {\n return [\n Suggestion({\n editor: this.editor,\n ...this.options.suggestion,\n }),\n ]\n },\n})\n"],"names":["PluginKey","Node","mergeAttributes","Suggestion"],"mappings":"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"}
|