@kerebron/extension-menu-legacy 0.4.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.
Files changed (98) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +82 -0
  3. package/assets/menu.css +539 -0
  4. package/esm/editor/src/CoreEditor.d.ts +40 -0
  5. package/esm/editor/src/CoreEditor.d.ts.map +1 -0
  6. package/esm/editor/src/CoreEditor.js +252 -0
  7. package/esm/editor/src/DummyEditorView.d.ts +60 -0
  8. package/esm/editor/src/DummyEditorView.d.ts.map +1 -0
  9. package/esm/editor/src/DummyEditorView.js +277 -0
  10. package/esm/editor/src/Extension.d.ts +31 -0
  11. package/esm/editor/src/Extension.d.ts.map +1 -0
  12. package/esm/editor/src/Extension.js +53 -0
  13. package/esm/editor/src/ExtensionManager.d.ts +32 -0
  14. package/esm/editor/src/ExtensionManager.d.ts.map +1 -0
  15. package/esm/editor/src/ExtensionManager.js +260 -0
  16. package/esm/editor/src/Mark.d.ts +23 -0
  17. package/esm/editor/src/Mark.d.ts.map +1 -0
  18. package/esm/editor/src/Mark.js +51 -0
  19. package/esm/editor/src/Node.d.ts +32 -0
  20. package/esm/editor/src/Node.d.ts.map +1 -0
  21. package/esm/editor/src/Node.js +60 -0
  22. package/esm/editor/src/commands/CommandManager.d.ts +23 -0
  23. package/esm/editor/src/commands/CommandManager.d.ts.map +1 -0
  24. package/esm/editor/src/commands/CommandManager.js +118 -0
  25. package/esm/editor/src/commands/baseCommandFactories.d.ts +3 -0
  26. package/esm/editor/src/commands/baseCommandFactories.d.ts.map +1 -0
  27. package/esm/editor/src/commands/baseCommandFactories.js +836 -0
  28. package/esm/editor/src/commands/createChainableState.d.ts +3 -0
  29. package/esm/editor/src/commands/createChainableState.d.ts.map +1 -0
  30. package/esm/editor/src/commands/createChainableState.js +29 -0
  31. package/esm/editor/src/commands/keyCommandFactories.d.ts +3 -0
  32. package/esm/editor/src/commands/keyCommandFactories.d.ts.map +1 -0
  33. package/esm/editor/src/commands/keyCommandFactories.js +10 -0
  34. package/esm/editor/src/commands/mod.d.ts +7 -0
  35. package/esm/editor/src/commands/mod.d.ts.map +1 -0
  36. package/esm/editor/src/commands/mod.js +76 -0
  37. package/esm/editor/src/commands/replaceCommandFactories.d.ts +3 -0
  38. package/esm/editor/src/commands/replaceCommandFactories.d.ts.map +1 -0
  39. package/esm/editor/src/commands/replaceCommandFactories.js +94 -0
  40. package/esm/editor/src/commands/types.d.ts +18 -0
  41. package/esm/editor/src/commands/types.d.ts.map +1 -0
  42. package/esm/editor/src/commands/types.js +1 -0
  43. package/esm/editor/src/mod.d.ts +9 -0
  44. package/esm/editor/src/mod.d.ts.map +1 -0
  45. package/esm/editor/src/mod.js +8 -0
  46. package/esm/editor/src/nodeToTreeString.d.ts +10 -0
  47. package/esm/editor/src/nodeToTreeString.d.ts.map +1 -0
  48. package/esm/editor/src/nodeToTreeString.js +74 -0
  49. package/esm/editor/src/plugins/TrackSelecionPlugin.d.ts +6 -0
  50. package/esm/editor/src/plugins/TrackSelecionPlugin.d.ts.map +1 -0
  51. package/esm/editor/src/plugins/TrackSelecionPlugin.js +24 -0
  52. package/esm/editor/src/plugins/input-rules/InputRulesPlugin.d.ts +23 -0
  53. package/esm/editor/src/plugins/input-rules/InputRulesPlugin.d.ts.map +1 -0
  54. package/esm/editor/src/plugins/input-rules/InputRulesPlugin.js +163 -0
  55. package/esm/editor/src/plugins/keymap/keymap.d.ts +11 -0
  56. package/esm/editor/src/plugins/keymap/keymap.d.ts.map +1 -0
  57. package/esm/editor/src/plugins/keymap/keymap.js +125 -0
  58. package/esm/editor/src/plugins/keymap/w3c-keyname.d.ts +4 -0
  59. package/esm/editor/src/plugins/keymap/w3c-keyname.d.ts.map +1 -0
  60. package/esm/editor/src/plugins/keymap/w3c-keyname.js +124 -0
  61. package/esm/editor/src/types.d.ts +52 -0
  62. package/esm/editor/src/types.d.ts.map +1 -0
  63. package/esm/editor/src/types.js +1 -0
  64. package/esm/editor/src/ui.d.ts +15 -0
  65. package/esm/editor/src/ui.d.ts.map +1 -0
  66. package/esm/editor/src/ui.js +16 -0
  67. package/esm/editor/src/utilities/SmartOutput.d.ts +41 -0
  68. package/esm/editor/src/utilities/SmartOutput.d.ts.map +1 -0
  69. package/esm/editor/src/utilities/SmartOutput.js +228 -0
  70. package/esm/editor/src/utilities/createNodeFromContent.d.ts +9 -0
  71. package/esm/editor/src/utilities/createNodeFromContent.d.ts.map +1 -0
  72. package/esm/editor/src/utilities/createNodeFromContent.js +32 -0
  73. package/esm/editor/src/utilities/getHtmlAttributes.d.ts +9 -0
  74. package/esm/editor/src/utilities/getHtmlAttributes.d.ts.map +1 -0
  75. package/esm/editor/src/utilities/getHtmlAttributes.js +47 -0
  76. package/esm/extension-menu-legacy/src/ExtensionMenuLegacy.d.ts +14 -0
  77. package/esm/extension-menu-legacy/src/ExtensionMenuLegacy.d.ts.map +1 -0
  78. package/esm/extension-menu-legacy/src/ExtensionMenuLegacy.js +32 -0
  79. package/esm/extension-menu-legacy/src/MenuPlugin.d.ts +9 -0
  80. package/esm/extension-menu-legacy/src/MenuPlugin.d.ts.map +1 -0
  81. package/esm/extension-menu-legacy/src/MenuPlugin.js +227 -0
  82. package/esm/extension-menu-legacy/src/buildMenu.d.ts +5 -0
  83. package/esm/extension-menu-legacy/src/buildMenu.d.ts.map +1 -0
  84. package/esm/extension-menu-legacy/src/buildMenu.js +331 -0
  85. package/esm/extension-menu-legacy/src/icons.d.ts +15 -0
  86. package/esm/extension-menu-legacy/src/icons.d.ts.map +1 -0
  87. package/esm/extension-menu-legacy/src/icons.js +118 -0
  88. package/esm/extension-menu-legacy/src/menu.d.ts +81 -0
  89. package/esm/extension-menu-legacy/src/menu.d.ts.map +1 -0
  90. package/esm/extension-menu-legacy/src/menu.js +350 -0
  91. package/esm/extension-menu-legacy/src/mod.d.ts +3 -0
  92. package/esm/extension-menu-legacy/src/mod.d.ts.map +1 -0
  93. package/esm/extension-menu-legacy/src/mod.js +2 -0
  94. package/esm/extension-menu-legacy/src/prompt.d.ts +36 -0
  95. package/esm/extension-menu-legacy/src/prompt.d.ts.map +1 -0
  96. package/esm/extension-menu-legacy/src/prompt.js +158 -0
  97. package/esm/package.json +3 -0
  98. package/package.json +22 -0
