markupeditor 0.9.31 → 0.9.33
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/markup-editor.js +80 -13
- package/package.json +1 -1
package/dist/markup-editor.js
CHANGED
|
@@ -235,9 +235,14 @@ class Registry {
|
|
|
235
235
|
|
|
236
236
|
/**
|
|
237
237
|
* Add `plugin` to the registry, keyed by `name`.
|
|
238
|
+
* A `plugin` object has `name` and `type` string properties at minimum.
|
|
239
|
+
* The invoker can add additional properties to the `plugin`.
|
|
240
|
+
* For example, a `run` function could be part of the `plugin`, which could,
|
|
241
|
+
* by convention of the application environment the markupeditor is used in,
|
|
242
|
+
* be used to run the `plugin` to perform some action or return something.
|
|
238
243
|
*
|
|
239
|
-
* @param {object} plugin Plugin object with string
|
|
240
|
-
* @param {string} name The key used to retrieve and invoke the plugin.
|
|
244
|
+
* @param {object} plugin Plugin object with string properties for {name, type} at minimum.
|
|
245
|
+
* @param {string} name The key used to retrieve and invoke the plugin. Taken from `plugin.name` by default.
|
|
241
246
|
*/
|
|
242
247
|
registerPlugin(plugin, name) {
|
|
243
248
|
this._plugins.set(name ?? plugin.name, plugin);
|
|
@@ -256,17 +261,17 @@ class Registry {
|
|
|
256
261
|
* Return the plugin object with `name`, or undefined if not found.
|
|
257
262
|
*
|
|
258
263
|
* @param {string} name The key used to identify the plugin.
|
|
259
|
-
* @returns {object|undefined}
|
|
264
|
+
* @returns {object | undefined}
|
|
260
265
|
*/
|
|
261
266
|
getPlugin(name) {
|
|
262
267
|
return this._plugins.get(name)
|
|
263
268
|
}
|
|
264
269
|
|
|
265
270
|
/**
|
|
266
|
-
* Return an array of registered plugins that match type
|
|
267
|
-
* Each entry contains {name, type, filename}
|
|
271
|
+
* Return an array of registered plugins that match `type`, all if not specified.
|
|
268
272
|
*
|
|
269
|
-
* @
|
|
273
|
+
* @param {string} type The plugin type to filter by; all plugins are returned if omitted.
|
|
274
|
+
* @returns {Array<object>} Array of plugin objects with string properties for {name, type} at minimum.
|
|
270
275
|
*/
|
|
271
276
|
getPlugins(type) {
|
|
272
277
|
if (type) {
|
|
@@ -512,10 +517,15 @@ const setSelectedID = _registry.setSelectedID.bind(_registry);
|
|
|
512
517
|
|
|
513
518
|
/**
|
|
514
519
|
* Add `plugin` to the registry, keyed by `name`.
|
|
520
|
+
* A `plugin` object has `name` and `type` string properties at minimum.
|
|
521
|
+
* The invoker can add additional properties to the `plugin`.
|
|
522
|
+
* For example, a `run` function could be part of the `plugin`, which could,
|
|
523
|
+
* by convention of the application environment the markupeditor is used in,
|
|
524
|
+
* be used to run the `plugin` to perform some action or return something.
|
|
515
525
|
*
|
|
516
526
|
* @function
|
|
517
|
-
* @param {object} plugin Plugin object with string
|
|
518
|
-
* @param {string} name The key used to retrieve and invoke the plugin.
|
|
527
|
+
* @param {object} plugin Plugin object with string properties for {name, type} at minimum.
|
|
528
|
+
* @param {string} name The key used to retrieve and invoke the plugin. Taken from `plugin.name` by default.
|
|
519
529
|
*/
|
|
520
530
|
const registerPlugin = _registry.registerPlugin.bind(_registry);
|
|
521
531
|
|
|
@@ -538,14 +548,36 @@ const getPlugin = _registry.getPlugin.bind(_registry);
|
|
|
538
548
|
|
|
539
549
|
/**
|
|
540
550
|
* Return an array of registered plugins that match `type`, all if not specified.
|
|
541
|
-
* Each entry contains {name, type, filename}
|
|
542
551
|
*
|
|
543
552
|
* @function
|
|
544
|
-
* @param {string}
|
|
545
|
-
* @returns {Array<{name
|
|
553
|
+
* @param {string} type The plugin type to filter by; all plugins are returned if omitted.
|
|
554
|
+
* @returns {Array<object>} Array of plugin objects with string properties for {name, type} at minimum.
|
|
546
555
|
*/
|
|
547
556
|
const getPlugins = _registry.getPlugins.bind(_registry);
|
|
548
557
|
|
|
558
|
+
/**
|
|
559
|
+
* Look up the plugin with `name` and invoke its `run` function, returning/awaiting whatever
|
|
560
|
+
* it resolves to.
|
|
561
|
+
*
|
|
562
|
+
* Content-agnostic and plugin-type-agnostic: `runPlugin` never fetches or supplies content
|
|
563
|
+
* on the plugin's behalf. The plugin's `run` function is responsible for getting
|
|
564
|
+
* whatever content it needs, via whichever accessor (e.g. `getHTML`) fits its purpose.
|
|
565
|
+
*
|
|
566
|
+
* Returns `null`, never rejects, when there's nothing to run: no plugin registered with
|
|
567
|
+
* `name`, or a plugin registered without a `run` function. If `run` itself rejects, that
|
|
568
|
+
* rejection propagates unchanged — it is not swallowed into `null`, so a caller can't
|
|
569
|
+
* confuse "nothing to run" with "the plugin failed."
|
|
570
|
+
*
|
|
571
|
+
* @function
|
|
572
|
+
* @param {string} name The key used to identify the plugin.
|
|
573
|
+
* @returns {Promise<*>} Whatever `plugin.run()` resolves to, or `null`.
|
|
574
|
+
*/
|
|
575
|
+
async function runPlugin(name) {
|
|
576
|
+
const plugin = getPlugin(name);
|
|
577
|
+
if (!plugin?.run) return null
|
|
578
|
+
return await plugin.run()
|
|
579
|
+
}
|
|
580
|
+
|
|
549
581
|
/**
|
|
550
582
|
* MUError captures internal errors and makes it easy to communicate them externally.
|
|
551
583
|
*
|
|
@@ -32935,6 +32967,40 @@ function handleDelete() {
|
|
|
32935
32967
|
return false
|
|
32936
32968
|
}
|
|
32937
32969
|
|
|
32970
|
+
/**
|
|
32971
|
+
* Delete a `\n` immediately before (dir -1) or after (dir +1) the cursor inside a code_block's
|
|
32972
|
+
* text, via a direct transaction rather than relying on native contenteditable editing.
|
|
32973
|
+
*
|
|
32974
|
+
* Safari/WebKit never issues a native deleteContentBackward/deleteContentForward `beforeinput`
|
|
32975
|
+
* at all when the adjacent `\n` is the last character in the block (cursor at the start of an
|
|
32976
|
+
* empty trailing line) under `white-space: pre-wrap` — confirmed by instrumenting keydown/
|
|
32977
|
+
* beforeinput/input: keydown fires and is not prevented, but no beforeinput or input event
|
|
32978
|
+
* follows, and neither the ProseMirror doc nor the DOM change. The unhandled key produces the
|
|
32979
|
+
* system beep. This only reproduces with the real `white-space: pre-wrap` styling the editor
|
|
32980
|
+
* ships with; it does not reproduce against an unstyled contenteditable. Newline deletion inside
|
|
32981
|
+
* a code_block is therefore always handled explicitly here so it never depends on native
|
|
32982
|
+
* contenteditable editing for this specific character.
|
|
32983
|
+
*
|
|
32984
|
+
* @ignore
|
|
32985
|
+
*/
|
|
32986
|
+
function deleteAdjacentNewline(dir) {
|
|
32987
|
+
return (state, dispatch) => {
|
|
32988
|
+
const { $from, empty } = state.selection;
|
|
32989
|
+
if (!empty || $from.parent.type !== state.schema.nodes.code_block) return false
|
|
32990
|
+
const text = $from.parent.textContent;
|
|
32991
|
+
const charOffset = dir < 0 ? $from.parentOffset - 1 : $from.parentOffset;
|
|
32992
|
+
if (charOffset < 0 || charOffset >= text.length || text[charOffset] !== '\n') return false
|
|
32993
|
+
if (dispatch) {
|
|
32994
|
+
const from = $from.pos + (dir < 0 ? -1 : 0);
|
|
32995
|
+
dispatch(state.tr.delete(from, from + 1));
|
|
32996
|
+
}
|
|
32997
|
+
return true
|
|
32998
|
+
}
|
|
32999
|
+
}
|
|
33000
|
+
|
|
33001
|
+
const deleteNewlineBackward = deleteAdjacentNewline(-1);
|
|
33002
|
+
const deleteNewlineForward = deleteAdjacentNewline(1);
|
|
33003
|
+
|
|
32938
33004
|
/**
|
|
32939
33005
|
* Called to set attributes to the editor div, typically to ,
|
|
32940
33006
|
* set spellcheck and autocorrect. Note that contenteditable
|
|
@@ -40591,7 +40657,7 @@ function buildKeymap(config, schema) {
|
|
|
40591
40657
|
// The MarkupEditor handles Shift-Enter as searchBackward when search is active.
|
|
40592
40658
|
bind("Shift-Enter", handleShiftEnter);
|
|
40593
40659
|
// The MarkupEditor needs to be notified of state changes on Delete, like Backspace
|
|
40594
|
-
bind("Delete", handleDelete);
|
|
40660
|
+
bind("Delete", chainCommands(handleDelete, deleteNewlineForward));
|
|
40595
40661
|
// Table navigation by Tab/Shift-Tab
|
|
40596
40662
|
bind('Tab', goToNextCell(1));
|
|
40597
40663
|
bind('Shift-Tab', goToNextCell(-1));
|
|
@@ -40607,7 +40673,7 @@ function buildKeymap(config, schema) {
|
|
|
40607
40673
|
// Correction (needs to be chained with stateChanged also)
|
|
40608
40674
|
bind(keymap.undo, undoCommand());
|
|
40609
40675
|
bind(keymap.redo, redoCommand());
|
|
40610
|
-
bind("Backspace", chainCommands(handleDelete, undoInputRule));
|
|
40676
|
+
bind("Backspace", chainCommands(handleDelete, deleteNewlineBackward, undoInputRule));
|
|
40611
40677
|
// List types
|
|
40612
40678
|
bind(keymap.bullet, wrapInListCommand(schema, schema.nodes.bullet_list));
|
|
40613
40679
|
bind(keymap.number, wrapInListCommand(schema, schema.nodes.ordered_list));
|
|
@@ -42529,6 +42595,7 @@ const MU = {
|
|
|
42529
42595
|
unregisterPlugin,
|
|
42530
42596
|
getPlugin,
|
|
42531
42597
|
getPlugins,
|
|
42598
|
+
runPlugin,
|
|
42532
42599
|
};
|
|
42533
42600
|
|
|
42534
42601
|
sheet.media.mediaText = '(prefers-color-scheme: dark)';
|