@dialpad/dialtone-vue 2.129.0 → 2.130.2
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/common/utils.cjs +8 -1
- package/dist/common/utils.cjs.map +1 -1
- package/dist/common/utils.js +8 -1
- package/dist/common/utils.js.map +1 -1
- package/dist/lib/message-input.cjs +63 -24
- package/dist/lib/message-input.cjs.map +1 -1
- package/dist/lib/message-input.js +63 -24
- package/dist/lib/message-input.js.map +1 -1
- package/dist/lib/rich-text-editor.cjs +463 -67
- package/dist/lib/rich-text-editor.cjs.map +1 -1
- package/dist/lib/rich-text-editor.js +464 -68
- package/dist/lib/rich-text-editor.js.map +1 -1
- package/dist/lib/tooltip.cjs +5 -4
- package/dist/lib/tooltip.cjs.map +1 -1
- package/dist/lib/tooltip.js +5 -4
- package/dist/lib/tooltip.js.map +1 -1
- package/dist/types/common/utils/index.d.ts.map +1 -1
- package/dist/types/components/rich_text_editor/extensions/channels/channel.d.ts +2 -1
- package/dist/types/components/rich_text_editor/extensions/channels/channel.d.ts.map +1 -1
- package/dist/types/components/rich_text_editor/extensions/emoji/emoji.d.ts +1 -0
- package/dist/types/components/rich_text_editor/extensions/emoji/emoji.d.ts.map +1 -1
- package/dist/types/components/rich_text_editor/extensions/mentions/mention.d.ts +2 -1
- package/dist/types/components/rich_text_editor/extensions/mentions/mention.d.ts.map +1 -1
- package/dist/types/components/rich_text_editor/extensions/slash_command/SlashCommandComponent.vue.d.ts +47 -0
- package/dist/types/components/rich_text_editor/extensions/slash_command/SlashCommandComponent.vue.d.ts.map +1 -0
- package/dist/types/components/rich_text_editor/extensions/slash_command/SlashCommandSuggestion.vue.d.ts +17 -0
- package/dist/types/components/rich_text_editor/extensions/slash_command/SlashCommandSuggestion.vue.d.ts.map +1 -0
- package/dist/types/components/rich_text_editor/extensions/slash_command/slash_command.d.ts +2 -0
- package/dist/types/components/rich_text_editor/extensions/slash_command/slash_command.d.ts.map +1 -0
- package/dist/types/components/rich_text_editor/extensions/slash_command/suggestion.d.ts +12 -0
- package/dist/types/components/rich_text_editor/extensions/slash_command/suggestion.d.ts.map +1 -0
- package/dist/types/components/rich_text_editor/rich_text_editor.vue.d.ts +48 -1
- package/dist/types/components/rich_text_editor/rich_text_editor.vue.d.ts.map +1 -1
- package/dist/types/components/rich_text_editor/slash_command_suggestion.d.ts +15 -0
- package/dist/types/components/rich_text_editor/slash_command_suggestion.d.ts.map +1 -0
- package/dist/types/recipes/conversation_view/message_input/message_input.vue.d.ts +38 -2
- package/dist/types/recipes/conversation_view/message_input/message_input.vue.d.ts.map +1 -1
- package/package.json +26 -26
|
@@ -33,10 +33,10 @@ const lib_link = require("./link.cjs");
|
|
|
33
33
|
const lib_avatar = require("./avatar.cjs");
|
|
34
34
|
const DtIconHash = require("@dialpad/dialtone-icons/vue2/hash");
|
|
35
35
|
const DtIconLock = require("@dialpad/dialtone-icons/vue2/lock");
|
|
36
|
+
const emojiRegex = require("emoji-regex");
|
|
36
37
|
require("./skeleton.cjs");
|
|
37
38
|
require("../chunks/icon_constants-QYpmdE0R.js");
|
|
38
39
|
require("@dialpad/dialtone-icons/icons.json");
|
|
39
|
-
require("emoji-regex");
|
|
40
40
|
require("emoji-toolkit/emoji_strategy.json");
|
|
41
41
|
require("../chunks/list_item_constants-EiqkqZvP.js");
|
|
42
42
|
require("./item-layout.cjs");
|
|
@@ -47,7 +47,7 @@ require("../common/constants.cjs");
|
|
|
47
47
|
require("vue");
|
|
48
48
|
require("../chunks/link_constants-Huj7D_hm.js");
|
|
49
49
|
require("./presence.cjs");
|
|
50
|
-
const _sfc_main$
|
|
50
|
+
const _sfc_main$9 = {
|
|
51
51
|
name: "EmojiComponent",
|
|
52
52
|
components: {
|
|
53
53
|
NodeViewWrapper: vue2.NodeViewWrapper,
|
|
@@ -55,23 +55,23 @@ const _sfc_main$7 = {
|
|
|
55
55
|
},
|
|
56
56
|
props: vue2.nodeViewProps
|
|
57
57
|
};
|
|
58
|
-
var _sfc_render$
|
|
58
|
+
var _sfc_render$9 = function render() {
|
|
59
59
|
var _vm = this, _c = _vm._self._c;
|
|
60
60
|
return _c("node-view-wrapper", { staticClass: "d-d-inline-block d-va-bottom d-lh0" }, [_c("dt-emoji", { attrs: { "size": "500", "code": _vm.node.attrs.code } })], 1);
|
|
61
61
|
};
|
|
62
|
-
var _sfc_staticRenderFns$
|
|
63
|
-
var __component__$
|
|
64
|
-
_sfc_main$
|
|
65
|
-
_sfc_render$
|
|
66
|
-
_sfc_staticRenderFns$
|
|
62
|
+
var _sfc_staticRenderFns$9 = [];
|
|
63
|
+
var __component__$9 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
|
|
64
|
+
_sfc_main$9,
|
|
65
|
+
_sfc_render$9,
|
|
66
|
+
_sfc_staticRenderFns$9,
|
|
67
67
|
false,
|
|
68
68
|
null,
|
|
69
69
|
null,
|
|
70
70
|
null,
|
|
71
71
|
null
|
|
72
72
|
);
|
|
73
|
-
const EmojiComponent = __component__$
|
|
74
|
-
const _sfc_main$
|
|
73
|
+
const EmojiComponent = __component__$9.exports;
|
|
74
|
+
const _sfc_main$8 = {
|
|
75
75
|
name: "SuggestionList",
|
|
76
76
|
components: {
|
|
77
77
|
DtListItem: lib_listItem.DtListItem
|
|
@@ -154,11 +154,14 @@ const _sfc_main$6 = {
|
|
|
154
154
|
case "channel":
|
|
155
155
|
this.command({ name: item.name, id: item.id });
|
|
156
156
|
break;
|
|
157
|
+
case "slash-command":
|
|
158
|
+
this.command({ command: item.command });
|
|
159
|
+
break;
|
|
157
160
|
}
|
|
158
161
|
}
|
|
159
162
|
}
|
|
160
163
|
};
|
|
161
|
-
var _sfc_render$
|
|
164
|
+
var _sfc_render$8 = function render2() {
|
|
162
165
|
var _vm = this, _c = _vm._self._c;
|
|
163
166
|
return _c("div", { staticClass: "d-popover__dialog" }, [_c("ul", { directives: [{ name: "show", rawName: "v-show", value: _vm.items.length, expression: "items.length" }], ref: "suggestionList", staticClass: "dt-suggestion-list" }, _vm._l(_vm.items, function(item, index) {
|
|
164
167
|
return _c("dt-list-item", { key: item.id, class: [
|
|
@@ -173,19 +176,19 @@ var _sfc_render$6 = function render2() {
|
|
|
173
176
|
} } }, [_c(_vm.itemComponent, { tag: "component", attrs: { "item": item } })], 1);
|
|
174
177
|
}), 1)]);
|
|
175
178
|
};
|
|
176
|
-
var _sfc_staticRenderFns$
|
|
177
|
-
var __component__$
|
|
178
|
-
_sfc_main$
|
|
179
|
-
_sfc_render$
|
|
180
|
-
_sfc_staticRenderFns$
|
|
179
|
+
var _sfc_staticRenderFns$8 = [];
|
|
180
|
+
var __component__$8 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
|
|
181
|
+
_sfc_main$8,
|
|
182
|
+
_sfc_render$8,
|
|
183
|
+
_sfc_staticRenderFns$8,
|
|
181
184
|
false,
|
|
182
185
|
null,
|
|
183
186
|
null,
|
|
184
187
|
null,
|
|
185
188
|
null
|
|
186
189
|
);
|
|
187
|
-
const SuggestionList = __component__$
|
|
188
|
-
const _sfc_main$
|
|
190
|
+
const SuggestionList = __component__$8.exports;
|
|
191
|
+
const _sfc_main$7 = {
|
|
189
192
|
name: "EmojiSuggestion",
|
|
190
193
|
components: {
|
|
191
194
|
DtEmoji: lib_emoji.DtEmoji,
|
|
@@ -198,22 +201,22 @@ const _sfc_main$5 = {
|
|
|
198
201
|
}
|
|
199
202
|
}
|
|
200
203
|
};
|
|
201
|
-
var _sfc_render$
|
|
204
|
+
var _sfc_render$7 = function render3() {
|
|
202
205
|
var _vm = this, _c = _vm._self._c;
|
|
203
206
|
return _c("dt-stack", { attrs: { "direction": "row", "gap": "400" } }, [_c("dt-emoji", { attrs: { "size": "200", "code": _vm.item.code } }), _vm._v(" " + _vm._s(_vm.item.code) + " ")], 1);
|
|
204
207
|
};
|
|
205
|
-
var _sfc_staticRenderFns$
|
|
206
|
-
var __component__$
|
|
207
|
-
_sfc_main$
|
|
208
|
-
_sfc_render$
|
|
209
|
-
_sfc_staticRenderFns$
|
|
208
|
+
var _sfc_staticRenderFns$7 = [];
|
|
209
|
+
var __component__$7 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
|
|
210
|
+
_sfc_main$7,
|
|
211
|
+
_sfc_render$7,
|
|
212
|
+
_sfc_staticRenderFns$7,
|
|
210
213
|
false,
|
|
211
214
|
null,
|
|
212
215
|
null,
|
|
213
216
|
null,
|
|
214
217
|
null
|
|
215
218
|
);
|
|
216
|
-
const EmojiSuggestion = __component__$
|
|
219
|
+
const EmojiSuggestion = __component__$7.exports;
|
|
217
220
|
const suggestionOptions = {
|
|
218
221
|
items: ({ query }) => {
|
|
219
222
|
if (query.length < 2) {
|
|
@@ -304,7 +307,7 @@ const suggestionOptions = {
|
|
|
304
307
|
};
|
|
305
308
|
const EmojiPluginKey = new state.PluginKey("emoji");
|
|
306
309
|
const inputShortCodeRegex = /:\w+:$/;
|
|
307
|
-
const
|
|
310
|
+
const emojiShortCodeRegex = /:\w+:/g;
|
|
308
311
|
const inputUnicodeRegex = /(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])$/;
|
|
309
312
|
const pasteUnicodeRegex = /(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/g;
|
|
310
313
|
const inputRuleMatch = (match) => {
|
|
@@ -317,7 +320,7 @@ const inputRuleMatch = (match) => {
|
|
|
317
320
|
}
|
|
318
321
|
};
|
|
319
322
|
const shortCodePasteMatch = (text) => {
|
|
320
|
-
const matches = [...text.matchAll(
|
|
323
|
+
const matches = [...text.matchAll(emojiShortCodeRegex)];
|
|
321
324
|
return matches.filter((match) => common_emoji.codeToEmojiData(match[0])).map((match) => ({
|
|
322
325
|
index: match.index,
|
|
323
326
|
text: match[0],
|
|
@@ -386,7 +389,7 @@ const Emoji = core.Node.create({
|
|
|
386
389
|
},
|
|
387
390
|
type: this.type,
|
|
388
391
|
getAttributes(attrs) {
|
|
389
|
-
const unicode = common_emoji.
|
|
392
|
+
const unicode = common_emoji.codeToEmojiData(attrs[0]).unicode_output;
|
|
390
393
|
const emoji = String.fromCodePoint(parseInt(unicode, 16));
|
|
391
394
|
return {
|
|
392
395
|
code: emoji,
|
|
@@ -564,7 +567,7 @@ function autolink(options) {
|
|
|
564
567
|
});
|
|
565
568
|
}
|
|
566
569
|
const defaultAttributes = {
|
|
567
|
-
class: "d-link d-c-text d-d-inline-block",
|
|
570
|
+
class: "d-link d-c-text d-d-inline-block d-wb-break-all",
|
|
568
571
|
rel: "noopener noreferrer nofollow"
|
|
569
572
|
};
|
|
570
573
|
const Link = core.Mark.create({
|
|
@@ -589,7 +592,7 @@ const Link = core.Mark.create({
|
|
|
589
592
|
];
|
|
590
593
|
}
|
|
591
594
|
});
|
|
592
|
-
const _sfc_main$
|
|
595
|
+
const _sfc_main$6 = {
|
|
593
596
|
name: "MentionComponent",
|
|
594
597
|
components: {
|
|
595
598
|
NodeViewWrapper: vue2.NodeViewWrapper,
|
|
@@ -602,23 +605,50 @@ const _sfc_main$4 = {
|
|
|
602
605
|
}
|
|
603
606
|
}
|
|
604
607
|
};
|
|
605
|
-
var _sfc_render$
|
|
608
|
+
var _sfc_render$6 = function render4() {
|
|
606
609
|
var _vm = this, _c = _vm._self._c;
|
|
607
610
|
return _c("node-view-wrapper", { staticClass: "d-d-inline-block" }, [_c("dt-link", { attrs: { "kind": "mention" } }, [_vm._v(" " + _vm._s(_vm.text) + " ")])], 1);
|
|
608
611
|
};
|
|
609
|
-
var _sfc_staticRenderFns$
|
|
610
|
-
var __component__$
|
|
611
|
-
_sfc_main$
|
|
612
|
-
_sfc_render$
|
|
613
|
-
_sfc_staticRenderFns$
|
|
612
|
+
var _sfc_staticRenderFns$6 = [];
|
|
613
|
+
var __component__$6 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
|
|
614
|
+
_sfc_main$6,
|
|
615
|
+
_sfc_render$6,
|
|
616
|
+
_sfc_staticRenderFns$6,
|
|
614
617
|
false,
|
|
615
618
|
null,
|
|
616
619
|
null,
|
|
617
620
|
null,
|
|
618
621
|
null
|
|
619
622
|
);
|
|
620
|
-
const MentionComponent = __component__$
|
|
623
|
+
const MentionComponent = __component__$6.exports;
|
|
624
|
+
const mentionRegex = /@([\w.-]+)[^\w.-]?/g;
|
|
625
|
+
const mentionPasteMatch = (text, suggestions) => {
|
|
626
|
+
const matches = [...text.matchAll(mentionRegex)];
|
|
627
|
+
return matches.filter((match) => suggestions.some(({ id }) => id === match[1].trim())).map((match) => {
|
|
628
|
+
let mention = match[1];
|
|
629
|
+
if (!mention.endsWith(" "))
|
|
630
|
+
mention += " ";
|
|
631
|
+
return {
|
|
632
|
+
index: match.index,
|
|
633
|
+
text: mention,
|
|
634
|
+
match
|
|
635
|
+
};
|
|
636
|
+
});
|
|
637
|
+
};
|
|
638
|
+
const mentionInputMatch = (text, suggestions) => {
|
|
639
|
+
const match = text.match(/@([\w.-]+)[^\w.-]$/);
|
|
640
|
+
if (!match || !suggestions.some(({ id }) => id === match[1]))
|
|
641
|
+
return;
|
|
642
|
+
return {
|
|
643
|
+
index: match.index,
|
|
644
|
+
text: match[0],
|
|
645
|
+
match
|
|
646
|
+
};
|
|
647
|
+
};
|
|
621
648
|
const MentionPlugin = Mention.extend({
|
|
649
|
+
name: "mention",
|
|
650
|
+
group: "inline",
|
|
651
|
+
inline: true,
|
|
622
652
|
addNodeView() {
|
|
623
653
|
return vue2.VueNodeViewRenderer(MentionComponent);
|
|
624
654
|
},
|
|
@@ -646,10 +676,41 @@ const MentionPlugin = Mention.extend({
|
|
|
646
676
|
return `@${node.attrs.id}`;
|
|
647
677
|
},
|
|
648
678
|
renderHTML({ HTMLAttributes }) {
|
|
649
|
-
return ["mention-component", core.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)
|
|
679
|
+
return ["mention-component", core.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];
|
|
680
|
+
},
|
|
681
|
+
addInputRules() {
|
|
682
|
+
var _a;
|
|
683
|
+
const suggestions = (_a = this.options.suggestion) == null ? void 0 : _a.items({ query: "" });
|
|
684
|
+
return [
|
|
685
|
+
core.nodeInputRule({
|
|
686
|
+
find: (text) => mentionInputMatch(text, suggestions),
|
|
687
|
+
type: this.type,
|
|
688
|
+
getAttributes(attrs) {
|
|
689
|
+
return suggestions.find(({ id }) => id === attrs[0].replace("@", "").trim());
|
|
690
|
+
}
|
|
691
|
+
})
|
|
692
|
+
];
|
|
693
|
+
},
|
|
694
|
+
addPasteRules() {
|
|
695
|
+
var _a;
|
|
696
|
+
const suggestions = (_a = this.options.suggestion) == null ? void 0 : _a.items({ query: "" });
|
|
697
|
+
return [
|
|
698
|
+
core.nodePasteRule({
|
|
699
|
+
find: (text) => mentionPasteMatch(text, suggestions),
|
|
700
|
+
type: this.type,
|
|
701
|
+
getAttributes(attrs) {
|
|
702
|
+
return suggestions.find(({ id }) => id === attrs[0].trim());
|
|
703
|
+
}
|
|
704
|
+
})
|
|
705
|
+
];
|
|
706
|
+
}
|
|
707
|
+
}).configure({
|
|
708
|
+
suggestion: {
|
|
709
|
+
char: "@",
|
|
710
|
+
pluginKey: new state.PluginKey("mentionSuggestion")
|
|
650
711
|
}
|
|
651
712
|
});
|
|
652
|
-
const _sfc_main$
|
|
713
|
+
const _sfc_main$5 = {
|
|
653
714
|
name: "ChannelComponent",
|
|
654
715
|
components: {
|
|
655
716
|
NodeViewWrapper: vue2.NodeViewWrapper,
|
|
@@ -662,24 +723,50 @@ const _sfc_main$3 = {
|
|
|
662
723
|
}
|
|
663
724
|
}
|
|
664
725
|
};
|
|
665
|
-
var _sfc_render$
|
|
726
|
+
var _sfc_render$5 = function render5() {
|
|
666
727
|
var _vm = this, _c = _vm._self._c;
|
|
667
728
|
return _c("node-view-wrapper", { staticClass: "d-d-inline-block" }, [_c("dt-link", { attrs: { "kind": "mention" } }, [_vm._v(" " + _vm._s(_vm.text) + " ")])], 1);
|
|
668
729
|
};
|
|
669
|
-
var _sfc_staticRenderFns$
|
|
670
|
-
var __component__$
|
|
671
|
-
_sfc_main$
|
|
672
|
-
_sfc_render$
|
|
673
|
-
_sfc_staticRenderFns$
|
|
730
|
+
var _sfc_staticRenderFns$5 = [];
|
|
731
|
+
var __component__$5 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
|
|
732
|
+
_sfc_main$5,
|
|
733
|
+
_sfc_render$5,
|
|
734
|
+
_sfc_staticRenderFns$5,
|
|
674
735
|
false,
|
|
675
736
|
null,
|
|
676
737
|
null,
|
|
677
738
|
null,
|
|
678
739
|
null
|
|
679
740
|
);
|
|
680
|
-
const ChannelComponent = __component__$
|
|
741
|
+
const ChannelComponent = __component__$5.exports;
|
|
742
|
+
const channelRegex = /#([\w-]+)[^\w-]?/g;
|
|
743
|
+
const channelPasteMatch = (text, suggestions) => {
|
|
744
|
+
const matches = [...text.matchAll(channelRegex)];
|
|
745
|
+
return matches.filter((match) => suggestions.some(({ id }) => id === match[1].trim())).map((match) => {
|
|
746
|
+
let channel = match[1];
|
|
747
|
+
if (!channel.endsWith(" "))
|
|
748
|
+
channel += " ";
|
|
749
|
+
return {
|
|
750
|
+
index: match.index,
|
|
751
|
+
text: channel,
|
|
752
|
+
match
|
|
753
|
+
};
|
|
754
|
+
});
|
|
755
|
+
};
|
|
756
|
+
const channelInputMatch = (text, suggestions) => {
|
|
757
|
+
const match = text.match(/#([\w-]+)[^\w-]$/);
|
|
758
|
+
if (!match || !suggestions.some(({ id }) => id === match[1]))
|
|
759
|
+
return;
|
|
760
|
+
return {
|
|
761
|
+
index: match.index,
|
|
762
|
+
text: match[0],
|
|
763
|
+
match
|
|
764
|
+
};
|
|
765
|
+
};
|
|
681
766
|
const ChannelPlugin = Mention.extend({
|
|
682
767
|
name: "channel",
|
|
768
|
+
group: "inline",
|
|
769
|
+
inline: true,
|
|
683
770
|
addNodeView() {
|
|
684
771
|
return vue2.VueNodeViewRenderer(ChannelComponent);
|
|
685
772
|
},
|
|
@@ -707,7 +794,33 @@ const ChannelPlugin = Mention.extend({
|
|
|
707
794
|
return `#${node.attrs.id}`;
|
|
708
795
|
},
|
|
709
796
|
renderHTML({ HTMLAttributes }) {
|
|
710
|
-
return ["channel-component", core.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)
|
|
797
|
+
return ["channel-component", core.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];
|
|
798
|
+
},
|
|
799
|
+
addInputRules() {
|
|
800
|
+
var _a;
|
|
801
|
+
const suggestions = (_a = this.options.suggestion) == null ? void 0 : _a.items({ query: "" });
|
|
802
|
+
return [
|
|
803
|
+
core.nodeInputRule({
|
|
804
|
+
find: (text) => channelInputMatch(text, suggestions),
|
|
805
|
+
type: this.type,
|
|
806
|
+
getAttributes(attrs) {
|
|
807
|
+
return suggestions.find(({ id }) => id === attrs[0].replace("#", "").trim());
|
|
808
|
+
}
|
|
809
|
+
})
|
|
810
|
+
];
|
|
811
|
+
},
|
|
812
|
+
addPasteRules() {
|
|
813
|
+
var _a;
|
|
814
|
+
const suggestions = (_a = this.options.suggestion) == null ? void 0 : _a.items({ query: "" });
|
|
815
|
+
return [
|
|
816
|
+
core.nodePasteRule({
|
|
817
|
+
find: (text) => channelPasteMatch(text, suggestions),
|
|
818
|
+
type: this.type,
|
|
819
|
+
getAttributes(attrs) {
|
|
820
|
+
return suggestions.find(({ id }) => id === attrs[0].trim());
|
|
821
|
+
}
|
|
822
|
+
})
|
|
823
|
+
];
|
|
711
824
|
}
|
|
712
825
|
}).configure({
|
|
713
826
|
suggestion: {
|
|
@@ -715,6 +828,118 @@ const ChannelPlugin = Mention.extend({
|
|
|
715
828
|
pluginKey: new state.PluginKey("channelSuggestion")
|
|
716
829
|
}
|
|
717
830
|
});
|
|
831
|
+
const _sfc_main$4 = {
|
|
832
|
+
name: "SlashCommandsComponent",
|
|
833
|
+
components: {
|
|
834
|
+
NodeViewWrapper: vue2.NodeViewWrapper
|
|
835
|
+
},
|
|
836
|
+
props: vue2.nodeViewProps,
|
|
837
|
+
emits: ["selected-command"],
|
|
838
|
+
computed: {
|
|
839
|
+
text() {
|
|
840
|
+
return "/" + this.$props.node.attrs.command;
|
|
841
|
+
}
|
|
842
|
+
},
|
|
843
|
+
created() {
|
|
844
|
+
this.$parent.$emit("selected-command", this.$props.node.attrs.command);
|
|
845
|
+
}
|
|
846
|
+
};
|
|
847
|
+
var _sfc_render$4 = function render6() {
|
|
848
|
+
var _vm = this, _c = _vm._self._c;
|
|
849
|
+
return _c("node-view-wrapper", { staticClass: "d-d-inline-block" }, [_vm._v(" " + _vm._s(_vm.text) + " ")]);
|
|
850
|
+
};
|
|
851
|
+
var _sfc_staticRenderFns$4 = [];
|
|
852
|
+
var __component__$4 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
|
|
853
|
+
_sfc_main$4,
|
|
854
|
+
_sfc_render$4,
|
|
855
|
+
_sfc_staticRenderFns$4,
|
|
856
|
+
false,
|
|
857
|
+
null,
|
|
858
|
+
null,
|
|
859
|
+
null,
|
|
860
|
+
null
|
|
861
|
+
);
|
|
862
|
+
const SlashCommandComponent = __component__$4.exports;
|
|
863
|
+
const slashCommandPasteMatch = (text, slashCommandRegex) => {
|
|
864
|
+
const matches = [...text.matchAll(slashCommandRegex)];
|
|
865
|
+
return matches.map((match) => {
|
|
866
|
+
let slashCommand = match[2];
|
|
867
|
+
if (!slashCommand.endsWith(" "))
|
|
868
|
+
slashCommand += " ";
|
|
869
|
+
return {
|
|
870
|
+
index: match.index,
|
|
871
|
+
text: slashCommand,
|
|
872
|
+
match
|
|
873
|
+
};
|
|
874
|
+
});
|
|
875
|
+
};
|
|
876
|
+
const SlashCommandPlugin = Mention.extend({
|
|
877
|
+
name: "slash-commands",
|
|
878
|
+
group: "inline",
|
|
879
|
+
inline: true,
|
|
880
|
+
addNodeView() {
|
|
881
|
+
return vue2.VueNodeViewRenderer(SlashCommandComponent);
|
|
882
|
+
},
|
|
883
|
+
parseHTML() {
|
|
884
|
+
return [
|
|
885
|
+
{
|
|
886
|
+
tag: "command-component"
|
|
887
|
+
}
|
|
888
|
+
];
|
|
889
|
+
},
|
|
890
|
+
addAttributes() {
|
|
891
|
+
return {
|
|
892
|
+
command: {
|
|
893
|
+
default: ""
|
|
894
|
+
},
|
|
895
|
+
paramentersExample: {
|
|
896
|
+
default: ""
|
|
897
|
+
},
|
|
898
|
+
description: {
|
|
899
|
+
default: ""
|
|
900
|
+
}
|
|
901
|
+
};
|
|
902
|
+
},
|
|
903
|
+
renderText({ node }) {
|
|
904
|
+
return `/${node.attrs.command}`;
|
|
905
|
+
},
|
|
906
|
+
renderHTML({ HTMLAttributes }) {
|
|
907
|
+
return ["command-component", core.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];
|
|
908
|
+
},
|
|
909
|
+
addInputRules() {
|
|
910
|
+
var _a;
|
|
911
|
+
const suggestions = (_a = this.options.suggestion) == null ? void 0 : _a.items({ query: "" }).map((suggestion) => suggestion.command);
|
|
912
|
+
const slashCommandRegex = new RegExp(`^((?:\\/)(${suggestions.join("|")})) $`);
|
|
913
|
+
return [
|
|
914
|
+
core.nodeInputRule({
|
|
915
|
+
find: slashCommandRegex,
|
|
916
|
+
type: this.type,
|
|
917
|
+
getAttributes(attrs) {
|
|
918
|
+
return { command: attrs[2] };
|
|
919
|
+
}
|
|
920
|
+
})
|
|
921
|
+
];
|
|
922
|
+
},
|
|
923
|
+
addPasteRules() {
|
|
924
|
+
var _a;
|
|
925
|
+
const suggestions = (_a = this.options.suggestion) == null ? void 0 : _a.items({ query: "" }).map((suggestion) => suggestion.command);
|
|
926
|
+
const slashCommandRegex = new RegExp(`^((?:\\/)(${suggestions.join("|")})) ?$`, "g");
|
|
927
|
+
return [
|
|
928
|
+
core.nodePasteRule({
|
|
929
|
+
find: (text) => slashCommandPasteMatch(text, slashCommandRegex),
|
|
930
|
+
type: this.type,
|
|
931
|
+
getAttributes(attrs) {
|
|
932
|
+
return { command: attrs[0].trim() };
|
|
933
|
+
}
|
|
934
|
+
})
|
|
935
|
+
];
|
|
936
|
+
}
|
|
937
|
+
}).configure({
|
|
938
|
+
suggestion: {
|
|
939
|
+
char: "/",
|
|
940
|
+
pluginKey: new state.PluginKey("slashCommandSuggestion")
|
|
941
|
+
}
|
|
942
|
+
});
|
|
718
943
|
const RICH_TEXT_EDITOR_OUTPUT_FORMATS = [
|
|
719
944
|
"text",
|
|
720
945
|
"json",
|
|
@@ -733,7 +958,7 @@ const RICH_TEXT_EDITOR_SUPPORTED_LINK_PROTOCOLS = [
|
|
|
733
958
|
"sftp",
|
|
734
959
|
"mailto"
|
|
735
960
|
];
|
|
736
|
-
const _sfc_main$
|
|
961
|
+
const _sfc_main$3 = {
|
|
737
962
|
name: "MentionSuggestion",
|
|
738
963
|
components: {
|
|
739
964
|
DtAvatar: lib_avatar.DtAvatar,
|
|
@@ -754,22 +979,22 @@ const _sfc_main$2 = {
|
|
|
754
979
|
}
|
|
755
980
|
}
|
|
756
981
|
};
|
|
757
|
-
var _sfc_render$
|
|
982
|
+
var _sfc_render$3 = function render7() {
|
|
758
983
|
var _vm = this, _c = _vm._self._c;
|
|
759
984
|
return _c("dt-stack", { attrs: { "direction": "row", "gap": "400" } }, [_c("dt-avatar", { attrs: { "full-name": _vm.name, "image-src": _vm.avatarSrc, "image-alt": _vm.name, "size": "xs" } }), _vm._v(" " + _vm._s(_vm.name) + " ")], 1);
|
|
760
985
|
};
|
|
761
|
-
var _sfc_staticRenderFns$
|
|
762
|
-
var __component__$
|
|
763
|
-
_sfc_main$
|
|
764
|
-
_sfc_render$
|
|
765
|
-
_sfc_staticRenderFns$
|
|
986
|
+
var _sfc_staticRenderFns$3 = [];
|
|
987
|
+
var __component__$3 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
|
|
988
|
+
_sfc_main$3,
|
|
989
|
+
_sfc_render$3,
|
|
990
|
+
_sfc_staticRenderFns$3,
|
|
766
991
|
false,
|
|
767
992
|
null,
|
|
768
993
|
null,
|
|
769
994
|
null,
|
|
770
995
|
null
|
|
771
996
|
);
|
|
772
|
-
const MentionSuggestion = __component__$
|
|
997
|
+
const MentionSuggestion = __component__$3.exports;
|
|
773
998
|
const mentionSuggestion = {
|
|
774
999
|
// This function comes from the user and passed to the editor directly.
|
|
775
1000
|
// This will also activate the mention plugin on the editor
|
|
@@ -825,7 +1050,7 @@ const mentionSuggestion = {
|
|
|
825
1050
|
};
|
|
826
1051
|
}
|
|
827
1052
|
};
|
|
828
|
-
const _sfc_main$
|
|
1053
|
+
const _sfc_main$2 = {
|
|
829
1054
|
name: "ChannelSuggestion",
|
|
830
1055
|
components: {
|
|
831
1056
|
DtStack: lib_stack.DtStack,
|
|
@@ -844,10 +1069,101 @@ const _sfc_main$1 = {
|
|
|
844
1069
|
}
|
|
845
1070
|
}
|
|
846
1071
|
};
|
|
847
|
-
var _sfc_render$
|
|
1072
|
+
var _sfc_render$2 = function render8() {
|
|
848
1073
|
var _vm = this, _c = _vm._self._c;
|
|
849
1074
|
return _c("dt-stack", { attrs: { "direction": "row", "gap": "400" } }, [!_vm.item.locked ? _c("dt-icon-hash", { attrs: { "size": "300" } }) : _c("dt-icon-lock", { attrs: { "size": "300" } }), _c("span", [_vm._v(_vm._s(_vm.name))])], 1);
|
|
850
1075
|
};
|
|
1076
|
+
var _sfc_staticRenderFns$2 = [];
|
|
1077
|
+
var __component__$2 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
|
|
1078
|
+
_sfc_main$2,
|
|
1079
|
+
_sfc_render$2,
|
|
1080
|
+
_sfc_staticRenderFns$2,
|
|
1081
|
+
false,
|
|
1082
|
+
null,
|
|
1083
|
+
null,
|
|
1084
|
+
null,
|
|
1085
|
+
null
|
|
1086
|
+
);
|
|
1087
|
+
const ChannelSuggestion = __component__$2.exports;
|
|
1088
|
+
const channelSuggestion = {
|
|
1089
|
+
// This function comes from the user and passed to the editor directly.
|
|
1090
|
+
// This will also activate the mention plugin on the editor
|
|
1091
|
+
// items: ({ query }) => { return [] },
|
|
1092
|
+
allowSpaces: true,
|
|
1093
|
+
render: () => {
|
|
1094
|
+
let component;
|
|
1095
|
+
let popup;
|
|
1096
|
+
return {
|
|
1097
|
+
onStart: (props) => {
|
|
1098
|
+
component = new vue2.VueRenderer(SuggestionList, {
|
|
1099
|
+
parent: void 0,
|
|
1100
|
+
propsData: {
|
|
1101
|
+
itemComponent: ChannelSuggestion,
|
|
1102
|
+
itemType: "channel",
|
|
1103
|
+
...props
|
|
1104
|
+
},
|
|
1105
|
+
editor: props.editor
|
|
1106
|
+
});
|
|
1107
|
+
if (!props.clientRect) {
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
popup = tippy("body", {
|
|
1111
|
+
getReferenceClientRect: props.clientRect,
|
|
1112
|
+
appendTo: () => document.body,
|
|
1113
|
+
content: component.element,
|
|
1114
|
+
showOnCreate: true,
|
|
1115
|
+
interactive: true,
|
|
1116
|
+
trigger: "manual",
|
|
1117
|
+
placement: "top-start"
|
|
1118
|
+
});
|
|
1119
|
+
},
|
|
1120
|
+
onUpdate(props) {
|
|
1121
|
+
component.updateProps(props);
|
|
1122
|
+
if (!props.clientRect) {
|
|
1123
|
+
return;
|
|
1124
|
+
}
|
|
1125
|
+
popup[0].setProps({
|
|
1126
|
+
getReferenceClientRect: props.clientRect
|
|
1127
|
+
});
|
|
1128
|
+
},
|
|
1129
|
+
onKeyDown(props) {
|
|
1130
|
+
if (props.event.key === "Escape") {
|
|
1131
|
+
popup[0].hide();
|
|
1132
|
+
return true;
|
|
1133
|
+
}
|
|
1134
|
+
return component == null ? void 0 : component.ref.onKeyDown(props);
|
|
1135
|
+
},
|
|
1136
|
+
onExit() {
|
|
1137
|
+
popup[0].destroy();
|
|
1138
|
+
component.destroy();
|
|
1139
|
+
}
|
|
1140
|
+
};
|
|
1141
|
+
}
|
|
1142
|
+
};
|
|
1143
|
+
const _sfc_main$1 = {
|
|
1144
|
+
name: "SlashCommandSuggestion",
|
|
1145
|
+
props: {
|
|
1146
|
+
item: {
|
|
1147
|
+
type: Object,
|
|
1148
|
+
required: true
|
|
1149
|
+
}
|
|
1150
|
+
},
|
|
1151
|
+
computed: {
|
|
1152
|
+
command() {
|
|
1153
|
+
return this.item.command;
|
|
1154
|
+
},
|
|
1155
|
+
description() {
|
|
1156
|
+
return this.item.description;
|
|
1157
|
+
},
|
|
1158
|
+
parametersExample() {
|
|
1159
|
+
return this.item.parametersExample;
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
};
|
|
1163
|
+
var _sfc_render$1 = function render9() {
|
|
1164
|
+
var _vm = this, _c = _vm._self._c;
|
|
1165
|
+
return _c("div", [_c("div", { staticClass: "d-body--md-compact" }, [_c("span", [_vm._v("/" + _vm._s(_vm.command))]), _vm.parametersExample ? _c("span", [_vm._v(" " + _vm._s(_vm.parametersExample))]) : _vm._e()]), _c("div", { staticClass: "d-body--sm" }, [_vm._v(" " + _vm._s(_vm.description) + " ")])]);
|
|
1166
|
+
};
|
|
851
1167
|
var _sfc_staticRenderFns$1 = [];
|
|
852
1168
|
var __component__$1 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
|
|
853
1169
|
_sfc_main$1,
|
|
@@ -859,12 +1175,13 @@ var __component__$1 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
|
|
|
859
1175
|
null,
|
|
860
1176
|
null
|
|
861
1177
|
);
|
|
862
|
-
const
|
|
863
|
-
const
|
|
1178
|
+
const SlashCommandSuggestion = __component__$1.exports;
|
|
1179
|
+
const slashCommandSuggestion = {
|
|
864
1180
|
// This function comes from the user and passed to the editor directly.
|
|
865
1181
|
// This will also activate the mention plugin on the editor
|
|
866
1182
|
// items: ({ query }) => { return [] },
|
|
867
1183
|
allowSpaces: true,
|
|
1184
|
+
startOfLine: true,
|
|
868
1185
|
render: () => {
|
|
869
1186
|
let component;
|
|
870
1187
|
let popup;
|
|
@@ -873,8 +1190,8 @@ const channelSuggestion = {
|
|
|
873
1190
|
component = new vue2.VueRenderer(SuggestionList, {
|
|
874
1191
|
parent: void 0,
|
|
875
1192
|
propsData: {
|
|
876
|
-
itemComponent:
|
|
877
|
-
itemType: "
|
|
1193
|
+
itemComponent: SlashCommandSuggestion,
|
|
1194
|
+
itemType: "slash-command",
|
|
878
1195
|
...props
|
|
879
1196
|
},
|
|
880
1197
|
editor: props.editor
|
|
@@ -1037,6 +1354,23 @@ const _sfc_main = {
|
|
|
1037
1354
|
type: Object,
|
|
1038
1355
|
default: null
|
|
1039
1356
|
},
|
|
1357
|
+
/**
|
|
1358
|
+
* suggestion object containing the items query function.
|
|
1359
|
+
* The valid keys passed into this object can be found here: https://tiptap.dev/api/utilities/suggestion
|
|
1360
|
+
*
|
|
1361
|
+
* The only required key is the items function which is used to query the slash commands for suggestion.
|
|
1362
|
+
* items({ query }) => { return [SlashCommandObject]; }
|
|
1363
|
+
* SlashCommandObject format:
|
|
1364
|
+
* { command: string, description: string, parametersExample?: string }
|
|
1365
|
+
* The "parametersExample" parameter is optional, and describes an example
|
|
1366
|
+
* of the parameters that command can take.
|
|
1367
|
+
*
|
|
1368
|
+
* When null, it does not add the plugin.
|
|
1369
|
+
*/
|
|
1370
|
+
slashCommandSuggestion: {
|
|
1371
|
+
type: Object,
|
|
1372
|
+
default: null
|
|
1373
|
+
},
|
|
1040
1374
|
/**
|
|
1041
1375
|
* Whether the input allows for block quote.
|
|
1042
1376
|
*/
|
|
@@ -1089,7 +1423,7 @@ const _sfc_main = {
|
|
|
1089
1423
|
"input",
|
|
1090
1424
|
/**
|
|
1091
1425
|
* Event to sync the value with the parent
|
|
1092
|
-
* @event
|
|
1426
|
+
* @event update:value
|
|
1093
1427
|
* @type {String|JSON}
|
|
1094
1428
|
*/
|
|
1095
1429
|
"update:value",
|
|
@@ -1109,7 +1443,8 @@ const _sfc_main = {
|
|
|
1109
1443
|
data() {
|
|
1110
1444
|
return {
|
|
1111
1445
|
editor: null,
|
|
1112
|
-
popoverOpened: false
|
|
1446
|
+
popoverOpened: false,
|
|
1447
|
+
internalValue: this.value
|
|
1113
1448
|
};
|
|
1114
1449
|
},
|
|
1115
1450
|
computed: {
|
|
@@ -1173,6 +1508,10 @@ const _sfc_main = {
|
|
|
1173
1508
|
const suggestionObject = { ...this.channelSuggestion, ...channelSuggestion };
|
|
1174
1509
|
extensions.push(ChannelPlugin.configure({ suggestion: suggestionObject }));
|
|
1175
1510
|
}
|
|
1511
|
+
if (this.slashCommandSuggestion) {
|
|
1512
|
+
const suggestionObject = { ...this.slashCommandSuggestion, ...slashCommandSuggestion };
|
|
1513
|
+
extensions.push(SlashCommandPlugin.configure({ suggestion: suggestionObject }));
|
|
1514
|
+
}
|
|
1176
1515
|
extensions.push(Emoji);
|
|
1177
1516
|
extensions.push(TextAlign.configure({
|
|
1178
1517
|
types: ["paragraph"],
|
|
@@ -1226,7 +1565,8 @@ const _sfc_main = {
|
|
|
1226
1565
|
if (newValue === currentValue) {
|
|
1227
1566
|
return;
|
|
1228
1567
|
}
|
|
1229
|
-
this.
|
|
1568
|
+
this.internalValue = newValue;
|
|
1569
|
+
this.insertContent();
|
|
1230
1570
|
}
|
|
1231
1571
|
},
|
|
1232
1572
|
created() {
|
|
@@ -1236,10 +1576,12 @@ const _sfc_main = {
|
|
|
1236
1576
|
this.destroyEditor();
|
|
1237
1577
|
},
|
|
1238
1578
|
methods: {
|
|
1579
|
+
onSelectedCommand(command) {
|
|
1580
|
+
this.$emit("selected-command", command);
|
|
1581
|
+
},
|
|
1239
1582
|
createEditor() {
|
|
1240
1583
|
this.editor = new vue2.Editor({
|
|
1241
1584
|
autofocus: this.autoFocus,
|
|
1242
|
-
content: this.value,
|
|
1243
1585
|
editable: this.editable,
|
|
1244
1586
|
extensions: this.extensions,
|
|
1245
1587
|
editorProps: {
|
|
@@ -1249,8 +1591,62 @@ const _sfc_main = {
|
|
|
1249
1591
|
}
|
|
1250
1592
|
}
|
|
1251
1593
|
});
|
|
1594
|
+
this.insertContent();
|
|
1252
1595
|
this.addEditorListeners();
|
|
1253
1596
|
},
|
|
1597
|
+
/**
|
|
1598
|
+
* This function is necessary as tiptap doesn't render the content passed
|
|
1599
|
+
* directly through `editor.commands.setContent` the content passed down to it
|
|
1600
|
+
* should be already parsed. So We're parsing the elements into it's corresponding
|
|
1601
|
+
* HTML version before setting it.
|
|
1602
|
+
*/
|
|
1603
|
+
insertContent() {
|
|
1604
|
+
this.parseMentions();
|
|
1605
|
+
this.parseChannels();
|
|
1606
|
+
this.parseEmojis();
|
|
1607
|
+
this.editor.commands.setContent(this.internalValue, true);
|
|
1608
|
+
},
|
|
1609
|
+
parseEmojis() {
|
|
1610
|
+
const matches = [...this.value.matchAll(emojiRegex()), ...this.value.matchAll(emojiShortCodeRegex)];
|
|
1611
|
+
if (!matches)
|
|
1612
|
+
return;
|
|
1613
|
+
matches.forEach((match) => {
|
|
1614
|
+
const emoji = common_emoji.codeToEmojiData(match[0]);
|
|
1615
|
+
if (!emoji)
|
|
1616
|
+
return;
|
|
1617
|
+
this.internalValue = this.internalValue.replace(new RegExp(` ${match[0]}`), ` <emoji-component code="${emoji.shortname}"></emoji-component>`);
|
|
1618
|
+
});
|
|
1619
|
+
},
|
|
1620
|
+
parseChannels() {
|
|
1621
|
+
if (!this.channelSuggestion)
|
|
1622
|
+
return;
|
|
1623
|
+
const suggestions = this.channelSuggestion.items({ query: "" });
|
|
1624
|
+
const matches = [...this.value.matchAll(channelRegex)].filter((match) => suggestions.some(({ id }) => id === match[1]));
|
|
1625
|
+
if (!matches)
|
|
1626
|
+
return;
|
|
1627
|
+
matches.forEach((match) => {
|
|
1628
|
+
const channel = suggestions.find(({ id }) => id === match[1]);
|
|
1629
|
+
this.internalValue = this.internalValue.replace(
|
|
1630
|
+
`#${match[1]}`,
|
|
1631
|
+
/** The space at the beginning is important as tiptap removes that while rendering.
|
|
1632
|
+
* So if multiple mentions, channels or emojis are next to each other it will fail
|
|
1633
|
+
*/
|
|
1634
|
+
` <channel-component name="${channel.name}" id="${channel.id}"></channel-component>`
|
|
1635
|
+
);
|
|
1636
|
+
});
|
|
1637
|
+
},
|
|
1638
|
+
parseMentions() {
|
|
1639
|
+
if (!this.mentionSuggestion)
|
|
1640
|
+
return;
|
|
1641
|
+
const suggestions = this.mentionSuggestion.items({ query: "" });
|
|
1642
|
+
const matches = [...this.value.matchAll(mentionRegex)].filter((match) => suggestions.some(({ id }) => id === match[1]));
|
|
1643
|
+
if (!matches)
|
|
1644
|
+
return;
|
|
1645
|
+
matches.forEach((match) => {
|
|
1646
|
+
const mention = suggestions.find(({ id }) => id === match[1]);
|
|
1647
|
+
this.internalValue = this.internalValue.replace(`@${match[1]}`, ` <mention-component name="${mention.name}" id="${mention.id}"></mention-component>`);
|
|
1648
|
+
});
|
|
1649
|
+
},
|
|
1254
1650
|
destroyEditor() {
|
|
1255
1651
|
this.editor.destroy();
|
|
1256
1652
|
},
|
|
@@ -1297,9 +1693,9 @@ const _sfc_main = {
|
|
|
1297
1693
|
}
|
|
1298
1694
|
}
|
|
1299
1695
|
};
|
|
1300
|
-
var _sfc_render = function
|
|
1696
|
+
var _sfc_render = function render10() {
|
|
1301
1697
|
var _vm = this, _c = _vm._self._c;
|
|
1302
|
-
return _c("editor-content", { staticClass: "dt-rich-text-editor", attrs: { "editor": _vm.editor, "data-qa": "dt-rich-text-editor" } });
|
|
1698
|
+
return _c("editor-content", { staticClass: "dt-rich-text-editor", attrs: { "editor": _vm.editor, "data-qa": "dt-rich-text-editor" }, on: { "selected-command": _vm.onSelectedCommand } });
|
|
1303
1699
|
};
|
|
1304
1700
|
var _sfc_staticRenderFns = [];
|
|
1305
1701
|
var __component__ = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
|