@cgboiler/biz-basic 1.0.45 → 1.0.47
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/es/index.d.ts +1 -1
- package/es/index.js +1 -1
- package/es/rich-text-editor/RichTextEditor.d.ts +3 -1
- package/es/rich-text-editor/RichTextEditor.js +1 -1
- package/es/rich-text-editor/useExtensions.d.ts +1 -1
- package/es/rich-text-editor/useExtensions.js +99 -4
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/rich-text-editor/RichTextEditor.d.ts +3 -1
- package/lib/rich-text-editor/RichTextEditor.js +1 -1
- package/lib/rich-text-editor/useExtensions.d.ts +1 -1
- package/lib/rich-text-editor/useExtensions.js +99 -4
- package/package.json +1 -1
package/es/index.d.ts
CHANGED
package/es/index.js
CHANGED
|
@@ -16,7 +16,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
16
16
|
type: BooleanConstructor;
|
|
17
17
|
default: boolean;
|
|
18
18
|
};
|
|
19
|
-
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("blur" | "focus" | "hashTag-triggered" | "hashTag-input" | "hashTag-exit" | "mention-triggered" | "update:modelValue" | "mention-clicked" | "hashTag-clicked")[], "blur" | "focus" | "hashTag-triggered" | "hashTag-input" | "hashTag-exit" | "mention-triggered" | "update:modelValue" | "mention-clicked" | "hashTag-clicked", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
19
|
+
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("blur" | "focus" | "hashTag-triggered" | "hashTag-input" | "hashTag-exit" | "mention-triggered" | "mention-input" | "mention-exit" | "update:modelValue" | "mention-clicked" | "hashTag-clicked")[], "blur" | "focus" | "hashTag-triggered" | "hashTag-input" | "hashTag-exit" | "mention-triggered" | "mention-input" | "mention-exit" | "update:modelValue" | "mention-clicked" | "hashTag-clicked", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
20
20
|
modelValue: {
|
|
21
21
|
type: StringConstructor;
|
|
22
22
|
default: string;
|
|
@@ -39,6 +39,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
39
39
|
"onHashTag-input"?: ((...args: any[]) => any) | undefined;
|
|
40
40
|
"onHashTag-exit"?: ((...args: any[]) => any) | undefined;
|
|
41
41
|
"onMention-triggered"?: ((...args: any[]) => any) | undefined;
|
|
42
|
+
"onMention-input"?: ((...args: any[]) => any) | undefined;
|
|
43
|
+
"onMention-exit"?: ((...args: any[]) => any) | undefined;
|
|
42
44
|
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
43
45
|
"onMention-clicked"?: ((...args: any[]) => any) | undefined;
|
|
44
46
|
"onHashTag-clicked"?: ((...args: any[]) => any) | undefined;
|
|
@@ -31,7 +31,7 @@ import "./index.css";
|
|
|
31
31
|
var stdin_default = defineComponent({
|
|
32
32
|
name: "RichTextEditor",
|
|
33
33
|
props: richTextEditorProps,
|
|
34
|
-
emits: ["update:modelValue", "mention-triggered", "mention-clicked", "hashTag-triggered", "hashTag-input", "hashTag-exit", "hashTag-clicked", "blur", "focus"],
|
|
34
|
+
emits: ["update:modelValue", "mention-triggered", "mention-input", "mention-exit", "mention-clicked", "hashTag-triggered", "hashTag-input", "hashTag-exit", "hashTag-clicked", "blur", "focus"],
|
|
35
35
|
setup(props, {
|
|
36
36
|
emit,
|
|
37
37
|
expose
|
|
@@ -8,4 +8,4 @@ import { Extension } from '@tiptap/core';
|
|
|
8
8
|
* - 返回值:Extension[] 扩展数组,用于初始化 TipTap 编辑器。
|
|
9
9
|
* - 异常:无显式抛出;若内部命令执行失败(例如插入内容时)可能由 TipTap 抛出异常,应在上层统一处理。
|
|
10
10
|
*/
|
|
11
|
-
export declare function useExtensions({ props, emit }: any): (import("@tiptap/core").Node<any, any> | import("@tiptap/core").Node<import("@tiptap/extension-mention").MentionOptions<any, import("@tiptap/extension-mention").MentionNodeAttrs>, any> | Extension<import("@tiptap/starter-kit").StarterKitOptions, any> |
|
|
11
|
+
export declare function useExtensions({ props, emit }: any): (import("@tiptap/core").Node<any, any> | import("@tiptap/core").Node<import("@tiptap/extension-mention").MentionOptions<any, import("@tiptap/extension-mention").MentionNodeAttrs>, any> | Extension<any, any> | Extension<import("@tiptap/starter-kit").StarterKitOptions, any> | import("@tiptap/core").Mark<import("@tiptap/extension-text-style").TextStyleOptions, any> | Extension<import("@tiptap/extension-text-style").ColorOptions, any> | Extension<import("tiptap-markdown").MarkdownOptions, import("tiptap-markdown").MarkdownStorage> | import("@tiptap/core").Node<import("@tiptap/extension-image").ImageOptions, any> | Extension<import("@tiptap/extension-table").TableKitOptions, any> | Extension<import("@tiptap/extensions").PlaceholderOptions, any> | Extension<import("@tiptap/extension-list").ListKitOptions, any>)[];
|
|
@@ -10,6 +10,9 @@ import { Extension, InputRule } from "@tiptap/core";
|
|
|
10
10
|
import HtmlBlock from "./extensions/HtmlBlock";
|
|
11
11
|
import { Placeholder } from "@tiptap/extensions";
|
|
12
12
|
function useExtensions({ props, emit }) {
|
|
13
|
+
let spentHashTagPositions = [];
|
|
14
|
+
let spentMentionPositions = [];
|
|
15
|
+
let activeEditor = null;
|
|
13
16
|
const HashTag = Mention.extend({
|
|
14
17
|
name: "hashTag",
|
|
15
18
|
renderHTML({ node, HTMLAttributes }) {
|
|
@@ -34,9 +37,20 @@ function useExtensions({ props, emit }) {
|
|
|
34
37
|
suggestion: {
|
|
35
38
|
char: "#",
|
|
36
39
|
allowedPrefixes: null,
|
|
40
|
+
allowSpaces: false,
|
|
41
|
+
/**
|
|
42
|
+
* allow
|
|
43
|
+
* - 功能:判断是否允许触发建议态。
|
|
44
|
+
* - 1. 若该位置的 # 已经触发过且未被删除,则不再重复触发(满足“单次触发制/光标静默”)。
|
|
45
|
+
*/
|
|
46
|
+
allow: ({ state, range }) => {
|
|
47
|
+
if (spentHashTagPositions.includes(range.from)) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return true;
|
|
51
|
+
},
|
|
37
52
|
render() {
|
|
38
53
|
let activeRange = null;
|
|
39
|
-
let activeEditor = null;
|
|
40
54
|
let exitCause = "unknown";
|
|
41
55
|
return {
|
|
42
56
|
onStart({ editor, range, command, query }) {
|
|
@@ -88,7 +102,7 @@ function useExtensions({ props, emit }) {
|
|
|
88
102
|
* - 返回值:无(通过 emit 派发事件)。
|
|
89
103
|
* - 异常:内部读取选择/文档时若发生异常,捕获后保持原有退出原因,不影响外部流程。
|
|
90
104
|
*/
|
|
91
|
-
onExit() {
|
|
105
|
+
onExit({ range }) {
|
|
92
106
|
var _a, _b, _c, _d, _e;
|
|
93
107
|
try {
|
|
94
108
|
const editorRef = activeEditor;
|
|
@@ -102,6 +116,9 @@ function useExtensions({ props, emit }) {
|
|
|
102
116
|
}
|
|
103
117
|
} catch (e) {
|
|
104
118
|
}
|
|
119
|
+
if ((range == null ? void 0 : range.from) !== void 0) {
|
|
120
|
+
spentHashTagPositions.push(range.from);
|
|
121
|
+
}
|
|
105
122
|
activeRange = null;
|
|
106
123
|
activeEditor = null;
|
|
107
124
|
const payload = {
|
|
@@ -114,6 +131,44 @@ function useExtensions({ props, emit }) {
|
|
|
114
131
|
}
|
|
115
132
|
}
|
|
116
133
|
});
|
|
134
|
+
const HashTagTracker = Extension.create({
|
|
135
|
+
name: "hashTagTracker",
|
|
136
|
+
onTransaction({ transaction }) {
|
|
137
|
+
if (spentHashTagPositions.length === 0)
|
|
138
|
+
return;
|
|
139
|
+
spentHashTagPositions = spentHashTagPositions.map((pos) => transaction.mapping.map(pos, -1));
|
|
140
|
+
spentHashTagPositions = spentHashTagPositions.filter((pos) => {
|
|
141
|
+
try {
|
|
142
|
+
if (pos < 0 || pos >= transaction.doc.content.size)
|
|
143
|
+
return false;
|
|
144
|
+
const char = transaction.doc.textBetween(pos, pos + 1);
|
|
145
|
+
return char === "#";
|
|
146
|
+
} catch (e) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
spentHashTagPositions = Array.from(new Set(spentHashTagPositions));
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
const MentionTracker = Extension.create({
|
|
154
|
+
name: "mentionTracker",
|
|
155
|
+
onTransaction({ transaction }) {
|
|
156
|
+
if (spentMentionPositions.length === 0)
|
|
157
|
+
return;
|
|
158
|
+
spentMentionPositions = spentMentionPositions.map((pos) => transaction.mapping.map(pos, -1));
|
|
159
|
+
spentMentionPositions = spentMentionPositions.filter((pos) => {
|
|
160
|
+
try {
|
|
161
|
+
if (pos < 0 || pos >= transaction.doc.content.size)
|
|
162
|
+
return false;
|
|
163
|
+
const char = transaction.doc.textBetween(pos, pos + 1);
|
|
164
|
+
return char === "@";
|
|
165
|
+
} catch (e) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
spentMentionPositions = Array.from(new Set(spentMentionPositions));
|
|
170
|
+
}
|
|
171
|
+
});
|
|
117
172
|
const extensions = [
|
|
118
173
|
StarterKit,
|
|
119
174
|
HtmlBlock,
|
|
@@ -244,21 +299,61 @@ function useExtensions({ props, emit }) {
|
|
|
244
299
|
suggestion: {
|
|
245
300
|
char: "@",
|
|
246
301
|
allowedPrefixes: null,
|
|
247
|
-
|
|
302
|
+
allowSpaces: false,
|
|
303
|
+
/**
|
|
304
|
+
* allow
|
|
305
|
+
* - 功能:判断是否允许触发建议态。
|
|
306
|
+
* - 1. 当@ 前面一个字符是数字/英文时,不触发,防止用户是想要输入邮箱。
|
|
307
|
+
* - 2. 触发以后如果包含数字,则收起(通过返回 false 销毁建议态)。
|
|
308
|
+
*/
|
|
309
|
+
allow: ({ state, range }) => {
|
|
310
|
+
if (spentMentionPositions.includes(range.from)) {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
const doc = state.doc;
|
|
314
|
+
const $from = doc.resolve(range.from);
|
|
315
|
+
const isAtStart = range.from === $from.start();
|
|
316
|
+
const prevChar = isAtStart ? "" : doc.textBetween(range.from - 1, range.from);
|
|
317
|
+
if (/[a-zA-Z0-9]/.test(prevChar)) {
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
const query = doc.textBetween(range.from + 1, range.to);
|
|
321
|
+
if (/[0-9]/.test(query)) {
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
return true;
|
|
325
|
+
},
|
|
248
326
|
render() {
|
|
249
327
|
return {
|
|
250
|
-
onStart({ command }) {
|
|
328
|
+
onStart({ editor, range, command, query }) {
|
|
329
|
+
activeEditor = editor;
|
|
251
330
|
emit("mention-triggered", (data) => {
|
|
252
331
|
command({
|
|
253
332
|
id: data.userId,
|
|
254
333
|
label: data.name
|
|
255
334
|
});
|
|
256
335
|
});
|
|
336
|
+
emit("mention-input", query != null ? query : "");
|
|
337
|
+
},
|
|
338
|
+
onUpdate({ query, editor }) {
|
|
339
|
+
activeEditor = editor;
|
|
340
|
+
emit("mention-input", query != null ? query : "");
|
|
341
|
+
},
|
|
342
|
+
onExit({ range }) {
|
|
343
|
+
if (range.from !== void 0) {
|
|
344
|
+
spentMentionPositions.push(range.from);
|
|
345
|
+
}
|
|
346
|
+
emit("mention-exit");
|
|
257
347
|
}
|
|
258
348
|
};
|
|
259
349
|
}
|
|
260
350
|
}
|
|
261
351
|
}),
|
|
352
|
+
/**
|
|
353
|
+
* 辅助扩展:追踪记录已失活的触发点
|
|
354
|
+
*/
|
|
355
|
+
MentionTracker,
|
|
356
|
+
HashTagTracker,
|
|
262
357
|
// HashTag 扩展:支持 # 触发、实时输入同步、完成后插入为 “#+文字”
|
|
263
358
|
HashTag
|
|
264
359
|
];
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -36,7 +36,7 @@ __export(stdin_exports, {
|
|
|
36
36
|
module.exports = __toCommonJS(stdin_exports);
|
|
37
37
|
var import_rich_text_editor = __toESM(require("./rich-text-editor"));
|
|
38
38
|
__reExport(stdin_exports, require("./rich-text-editor"), module.exports);
|
|
39
|
-
const version = "1.0.
|
|
39
|
+
const version = "1.0.46";
|
|
40
40
|
function install(app) {
|
|
41
41
|
const components = [
|
|
42
42
|
import_rich_text_editor.default
|
|
@@ -16,7 +16,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
16
16
|
type: BooleanConstructor;
|
|
17
17
|
default: boolean;
|
|
18
18
|
};
|
|
19
|
-
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("blur" | "focus" | "hashTag-triggered" | "hashTag-input" | "hashTag-exit" | "mention-triggered" | "update:modelValue" | "mention-clicked" | "hashTag-clicked")[], "blur" | "focus" | "hashTag-triggered" | "hashTag-input" | "hashTag-exit" | "mention-triggered" | "update:modelValue" | "mention-clicked" | "hashTag-clicked", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
19
|
+
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("blur" | "focus" | "hashTag-triggered" | "hashTag-input" | "hashTag-exit" | "mention-triggered" | "mention-input" | "mention-exit" | "update:modelValue" | "mention-clicked" | "hashTag-clicked")[], "blur" | "focus" | "hashTag-triggered" | "hashTag-input" | "hashTag-exit" | "mention-triggered" | "mention-input" | "mention-exit" | "update:modelValue" | "mention-clicked" | "hashTag-clicked", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
20
20
|
modelValue: {
|
|
21
21
|
type: StringConstructor;
|
|
22
22
|
default: string;
|
|
@@ -39,6 +39,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
39
39
|
"onHashTag-input"?: ((...args: any[]) => any) | undefined;
|
|
40
40
|
"onHashTag-exit"?: ((...args: any[]) => any) | undefined;
|
|
41
41
|
"onMention-triggered"?: ((...args: any[]) => any) | undefined;
|
|
42
|
+
"onMention-input"?: ((...args: any[]) => any) | undefined;
|
|
43
|
+
"onMention-exit"?: ((...args: any[]) => any) | undefined;
|
|
42
44
|
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
43
45
|
"onMention-clicked"?: ((...args: any[]) => any) | undefined;
|
|
44
46
|
"onHashTag-clicked"?: ((...args: any[]) => any) | undefined;
|
|
@@ -63,7 +63,7 @@ var import_index = require("./index.css");
|
|
|
63
63
|
var stdin_default = (0, import_vue2.defineComponent)({
|
|
64
64
|
name: "RichTextEditor",
|
|
65
65
|
props: import_types.richTextEditorProps,
|
|
66
|
-
emits: ["update:modelValue", "mention-triggered", "mention-clicked", "hashTag-triggered", "hashTag-input", "hashTag-exit", "hashTag-clicked", "blur", "focus"],
|
|
66
|
+
emits: ["update:modelValue", "mention-triggered", "mention-input", "mention-exit", "mention-clicked", "hashTag-triggered", "hashTag-input", "hashTag-exit", "hashTag-clicked", "blur", "focus"],
|
|
67
67
|
setup(props, {
|
|
68
68
|
emit,
|
|
69
69
|
expose
|
|
@@ -8,4 +8,4 @@ import { Extension } from '@tiptap/core';
|
|
|
8
8
|
* - 返回值:Extension[] 扩展数组,用于初始化 TipTap 编辑器。
|
|
9
9
|
* - 异常:无显式抛出;若内部命令执行失败(例如插入内容时)可能由 TipTap 抛出异常,应在上层统一处理。
|
|
10
10
|
*/
|
|
11
|
-
export declare function useExtensions({ props, emit }: any): (import("@tiptap/core").Node<any, any> | import("@tiptap/core").Node<import("@tiptap/extension-mention").MentionOptions<any, import("@tiptap/extension-mention").MentionNodeAttrs>, any> | Extension<import("@tiptap/starter-kit").StarterKitOptions, any> |
|
|
11
|
+
export declare function useExtensions({ props, emit }: any): (import("@tiptap/core").Node<any, any> | import("@tiptap/core").Node<import("@tiptap/extension-mention").MentionOptions<any, import("@tiptap/extension-mention").MentionNodeAttrs>, any> | Extension<any, any> | Extension<import("@tiptap/starter-kit").StarterKitOptions, any> | import("@tiptap/core").Mark<import("@tiptap/extension-text-style").TextStyleOptions, any> | Extension<import("@tiptap/extension-text-style").ColorOptions, any> | Extension<import("tiptap-markdown").MarkdownOptions, import("tiptap-markdown").MarkdownStorage> | import("@tiptap/core").Node<import("@tiptap/extension-image").ImageOptions, any> | Extension<import("@tiptap/extension-table").TableKitOptions, any> | Extension<import("@tiptap/extensions").PlaceholderOptions, any> | Extension<import("@tiptap/extension-list").ListKitOptions, any>)[];
|
|
@@ -42,6 +42,9 @@ var import_core = require("@tiptap/core");
|
|
|
42
42
|
var import_HtmlBlock = __toESM(require("./extensions/HtmlBlock"));
|
|
43
43
|
var import_extensions = require("@tiptap/extensions");
|
|
44
44
|
function useExtensions({ props, emit }) {
|
|
45
|
+
let spentHashTagPositions = [];
|
|
46
|
+
let spentMentionPositions = [];
|
|
47
|
+
let activeEditor = null;
|
|
45
48
|
const HashTag = import_extension_mention.default.extend({
|
|
46
49
|
name: "hashTag",
|
|
47
50
|
renderHTML({ node, HTMLAttributes }) {
|
|
@@ -66,9 +69,20 @@ function useExtensions({ props, emit }) {
|
|
|
66
69
|
suggestion: {
|
|
67
70
|
char: "#",
|
|
68
71
|
allowedPrefixes: null,
|
|
72
|
+
allowSpaces: false,
|
|
73
|
+
/**
|
|
74
|
+
* allow
|
|
75
|
+
* - 功能:判断是否允许触发建议态。
|
|
76
|
+
* - 1. 若该位置的 # 已经触发过且未被删除,则不再重复触发(满足“单次触发制/光标静默”)。
|
|
77
|
+
*/
|
|
78
|
+
allow: ({ state, range }) => {
|
|
79
|
+
if (spentHashTagPositions.includes(range.from)) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
},
|
|
69
84
|
render() {
|
|
70
85
|
let activeRange = null;
|
|
71
|
-
let activeEditor = null;
|
|
72
86
|
let exitCause = "unknown";
|
|
73
87
|
return {
|
|
74
88
|
onStart({ editor, range, command, query }) {
|
|
@@ -120,7 +134,7 @@ function useExtensions({ props, emit }) {
|
|
|
120
134
|
* - 返回值:无(通过 emit 派发事件)。
|
|
121
135
|
* - 异常:内部读取选择/文档时若发生异常,捕获后保持原有退出原因,不影响外部流程。
|
|
122
136
|
*/
|
|
123
|
-
onExit() {
|
|
137
|
+
onExit({ range }) {
|
|
124
138
|
var _a, _b, _c, _d, _e;
|
|
125
139
|
try {
|
|
126
140
|
const editorRef = activeEditor;
|
|
@@ -134,6 +148,9 @@ function useExtensions({ props, emit }) {
|
|
|
134
148
|
}
|
|
135
149
|
} catch (e) {
|
|
136
150
|
}
|
|
151
|
+
if ((range == null ? void 0 : range.from) !== void 0) {
|
|
152
|
+
spentHashTagPositions.push(range.from);
|
|
153
|
+
}
|
|
137
154
|
activeRange = null;
|
|
138
155
|
activeEditor = null;
|
|
139
156
|
const payload = {
|
|
@@ -146,6 +163,44 @@ function useExtensions({ props, emit }) {
|
|
|
146
163
|
}
|
|
147
164
|
}
|
|
148
165
|
});
|
|
166
|
+
const HashTagTracker = import_core.Extension.create({
|
|
167
|
+
name: "hashTagTracker",
|
|
168
|
+
onTransaction({ transaction }) {
|
|
169
|
+
if (spentHashTagPositions.length === 0)
|
|
170
|
+
return;
|
|
171
|
+
spentHashTagPositions = spentHashTagPositions.map((pos) => transaction.mapping.map(pos, -1));
|
|
172
|
+
spentHashTagPositions = spentHashTagPositions.filter((pos) => {
|
|
173
|
+
try {
|
|
174
|
+
if (pos < 0 || pos >= transaction.doc.content.size)
|
|
175
|
+
return false;
|
|
176
|
+
const char = transaction.doc.textBetween(pos, pos + 1);
|
|
177
|
+
return char === "#";
|
|
178
|
+
} catch (e) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
spentHashTagPositions = Array.from(new Set(spentHashTagPositions));
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
const MentionTracker = import_core.Extension.create({
|
|
186
|
+
name: "mentionTracker",
|
|
187
|
+
onTransaction({ transaction }) {
|
|
188
|
+
if (spentMentionPositions.length === 0)
|
|
189
|
+
return;
|
|
190
|
+
spentMentionPositions = spentMentionPositions.map((pos) => transaction.mapping.map(pos, -1));
|
|
191
|
+
spentMentionPositions = spentMentionPositions.filter((pos) => {
|
|
192
|
+
try {
|
|
193
|
+
if (pos < 0 || pos >= transaction.doc.content.size)
|
|
194
|
+
return false;
|
|
195
|
+
const char = transaction.doc.textBetween(pos, pos + 1);
|
|
196
|
+
return char === "@";
|
|
197
|
+
} catch (e) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
spentMentionPositions = Array.from(new Set(spentMentionPositions));
|
|
202
|
+
}
|
|
203
|
+
});
|
|
149
204
|
const extensions = [
|
|
150
205
|
import_starter_kit.default,
|
|
151
206
|
import_HtmlBlock.default,
|
|
@@ -276,21 +331,61 @@ function useExtensions({ props, emit }) {
|
|
|
276
331
|
suggestion: {
|
|
277
332
|
char: "@",
|
|
278
333
|
allowedPrefixes: null,
|
|
279
|
-
|
|
334
|
+
allowSpaces: false,
|
|
335
|
+
/**
|
|
336
|
+
* allow
|
|
337
|
+
* - 功能:判断是否允许触发建议态。
|
|
338
|
+
* - 1. 当@ 前面一个字符是数字/英文时,不触发,防止用户是想要输入邮箱。
|
|
339
|
+
* - 2. 触发以后如果包含数字,则收起(通过返回 false 销毁建议态)。
|
|
340
|
+
*/
|
|
341
|
+
allow: ({ state, range }) => {
|
|
342
|
+
if (spentMentionPositions.includes(range.from)) {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
const doc = state.doc;
|
|
346
|
+
const $from = doc.resolve(range.from);
|
|
347
|
+
const isAtStart = range.from === $from.start();
|
|
348
|
+
const prevChar = isAtStart ? "" : doc.textBetween(range.from - 1, range.from);
|
|
349
|
+
if (/[a-zA-Z0-9]/.test(prevChar)) {
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
const query = doc.textBetween(range.from + 1, range.to);
|
|
353
|
+
if (/[0-9]/.test(query)) {
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
return true;
|
|
357
|
+
},
|
|
280
358
|
render() {
|
|
281
359
|
return {
|
|
282
|
-
onStart({ command }) {
|
|
360
|
+
onStart({ editor, range, command, query }) {
|
|
361
|
+
activeEditor = editor;
|
|
283
362
|
emit("mention-triggered", (data) => {
|
|
284
363
|
command({
|
|
285
364
|
id: data.userId,
|
|
286
365
|
label: data.name
|
|
287
366
|
});
|
|
288
367
|
});
|
|
368
|
+
emit("mention-input", query != null ? query : "");
|
|
369
|
+
},
|
|
370
|
+
onUpdate({ query, editor }) {
|
|
371
|
+
activeEditor = editor;
|
|
372
|
+
emit("mention-input", query != null ? query : "");
|
|
373
|
+
},
|
|
374
|
+
onExit({ range }) {
|
|
375
|
+
if (range.from !== void 0) {
|
|
376
|
+
spentMentionPositions.push(range.from);
|
|
377
|
+
}
|
|
378
|
+
emit("mention-exit");
|
|
289
379
|
}
|
|
290
380
|
};
|
|
291
381
|
}
|
|
292
382
|
}
|
|
293
383
|
}),
|
|
384
|
+
/**
|
|
385
|
+
* 辅助扩展:追踪记录已失活的触发点
|
|
386
|
+
*/
|
|
387
|
+
MentionTracker,
|
|
388
|
+
HashTagTracker,
|
|
294
389
|
// HashTag 扩展:支持 # 触发、实时输入同步、完成后插入为 “#+文字”
|
|
295
390
|
HashTag
|
|
296
391
|
];
|