@@ -0,0 +1,350 @@
1
+ import { getIcon } from './icons.js';
2
+ /// An icon or label that, when clicked, executes a command.
3
+ export class MenuItem {
4
+ /// Create a menu item.
5
+ constructor(
6
+ /// The spec used to create this item.
7
+ spec) {
8
+ Object.defineProperty(this, "spec", {
9
+ enumerable: true,
10
+ configurable: true,
11
+ writable: true,
12
+ value: spec
13
+ });
14
+ Object.defineProperty(this, "CSS_PREFIX", {
15
+ enumerable: true,
16
+ configurable: true,
17
+ writable: true,
18
+ value: 'kb-menu__button'
19
+ });
20
+ }
21
+ /// Renders the icon according to its [display
22
+ /// spec](#menu.MenuItemSpec.display), and adds an event handler which
23
+ /// executes the command when the representation is clicked.
24
+ render(view) {
25
+ let spec = this.spec;
26
+ let dom = spec.render ? spec.render(view) : null;
27
+ if (!dom) {
28
+ // Create a proper button element for better accessibility
29
+ dom = document.createElement('button');
30
+ dom.setAttribute('type', 'button');
31
+ // Add our new CSS classes while maintaining backward compatibility
32
+ dom.classList.add(this.CSS_PREFIX);
33
+ if (spec.icon) {
34
+ const icon = getIcon(view.root, spec.icon);
35
+ dom.appendChild(icon);
36
+ dom.classList.add(this.CSS_PREFIX + '--icon-only');
37
+ }
38
+ if (spec.label) {
39
+ const labelSpan = document.createElement('span');
40
+ labelSpan.appendChild(document.createTextNode(translate(view, spec.label)));
41
+ dom.appendChild(labelSpan);
42
+ if (spec.icon) {
43
+ dom.classList.remove(this.CSS_PREFIX + '--icon-only');
44
+ }
45
+ }
46
+ if (!spec.icon && !spec.label) {
47
+ throw new RangeError('MenuItem without icon or label property');
48
+ }
49
+ }
50
+ if (spec.title) {
51
+ const title = typeof spec.title === 'function'
52
+ ? spec.title(view.state)
53
+ : spec.title;
54
+ dom.setAttribute('title', translate(view, title));
55
+ dom.setAttribute('aria-label', translate(view, title));
56
+ }
57
+ if (spec.class)
58
+ dom.classList.add(spec.class);
59
+ if (spec.css)
60
+ dom.style.cssText += spec.css;
61
+ dom.addEventListener('mousedown', (e) => {
62
+ e.preventDefault();
63
+ if (!dom.classList.contains(this.CSS_PREFIX + '--disabled')) {
64
+ spec.run(view.state, view.dispatch);
65
+ }
66
+ });
67
+ const update = (state) => {
68
+ if (spec.select) {
69
+ let selected = spec.select(state);
70
+ dom.style.display = selected ? '' : 'none';
71
+ if (!selected)
72
+ return false;
73
+ }
74
+ let enabled = true;
75
+ if (spec.enable) {
76
+ enabled = spec.enable(state) || false;
77
+ setClass(dom, this.CSS_PREFIX + '--disabled', !enabled);
78
+ dom.setAttribute('aria-disabled', (!enabled).toString());
79
+ }
80
+ if (spec.active) {
81
+ let active = enabled && spec.active(state) || false;
82
+ setClass(dom, this.CSS_PREFIX + '--active', active);
83
+ dom.setAttribute('aria-pressed', active.toString());
84
+ }
85
+ return true;
86
+ };
87
+ return { dom, update };
88
+ }
89
+ }
90
+ function translate(view, text) {
91
+ return view._props.translate
92
+ ? view._props.translate(text)
93
+ : text;
94
+ }
95
+ let lastMenuEvent = {
96
+ time: 0,
97
+ node: null,
98
+ };
99
+ function markMenuEvent(e) {
100
+ lastMenuEvent.time = Date.now();
101
+ lastMenuEvent.node = e.target;
102
+ }
103
+ function isMenuEvent(wrapper) {
104
+ return Date.now() - 100 < lastMenuEvent.time &&
105
+ lastMenuEvent.node && wrapper.contains(lastMenuEvent.node);
106
+ }
107
+ /// A drop-down menu, displayed as a label with a downwards-pointing
108
+ /// triangle to the right of it.
109
+ export class Dropdown {
110
+ /// Create a dropdown wrapping the elements.
111
+ constructor(content,
112
+ /// @internal
113
+ options = {}) {
114
+ Object.defineProperty(this, "options", {
115
+ enumerable: true,
116
+ configurable: true,
117
+ writable: true,
118
+ value: options
119
+ });
120
+ Object.defineProperty(this, "CSS_PREFIX", {
121
+ enumerable: true,
122
+ configurable: true,
123
+ writable: true,
124
+ value: 'kb-dropdown'
125
+ });
126
+ /// @internal
127
+ Object.defineProperty(this, "content", {
128
+ enumerable: true,
129
+ configurable: true,
130
+ writable: true,
131
+ value: void 0
132
+ });
133
+ this.options = options || {};
134
+ this.content = Array.isArray(content) ? content : [content];
135
+ }
136
+ /// Render the dropdown menu and sub-items.
137
+ render(view) {
138
+ let content = renderDropdownItems(this.content, view);
139
+ let win = view.dom.ownerDocument.defaultView;
140
+ // Create a button element instead of div for better accessibility
141
+ let label = document.createElement('button');
142
+ label.setAttribute('type', 'button');
143
+ label.classList.add(this.CSS_PREFIX + '__label');
144
+ if (this.options.class) {
145
+ label.classList.add(this.options.class);
146
+ }
147
+ if (this.options.css)
148
+ label.setAttribute('style', this.options.css);
149
+ label.appendChild(document.createTextNode(translate(view, this.options.label || '')));
150
+ if (this.options.title) {
151
+ const title = translate(view, this.options.title);
152
+ label.setAttribute('title', title);
153
+ label.setAttribute('aria-label', title);
154
+ }
155
+ // Set ARIA attributes for accessibility
156
+ label.setAttribute('aria-haspopup', 'true');
157
+ label.setAttribute('aria-expanded', 'false');
158
+ let wrap = document.createElement('div');
159
+ wrap.classList.add(this.CSS_PREFIX);
160
+ wrap.appendChild(label);
161
+ let open = null;
162
+ let listeningOnClose = null;
163
+ let close = () => {
164
+ if (open && open.close()) {
165
+ open = null;
166
+ win.removeEventListener('mousedown', listeningOnClose);
167
+ }
168
+ };
169
+ label.addEventListener('mousedown', (e) => {
170
+ e.preventDefault();
171
+ markMenuEvent(e);
172
+ if (open) {
173
+ close();
174
+ wrap.classList.remove('kb-dropdown--open');
175
+ }
176
+ else {
177
+ open = this.expand(wrap, content.dom);
178
+ wrap.classList.add('kb-dropdown--open');
179
+ win.addEventListener('mousedown', listeningOnClose = () => {
180
+ if (!isMenuEvent(wrap))
181
+ close();
182
+ });
183
+ }
184
+ });
185
+ function update(state) {
186
+ let inner = content.update(state);
187
+ wrap.style.display = inner ? '' : 'none';
188
+ return inner;
189
+ }
190
+ return { dom: wrap, update };
191
+ }
192
+ /// @internal
193
+ expand(dom, items) {
194
+ const menuDOM = document.createElement('div');
195
+ menuDOM.classList.add('kb-dropdown__menu');
196
+ menuDOM.setAttribute('role', 'menu');
197
+ if (this.options.class) {
198
+ menuDOM.classList.add(this.options.class);
199
+ }
200
+ items.forEach((item) => menuDOM.appendChild(item));
201
+ let done = false;
202
+ function close() {
203
+ if (done)
204
+ return false;
205
+ done = true;
206
+ dom.removeChild(menuDOM);
207
+ return true;
208
+ }
209
+ dom.appendChild(menuDOM);
210
+ return { close, node: menuDOM };
211
+ }
212
+ }
213
+ function renderDropdownItems(items, view) {
214
+ let rendered = [], updates = [];
215
+ for (let i = 0; i < items.length; i++) {
216
+ let { dom, update } = items[i].render(view);
217
+ const item = document.createElement('div');
218
+ item.classList.add('kb-dropdown__item');
219
+ item.appendChild(dom);
220
+ rendered.push(item);
221
+ updates.push(update);
222
+ }
223
+ return { dom: rendered, update: combineUpdates(updates, rendered) };
224
+ }
225
+ function combineUpdates(updates, nodes) {
226
+ return (state) => {
227
+ let something = false;
228
+ for (let i = 0; i < updates.length; i++) {
229
+ let up = updates[i](state);
230
+ nodes[i].style.display = up ? '' : 'none';
231
+ if (up)
232
+ something = true;
233
+ }
234
+ return something;
235
+ };
236
+ }
237
+ /// Represents a submenu wrapping a group of elements that start
238
+ /// hidden and expand to the right when hovered over or tapped.
239
+ export class DropdownSubmenu {
240
+ /// Creates a submenu for the given group of menu elements. The
241
+ /// following options are recognized:
242
+ constructor(content,
243
+ /// @internal
244
+ options = {}) {
245
+ Object.defineProperty(this, "options", {
246
+ enumerable: true,
247
+ configurable: true,
248
+ writable: true,
249
+ value: options
250
+ });
251
+ /// @internal
252
+ Object.defineProperty(this, "content", {
253
+ enumerable: true,
254
+ configurable: true,
255
+ writable: true,
256
+ value: void 0
257
+ });
258
+ this.content = Array.isArray(content) ? content : [content];
259
+ }
260
+ /// Renders the submenu.
261
+ render(view) {
262
+ const CSS_PREFIX = 'kb-submenu';
263
+ const items = renderDropdownItems(this.content, view);
264
+ const win = view.dom.ownerDocument.defaultView;
265
+ const wrap = document.createElement('div');
266
+ wrap.classList.add(CSS_PREFIX);
267
+ const label = document.createElement('div');
268
+ label.classList.add(CSS_PREFIX + '__label');
269
+ label.appendChild(document.createTextNode(translate(view, this.options.label || '')));
270
+ wrap.appendChild(label);
271
+ const submenu = document.createElement('div');
272
+ submenu.classList.add(CSS_PREFIX + '__content');
273
+ items.dom.forEach((item) => submenu.appendChild(item));
274
+ wrap.appendChild(submenu);
275
+ let listeningOnClose = null;
276
+ label.addEventListener('mousedown', (e) => {
277
+ e.preventDefault();
278
+ markMenuEvent(e);
279
+ const isOpen = wrap.classList.contains(CSS_PREFIX + '--open');
280
+ setClass(wrap, CSS_PREFIX + '--open', !isOpen);
281
+ if (!isOpen && !listeningOnClose) {
282
+ win.addEventListener('mousedown', listeningOnClose = () => {
283
+ if (!isMenuEvent(wrap)) {
284
+ wrap.classList.remove(CSS_PREFIX + '--open');
285
+ win.removeEventListener('mousedown', listeningOnClose);
286
+ listeningOnClose = null;
287
+ }
288
+ });
289
+ }
290
+ });
291
+ function update(state) {
292
+ let inner = items.update(state);
293
+ wrap.style.display = inner ? '' : 'none';
294
+ return inner;
295
+ }
296
+ return { dom: wrap, update };
297
+ }
298
+ }
299
+ /// Render the given, possibly nested, array of menu elements into a
300
+ /// document fragment, placing separators between them (and ensuring no
301
+ /// superfluous separators appear when some of the groups turn out to
302
+ /// be empty).
303
+ export function renderGrouped(view, content) {
304
+ let result = document.createDocumentFragment();
305
+ let updates = [], separators = [];
306
+ for (let i = 0; i < content.length; i++) {
307
+ let items = content[i], localUpdates = [], localNodes = [];
308
+ for (let j = 0; j < items.length; j++) {
309
+ let { dom, update } = items[j].render(view);
310
+ let span = document.createElement('span');
311
+ span.classList.add('kb-menu__item');
312
+ span.appendChild(dom);
313
+ result.appendChild(span);
314
+ localNodes.push(span);
315
+ localUpdates.push(update);
316
+ }
317
+ if (localUpdates.length) {
318
+ updates.push(combineUpdates(localUpdates, localNodes));
319
+ if (i < content.length - 1) {
320
+ separators.push(result.appendChild(separator()));
321
+ }
322
+ }
323
+ }
324
+ function update(state) {
325
+ let something = false, needSep = false;
326
+ for (let i = 0; i < updates.length; i++) {
327
+ let hasContent = updates[i](state);
328
+ if (i) {
329
+ separators[i - 1].style.display = needSep && hasContent ? '' : 'none';
330
+ }
331
+ needSep = hasContent;
332
+ if (hasContent)
333
+ something = true;
334
+ }
335
+ return something;
336
+ }
337
+ return { dom: result, update };
338
+ }
339
+ function separator() {
340
+ const elem = document.createElement('div');
341
+ elem.classList.add('kb-menu__separator');
342
+ return elem;
343
+ }
344
+ // Work around classList.toggle being broken in IE11
345
+ function setClass(dom, cls, on) {
346
+ if (on)
347
+ dom.classList.add(cls);
348
+ else
349
+ dom.classList.remove(cls);
350
+ }
@@ -0,0 +1,3 @@
1
+ export { Dropdown, DropdownSubmenu, type MenuElement, MenuItem, type MenuItemSpec, } from './menu.js';
2
+ export * from './ExtensionMenuLegacy.js';
3
+ //# sourceMappingURL=mod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../src/extension-menu-legacy/src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,eAAe,EACf,KAAK,WAAW,EAChB,QAAQ,EACR,KAAK,YAAY,GAClB,MAAM,WAAW,CAAC;AAEnB,cAAc,0BAA0B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { Dropdown, DropdownSubmenu, MenuItem, } from './menu.js';
2
+ export * from './ExtensionMenuLegacy.js';
@@ -0,0 +1,36 @@
1
+ import { Attrs } from 'prosemirror-model';
2
+ export declare function openPrompt(options: {
3
+ title: string;
4
+ fields: {
5
+ [name: string]: Field;
6
+ };
7
+ callback: (attrs: Attrs) => void;
8
+ }): void;
9
+ export declare abstract class Field {
10
+ readonly options: {
11
+ value?: any;
12
+ label: string;
13
+ required?: boolean;
14
+ validate?: (value: any) => string | null;
15
+ clean?: (value: any) => any;
16
+ };
17
+ constructor(options: {
18
+ value?: any;
19
+ label: string;
20
+ required?: boolean;
21
+ validate?: (value: any) => string | null;
22
+ clean?: (value: any) => any;
23
+ });
24
+ abstract render(): HTMLElement;
25
+ read(dom: HTMLElement): any;
26
+ validateType(value: any): string | null;
27
+ validate(value: any): string | null;
28
+ clean(value: any): any;
29
+ }
30
+ export declare class TextField extends Field {
31
+ render(): any;
32
+ }
33
+ export declare class SelectField extends Field {
34
+ render(): any;
35
+ }
36
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../src/extension-menu-legacy/src/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAI1C,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAA;KAAE,CAAC;IAClC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC,QA0EA;AA+BD,8BAAsB,KAAK;IAKvB,QAAQ,CAAC,OAAO,EAAE;QAEhB,KAAK,CAAC,EAAE,GAAG,CAAC;QAGZ,KAAK,EAAE,MAAM,CAAC;QAGd,QAAQ,CAAC,EAAE,OAAO,CAAC;QAInB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,GAAG,IAAI,CAAC;QAGzC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC;KAC7B;gBAhBQ,OAAO,EAAE;QAEhB,KAAK,CAAC,EAAE,GAAG,CAAC;QAGZ,KAAK,EAAE,MAAM,CAAC;QAGd,QAAQ,CAAC,EAAE,OAAO,CAAC;QAInB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,GAAG,IAAI,CAAC;QAGzC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC;KAC7B;IAIH,QAAQ,CAAC,MAAM,IAAI,WAAW;IAG9B,IAAI,CAAC,GAAG,EAAE,WAAW;IAKrB,YAAY,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM,GAAG,IAAI;IAKvC,QAAQ,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM,GAAG,IAAI;IAQnC,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG;CAGvB;AAGD,qBAAa,SAAU,SAAQ,KAAK;IAClC,MAAM;CAQP;AAMD,qBAAa,WAAY,SAAQ,KAAK;IACpC,MAAM;CAWP"}
@@ -0,0 +1,158 @@
1
+ const CSS_PREFIX = 'kb-prompt';
2
+ export function openPrompt(options) {
3
+ let wrapper = document.body.appendChild(document.createElement('div'));
4
+ wrapper.className = CSS_PREFIX;
5
+ let mouseOutside = (e) => {
6
+ if (!wrapper.contains(e.target))
7
+ close();
8
+ };
9
+ setTimeout(() => globalThis.addEventListener('mousedown', mouseOutside), 50);
10
+ let close = () => {
11
+ globalThis.removeEventListener('mousedown', mouseOutside);
12
+ if (wrapper.parentNode)
13
+ wrapper.parentNode.removeChild(wrapper);
14
+ };
15
+ let domFields = [];
16
+ for (let name in options.fields) {
17
+ domFields.push(options.fields[name].render());
18
+ }
19
+ let submitButton = document.createElement('button');
20
+ submitButton.type = 'submit';
21
+ submitButton.className = CSS_PREFIX + '--submit';
22
+ submitButton.textContent = 'OK';
23
+ let cancelButton = document.createElement('button');
24
+ cancelButton.type = 'button';
25
+ cancelButton.className = CSS_PREFIX + '--cancel';
26
+ cancelButton.textContent = 'Cancel';
27
+ cancelButton.addEventListener('click', close);
28
+ let form = wrapper.appendChild(document.createElement('form'));
29
+ if (options.title) {
30
+ form.appendChild(document.createElement('h5')).textContent = options.title;
31
+ }
32
+ domFields.forEach((field) => {
33
+ form.appendChild(document.createElement('div')).appendChild(field);
34
+ });
35
+ let buttons = form.appendChild(document.createElement('div'));
36
+ buttons.className = CSS_PREFIX + '__buttons';
37
+ buttons.appendChild(submitButton);
38
+ buttons.appendChild(document.createTextNode(' '));
39
+ buttons.appendChild(cancelButton);
40
+ let box = wrapper.getBoundingClientRect();
41
+ wrapper.style.top = ((globalThis.innerHeight - box.height) / 2) + 'px';
42
+ wrapper.style.left = ((globalThis.innerWidth - box.width) / 2) + 'px';
43
+ let submit = () => {
44
+ let params = getValues(options.fields, domFields);
45
+ if (params) {
46
+ close();
47
+ options.callback(params);
48
+ }
49
+ };
50
+ form.addEventListener('submit', (e) => {
51
+ e.preventDefault();
52
+ submit();
53
+ });
54
+ form.addEventListener('keydown', (e) => {
55
+ if (e.keyCode == 27) {
56
+ e.preventDefault();
57
+ close();
58
+ }
59
+ else if (e.keyCode == 13 && !(e.ctrlKey || e.metaKey || e.shiftKey)) {
60
+ e.preventDefault();
61
+ submit();
62
+ }
63
+ else if (e.keyCode == 9) {
64
+ globalThis.setTimeout(() => {
65
+ if (!wrapper.contains(document.activeElement))
66
+ close();
67
+ }, 500);
68
+ }
69
+ });
70
+ let input = form.elements[0];
71
+ if (input)
72
+ input.focus();
73
+ }
74
+ function getValues(fields, domFields) {
75
+ let result = Object.create(null), i = 0;
76
+ for (let name in fields) {
77
+ let field = fields[name], dom = domFields[i++];
78
+ let value = field.read(dom), bad = field.validate(value);
79
+ if (bad) {
80
+ reportInvalid(dom, bad);
81
+ return null;
82
+ }
83
+ result[name] = field.clean(value);
84
+ }
85
+ return result;
86
+ }
87
+ function reportInvalid(dom, message) {
88
+ // FIXME this is awful and needs a lot more work
89
+ let parent = dom.parentNode;
90
+ let msg = parent.appendChild(document.createElement('div'));
91
+ msg.style.left = (dom.offsetLeft + dom.offsetWidth + 2) + 'px';
92
+ msg.style.top = (dom.offsetTop - 5) + 'px';
93
+ msg.className = 'kb-invalid';
94
+ msg.textContent = message;
95
+ setTimeout(() => parent.removeChild(msg), 1500);
96
+ }
97
+ /// The type of field that `openPrompt` expects to be passed to it.
98
+ export class Field {
99
+ /// Create a field with the given options. Options support by all
100
+ /// field types are:
101
+ constructor(
102
+ /// @internal
103
+ options) {
104
+ Object.defineProperty(this, "options", {
105
+ enumerable: true,
106
+ configurable: true,
107
+ writable: true,
108
+ value: options
109
+ });
110
+ }
111
+ /// Read the field's value from its DOM node.
112
+ read(dom) {
113
+ return dom.value;
114
+ }
115
+ /// A field-type-specific validation function.
116
+ validateType(value) {
117
+ return null;
118
+ }
119
+ /// @internal
120
+ validate(value) {
121
+ if (!value && this.options.required) {
122
+ return 'Required field';
123
+ }
124
+ return this.validateType(value) ||
125
+ (this.options.validate ? this.options.validate(value) : null);
126
+ }
127
+ clean(value) {
128
+ return this.options.clean ? this.options.clean(value) : value;
129
+ }
130
+ }
131
+ /// A field class for single-line text fields.
132
+ export class TextField extends Field {
133
+ render() {
134
+ let input = document.createElement('input');
135
+ input.type = 'text';
136
+ input.placeholder = this.options.label;
137
+ input.value = this.options.value || '';
138
+ input.autocomplete = 'off';
139
+ return input;
140
+ }
141
+ }
142
+ /// A field class for dropdown fields based on a plain `<select>`
143
+ /// tag. Expects an option `options`, which should be an array of
144
+ /// `{value: string, label: string}` objects, or a function taking a
145
+ /// `ProseMirror` instance and returning such an array.
146
+ export class SelectField extends Field {
147
+ render() {
148
+ let select = document.createElement('select');
149
+ this.options.options
150
+ .forEach((o) => {
151
+ let opt = select.appendChild(document.createElement('option'));
152
+ opt.value = o.value;
153
+ opt.selected = o.value == this.options.value;
154
+ opt.label = o.label;
155
+ });
156
+ return select;
157
+ }
158
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@kerebron/extension-menu-legacy",
3
+ "version": "0.4.0",
4
+ "license": "MIT",
5
+ "module": "./esm/extension-menu-legacy/src/mod.js",
6
+ "exports": {
7
+ ".": {
8
+ "import": "./esm/extension-menu-legacy/src/mod.js"
9
+ }
10
+ },
11
+ "scripts": {},
12
+ "dependencies": {
13
+ "prosemirror-model": "1.25.3",
14
+ "prosemirror-state": "1.4.3",
15
+ "prosemirror-transform": "1.10.4",
16
+ "prosemirror-view": "1.40.0"
17
+ },
18
+ "devDependencies": {
19
+ "@types/node": "^20.9.0"
20
+ },
21
+ "_generatedBy": "dnt@dev"
22
+ }