@limetech/lime-elements 37.45.1 → 37.46.0
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/CHANGELOG.md +18 -0
- package/dist/cjs/component-cba208a8.js +2448 -0
- package/dist/cjs/component-cba208a8.js.map +1 -0
- package/dist/cjs/{dom-ee8ee17d.js → debounce-2e5f4b7e.js} +1 -31
- package/dist/cjs/debounce-2e5f4b7e.js.map +1 -0
- package/dist/cjs/dom-81eaa633.js +34 -0
- package/dist/cjs/dom-81eaa633.js.map +1 -0
- package/dist/cjs/lime-elements.cjs.js +1 -1
- package/dist/cjs/{limel-action-bar_3.cjs.entry.js → limel-action-bar_4.cjs.entry.js} +68 -1
- package/dist/cjs/limel-action-bar_4.cjs.entry.js.map +1 -0
- package/dist/cjs/{limel-breadcrumbs_7.cjs.entry.js → limel-breadcrumbs_5.cjs.entry.js} +412 -3357
- package/dist/cjs/limel-breadcrumbs_5.cjs.entry.js.map +1 -0
- package/dist/cjs/limel-callout.cjs.entry.js +1 -1
- package/dist/cjs/limel-chip_2.cjs.entry.js +2 -2
- package/dist/cjs/limel-dynamic-label_4.cjs.entry.js +610 -0
- package/dist/cjs/limel-dynamic-label_4.cjs.entry.js.map +1 -0
- package/dist/cjs/limel-file-viewer.cjs.entry.js +1 -1
- package/dist/cjs/limel-file.cjs.entry.js +1 -1
- package/dist/cjs/limel-flatpickr-adapter.cjs.entry.js +1 -1
- package/dist/cjs/limel-form.cjs.entry.js +1 -1
- package/dist/cjs/limel-form.cjs.entry.js.map +1 -1
- package/dist/cjs/{limel-portal.cjs.entry.js → limel-icon_2.cjs.entry.js} +201 -1
- package/dist/cjs/limel-icon_2.cjs.entry.js.map +1 -0
- package/dist/cjs/limel-picker.cjs.entry.js +3 -2
- package/dist/cjs/limel-picker.cjs.entry.js.map +1 -1
- package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js +303 -16
- package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js.map +1 -1
- package/dist/cjs/limel-snackbar.cjs.entry.js +1 -1
- package/dist/cjs/{link-helper-b7e6c8df.js → link-helper-563b01c0.js} +3 -1
- package/dist/cjs/link-helper-563b01c0.js.map +1 -0
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{translations-988a3f51.js → translations-83a68e56.js} +25 -1
- package/dist/cjs/translations-83a68e56.js.map +1 -0
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/components/chip/chip.js +2 -2
- package/dist/collection/components/text-editor/link-menu/editor-link-menu.css +12 -0
- package/dist/collection/components/text-editor/link-menu/editor-link-menu.js +201 -0
- package/dist/collection/components/text-editor/link-menu/editor-link-menu.js.map +1 -0
- package/dist/collection/components/text-editor/prosemirror-adapter/menu/menu-commands.js +72 -11
- package/dist/collection/components/text-editor/prosemirror-adapter/menu/menu-commands.js.map +1 -1
- package/dist/collection/components/text-editor/prosemirror-adapter/menu/menu-items.js +6 -0
- package/dist/collection/components/text-editor/prosemirror-adapter/menu/menu-items.js.map +1 -1
- package/dist/collection/components/text-editor/prosemirror-adapter/menu/types.js.map +1 -1
- package/dist/collection/components/text-editor/prosemirror-adapter/plugins/link-plugin.js +172 -0
- package/dist/collection/components/text-editor/prosemirror-adapter/plugins/link-plugin.js.map +1 -0
- package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.css +4 -0
- package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.js +62 -6
- package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.js.map +1 -1
- package/dist/collection/translations/da.js +4 -0
- package/dist/collection/translations/da.js.map +1 -1
- package/dist/collection/translations/en.js +4 -0
- package/dist/collection/translations/en.js.map +1 -1
- package/dist/collection/translations/fi.js +4 -0
- package/dist/collection/translations/fi.js.map +1 -1
- package/dist/collection/translations/nl.js +4 -0
- package/dist/collection/translations/nl.js.map +1 -1
- package/dist/collection/translations/no.js +4 -0
- package/dist/collection/translations/no.js.map +1 -1
- package/dist/collection/translations/sv.js +4 -0
- package/dist/collection/translations/sv.js.map +1 -1
- package/dist/collection/util/link-helper.js +1 -1
- package/dist/collection/util/link-helper.js.map +1 -1
- package/dist/esm/component-db286494.js +2440 -0
- package/dist/esm/component-db286494.js.map +1 -0
- package/dist/esm/{dom-ae531ebc.js → debounce-9a05c91c.js} +2 -31
- package/dist/esm/debounce-9a05c91c.js.map +1 -0
- package/dist/esm/dom-0b0170a0.js +32 -0
- package/dist/esm/dom-0b0170a0.js.map +1 -0
- package/dist/esm/lime-elements.js +1 -1
- package/dist/esm/{limel-action-bar_3.entry.js → limel-action-bar_4.entry.js} +68 -2
- package/dist/esm/limel-action-bar_4.entry.js.map +1 -0
- package/dist/esm/{limel-breadcrumbs_7.entry.js → limel-breadcrumbs_5.entry.js} +404 -3347
- package/dist/esm/limel-breadcrumbs_5.entry.js.map +1 -0
- package/dist/esm/limel-callout.entry.js +1 -1
- package/dist/esm/limel-chip_2.entry.js +2 -2
- package/dist/esm/limel-dynamic-label_4.entry.js +603 -0
- package/dist/esm/limel-dynamic-label_4.entry.js.map +1 -0
- package/dist/esm/limel-file-viewer.entry.js +1 -1
- package/dist/esm/limel-file.entry.js +1 -1
- package/dist/esm/limel-flatpickr-adapter.entry.js +1 -1
- package/dist/esm/limel-form.entry.js +1 -1
- package/dist/esm/limel-form.entry.js.map +1 -1
- package/dist/esm/{limel-portal.entry.js → limel-icon_2.entry.js} +201 -2
- package/dist/esm/limel-icon_2.entry.js.map +1 -0
- package/dist/esm/limel-picker.entry.js +2 -1
- package/dist/esm/limel-picker.entry.js.map +1 -1
- package/dist/esm/limel-prosemirror-adapter.entry.js +303 -16
- package/dist/esm/limel-prosemirror-adapter.entry.js.map +1 -1
- package/dist/esm/limel-snackbar.entry.js +1 -1
- package/dist/esm/{link-helper-725a9166.js → link-helper-2a16b323.js} +2 -2
- package/dist/esm/link-helper-2a16b323.js.map +1 -0
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{translations-e73d7840.js → translations-5ae8ec7b.js} +25 -1
- package/dist/esm/translations-5ae8ec7b.js.map +1 -0
- package/dist/lime-elements/lime-elements.esm.js +1 -1
- package/dist/lime-elements/lime-elements.esm.js.map +1 -1
- package/dist/lime-elements/p-18c97232.js +2 -0
- package/dist/lime-elements/p-18c97232.js.map +1 -0
- package/dist/lime-elements/{p-5cfed8a8.entry.js → p-26a43fd9.entry.js} +5 -5
- package/dist/lime-elements/p-29e0e5bd.js +2 -0
- package/dist/lime-elements/p-29e0e5bd.js.map +1 -0
- package/dist/lime-elements/{p-dfc28411.entry.js → p-42b6ba6d.entry.js} +2 -2
- package/dist/lime-elements/{p-c8ce7cd4.entry.js → p-4bd0b7fb.entry.js} +2 -2
- package/dist/lime-elements/p-50b604b9.entry.js +2 -0
- package/dist/lime-elements/p-50b604b9.entry.js.map +1 -0
- package/dist/lime-elements/{p-ab13cb4a.entry.js → p-5e2604e5.entry.js} +2 -2
- package/dist/lime-elements/p-5e7b7b03.js +2 -0
- package/dist/lime-elements/p-5e7b7b03.js.map +1 -0
- package/dist/lime-elements/{p-516619d3.js → p-6465625e.js} +2 -2
- package/dist/lime-elements/p-6465625e.js.map +1 -0
- package/dist/lime-elements/{p-7681dae8.entry.js → p-70bfa812.entry.js} +2 -2
- package/dist/lime-elements/p-8d71c9e5.entry.js +2 -0
- package/dist/lime-elements/p-8d71c9e5.entry.js.map +1 -0
- package/dist/lime-elements/{p-e3eb403a.entry.js → p-91a8c244.entry.js} +2 -2
- package/dist/lime-elements/p-b8bfe44d.entry.js +2 -0
- package/dist/lime-elements/{p-3f4d2f62.entry.js.map → p-b8bfe44d.entry.js.map} +1 -1
- package/dist/lime-elements/p-bcfb5db5.entry.js +68 -0
- package/dist/lime-elements/p-bcfb5db5.entry.js.map +1 -0
- package/dist/lime-elements/p-d4d2593b.entry.js +2 -0
- package/dist/lime-elements/p-d4d2593b.entry.js.map +1 -0
- package/dist/lime-elements/p-eb9ab3d4.entry.js +2 -0
- package/dist/lime-elements/p-eb9ab3d4.entry.js.map +1 -0
- package/dist/lime-elements/p-f764b655.js +200 -0
- package/dist/lime-elements/p-f764b655.js.map +1 -0
- package/dist/lime-elements/{p-cfe4e725.entry.js → p-fe5e8f22.entry.js} +2 -2
- package/dist/lime-elements/{p-cfe4e725.entry.js.map → p-fe5e8f22.entry.js.map} +1 -1
- package/dist/types/components/file-viewer/file-viewer.d.ts +126 -0
- package/dist/types/components/progress-flow/progress-flow-item/progress-flow-item.d.ts +36 -0
- package/dist/types/components/progress-flow/progress-flow.d.ts +49 -0
- package/dist/types/components/text-editor/link-menu/editor-link-menu.d.ts +47 -0
- package/dist/types/components/text-editor/prosemirror-adapter/menu/menu-commands.d.ts +5 -2
- package/dist/types/components/text-editor/prosemirror-adapter/menu/types.d.ts +49 -0
- package/dist/types/components/text-editor/prosemirror-adapter/plugins/link-plugin.d.ts +9 -0
- package/dist/types/components/text-editor/prosemirror-adapter/prosemirror-adapter.d.ts +15 -3
- package/dist/types/components.d.ts +79 -0
- package/dist/types/translations/da.d.ts +4 -0
- package/dist/types/translations/en.d.ts +4 -0
- package/dist/types/translations/fi.d.ts +4 -0
- package/dist/types/translations/nl.d.ts +4 -0
- package/dist/types/translations/no.d.ts +4 -0
- package/dist/types/translations/sv.d.ts +4 -0
- package/dist/types/util/link-helper.d.ts +1 -0
- package/package.json +2 -2
- package/dist/cjs/dom-ee8ee17d.js.map +0 -1
- package/dist/cjs/limel-action-bar_3.cjs.entry.js.map +0 -1
- package/dist/cjs/limel-breadcrumbs_7.cjs.entry.js.map +0 -1
- package/dist/cjs/limel-dynamic-label_2.cjs.entry.js +0 -91
- package/dist/cjs/limel-dynamic-label_2.cjs.entry.js.map +0 -1
- package/dist/cjs/limel-icon.cjs.entry.js +0 -208
- package/dist/cjs/limel-icon.cjs.entry.js.map +0 -1
- package/dist/cjs/limel-portal.cjs.entry.js.map +0 -1
- package/dist/cjs/link-helper-b7e6c8df.js.map +0 -1
- package/dist/cjs/translations-988a3f51.js.map +0 -1
- package/dist/esm/dom-ae531ebc.js.map +0 -1
- package/dist/esm/limel-action-bar_3.entry.js.map +0 -1
- package/dist/esm/limel-breadcrumbs_7.entry.js.map +0 -1
- package/dist/esm/limel-dynamic-label_2.entry.js +0 -86
- package/dist/esm/limel-dynamic-label_2.entry.js.map +0 -1
- package/dist/esm/limel-icon.entry.js +0 -204
- package/dist/esm/limel-icon.entry.js.map +0 -1
- package/dist/esm/limel-portal.entry.js.map +0 -1
- package/dist/esm/link-helper-725a9166.js.map +0 -1
- package/dist/esm/translations-e73d7840.js.map +0 -1
- package/dist/lime-elements/p-2f453044.entry.js +0 -266
- package/dist/lime-elements/p-2f453044.entry.js.map +0 -1
- package/dist/lime-elements/p-35a4a846.entry.js +0 -2
- package/dist/lime-elements/p-35a4a846.entry.js.map +0 -1
- package/dist/lime-elements/p-3ae3b23e.entry.js +0 -2
- package/dist/lime-elements/p-3ae3b23e.entry.js.map +0 -1
- package/dist/lime-elements/p-3f4d2f62.entry.js +0 -2
- package/dist/lime-elements/p-516619d3.js.map +0 -1
- package/dist/lime-elements/p-5c9fbe6f.entry.js +0 -2
- package/dist/lime-elements/p-5c9fbe6f.entry.js.map +0 -1
- package/dist/lime-elements/p-714d6937.js +0 -2
- package/dist/lime-elements/p-714d6937.js.map +0 -1
- package/dist/lime-elements/p-a2d19673.entry.js +0 -2
- package/dist/lime-elements/p-a2d19673.entry.js.map +0 -1
- package/dist/lime-elements/p-cd6b9ff0.js +0 -2
- package/dist/lime-elements/p-cd6b9ff0.js.map +0 -1
- package/dist/lime-elements/p-f548d996.entry.js +0 -2
- package/dist/lime-elements/p-f548d996.entry.js.map +0 -1
- /package/dist/lime-elements/{p-5cfed8a8.entry.js.map → p-26a43fd9.entry.js.map} +0 -0
- /package/dist/lime-elements/{p-dfc28411.entry.js.map → p-42b6ba6d.entry.js.map} +0 -0
- /package/dist/lime-elements/{p-c8ce7cd4.entry.js.map → p-4bd0b7fb.entry.js.map} +0 -0
- /package/dist/lime-elements/{p-ab13cb4a.entry.js.map → p-5e2604e5.entry.js.map} +0 -0
- /package/dist/lime-elements/{p-7681dae8.entry.js.map → p-70bfa812.entry.js.map} +0 -0
- /package/dist/lime-elements/{p-e3eb403a.entry.js.map → p-91a8c244.entry.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { toggleMark, setBlockType, wrapIn } from 'prosemirror-commands';
|
|
2
2
|
import { findWrapping, liftTarget } from 'prosemirror-transform';
|
|
3
|
-
import { TextSelection } from 'prosemirror-state';
|
|
3
|
+
import { TextSelection, } from 'prosemirror-state';
|
|
4
4
|
import { EditorMenuTypes, LevelMapping } from './types';
|
|
5
5
|
const setActiveMethodForMark = (command, markType) => {
|
|
6
6
|
command.active = (state) => {
|
|
@@ -41,26 +41,56 @@ const setActiveMethodForWrap = (command, nodeType) => {
|
|
|
41
41
|
return false;
|
|
42
42
|
};
|
|
43
43
|
};
|
|
44
|
-
const
|
|
44
|
+
const createInsertLinkCommand = (schema, _, link) => {
|
|
45
|
+
const command = (state, dispatch) => {
|
|
46
|
+
const { from, to } = state.selection;
|
|
47
|
+
if (from === to) {
|
|
48
|
+
// If no text is selected, insert new text with link
|
|
49
|
+
const linkMark = schema.marks.link.create({
|
|
50
|
+
href: link.href,
|
|
51
|
+
title: link.href,
|
|
52
|
+
target: isExternalLink(link.href) ? '_blank' : null,
|
|
53
|
+
});
|
|
54
|
+
const linkText = link.text || link.href;
|
|
55
|
+
const newLink = schema.text(linkText, [linkMark]);
|
|
56
|
+
dispatch(state.tr.insert(from, newLink));
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// If text is selected, replace selected text with link text
|
|
60
|
+
const linkMark = schema.marks.link.create({
|
|
61
|
+
href: link.href,
|
|
62
|
+
title: link.href,
|
|
63
|
+
target: isExternalLink(link.href) ? '_blank' : null,
|
|
64
|
+
});
|
|
65
|
+
const selectedText = state.doc.textBetween(from, to, ' ');
|
|
66
|
+
const newLink = schema.text(link.text || selectedText, [linkMark]);
|
|
67
|
+
dispatch(state.tr.replaceWith(from, to, newLink));
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
};
|
|
71
|
+
setActiveMethodForMark(command, schema.marks.link);
|
|
72
|
+
return command;
|
|
73
|
+
};
|
|
74
|
+
const createToggleMarkCommand = (schema, markName, link) => {
|
|
45
75
|
const markType = schema.marks[markName];
|
|
46
76
|
if (!markType) {
|
|
47
77
|
throw new Error(`Mark "${markName}" not found in schema`);
|
|
48
78
|
}
|
|
49
|
-
const attrs = getAttributes(markName,
|
|
79
|
+
const attrs = getAttributes(markName, link);
|
|
50
80
|
const command = toggleMark(markType, attrs);
|
|
51
81
|
setActiveMethodForMark(command, markType);
|
|
52
82
|
return command;
|
|
53
83
|
};
|
|
54
|
-
const getAttributes = (markName,
|
|
55
|
-
if (markName === EditorMenuTypes.Link &&
|
|
84
|
+
const getAttributes = (markName, link) => {
|
|
85
|
+
if (markName === EditorMenuTypes.Link && link.href) {
|
|
56
86
|
return {
|
|
57
|
-
href:
|
|
58
|
-
target: isExternalLink(
|
|
87
|
+
href: link.href,
|
|
88
|
+
target: isExternalLink(link.href) ? '_blank' : null,
|
|
59
89
|
};
|
|
60
90
|
}
|
|
61
91
|
return undefined;
|
|
62
92
|
};
|
|
63
|
-
const isExternalLink = (url) => {
|
|
93
|
+
export const isExternalLink = (url) => {
|
|
64
94
|
return !url.startsWith(window.location.origin);
|
|
65
95
|
};
|
|
66
96
|
const toggleBlockType = (schema, type, attrs = {}, wrap = false) => {
|
|
@@ -88,6 +118,15 @@ const toggleBlockType = (schema, type, attrs = {}, wrap = false) => {
|
|
|
88
118
|
return false;
|
|
89
119
|
};
|
|
90
120
|
};
|
|
121
|
+
export const isValidUrl = (text) => {
|
|
122
|
+
try {
|
|
123
|
+
new URL(text);
|
|
124
|
+
}
|
|
125
|
+
catch (_a) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
return true;
|
|
129
|
+
};
|
|
91
130
|
const createSetNodeTypeCommand = (schema, nodeType, level) => {
|
|
92
131
|
const type = schema.nodes[nodeType];
|
|
93
132
|
if (!type) {
|
|
@@ -160,13 +199,34 @@ const createListCommand = (schema, listType) => {
|
|
|
160
199
|
setActiveMethodForWrap(command, type);
|
|
161
200
|
return command;
|
|
162
201
|
};
|
|
202
|
+
const copyPasteLinkCommand = (state, dispatch) => {
|
|
203
|
+
const { from, to } = state.selection;
|
|
204
|
+
if (from === to) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
const clipboardData = window.clipboardData;
|
|
208
|
+
if (!clipboardData) {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
const copyPastedText = clipboardData.getData('text');
|
|
212
|
+
if (!isValidUrl(copyPastedText)) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
const linkMark = state.schema.marks.link.create({
|
|
216
|
+
href: copyPastedText,
|
|
217
|
+
target: isExternalLink(copyPastedText) ? '_blank' : null,
|
|
218
|
+
});
|
|
219
|
+
const selectedText = state.doc.textBetween(from, to, ' ');
|
|
220
|
+
const newLink = state.schema.text(selectedText, [linkMark]);
|
|
221
|
+
dispatch(state.tr.replaceWith(from, to, newLink));
|
|
222
|
+
};
|
|
163
223
|
const commandMapping = {
|
|
164
224
|
strong: createToggleMarkCommand,
|
|
165
225
|
em: createToggleMarkCommand,
|
|
166
226
|
underline: createToggleMarkCommand,
|
|
167
227
|
strikethrough: createToggleMarkCommand,
|
|
168
228
|
code: createToggleMarkCommand,
|
|
169
|
-
link:
|
|
229
|
+
link: createInsertLinkCommand,
|
|
170
230
|
headerlevel1: (schema) => createSetNodeTypeCommand(schema, LevelMapping.Heading, LevelMapping.one),
|
|
171
231
|
headerlevel2: (schema) => createSetNodeTypeCommand(schema, LevelMapping.Heading, LevelMapping.two),
|
|
172
232
|
headerlevel3: (schema) => createSetNodeTypeCommand(schema, LevelMapping.Heading, LevelMapping.three),
|
|
@@ -181,12 +241,12 @@ export class MenuCommandFactory {
|
|
|
181
241
|
constructor(schema) {
|
|
182
242
|
this.schema = schema;
|
|
183
243
|
}
|
|
184
|
-
getCommand(mark,
|
|
244
|
+
getCommand(mark, link) {
|
|
185
245
|
const commandFunc = commandMapping[mark];
|
|
186
246
|
if (!commandFunc) {
|
|
187
247
|
throw new Error(`The Mark "${mark}" is not supported`);
|
|
188
248
|
}
|
|
189
|
-
return commandFunc(this.schema, mark,
|
|
249
|
+
return commandFunc(this.schema, mark, link);
|
|
190
250
|
}
|
|
191
251
|
buildKeymap() {
|
|
192
252
|
return {
|
|
@@ -198,6 +258,7 @@ export class MenuCommandFactory {
|
|
|
198
258
|
'Mod-Shift-X': this.getCommand(EditorMenuTypes.Strikethrough),
|
|
199
259
|
'Mod-`': this.getCommand(EditorMenuTypes.Code),
|
|
200
260
|
'Mod-Shift-C': this.getCommand(EditorMenuTypes.CodeBlock),
|
|
261
|
+
'Mod-v': copyPasteLinkCommand,
|
|
201
262
|
};
|
|
202
263
|
}
|
|
203
264
|
}
|
package/dist/collection/components/text-editor/prosemirror-adapter/menu/menu-commands.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-commands.js","sourceRoot":"","sources":["../../../../../src/components/text-editor/prosemirror-adapter/menu/menu-commands.ts"],"names":[],"mappings":"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","sourcesContent":["import { toggleMark, setBlockType, wrapIn } from 'prosemirror-commands';\nimport { Schema, MarkType, NodeType, Attrs } from 'prosemirror-model';\nimport { findWrapping, liftTarget } from 'prosemirror-transform';\nimport { Command, EditorState, TextSelection } from 'prosemirror-state';\nimport { EditorMenuTypes, LevelMapping } from './types';\n\ntype CommandFunction = (\n schema: Schema,\n mark: EditorMenuTypes,\n url?: string,\n) => CommandWithActive;\n\ninterface CommandMapping {\n [key: string]: CommandFunction;\n}\n\nexport interface CommandWithActive extends Command {\n active?: (state: EditorState) => boolean;\n}\n\nconst setActiveMethodForMark = (\n command: CommandWithActive,\n markType: MarkType,\n) => {\n command.active = (state) => {\n const { from, $from, to, empty } = state.selection;\n if (empty) {\n return !!markType.isInSet(state.storedMarks || $from.marks());\n } else {\n return state.doc.rangeHasMark(from, to, markType);\n }\n };\n};\n\nconst setActiveMethodForNode = (\n command: CommandWithActive,\n nodeType: NodeType,\n level?: number,\n) => {\n command.active = (state) => {\n const { $from } = state.selection;\n const node = $from.node($from.depth);\n\n if (node && node.type.name === nodeType.name) {\n if (nodeType.name === LevelMapping.Heading && level) {\n return node.attrs.level === level;\n }\n\n return true;\n }\n\n return false;\n };\n};\n\nconst setActiveMethodForWrap = (\n command: CommandWithActive,\n nodeType: NodeType,\n) => {\n command.active = (state) => {\n const { from, to } = state.selection;\n\n for (let pos = from; pos <= to; pos++) {\n const resolvedPos = state.doc.resolve(pos);\n for (let i = resolvedPos.depth; i > 0; i--) {\n const node = resolvedPos.node(i);\n if (node && node.type.name === nodeType.name) {\n return true;\n }\n }\n }\n\n return false;\n };\n};\n\nconst createToggleMarkCommand = (\n schema: Schema,\n markName: string,\n url?: string,\n): CommandWithActive => {\n const markType: MarkType | undefined = schema.marks[markName];\n if (!markType) {\n throw new Error(`Mark \"${markName}\" not found in schema`);\n }\n\n const attrs = getAttributes(markName, url);\n\n const command: CommandWithActive = toggleMark(markType, attrs);\n setActiveMethodForMark(command, markType);\n\n return command;\n};\n\nconst getAttributes = (markName: string, url: string): Attrs | null => {\n if (markName === EditorMenuTypes.Link && url) {\n return {\n href: url,\n target: isExternalLink(url) ? '_blank' : null,\n };\n }\n\n return undefined;\n};\n\nconst isExternalLink = (url: string): boolean => {\n return !url.startsWith(window.location.origin);\n};\n\nconst toggleBlockType = (schema, type, attrs = {}, wrap = false) => {\n const blockType = schema.nodes[type];\n const paragraphType = schema.nodes.paragraph;\n\n return (state, dispatch) => {\n const { $from, to } = state.selection;\n if (\n state.selection instanceof TextSelection &&\n $from.sameParent($from.doc.resolve(to))\n ) {\n if ($from.parent.type === blockType) {\n if (dispatch) {\n dispatch(\n state.tr.setBlockType($from.pos, to, paragraphType),\n );\n }\n\n return true;\n } else {\n if (wrap) {\n return wrapIn(blockType, attrs)(state, dispatch);\n } else {\n return setBlockType(blockType, attrs)(state, dispatch);\n }\n }\n }\n\n return false;\n };\n};\n\nconst createSetNodeTypeCommand = (\n schema: Schema,\n nodeType: string,\n level?: number,\n): CommandWithActive => {\n const type: NodeType | undefined = schema.nodes[nodeType];\n if (!type) {\n throw new Error(`Node type \"${nodeType}\" not found in schema`);\n }\n\n let command: CommandWithActive;\n if (nodeType === LevelMapping.Heading && level) {\n command = toggleBlockType(schema, LevelMapping.Heading, {\n level: level,\n });\n } else if (nodeType === EditorMenuTypes.CodeBlock) {\n command = toggleBlockType(schema, EditorMenuTypes.CodeBlock);\n } else {\n command = setBlockType(type);\n }\n\n setActiveMethodForNode(command, type, level);\n\n return command;\n};\n\nconst createWrapInCommand = (\n schema: Schema,\n nodeType: string,\n): CommandWithActive => {\n const type: NodeType | undefined = schema.nodes[nodeType];\n if (!type) {\n throw new Error(`Node type \"${nodeType}\" not found in schema`);\n }\n\n let command: CommandWithActive;\n if (nodeType === EditorMenuTypes.Blockquote) {\n command = toggleBlockType(schema, EditorMenuTypes.Blockquote, {}, true);\n } else {\n command = wrapIn(type);\n }\n\n setActiveMethodForWrap(command, type);\n\n return command;\n};\n\nconst toggleList = (listType) => {\n return (state, dispatch) => {\n const { $from, $to } = state.selection;\n const range = $from.blockRange($to);\n\n if (!range) {\n return false;\n }\n\n const wrapping = range && findWrapping(range, listType);\n\n if (wrapping) {\n // Wrap the selection in a list\n if (dispatch) {\n dispatch(state.tr.wrap(range, wrapping).scrollIntoView());\n }\n\n return true;\n } else {\n // Check if we are in a list item and lift out of the list\n const liftRange = range && liftTarget(range);\n if (liftRange !== null) {\n if (dispatch) {\n dispatch(state.tr.lift(range, liftRange).scrollIntoView());\n }\n\n return true;\n }\n\n return false;\n }\n };\n};\n\nconst createListCommand = (\n schema: Schema,\n listType: string,\n): CommandWithActive => {\n const type: NodeType | undefined = schema.nodes[listType];\n if (!type) {\n throw new Error(`List type \"${listType}\" not found in schema`);\n }\n\n const command: CommandWithActive = toggleList(type);\n setActiveMethodForWrap(command, type);\n\n return command;\n};\n\nconst commandMapping: CommandMapping = {\n strong: createToggleMarkCommand,\n em: createToggleMarkCommand,\n underline: createToggleMarkCommand,\n strikethrough: createToggleMarkCommand,\n code: createToggleMarkCommand,\n link: createToggleMarkCommand,\n headerlevel1: (schema) =>\n createSetNodeTypeCommand(\n schema,\n LevelMapping.Heading,\n LevelMapping.one,\n ),\n headerlevel2: (schema) =>\n createSetNodeTypeCommand(\n schema,\n LevelMapping.Heading,\n LevelMapping.two,\n ),\n headerlevel3: (schema) =>\n createSetNodeTypeCommand(\n schema,\n LevelMapping.Heading,\n LevelMapping.three,\n ),\n blockquote: (schema) =>\n createWrapInCommand(schema, EditorMenuTypes.Blockquote),\n /* eslint-disable camelcase */\n code_block: (schema) =>\n createSetNodeTypeCommand(schema, EditorMenuTypes.CodeBlock),\n ordered_list: (schema) =>\n createListCommand(schema, EditorMenuTypes.OrderedList),\n bullet_list: (schema) =>\n createListCommand(schema, EditorMenuTypes.BulletList),\n /* eslint-enable camelcase */\n};\n\nexport class MenuCommandFactory {\n private schema: Schema;\n\n constructor(schema: Schema) {\n this.schema = schema;\n }\n\n public getCommand(mark: EditorMenuTypes, url?: string) {\n const commandFunc = commandMapping[mark];\n if (!commandFunc) {\n throw new Error(`The Mark \"${mark}\" is not supported`);\n }\n\n return commandFunc(this.schema, mark, url);\n }\n\n buildKeymap() {\n return {\n 'Mod-B': this.getCommand(EditorMenuTypes.Bold),\n 'Mod-I': this.getCommand(EditorMenuTypes.Italic),\n 'Mod-Shift-1': this.getCommand(EditorMenuTypes.HeaderLevel1),\n 'Mod-Shift-2': this.getCommand(EditorMenuTypes.HeaderLevel2),\n 'Mod-Shift-3': this.getCommand(EditorMenuTypes.HeaderLevel3),\n 'Mod-Shift-X': this.getCommand(EditorMenuTypes.Strikethrough),\n 'Mod-`': this.getCommand(EditorMenuTypes.Code),\n 'Mod-Shift-C': this.getCommand(EditorMenuTypes.CodeBlock),\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"menu-commands.js","sourceRoot":"","sources":["../../../../../src/components/text-editor/prosemirror-adapter/menu/menu-commands.ts"],"names":[],"mappings":"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","sourcesContent":["import { toggleMark, setBlockType, wrapIn } from 'prosemirror-commands';\nimport { Schema, MarkType, NodeType, Attrs } from 'prosemirror-model';\nimport { findWrapping, liftTarget } from 'prosemirror-transform';\nimport {\n Command,\n EditorState,\n Transaction,\n TextSelection,\n} from 'prosemirror-state';\nimport { EditorMenuTypes, EditorTextLink, LevelMapping } from './types';\n\ntype CommandFunction = (\n schema: Schema,\n mark: EditorMenuTypes,\n link?: EditorTextLink,\n) => CommandWithActive;\n\ninterface CommandMapping {\n [key: string]: CommandFunction;\n}\n\nexport interface CommandWithActive extends Command {\n active?: (state: EditorState) => boolean;\n}\n\nconst setActiveMethodForMark = (\n command: CommandWithActive,\n markType: MarkType,\n) => {\n command.active = (state) => {\n const { from, $from, to, empty } = state.selection;\n if (empty) {\n return !!markType.isInSet(state.storedMarks || $from.marks());\n } else {\n return state.doc.rangeHasMark(from, to, markType);\n }\n };\n};\n\nconst setActiveMethodForNode = (\n command: CommandWithActive,\n nodeType: NodeType,\n level?: number,\n) => {\n command.active = (state) => {\n const { $from } = state.selection;\n const node = $from.node($from.depth);\n\n if (node && node.type.name === nodeType.name) {\n if (nodeType.name === LevelMapping.Heading && level) {\n return node.attrs.level === level;\n }\n\n return true;\n }\n\n return false;\n };\n};\n\nconst setActiveMethodForWrap = (\n command: CommandWithActive,\n nodeType: NodeType,\n) => {\n command.active = (state) => {\n const { from, to } = state.selection;\n\n for (let pos = from; pos <= to; pos++) {\n const resolvedPos = state.doc.resolve(pos);\n for (let i = resolvedPos.depth; i > 0; i--) {\n const node = resolvedPos.node(i);\n if (node && node.type.name === nodeType.name) {\n return true;\n }\n }\n }\n\n return false;\n };\n};\n\nconst createInsertLinkCommand: CommandFunction = (\n schema: Schema,\n _: EditorMenuTypes,\n link?: EditorTextLink,\n): CommandWithActive => {\n const command: Command = (state, dispatch) => {\n const { from, to } = state.selection;\n if (from === to) {\n // If no text is selected, insert new text with link\n const linkMark = schema.marks.link.create({\n href: link.href,\n title: link.href,\n target: isExternalLink(link.href) ? '_blank' : null,\n });\n const linkText = link.text || link.href;\n const newLink = schema.text(linkText, [linkMark]);\n dispatch(state.tr.insert(from, newLink));\n } else {\n // If text is selected, replace selected text with link text\n const linkMark = schema.marks.link.create({\n href: link.href,\n title: link.href,\n target: isExternalLink(link.href) ? '_blank' : null,\n });\n const selectedText = state.doc.textBetween(from, to, ' ');\n const newLink = schema.text(link.text || selectedText, [linkMark]);\n dispatch(state.tr.replaceWith(from, to, newLink));\n }\n\n return true;\n };\n\n setActiveMethodForMark(command, schema.marks.link);\n\n return command;\n};\n\nconst createToggleMarkCommand = (\n schema: Schema,\n markName: string,\n link?: EditorTextLink,\n): CommandWithActive => {\n const markType: MarkType | undefined = schema.marks[markName];\n if (!markType) {\n throw new Error(`Mark \"${markName}\" not found in schema`);\n }\n\n const attrs = getAttributes(markName, link);\n\n const command: CommandWithActive = toggleMark(markType, attrs);\n setActiveMethodForMark(command, markType);\n\n return command;\n};\n\nconst getAttributes = (\n markName: string,\n link: EditorTextLink,\n): Attrs | null => {\n if (markName === EditorMenuTypes.Link && link.href) {\n return {\n href: link.href,\n target: isExternalLink(link.href) ? '_blank' : null,\n };\n }\n\n return undefined;\n};\n\nexport const isExternalLink = (url: string): boolean => {\n return !url.startsWith(window.location.origin);\n};\n\nconst toggleBlockType = (schema, type, attrs = {}, wrap = false) => {\n const blockType = schema.nodes[type];\n const paragraphType = schema.nodes.paragraph;\n\n return (state, dispatch) => {\n const { $from, to } = state.selection;\n if (\n state.selection instanceof TextSelection &&\n $from.sameParent($from.doc.resolve(to))\n ) {\n if ($from.parent.type === blockType) {\n if (dispatch) {\n dispatch(\n state.tr.setBlockType($from.pos, to, paragraphType),\n );\n }\n\n return true;\n } else {\n if (wrap) {\n return wrapIn(blockType, attrs)(state, dispatch);\n } else {\n return setBlockType(blockType, attrs)(state, dispatch);\n }\n }\n }\n\n return false;\n };\n};\n\nexport const isValidUrl = (text: string): boolean => {\n try {\n new URL(text);\n } catch {\n return false;\n }\n\n return true;\n};\n\nconst createSetNodeTypeCommand = (\n schema: Schema,\n nodeType: string,\n level?: number,\n): CommandWithActive => {\n const type: NodeType | undefined = schema.nodes[nodeType];\n if (!type) {\n throw new Error(`Node type \"${nodeType}\" not found in schema`);\n }\n\n let command: CommandWithActive;\n if (nodeType === LevelMapping.Heading && level) {\n command = toggleBlockType(schema, LevelMapping.Heading, {\n level: level,\n });\n } else if (nodeType === EditorMenuTypes.CodeBlock) {\n command = toggleBlockType(schema, EditorMenuTypes.CodeBlock);\n } else {\n command = setBlockType(type);\n }\n\n setActiveMethodForNode(command, type, level);\n\n return command;\n};\n\nconst createWrapInCommand = (\n schema: Schema,\n nodeType: string,\n): CommandWithActive => {\n const type: NodeType | undefined = schema.nodes[nodeType];\n if (!type) {\n throw new Error(`Node type \"${nodeType}\" not found in schema`);\n }\n\n let command: CommandWithActive;\n if (nodeType === EditorMenuTypes.Blockquote) {\n command = toggleBlockType(schema, EditorMenuTypes.Blockquote, {}, true);\n } else {\n command = wrapIn(type);\n }\n\n setActiveMethodForWrap(command, type);\n\n return command;\n};\n\nconst toggleList = (listType) => {\n return (state, dispatch) => {\n const { $from, $to } = state.selection;\n const range = $from.blockRange($to);\n\n if (!range) {\n return false;\n }\n\n const wrapping = range && findWrapping(range, listType);\n\n if (wrapping) {\n // Wrap the selection in a list\n if (dispatch) {\n dispatch(state.tr.wrap(range, wrapping).scrollIntoView());\n }\n\n return true;\n } else {\n // Check if we are in a list item and lift out of the list\n const liftRange = range && liftTarget(range);\n if (liftRange !== null) {\n if (dispatch) {\n dispatch(state.tr.lift(range, liftRange).scrollIntoView());\n }\n\n return true;\n }\n\n return false;\n }\n };\n};\n\nconst createListCommand = (\n schema: Schema,\n listType: string,\n): CommandWithActive => {\n const type: NodeType | undefined = schema.nodes[listType];\n if (!type) {\n throw new Error(`List type \"${listType}\" not found in schema`);\n }\n\n const command: CommandWithActive = toggleList(type);\n setActiveMethodForWrap(command, type);\n\n return command;\n};\n\nconst copyPasteLinkCommand: Command = (\n state: EditorState,\n dispatch: (tr: Transaction) => void,\n) => {\n const { from, to } = state.selection;\n if (from === to) {\n return false;\n }\n\n const clipboardData = (window as any).clipboardData;\n if (!clipboardData) {\n return false;\n }\n\n const copyPastedText = clipboardData.getData('text');\n if (!isValidUrl(copyPastedText)) {\n return false;\n }\n\n const linkMark = state.schema.marks.link.create({\n href: copyPastedText,\n target: isExternalLink(copyPastedText) ? '_blank' : null,\n });\n\n const selectedText = state.doc.textBetween(from, to, ' ');\n const newLink = state.schema.text(selectedText, [linkMark]);\n dispatch(state.tr.replaceWith(from, to, newLink));\n};\n\nconst commandMapping: CommandMapping = {\n strong: createToggleMarkCommand,\n em: createToggleMarkCommand,\n underline: createToggleMarkCommand,\n strikethrough: createToggleMarkCommand,\n code: createToggleMarkCommand,\n link: createInsertLinkCommand,\n headerlevel1: (schema) =>\n createSetNodeTypeCommand(\n schema,\n LevelMapping.Heading,\n LevelMapping.one,\n ),\n headerlevel2: (schema) =>\n createSetNodeTypeCommand(\n schema,\n LevelMapping.Heading,\n LevelMapping.two,\n ),\n headerlevel3: (schema) =>\n createSetNodeTypeCommand(\n schema,\n LevelMapping.Heading,\n LevelMapping.three,\n ),\n blockquote: (schema) =>\n createWrapInCommand(schema, EditorMenuTypes.Blockquote),\n /* eslint-disable camelcase */\n code_block: (schema) =>\n createSetNodeTypeCommand(schema, EditorMenuTypes.CodeBlock),\n ordered_list: (schema) =>\n createListCommand(schema, EditorMenuTypes.OrderedList),\n bullet_list: (schema) =>\n createListCommand(schema, EditorMenuTypes.BulletList),\n /* eslint-enable camelcase */\n};\n\nexport class MenuCommandFactory {\n private schema: Schema;\n\n constructor(schema: Schema) {\n this.schema = schema;\n }\n\n public getCommand(mark: EditorMenuTypes, link?: EditorTextLink) {\n const commandFunc = commandMapping[mark];\n if (!commandFunc) {\n throw new Error(`The Mark \"${mark}\" is not supported`);\n }\n\n return commandFunc(this.schema, mark, link);\n }\n\n buildKeymap() {\n return {\n 'Mod-B': this.getCommand(EditorMenuTypes.Bold),\n 'Mod-I': this.getCommand(EditorMenuTypes.Italic),\n 'Mod-Shift-1': this.getCommand(EditorMenuTypes.HeaderLevel1),\n 'Mod-Shift-2': this.getCommand(EditorMenuTypes.HeaderLevel2),\n 'Mod-Shift-3': this.getCommand(EditorMenuTypes.HeaderLevel3),\n 'Mod-Shift-X': this.getCommand(EditorMenuTypes.Strikethrough),\n 'Mod-`': this.getCommand(EditorMenuTypes.Code),\n 'Mod-Shift-C': this.getCommand(EditorMenuTypes.CodeBlock),\n 'Mod-v': copyPasteLinkCommand,\n };\n }\n}\n"]}
|
|
@@ -96,6 +96,12 @@ const textEditorMenuItems = [
|
|
|
96
96
|
iconOnly: true,
|
|
97
97
|
selected: false,
|
|
98
98
|
},
|
|
99
|
+
{
|
|
100
|
+
value: EditorMenuTypes.Link,
|
|
101
|
+
text: 'Link',
|
|
102
|
+
icon: '-lime-text-link',
|
|
103
|
+
iconOnly: true,
|
|
104
|
+
},
|
|
99
105
|
];
|
|
100
106
|
export const getTextEditorMenuItems = () => cloneDeep(textEditorMenuItems);
|
|
101
107
|
export const menuTranslationIDs = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-items.js","sourceRoot":"","sources":["../../../../../src/components/text-editor/prosemirror-adapter/menu/menu-items.ts"],"names":[],"mappings":"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","sourcesContent":["import { ActionBarItem } from 'src/components/action-bar/action-bar.types';\nimport { ListSeparator } from 'src/components/list/list-item.types';\nimport { EditorMenuTypes } from './types';\nimport { cloneDeep } from 'lodash-es';\n\nconst getCommandSymbols = (): {\n mod: string;\n option: string;\n shift: string;\n} => {\n const macUserAgent = /Macintosh|MacIntel|MacPPC|Mac68K/;\n if (navigator.userAgent.match(macUserAgent)) {\n return { mod: '⌘', option: '⌥', shift: '⇧' };\n }\n\n return { mod: 'Ctrl', option: 'Alt', shift: 'Shift' };\n};\n\nconst { mod, shift } = getCommandSymbols();\n\nconst textEditorMenuItems: Array<\n ActionBarItem<EditorMenuTypes> | ListSeparator\n> = [\n {\n value: EditorMenuTypes.Bold,\n text: 'Bold',\n commandText: `${mod} B`,\n icon: '-lime-text-bold',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.Italic,\n text: 'Italic',\n commandText: `${mod} I`,\n icon: '-lime-text-italic',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.Strikethrough,\n text: 'Strikethrough',\n commandText: `${mod} ${shift} X`,\n icon: '-lime-text-strikethrough',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.Code,\n text: 'Code',\n commandText: `${mod} \\``,\n icon: '-lime-text-code',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.CodeBlock,\n text: 'Code Block',\n commandText: `${mod} ${shift} C`,\n icon: '-lime-text-code-block',\n iconOnly: true,\n selected: false,\n },\n { separator: true },\n {\n value: EditorMenuTypes.HeaderLevel1,\n text: 'Header 1',\n commandText: `${mod} ${shift} 1`,\n icon: '-lime-text-h-heading-1',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.HeaderLevel2,\n text: 'Header 2',\n commandText: `${mod} ${shift} 2`,\n icon: '-lime-text-h-heading-2',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.HeaderLevel3,\n text: 'Header 3',\n commandText: `${mod} ${shift} 3`,\n icon: '-lime-text-h-heading-3',\n iconOnly: true,\n selected: false,\n },\n { separator: true },\n {\n value: EditorMenuTypes.BulletList,\n text: 'Bullet list',\n icon: '-lime-text-bulleted-list',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.OrderedList,\n text: 'Numbered list',\n icon: '-lime-text-ordered-list',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.Blockquote,\n text: 'Blockquote',\n icon: '-lime-text-blockquote',\n iconOnly: true,\n selected: false,\n },\n];\n\nexport const getTextEditorMenuItems = () => cloneDeep(textEditorMenuItems);\n\nexport const menuTranslationIDs = {\n strong: 'editor-menu.bold',\n em: 'editor-menu.italic',\n headerlevel1: 'editor-menu.h1',\n headerlevel2: 'editor-menu.h2',\n headerlevel3: 'editor-menu.h3',\n /* eslint-disable camelcase */\n bullet_list: 'editor-menu.bulleted-list',\n ordered_list: 'editor-menu.numbered-list',\n code_block: 'editor-menu.code-block',\n /* eslint-enable camelcase */\n blockquote: 'editor-menu.blockquote',\n link: 'editor-menu.link',\n strikethrough: 'editor-menu.strikethrough',\n code: 'editor-menu.code',\n};\n\nexport type menuTranslationIDs =\n (typeof menuTranslationIDs)[keyof typeof menuTranslationIDs];\n"]}
|
|
1
|
+
{"version":3,"file":"menu-items.js","sourceRoot":"","sources":["../../../../../src/components/text-editor/prosemirror-adapter/menu/menu-items.ts"],"names":[],"mappings":"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","sourcesContent":["import { ActionBarItem } from 'src/components/action-bar/action-bar.types';\nimport { ListSeparator } from 'src/components/list/list-item.types';\nimport { EditorMenuTypes } from './types';\nimport { cloneDeep } from 'lodash-es';\n\nconst getCommandSymbols = (): {\n mod: string;\n option: string;\n shift: string;\n} => {\n const macUserAgent = /Macintosh|MacIntel|MacPPC|Mac68K/;\n if (navigator.userAgent.match(macUserAgent)) {\n return { mod: '⌘', option: '⌥', shift: '⇧' };\n }\n\n return { mod: 'Ctrl', option: 'Alt', shift: 'Shift' };\n};\n\nconst { mod, shift } = getCommandSymbols();\n\nconst textEditorMenuItems: Array<\n ActionBarItem<EditorMenuTypes> | ListSeparator\n> = [\n {\n value: EditorMenuTypes.Bold,\n text: 'Bold',\n commandText: `${mod} B`,\n icon: '-lime-text-bold',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.Italic,\n text: 'Italic',\n commandText: `${mod} I`,\n icon: '-lime-text-italic',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.Strikethrough,\n text: 'Strikethrough',\n commandText: `${mod} ${shift} X`,\n icon: '-lime-text-strikethrough',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.Code,\n text: 'Code',\n commandText: `${mod} \\``,\n icon: '-lime-text-code',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.CodeBlock,\n text: 'Code Block',\n commandText: `${mod} ${shift} C`,\n icon: '-lime-text-code-block',\n iconOnly: true,\n selected: false,\n },\n { separator: true },\n {\n value: EditorMenuTypes.HeaderLevel1,\n text: 'Header 1',\n commandText: `${mod} ${shift} 1`,\n icon: '-lime-text-h-heading-1',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.HeaderLevel2,\n text: 'Header 2',\n commandText: `${mod} ${shift} 2`,\n icon: '-lime-text-h-heading-2',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.HeaderLevel3,\n text: 'Header 3',\n commandText: `${mod} ${shift} 3`,\n icon: '-lime-text-h-heading-3',\n iconOnly: true,\n selected: false,\n },\n { separator: true },\n {\n value: EditorMenuTypes.BulletList,\n text: 'Bullet list',\n icon: '-lime-text-bulleted-list',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.OrderedList,\n text: 'Numbered list',\n icon: '-lime-text-ordered-list',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.Blockquote,\n text: 'Blockquote',\n icon: '-lime-text-blockquote',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.Link,\n text: 'Link',\n icon: '-lime-text-link',\n iconOnly: true,\n },\n];\n\nexport const getTextEditorMenuItems = () => cloneDeep(textEditorMenuItems);\n\nexport const menuTranslationIDs = {\n strong: 'editor-menu.bold',\n em: 'editor-menu.italic',\n headerlevel1: 'editor-menu.h1',\n headerlevel2: 'editor-menu.h2',\n headerlevel3: 'editor-menu.h3',\n /* eslint-disable camelcase */\n bullet_list: 'editor-menu.bulleted-list',\n ordered_list: 'editor-menu.numbered-list',\n code_block: 'editor-menu.code-block',\n /* eslint-enable camelcase */\n blockquote: 'editor-menu.blockquote',\n link: 'editor-menu.link',\n strikethrough: 'editor-menu.strikethrough',\n code: 'editor-menu.code',\n};\n\nexport type menuTranslationIDs =\n (typeof menuTranslationIDs)[keyof typeof menuTranslationIDs];\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/components/text-editor/prosemirror-adapter/menu/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG;EAC3B,IAAI,EAAE,QAAQ;EACd,MAAM,EAAE,IAAI;EACZ,UAAU,EAAE,YAAY;EACxB,YAAY,EAAE,cAAc;EAC5B,YAAY,EAAE,cAAc;EAC5B,YAAY,EAAE,cAAc;EAC5B,IAAI,EAAE,MAAM;EACZ,WAAW,EAAE,cAAc;EAC3B,UAAU,EAAE,aAAa;EACzB,aAAa,EAAE,eAAe;EAC9B,IAAI,EAAE,MAAM;EACZ,SAAS,EAAE,YAAY;CAC1B,CAAC;AAKF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;EACxB,OAAO,EAAE,SAAS;EAClB,GAAG,EAAE,CAAC;EACN,GAAG,EAAE,CAAC;EACN,KAAK,EAAE,CAAC;CACX,CAAC","sourcesContent":["/**\n * The `EditorMenuType` type is used to specify the type of menu items that can be added to the editor toolbar.\n * Each one represents a different type to be used for creating the prosemirror commands relevant to the button.\n * The values correspond to the types that can be used with the `prosemirror-commands` library.\n * @beta\n */\n\nexport const EditorMenuTypes = {\n Bold: 'strong',\n Italic: 'em',\n Blockquote: 'blockquote',\n HeaderLevel1: 'headerlevel1',\n HeaderLevel2: 'headerlevel2',\n HeaderLevel3: 'headerlevel3',\n Link: 'link',\n OrderedList: 'ordered_list',\n BulletList: 'bullet_list',\n Strikethrough: 'strikethrough',\n Code: 'code',\n CodeBlock: 'code_block',\n};\n\nexport type EditorMenuTypes =\n (typeof EditorMenuTypes)[keyof typeof EditorMenuTypes];\n\n/**\n * `LevelMapping` is used to map string identifiers to numerical header levels.\n * It provides a way to represent different levels of headings in ProseMirror commands.\n *\n * The `Heading` identifier is not a valid level and is used to identify the node type.\n * The numerical values are used for creating ProseMirror commands to set the level of a heading node in the editor.\n * @beta\n */\nexport const LevelMapping = {\n Heading: 'heading',\n one: 1,\n two: 2,\n three: 3,\n};\n\nexport type LevelMapping = (typeof LevelMapping)[keyof typeof LevelMapping];\n\nexport type ProseMirrorAdapterElementWithFocus =\n HTMLLimelProsemirrorAdapterElement & {\n setFocus: () => void;\n };\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/components/text-editor/prosemirror-adapter/menu/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG;EAC3B,IAAI,EAAE,QAAQ;EACd,MAAM,EAAE,IAAI;EACZ,UAAU,EAAE,YAAY;EACxB,YAAY,EAAE,cAAc;EAC5B,YAAY,EAAE,cAAc;EAC5B,YAAY,EAAE,cAAc;EAC5B,IAAI,EAAE,MAAM;EACZ,WAAW,EAAE,cAAc;EAC3B,UAAU,EAAE,aAAa;EACzB,aAAa,EAAE,eAAe;EAC9B,IAAI,EAAE,MAAM;EACZ,SAAS,EAAE,YAAY;CAC1B,CAAC;AAKF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;EACxB,OAAO,EAAE,SAAS;EAClB,GAAG,EAAE,CAAC;EACN,GAAG,EAAE,CAAC;EACN,KAAK,EAAE,CAAC;CACX,CAAC","sourcesContent":["/**\n * The `EditorMenuType` type is used to specify the type of menu items that can be added to the editor toolbar.\n * Each one represents a different type to be used for creating the prosemirror commands relevant to the button.\n * The values correspond to the types that can be used with the `prosemirror-commands` library.\n * @beta\n */\n\nexport const EditorMenuTypes = {\n Bold: 'strong',\n Italic: 'em',\n Blockquote: 'blockquote',\n HeaderLevel1: 'headerlevel1',\n HeaderLevel2: 'headerlevel2',\n HeaderLevel3: 'headerlevel3',\n Link: 'link',\n OrderedList: 'ordered_list',\n BulletList: 'bullet_list',\n Strikethrough: 'strikethrough',\n Code: 'code',\n CodeBlock: 'code_block',\n};\n\nexport type EditorMenuTypes =\n (typeof EditorMenuTypes)[keyof typeof EditorMenuTypes];\n\n/**\n * `LevelMapping` is used to map string identifiers to numerical header levels.\n * It provides a way to represent different levels of headings in ProseMirror commands.\n *\n * The `Heading` identifier is not a valid level and is used to identify the node type.\n * The numerical values are used for creating ProseMirror commands to set the level of a heading node in the editor.\n * @beta\n */\nexport const LevelMapping = {\n Heading: 'heading',\n one: 1,\n two: 2,\n three: 3,\n};\n\nexport type LevelMapping = (typeof LevelMapping)[keyof typeof LevelMapping];\n\nexport type ProseMirrorAdapterElementWithFocus =\n HTMLLimelProsemirrorAdapterElement & {\n setFocus: () => void;\n };\n\n/**\n * The `EditorTextLink` type is used to represent a link in the editor.\n * @beta\n * @private\n */\nexport type EditorTextLink = {\n text?: string;\n href: string;\n};\n"]}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { Plugin, PluginKey, TextSelection } from 'prosemirror-state';
|
|
2
|
+
import { schema } from 'prosemirror-schema-basic';
|
|
3
|
+
import { isExternalLink, isValidUrl } from '../menu/menu-commands';
|
|
4
|
+
import { EditorMenuTypes } from '../menu/types';
|
|
5
|
+
export const linkPluginKey = new PluginKey('linkPlugin');
|
|
6
|
+
const updateLink = (view, updateLinkCallback) => {
|
|
7
|
+
const { from, to } = view.state.selection;
|
|
8
|
+
let text = '';
|
|
9
|
+
let href = '';
|
|
10
|
+
view.state.doc.nodesBetween(from, to, (node) => {
|
|
11
|
+
if (node.type.name === 'text') {
|
|
12
|
+
text = node.text;
|
|
13
|
+
node.marks.forEach((mark) => {
|
|
14
|
+
if (mark.type.name === 'link') {
|
|
15
|
+
href = mark.attrs.href;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
if (updateLinkCallback) {
|
|
21
|
+
updateLinkCallback(text, href);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Finds the start position of the link node ensuring the href matches the original link's href.
|
|
26
|
+
* @param doc - The ProseMirror document.
|
|
27
|
+
* @param pos - The position to start searching from.
|
|
28
|
+
* @param href - The href attribute of the original link mark.
|
|
29
|
+
* @returns The start position of the link node.
|
|
30
|
+
*/
|
|
31
|
+
const findStart = (doc, pos, href) => {
|
|
32
|
+
while (pos > 0) {
|
|
33
|
+
const node = doc.nodeAt(pos - 1);
|
|
34
|
+
if (!(node === null || node === void 0 ? void 0 : node.isText) ||
|
|
35
|
+
!node.marks.some((mark) => mark.type.name === EditorMenuTypes.Link &&
|
|
36
|
+
mark.attrs.href === href)) {
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
pos--;
|
|
40
|
+
}
|
|
41
|
+
return pos;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Finds the end position of the link node ensuring the href matches the original link's href.
|
|
45
|
+
* @param doc - The ProseMirror document.
|
|
46
|
+
* @param pos - The position to start searching from.
|
|
47
|
+
* @param href - The href attribute of the original link mark.
|
|
48
|
+
* @returns The end position of the link node.
|
|
49
|
+
*/
|
|
50
|
+
const findEnd = (doc, pos, href) => {
|
|
51
|
+
while (pos < doc.content.size) {
|
|
52
|
+
const node = doc.nodeAt(pos);
|
|
53
|
+
if (!(node === null || node === void 0 ? void 0 : node.isText) ||
|
|
54
|
+
!node.marks.some((mark) => mark.type.name === EditorMenuTypes.Link &&
|
|
55
|
+
mark.attrs.href === href)) {
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
pos++;
|
|
59
|
+
}
|
|
60
|
+
return pos;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Gets the link data at the specified position.
|
|
64
|
+
* @param view - The ProseMirror editor view.
|
|
65
|
+
* @param event - The mouse event.
|
|
66
|
+
* @returns An object containing the link data or null if no link is found.
|
|
67
|
+
*/
|
|
68
|
+
const getLinkDataAtPosition = (view, event) => {
|
|
69
|
+
const pos = view.posAtCoords({ left: event.clientX, top: event.clientY });
|
|
70
|
+
const node = view.state.doc.nodeAt(pos.pos);
|
|
71
|
+
if (!node) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const linkMark = node.marks.find((mark) => mark.type.name === EditorMenuTypes.Link);
|
|
75
|
+
if (!linkMark) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
const href = linkMark.attrs.href;
|
|
79
|
+
const from = findStart(view.state.doc, pos.pos, href);
|
|
80
|
+
const to = findEnd(view.state.doc, pos.pos, href);
|
|
81
|
+
const text = view.state.doc.textBetween(from, to, ' ');
|
|
82
|
+
return { href: href, text: text, from: from, to: to };
|
|
83
|
+
};
|
|
84
|
+
const processModClickEvent = (view, event) => {
|
|
85
|
+
const { href } = getLinkDataAtPosition(view, event);
|
|
86
|
+
if (href) {
|
|
87
|
+
window.open(href, '_blank');
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
return false;
|
|
91
|
+
};
|
|
92
|
+
const openLinkMenu = (view, href, text) => {
|
|
93
|
+
const event = new CustomEvent('open-editor-link-menu', {
|
|
94
|
+
detail: { href: href, text: text },
|
|
95
|
+
bubbles: true,
|
|
96
|
+
composed: true,
|
|
97
|
+
});
|
|
98
|
+
view.dom.dispatchEvent(event);
|
|
99
|
+
};
|
|
100
|
+
let lastClickTime = 0;
|
|
101
|
+
const DOUBLE_CLICK_DELAY = 200;
|
|
102
|
+
let clickTimeout;
|
|
103
|
+
const processDoubleClickEvent = (view, event) => {
|
|
104
|
+
const now = Date.now();
|
|
105
|
+
if (now - lastClickTime < DOUBLE_CLICK_DELAY) {
|
|
106
|
+
clearTimeout(clickTimeout);
|
|
107
|
+
lastClickTime = now; // Reset lastClickTime to prevent single-click action
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
lastClickTime = now;
|
|
111
|
+
clickTimeout = setTimeout(() => {
|
|
112
|
+
const linkData = getLinkDataAtPosition(view, event);
|
|
113
|
+
if (linkData) {
|
|
114
|
+
const { href, text, from, to } = linkData;
|
|
115
|
+
const transaction = view.state.tr.setSelection(TextSelection.create(view.state.doc, from, to));
|
|
116
|
+
view.dispatch(transaction);
|
|
117
|
+
openLinkMenu(view, href, text);
|
|
118
|
+
}
|
|
119
|
+
}, DOUBLE_CLICK_DELAY);
|
|
120
|
+
return true;
|
|
121
|
+
};
|
|
122
|
+
const processPasteEvent = (view, event) => {
|
|
123
|
+
const clipboardData = event.clipboardData;
|
|
124
|
+
if (!clipboardData) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
const text = clipboardData.getData('text/plain');
|
|
128
|
+
if (!isValidUrl(text)) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
pasteAsLink(view, text);
|
|
132
|
+
return true;
|
|
133
|
+
};
|
|
134
|
+
const pasteAsLink = (view, href) => {
|
|
135
|
+
const { state, dispatch } = view;
|
|
136
|
+
const { from, to } = state.selection;
|
|
137
|
+
const linkMark = schema.marks.link.create({
|
|
138
|
+
href: href,
|
|
139
|
+
title: href,
|
|
140
|
+
target: isExternalLink(href) ? '_blank' : null,
|
|
141
|
+
});
|
|
142
|
+
const selectedText = state.doc.textBetween(from, to, ' ') || href;
|
|
143
|
+
const transaction = state.tr
|
|
144
|
+
.insertText(selectedText, from, to)
|
|
145
|
+
.addMark(from, from + selectedText.length, linkMark);
|
|
146
|
+
dispatch(transaction);
|
|
147
|
+
};
|
|
148
|
+
export const createLinkPlugin = (updateLinkCallback) => {
|
|
149
|
+
return new Plugin({
|
|
150
|
+
key: linkPluginKey,
|
|
151
|
+
props: {
|
|
152
|
+
handlePaste: (view, event) => {
|
|
153
|
+
return processPasteEvent(view, event);
|
|
154
|
+
},
|
|
155
|
+
handleDOMEvents: {
|
|
156
|
+
mousedown: (view, event) => {
|
|
157
|
+
if ((event.metaKey || event.ctrlKey) &&
|
|
158
|
+
event.button === 0) {
|
|
159
|
+
return processModClickEvent(view, event);
|
|
160
|
+
}
|
|
161
|
+
return processDoubleClickEvent(view, event);
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
view: () => ({
|
|
166
|
+
update: (view) => {
|
|
167
|
+
updateLink(view, updateLinkCallback);
|
|
168
|
+
},
|
|
169
|
+
}),
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
//# sourceMappingURL=link-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link-plugin.js","sourceRoot":"","sources":["../../../../../src/components/text-editor/prosemirror-adapter/plugins/link-plugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { Plugin, PluginKey, TextSelection } from 'prosemirror-state';\nimport { EditorView } from 'prosemirror-view';\nimport { schema } from 'prosemirror-schema-basic';\nimport { Mark } from 'prosemirror-model';\nimport { isExternalLink, isValidUrl } from '../menu/menu-commands';\nimport { EditorMenuTypes } from '../menu/types';\n\nexport const linkPluginKey = new PluginKey('linkPlugin');\n\nexport type UpdateLinkCallback = (text: string, href: string) => void;\n\nexport interface EditorLinkMenuEventDetail {\n href: string;\n text: string;\n}\n\nconst updateLink = (\n view: EditorView,\n updateLinkCallback?: UpdateLinkCallback,\n) => {\n const { from, to } = view.state.selection;\n\n let text = '';\n let href = '';\n view.state.doc.nodesBetween(from, to, (node) => {\n if (node.type.name === 'text') {\n text = node.text;\n node.marks.forEach((mark: Mark) => {\n if (mark.type.name === 'link') {\n href = mark.attrs.href;\n }\n });\n }\n });\n\n if (updateLinkCallback) {\n updateLinkCallback(text, href);\n }\n};\n\n/**\n * Finds the start position of the link node ensuring the href matches the original link's href.\n * @param doc - The ProseMirror document.\n * @param pos - The position to start searching from.\n * @param href - The href attribute of the original link mark.\n * @returns The start position of the link node.\n */\nconst findStart = (doc, pos, href) => {\n while (pos > 0) {\n const node = doc.nodeAt(pos - 1);\n if (\n !node?.isText ||\n !node.marks.some(\n (mark: Mark) =>\n mark.type.name === EditorMenuTypes.Link &&\n mark.attrs.href === href,\n )\n ) {\n break;\n }\n\n pos--;\n }\n\n return pos;\n};\n\n/**\n * Finds the end position of the link node ensuring the href matches the original link's href.\n * @param doc - The ProseMirror document.\n * @param pos - The position to start searching from.\n * @param href - The href attribute of the original link mark.\n * @returns The end position of the link node.\n */\nconst findEnd = (doc, pos, href) => {\n while (pos < doc.content.size) {\n const node = doc.nodeAt(pos);\n if (\n !node?.isText ||\n !node.marks.some(\n (mark) =>\n mark.type.name === EditorMenuTypes.Link &&\n mark.attrs.href === href,\n )\n ) {\n break;\n }\n\n pos++;\n }\n\n return pos;\n};\n\n/**\n * Gets the link data at the specified position.\n * @param view - The ProseMirror editor view.\n * @param event - The mouse event.\n * @returns An object containing the link data or null if no link is found.\n */\nconst getLinkDataAtPosition = (view: EditorView, event: MouseEvent) => {\n const pos = view.posAtCoords({ left: event.clientX, top: event.clientY });\n const node = view.state.doc.nodeAt(pos.pos);\n if (!node) {\n return null;\n }\n\n const linkMark = node.marks.find(\n (mark) => mark.type.name === EditorMenuTypes.Link,\n );\n if (!linkMark) {\n return null;\n }\n\n const href = linkMark.attrs.href;\n const from = findStart(view.state.doc, pos.pos, href);\n const to = findEnd(view.state.doc, pos.pos, href);\n const text = view.state.doc.textBetween(from, to, ' ');\n\n return { href: href, text: text, from: from, to: to };\n};\n\nconst processModClickEvent = (view: EditorView, event: MouseEvent): boolean => {\n const { href } = getLinkDataAtPosition(view, event);\n if (href) {\n window.open(href, '_blank');\n\n return true;\n }\n\n return false;\n};\n\nconst openLinkMenu = (view: EditorView, href: string, text: string) => {\n const event = new CustomEvent<EditorLinkMenuEventDetail>(\n 'open-editor-link-menu',\n {\n detail: { href: href, text: text },\n bubbles: true,\n composed: true,\n },\n );\n view.dom.dispatchEvent(event);\n};\n\nlet lastClickTime = 0;\nconst DOUBLE_CLICK_DELAY = 200;\nlet clickTimeout;\n\nconst processDoubleClickEvent = (\n view: EditorView,\n event: MouseEvent,\n): boolean => {\n const now = Date.now();\n\n if (now - lastClickTime < DOUBLE_CLICK_DELAY) {\n clearTimeout(clickTimeout);\n lastClickTime = now; // Reset lastClickTime to prevent single-click action\n\n return false;\n }\n\n lastClickTime = now;\n\n clickTimeout = setTimeout(() => {\n const linkData = getLinkDataAtPosition(view, event);\n if (linkData) {\n const { href, text, from, to } = linkData;\n const transaction = view.state.tr.setSelection(\n TextSelection.create(view.state.doc, from, to),\n );\n view.dispatch(transaction);\n openLinkMenu(view, href, text);\n }\n }, DOUBLE_CLICK_DELAY);\n\n return true;\n};\n\nconst processPasteEvent = (\n view: EditorView,\n event: ClipboardEvent,\n): boolean => {\n const clipboardData = event.clipboardData;\n if (!clipboardData) {\n return false;\n }\n\n const text = clipboardData.getData('text/plain');\n\n if (!isValidUrl(text)) {\n return false;\n }\n\n pasteAsLink(view, text);\n\n return true;\n};\n\nconst pasteAsLink = (view: EditorView, href: string) => {\n const { state, dispatch } = view;\n const { from, to } = state.selection;\n const linkMark = schema.marks.link.create({\n href: href,\n title: href,\n target: isExternalLink(href) ? '_blank' : null,\n });\n const selectedText = state.doc.textBetween(from, to, ' ') || href;\n const transaction = state.tr\n .insertText(selectedText, from, to)\n .addMark(from, from + selectedText.length, linkMark);\n\n dispatch(transaction);\n};\n\nexport const createLinkPlugin = (updateLinkCallback?: UpdateLinkCallback) => {\n return new Plugin({\n key: linkPluginKey,\n props: {\n handlePaste: (view, event) => {\n return processPasteEvent(view, event);\n },\n handleDOMEvents: {\n mousedown: (view, event) => {\n if (\n (event.metaKey || event.ctrlKey) &&\n event.button === 0\n ) {\n return processModClickEvent(view, event);\n }\n\n return processDoubleClickEvent(view, event);\n },\n },\n },\n view: () => ({\n update: (view) => {\n updateLink(view, updateLinkCallback);\n },\n }),\n });\n};\n"]}
|