@kerebron/editor 0.4.26 → 0.4.28
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/assets/base.css +7 -0
- package/assets/vars.css +21 -8
- package/esm/commands/baseCommandFactories.d.ts.map +1 -1
- package/esm/commands/baseCommandFactories.js +86 -61
- package/esm/commands/keyCommandFactories.d.ts.map +1 -1
- package/esm/commands/keyCommandFactories.js +1 -1
- package/esm/commands/mod.d.ts.map +1 -1
- package/esm/commands/mod.js +7 -2
- package/esm/commands/types.d.ts +6 -2
- package/esm/commands/types.d.ts.map +1 -1
- package/esm/plugins/input-rules/InputRulesPlugin.d.ts +10 -8
- package/esm/plugins/input-rules/InputRulesPlugin.d.ts.map +1 -1
- package/esm/plugins/input-rules/InputRulesPlugin.js +77 -53
- package/esm/plugins/input-rules/rulebuilders.d.ts +1 -0
- package/esm/plugins/input-rules/rulebuilders.d.ts.map +1 -1
- package/esm/plugins/input-rules/rulebuilders.js +20 -6
- package/esm/plugins/keymap/keymap.d.ts +2 -1
- package/esm/plugins/keymap/keymap.d.ts.map +1 -1
- package/esm/search/search.d.ts +2 -1
- package/esm/search/search.d.ts.map +1 -1
- package/package.json +1 -1
package/assets/base.css
CHANGED
package/assets/vars.css
CHANGED
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
--kb-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
|
|
32
32
|
|
|
33
33
|
/* Z-index Scale */
|
|
34
|
-
--kb-z-dropdown:
|
|
35
|
-
--kb-z-tooltip:
|
|
36
|
-
--kb-z-modal:
|
|
37
|
-
--kb-z-notification:
|
|
34
|
+
--kb-z-dropdown: 1100;
|
|
35
|
+
--kb-z-tooltip: 1200;
|
|
36
|
+
--kb-z-modal: 1300;
|
|
37
|
+
--kb-z-notification: 1400;
|
|
38
38
|
|
|
39
39
|
/* Brand Colors (Customizable) */
|
|
40
40
|
--kb-color-primary: #3b82f6;
|
|
@@ -49,10 +49,11 @@
|
|
|
49
49
|
--kb-color-border: #e5e7eb;
|
|
50
50
|
--kb-color-border-strong: #d1d5db;
|
|
51
51
|
|
|
52
|
-
/* Menu specific colors (Google Docs style) */
|
|
53
|
-
--kb-menu-dropdown-
|
|
54
|
-
--kb-menu-dropdown-
|
|
55
|
-
--kb-menu-dropdown-
|
|
52
|
+
/* Menu specific colors (Google Docs style) - Light mode */
|
|
53
|
+
--kb-menu-dropdown-bg: #ffffff;
|
|
54
|
+
--kb-menu-dropdown-border: #dadce0;
|
|
55
|
+
--kb-menu-dropdown-text: #3c4043;
|
|
56
|
+
--kb-menu-dropdown-hover: rgba(60, 64, 67, 0.08);
|
|
56
57
|
--kb-menu-info-bg: #e8f0fe;
|
|
57
58
|
--kb-menu-info-text: #1967d2;
|
|
58
59
|
}
|
|
@@ -69,6 +70,12 @@
|
|
|
69
70
|
--kb-color-border-strong: #4b5563;
|
|
70
71
|
--kb-color-hover: rgba(59, 130, 246, 0.1);
|
|
71
72
|
--kb-color-active: rgba(59, 130, 246, 0.2);
|
|
73
|
+
|
|
74
|
+
/* Menu dropdown - Dark mode */
|
|
75
|
+
--kb-menu-dropdown-bg: #344154;
|
|
76
|
+
--kb-menu-dropdown-border: #5f6368;
|
|
77
|
+
--kb-menu-dropdown-text: #e8eaed;
|
|
78
|
+
--kb-menu-dropdown-hover: rgba(232, 234, 237, 0.08);
|
|
72
79
|
}
|
|
73
80
|
}
|
|
74
81
|
|
|
@@ -94,4 +101,10 @@
|
|
|
94
101
|
--kb-color-border-strong: #4b5563;
|
|
95
102
|
--kb-color-hover: rgba(59, 130, 246, 0.1);
|
|
96
103
|
--kb-color-active: rgba(59, 130, 246, 0.2);
|
|
104
|
+
|
|
105
|
+
/* Menu dropdown - Dark mode */
|
|
106
|
+
--kb-menu-dropdown-bg: #344154;
|
|
107
|
+
--kb-menu-dropdown-border: #5f6368;
|
|
108
|
+
--kb-menu-dropdown-text: #e8eaed;
|
|
109
|
+
--kb-menu-dropdown-hover: rgba(232, 234, 237, 0.08);
|
|
97
110
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"baseCommandFactories.d.ts","sourceRoot":"","sources":["../../src/commands/baseCommandFactories.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAgB,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"baseCommandFactories.d.ts","sourceRoot":"","sources":["../../src/commands/baseCommandFactories.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAgB,cAAc,EAAE,MAAM,YAAY,CAAC;AAihC1D,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CA6B/D,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { canJoin, canSplit, findWrapping, joinPoint, liftTarget, ReplaceAroundStep, ReplaceStep, replaceStep, } from 'prosemirror-transform';
|
|
2
2
|
import { Fragment, NodeRange, Slice, } from 'prosemirror-model';
|
|
3
3
|
import { AllSelection, NodeSelection, Selection, SelectionRange, TextSelection, } from 'prosemirror-state';
|
|
4
|
+
import { runInputRules, undoInputRuleCommand, } from '../plugins/input-rules/InputRulesPlugin.js';
|
|
4
5
|
/// Returns a command function that wraps the selection in a list with
|
|
5
6
|
/// the given type an attributes. If `dispatch` is null, only return a
|
|
6
7
|
/// value to indicate whether this is possible, but don't actually
|
|
@@ -26,27 +27,30 @@ const wrapInList = (listType, attrs = null) => {
|
|
|
26
27
|
/// `null`, the function only queries whether the wrapping is
|
|
27
28
|
/// possible.
|
|
28
29
|
const wrapRangeInList = (tr, range, listType, attrs = null) => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
30
|
+
const cmd = () => {
|
|
31
|
+
let doJoin = false, outerRange = range, doc = range.$from.doc;
|
|
32
|
+
// This is at the top of an existing list item
|
|
33
|
+
if (range.depth >= 2 &&
|
|
34
|
+
range.$from.node(range.depth - 1).type.compatibleContent(listType) &&
|
|
35
|
+
range.startIndex == 0) {
|
|
36
|
+
// Don't do anything if this is the top of the list
|
|
37
|
+
if (range.$from.index(range.depth - 1) == 0)
|
|
38
|
+
return false;
|
|
39
|
+
let $insert = doc.resolve(range.start - 2);
|
|
40
|
+
outerRange = new NodeRange($insert, $insert, range.depth);
|
|
41
|
+
if (range.endIndex < range.parent.childCount) {
|
|
42
|
+
range = new NodeRange(range.$from, doc.resolve(range.$to.end(range.depth)), range.depth);
|
|
43
|
+
}
|
|
44
|
+
doJoin = true;
|
|
41
45
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return
|
|
46
|
+
let wrap = findWrapping(outerRange, listType, attrs, range);
|
|
47
|
+
if (!wrap)
|
|
48
|
+
return false;
|
|
49
|
+
if (tr)
|
|
50
|
+
doWrapInList(tr, range, wrap, doJoin, listType);
|
|
51
|
+
return true;
|
|
52
|
+
};
|
|
53
|
+
return cmd;
|
|
50
54
|
};
|
|
51
55
|
function doWrapInList(tr, range, wrappers, joinBefore, listType) {
|
|
52
56
|
let content = Fragment.empty;
|
|
@@ -388,15 +392,21 @@ const lift = () => (state, dispatch) => {
|
|
|
388
392
|
/// If the selection is in a node whose type has a truthy
|
|
389
393
|
/// [`code`](#model.NodeSpec.code) property in its spec, replace the
|
|
390
394
|
/// selection with a newline character.
|
|
391
|
-
const newlineInCode = () =>
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
395
|
+
const newlineInCode = () => {
|
|
396
|
+
const cmd = (state, dispatch) => {
|
|
397
|
+
let { $head, $anchor } = state.selection;
|
|
398
|
+
if (!$head.parent.type.spec.code || !$head.sameParent($anchor)) {
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
401
|
+
if (dispatch)
|
|
402
|
+
dispatch(state.tr.insertText('\n').scrollIntoView());
|
|
403
|
+
return true;
|
|
404
|
+
};
|
|
405
|
+
cmd.displayName = 'newlineInCode()';
|
|
406
|
+
return cmd;
|
|
398
407
|
};
|
|
399
408
|
function defaultBlockAt(match) {
|
|
409
|
+
console.log('defaultBlockAt', match);
|
|
400
410
|
for (let i = 0; i < match.edgeCount; i++) {
|
|
401
411
|
let { type } = match.edge(i);
|
|
402
412
|
if (type.isTextblock && !type.hasRequiredAttrs())
|
|
@@ -423,48 +433,58 @@ const exitCode = () => (state, dispatch) => {
|
|
|
423
433
|
};
|
|
424
434
|
/// If a block node is selected, create an empty paragraph before (if
|
|
425
435
|
/// it is its parent's first child) or after it.
|
|
426
|
-
const createParagraphNear = () =>
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
$
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
.
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
436
|
+
const createParagraphNear = () => {
|
|
437
|
+
const cmd = (state, dispatch) => {
|
|
438
|
+
let sel = state.selection, { $from, $to } = sel;
|
|
439
|
+
if (sel instanceof AllSelection || $from.parent.inlineContent ||
|
|
440
|
+
$to.parent.inlineContent)
|
|
441
|
+
return false;
|
|
442
|
+
let type = defaultBlockAt($to.parent.contentMatchAt($to.indexAfter()));
|
|
443
|
+
if (!type || !type.isTextblock)
|
|
444
|
+
return false;
|
|
445
|
+
if (dispatch) {
|
|
446
|
+
let side = (!$from.parentOffset && $to.index() < $to.parent.childCount
|
|
447
|
+
? $from
|
|
448
|
+
: $to)
|
|
449
|
+
.pos;
|
|
450
|
+
let tr = state.tr.insert(side, type.createAndFill());
|
|
451
|
+
tr.setSelection(TextSelection.create(tr.doc, side + 1));
|
|
452
|
+
dispatch(tr.scrollIntoView());
|
|
453
|
+
}
|
|
454
|
+
return true;
|
|
455
|
+
};
|
|
456
|
+
cmd.displayName = 'createParagraphNear()';
|
|
457
|
+
return cmd;
|
|
442
458
|
};
|
|
443
459
|
/// If the cursor is in an empty textblock that can be lifted, lift the
|
|
444
460
|
/// block.
|
|
445
|
-
const liftEmptyBlock = () =>
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
if (
|
|
453
|
-
dispatch
|
|
454
|
-
|
|
461
|
+
const liftEmptyBlock = () => {
|
|
462
|
+
const cmd = (state, dispatch) => {
|
|
463
|
+
let { $cursor } = state.selection;
|
|
464
|
+
if (!$cursor || $cursor.parent.content.size)
|
|
465
|
+
return false;
|
|
466
|
+
if ($cursor.depth > 1 && $cursor.after() != $cursor.end(-1)) {
|
|
467
|
+
let before = $cursor.before();
|
|
468
|
+
if (canSplit(state.doc, before)) {
|
|
469
|
+
if (dispatch)
|
|
470
|
+
dispatch(state.tr.split(before).scrollIntoView());
|
|
471
|
+
return true;
|
|
472
|
+
}
|
|
455
473
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
474
|
+
let range = $cursor.blockRange(), target = range && liftTarget(range);
|
|
475
|
+
if (target == null)
|
|
476
|
+
return false;
|
|
477
|
+
if (dispatch)
|
|
478
|
+
dispatch(state.tr.lift(range, target).scrollIntoView());
|
|
479
|
+
return true;
|
|
480
|
+
};
|
|
481
|
+
cmd.displayName = 'liftEmptyBlock()';
|
|
482
|
+
return cmd;
|
|
463
483
|
};
|
|
464
484
|
/// Create a variant of [`splitBlock`](#commands.splitBlock) that uses
|
|
465
485
|
/// a custom function to determine the type of the newly split off block.
|
|
466
486
|
const splitBlockAs = (splitNode) => {
|
|
467
|
-
|
|
487
|
+
const cmd = (state, dispatch) => {
|
|
468
488
|
let { $from, $to } = state.selection;
|
|
469
489
|
if (state.selection instanceof NodeSelection && state.selection.node.isBlock) {
|
|
470
490
|
if (!$from.parentOffset || !canSplit(state.doc, $from.pos))
|
|
@@ -516,6 +536,8 @@ const splitBlockAs = (splitNode) => {
|
|
|
516
536
|
dispatch(tr.scrollIntoView());
|
|
517
537
|
return true;
|
|
518
538
|
};
|
|
539
|
+
cmd.displayName = 'splitBlockAs()';
|
|
540
|
+
return cmd;
|
|
519
541
|
};
|
|
520
542
|
/// Split the parent block of the selection. If the selection is a text
|
|
521
543
|
/// selection, also delete its content.
|
|
@@ -806,6 +828,7 @@ function toggleMark(markType, attrs = null, options) {
|
|
|
806
828
|
return true;
|
|
807
829
|
};
|
|
808
830
|
}
|
|
831
|
+
const undoInputRule = () => undoInputRuleCommand;
|
|
809
832
|
export const baseCommandFactories = {
|
|
810
833
|
wrapInList,
|
|
811
834
|
wrapRangeInList,
|
|
@@ -833,4 +856,6 @@ export const baseCommandFactories = {
|
|
|
833
856
|
wrapIn,
|
|
834
857
|
setBlockType,
|
|
835
858
|
toggleMark,
|
|
859
|
+
undoInputRule,
|
|
860
|
+
runInputRules,
|
|
836
861
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyCommandFactories.d.ts","sourceRoot":"","sources":["../../src/commands/keyCommandFactories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAgB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"keyCommandFactories.d.ts","sourceRoot":"","sources":["../../src/commands/keyCommandFactories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAgB,MAAM,UAAU,CAAC;AAqBxD,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAI9D,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { firstCommand } from './mod.js';
|
|
2
2
|
import { baseCommandFactories } from './baseCommandFactories.js';
|
|
3
|
-
const backspace = firstCommand(baseCommandFactories.deleteSelection(), baseCommandFactories.joinBackward(), baseCommandFactories.selectNodeBackward());
|
|
3
|
+
const backspace = firstCommand(baseCommandFactories.undoInputRule(), baseCommandFactories.deleteSelection(), baseCommandFactories.joinBackward(), baseCommandFactories.selectNodeBackward());
|
|
4
4
|
const del = firstCommand(baseCommandFactories.deleteSelection(), baseCommandFactories.joinForward(), baseCommandFactories.selectNodeForward());
|
|
5
5
|
const enter = firstCommand(baseCommandFactories.newlineInCode(), baseCommandFactories.createParagraphNear(), baseCommandFactories.liftEmptyBlock(), baseCommandFactories.splitBlock());
|
|
6
6
|
export const keyCommandFactories = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/commands/mod.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,cAAc,YAAY,CAAC;AAI3B,wBAAgB,YAAY,CAAC,GAAG,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/commands/mod.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,cAAc,YAAY,CAAC;AAI3B,wBAAgB,YAAY,CAAC,GAAG,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAmBrE;AAED,wBAAgB,mBAAmB,CAAC,GAAG,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAO5E;AAyDD,wBAAgB,QAAQ,CACtB,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,KAAK,OAAO,CAAC,GAAG,SAAS,MAAM,EAAE,GACvE,OAAO,CAMT"}
|
package/esm/commands/mod.js
CHANGED
|
@@ -3,15 +3,20 @@ export * from './types.js';
|
|
|
3
3
|
/// Combine a number of command functions into a single function (which
|
|
4
4
|
/// calls them one by one until one returns true).
|
|
5
5
|
export function firstCommand(...commands) {
|
|
6
|
-
|
|
6
|
+
const cmd = function (state, dispatch, view) {
|
|
7
7
|
for (let i = 0; i < commands.length; i++) {
|
|
8
8
|
if (commands[i](state, dispatch, view)) {
|
|
9
|
-
|
|
9
|
+
const cmd = commands[i];
|
|
10
|
+
if (cmd.displayName !== 'first') {
|
|
11
|
+
console.debug('firstCommand: ', commands[i].displayName || commands[i]);
|
|
12
|
+
}
|
|
10
13
|
return true;
|
|
11
14
|
}
|
|
12
15
|
}
|
|
13
16
|
return false;
|
|
14
17
|
};
|
|
18
|
+
cmd.displayName = 'first';
|
|
19
|
+
return cmd;
|
|
15
20
|
}
|
|
16
21
|
export function alternativeCommands(...commands) {
|
|
17
22
|
return function (state, dispatch, view) {
|
package/esm/commands/types.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import type { Command } from 'prosemirror-state';
|
|
2
|
-
|
|
1
|
+
import type { Command as PmCommand } from 'prosemirror-state';
|
|
2
|
+
interface Command extends PmCommand {
|
|
3
|
+
displayName?: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
}
|
|
6
|
+
export type { Command };
|
|
3
7
|
export type CommandFactory = (...args: any[]) => Command;
|
|
4
8
|
export interface Commands {
|
|
5
9
|
[name: string]: Command;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/commands/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/commands/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9D,UAAU,OAAQ,SAAQ,SAAS;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,YAAY,EAAE,OAAO,EAAE,CAAC;AAExB,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC;AAEzD,MAAM,WAAW,QAAQ;IACvB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAAC;CAChC;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,eAAe,GACvB;KACC,IAAI,IAAI,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,eAAe;CAClE,GACC;IACA,GAAG,EAAE,MAAM,OAAO,CAAC;CACpB,CAAC"}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EditorState, Plugin, Transaction } from 'prosemirror-state';
|
|
2
|
+
import type { Command, CommandFactory } from '../../commands/types.js';
|
|
3
|
+
type PluginState = {
|
|
4
|
+
transform: Transaction;
|
|
5
|
+
from: number;
|
|
6
|
+
to: number;
|
|
7
|
+
text: string;
|
|
8
|
+
} | null;
|
|
2
9
|
export declare class InputRule {
|
|
3
10
|
readonly match: RegExp;
|
|
4
11
|
handler: (state: EditorState, match: RegExpMatchArray, start: number, end: number) => Transaction | null;
|
|
@@ -9,15 +16,10 @@ export declare class InputRule {
|
|
|
9
16
|
inCode?: boolean | 'only';
|
|
10
17
|
});
|
|
11
18
|
}
|
|
12
|
-
type PluginState = {
|
|
13
|
-
transform: Transaction;
|
|
14
|
-
from: number;
|
|
15
|
-
to: number;
|
|
16
|
-
text: string;
|
|
17
|
-
} | null;
|
|
18
19
|
export declare class InputRulesPlugin extends Plugin<PluginState> {
|
|
19
20
|
constructor(rules: readonly InputRule[]);
|
|
20
21
|
}
|
|
21
|
-
export declare const
|
|
22
|
+
export declare const runInputRules: CommandFactory;
|
|
23
|
+
export declare const undoInputRuleCommand: Command;
|
|
22
24
|
export {};
|
|
23
25
|
//# sourceMappingURL=InputRulesPlugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputRulesPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/input-rules/InputRulesPlugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"InputRulesPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/input-rules/InputRulesPlugin.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,MAAM,EAEN,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAIvE,KAAK,WAAW,GAAG;IACjB,SAAS,EAAE,WAAW,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,IAAI,CAAC;AAMT,qBAAa,SAAS;IA8BlB,QAAQ,CAAC,KAAK,EAAE,MAAM;IA5BxB,OAAO,EAAE,CACP,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,KACR,WAAW,GAAG,IAAI,CAAC;IAGxB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;gBAmBd,KAAK,EAAE,MAAM,EACtB,OAAO,EACH,MAAM,GACN,CAAC,CACD,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,KACR,WAAW,GAAG,IAAI,CAAC,EAC1B,OAAO,GAAE;QAIP,QAAQ,CAAC,EAAE,OAAO,CAAC;QAInB,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;KACtB;CAST;AA2BD,qBAAa,gBAAiB,SAAQ,MAAM,CAAC,WAAW,CAAC;gBAC3C,KAAK,EAAE,SAAS,SAAS,EAAE;CA4CxC;AAED,eAAO,MAAM,aAAa,EAAE,cAiD3B,CAAC;AAIF,eAAO,MAAM,oBAAoB,EAAE,OAiClC,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Plugin, } from 'prosemirror-state';
|
|
2
|
+
const MAX_MATCH = 500;
|
|
2
3
|
/// Input rules are regular expressions describing a piece of text
|
|
3
4
|
/// that, when typed, causes something to happen. This might be
|
|
4
5
|
/// changing two dashes into an emdash, wrapping a paragraph starting
|
|
@@ -41,10 +42,10 @@ function stringHandler(string) {
|
|
|
41
42
|
return function (state, match, start, end) {
|
|
42
43
|
let insert = string;
|
|
43
44
|
if (match[1]) {
|
|
44
|
-
|
|
45
|
+
const offset = match[0].lastIndexOf(match[1]);
|
|
45
46
|
insert += match[0].slice(offset + match[1].length);
|
|
46
47
|
start += offset;
|
|
47
|
-
|
|
48
|
+
const cutOff = start - end;
|
|
48
49
|
if (cutOff > 0) {
|
|
49
50
|
insert = match[0].slice(offset - cutOff, offset) + insert;
|
|
50
51
|
start = end;
|
|
@@ -53,7 +54,6 @@ function stringHandler(string) {
|
|
|
53
54
|
return state.tr.insertText(insert, start, end);
|
|
54
55
|
};
|
|
55
56
|
}
|
|
56
|
-
const MAX_MATCH = 500;
|
|
57
57
|
/// Create an input rules plugin. When enabled, it will cause text
|
|
58
58
|
/// input that matches any of the given rules to trigger the rule's
|
|
59
59
|
/// action.
|
|
@@ -65,22 +65,33 @@ export class InputRulesPlugin extends Plugin {
|
|
|
65
65
|
return null;
|
|
66
66
|
},
|
|
67
67
|
apply(tr, prev) {
|
|
68
|
-
|
|
69
|
-
if (stored)
|
|
68
|
+
const stored = tr.getMeta(this);
|
|
69
|
+
if (stored) {
|
|
70
70
|
return stored;
|
|
71
|
+
}
|
|
71
72
|
return tr.selectionSet || tr.docChanged ? null : prev;
|
|
72
73
|
},
|
|
73
74
|
},
|
|
74
75
|
props: {
|
|
75
76
|
handleTextInput(view, from, to, text) {
|
|
76
|
-
|
|
77
|
+
const cmd = runInputRules(from, to, text, rules);
|
|
78
|
+
const dispatch = (tr) => {
|
|
79
|
+
view.dispatch(tr);
|
|
80
|
+
};
|
|
81
|
+
return cmd(view.state, dispatch, view);
|
|
82
|
+
// return run(view, from, to, text, rules, this);
|
|
77
83
|
},
|
|
78
84
|
handleDOMEvents: {
|
|
79
85
|
compositionend: (view) => {
|
|
80
86
|
setTimeout(() => {
|
|
81
|
-
|
|
87
|
+
const { $cursor } = view.state.selection;
|
|
82
88
|
if ($cursor) {
|
|
83
|
-
|
|
89
|
+
const cmd = runInputRules($cursor.pos, $cursor.pos, '', rules);
|
|
90
|
+
const dispatch = (tr) => {
|
|
91
|
+
view.dispatch(tr);
|
|
92
|
+
};
|
|
93
|
+
return cmd(view.state, dispatch, view);
|
|
94
|
+
// run(view, $cursor.pos, $cursor.pos, '', rules, this);
|
|
84
95
|
}
|
|
85
96
|
});
|
|
86
97
|
},
|
|
@@ -90,55 +101,68 @@ export class InputRulesPlugin extends Plugin {
|
|
|
90
101
|
});
|
|
91
102
|
}
|
|
92
103
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
let rule = rules[i];
|
|
100
|
-
if ($from.parent.type.spec.code) {
|
|
101
|
-
if (!rule.inCode)
|
|
102
|
-
continue;
|
|
104
|
+
export const runInputRules = (from, to, text, rules) => {
|
|
105
|
+
const cmd = (state, dispatch, view) => {
|
|
106
|
+
const plugins = state.plugins;
|
|
107
|
+
const plugin = plugins.find((plugin) => plugin.spec.isInputRules);
|
|
108
|
+
if (!plugin) {
|
|
109
|
+
return false;
|
|
103
110
|
}
|
|
104
|
-
|
|
105
|
-
|
|
111
|
+
if (view?.composing)
|
|
112
|
+
return false;
|
|
113
|
+
const $from = state.doc.resolve(from);
|
|
114
|
+
const textBefore = $from.parent.textBetween(Math.max(0, $from.parentOffset - MAX_MATCH), $from.parentOffset, null, '\ufffc') + text;
|
|
115
|
+
for (let i = 0; i < rules.length; i++) {
|
|
116
|
+
const rule = rules[i];
|
|
117
|
+
if ($from.parent.type.spec.code) {
|
|
118
|
+
if (!rule.inCode)
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
else if (rule.inCode === 'only') {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const match = rule.match.exec(textBefore);
|
|
125
|
+
const tr = match &&
|
|
126
|
+
rule.handler(state, match, from - (match[0].length - text.length), to);
|
|
127
|
+
if (!tr)
|
|
128
|
+
continue;
|
|
129
|
+
if (rule.undoable) {
|
|
130
|
+
tr.setMeta(plugin, { transform: tr, from, to, text });
|
|
131
|
+
}
|
|
132
|
+
view?.dispatch(tr);
|
|
133
|
+
return true;
|
|
106
134
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (rule.undoable)
|
|
113
|
-
tr.setMeta(plugin, { transform: tr, from, to, text });
|
|
114
|
-
view.dispatch(tr);
|
|
115
|
-
return true;
|
|
116
|
-
}
|
|
117
|
-
return false;
|
|
118
|
-
}
|
|
135
|
+
return false;
|
|
136
|
+
};
|
|
137
|
+
cmd.displayName = 'runInputRules';
|
|
138
|
+
return cmd;
|
|
139
|
+
};
|
|
119
140
|
/// This is a command that will undo an input rule, if applying such a
|
|
120
141
|
/// rule was the last thing that the user did.
|
|
121
|
-
export const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
142
|
+
export const undoInputRuleCommand = (state, dispatch) => {
|
|
143
|
+
const plugins = state.plugins;
|
|
144
|
+
const plugin = plugins.find((plugin) => plugin.spec.isInputRules);
|
|
145
|
+
if (!plugin) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
const undoable = plugin.getState(state);
|
|
149
|
+
if (!undoable) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
if (dispatch) {
|
|
153
|
+
const tr = state.tr;
|
|
154
|
+
const toUndo = undoable.transform;
|
|
155
|
+
for (let j = toUndo.steps.length - 1; j >= 0; j--) {
|
|
156
|
+
tr.step(toUndo.steps[j].invert(toUndo.docs[j]));
|
|
157
|
+
}
|
|
158
|
+
if (undoable.text) {
|
|
159
|
+
const marks = tr.doc.resolve(undoable.from).marks();
|
|
160
|
+
tr.replaceWith(undoable.from, undoable.to, state.schema.text(undoable.text, marks));
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
tr.delete(undoable.from, undoable.to);
|
|
141
164
|
}
|
|
165
|
+
dispatch(tr);
|
|
142
166
|
}
|
|
143
|
-
return
|
|
167
|
+
return true;
|
|
144
168
|
};
|
|
@@ -2,4 +2,5 @@ import { Attrs, Node, NodeType } from 'prosemirror-model';
|
|
|
2
2
|
import { InputRule } from './InputRulesPlugin.js';
|
|
3
3
|
export declare function wrappingInputRule(regexp: RegExp, nodeType: NodeType, getAttrs?: Attrs | null | ((matches: RegExpMatchArray) => Attrs | null), joinPredicate?: (match: RegExpMatchArray, node: Node) => boolean): InputRule;
|
|
4
4
|
export declare function textblockTypeInputRule(regexp: RegExp, nodeType: NodeType, getAttrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null)): InputRule;
|
|
5
|
+
export declare function replaceInlineNode(regexp: RegExp, nodeType: NodeType, getAttrs?: Attrs | null | ((matches: RegExpMatchArray) => Attrs | null)): InputRule;
|
|
5
6
|
//# sourceMappingURL=rulebuilders.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rulebuilders.d.ts","sourceRoot":"","sources":["../../../src/plugins/input-rules/rulebuilders.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"rulebuilders.d.ts","sourceRoot":"","sources":["../../../src/plugins/input-rules/rulebuilders.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAY,IAAI,EAAE,QAAQ,EAAS,MAAM,mBAAmB,CAAC;AAE3E,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAiBlD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,QAAQ,GAAE,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,gBAAgB,KAAK,KAAK,GAAG,IAAI,CAAQ,EAC7E,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,KAAK,OAAO,aAmBjE;AAQD,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,QAAQ,GAAE,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,gBAAgB,KAAK,KAAK,GAAG,IAAI,CAAQ,aAgB5E;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,QAAQ,GAAE,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,gBAAgB,KAAK,KAAK,GAAG,IAAI,CAAQ,aAY9E"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { canJoin, findWrapping } from 'prosemirror-transform';
|
|
2
|
+
import { Fragment, Slice } from 'prosemirror-model';
|
|
2
3
|
import { InputRule } from './InputRulesPlugin.js';
|
|
3
4
|
/// Build an input rule for automatically wrapping a textblock when a
|
|
4
5
|
/// given string is typed. The `regexp` argument is
|
|
@@ -17,13 +18,15 @@ import { InputRule } from './InputRulesPlugin.js';
|
|
|
17
18
|
/// return a boolean to indicate whether a join should happen.
|
|
18
19
|
export function wrappingInputRule(regexp, nodeType, getAttrs = null, joinPredicate) {
|
|
19
20
|
return new InputRule(regexp, (state, match, start, end) => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
const attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs;
|
|
22
|
+
const tr = state.tr.delete(start, end);
|
|
23
|
+
const $start = tr.doc.resolve(start);
|
|
24
|
+
const range = $start.blockRange();
|
|
25
|
+
const wrapping = range && findWrapping(range, nodeType, attrs);
|
|
23
26
|
if (!wrapping)
|
|
24
27
|
return null;
|
|
25
28
|
tr.wrap(range, wrapping);
|
|
26
|
-
|
|
29
|
+
const before = tr.doc.resolve(start - 1).nodeBefore;
|
|
27
30
|
if (before && before.type == nodeType && canJoin(tr.doc, start - 1) &&
|
|
28
31
|
(!joinPredicate || joinPredicate(match, before))) {
|
|
29
32
|
tr.join(start - 1);
|
|
@@ -39,8 +42,8 @@ export function wrappingInputRule(regexp, nodeType, getAttrs = null, joinPredica
|
|
|
39
42
|
/// `wrappingInputRule` function.
|
|
40
43
|
export function textblockTypeInputRule(regexp, nodeType, getAttrs = null) {
|
|
41
44
|
return new InputRule(regexp, (state, match, start, end) => {
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
const $start = state.doc.resolve(start);
|
|
46
|
+
const attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs;
|
|
44
47
|
if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), nodeType))
|
|
45
48
|
return null;
|
|
46
49
|
return state.tr
|
|
@@ -48,3 +51,14 @@ export function textblockTypeInputRule(regexp, nodeType, getAttrs = null) {
|
|
|
48
51
|
.setBlockType(start, start, nodeType, attrs);
|
|
49
52
|
});
|
|
50
53
|
}
|
|
54
|
+
export function replaceInlineNode(regexp, nodeType, getAttrs = null) {
|
|
55
|
+
return new InputRule(regexp, (state, match, start, end) => {
|
|
56
|
+
const attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs;
|
|
57
|
+
const node = nodeType.createAndFill(attrs);
|
|
58
|
+
const slice = new Slice(Fragment.from(node), 0, 0);
|
|
59
|
+
const tr = state.tr;
|
|
60
|
+
const from = tr.mapping.map(start);
|
|
61
|
+
const to = tr.mapping.map(end);
|
|
62
|
+
return tr.replace(from, to, slice);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Plugin } from 'prosemirror-state';
|
|
2
2
|
import { EditorView } from 'prosemirror-view';
|
|
3
|
+
import type { Command } from '../../commands/types.js';
|
|
3
4
|
export declare class KeymapPlugin extends Plugin {
|
|
4
5
|
constructor(bindings: {
|
|
5
6
|
[key: string]: Command;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keymap.d.ts","sourceRoot":"","sources":["../../../src/plugins/keymap/keymap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"keymap.d.ts","sourceRoot":"","sources":["../../../src/plugins/keymap/keymap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAyEvD,qBAAa,YAAa,SAAQ,MAAM;gBAC1B,QAAQ,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE;CAGjD;AAKD,wBAAgB,cAAc,CAC5B,QAAQ,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,GACnC,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,KAAK,OAAO,CA6BrD"}
|
package/esm/search/search.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EditorState, Plugin, Transaction } from 'prosemirror-state';
|
|
2
2
|
import { DecorationSet } from 'prosemirror-view';
|
|
3
|
+
import { type Command } from '../commands/types.js';
|
|
3
4
|
import { SearchQuery } from './query.js';
|
|
4
5
|
export declare function search(options?: {
|
|
5
6
|
initialQuery?: SearchQuery;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/search/search.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/search/search.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,MAAM,EAGN,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAc,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAgB,MAAM,YAAY,CAAC;AAqCvD,wBAAgB,MAAM,CACpB,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,YAAY,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;CACxC,GACL,MAAM,CA8CR;AAID,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG;IAClD,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC5C,GAAG,SAAS,CAEZ;AAID,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,iBAGpD;AAID,wBAAgB,cAAc,CAC5B,EAAE,EAAE,WAAW,EACf,KAAK,EAAE,WAAW,EAClB,KAAK,GAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,IAAW,eAGlD;AA6DD,eAAO,MAAM,QAAQ,SAAuB,CAAC;AAI7C,eAAO,MAAM,cAAc,SAAwB,CAAC;AAIpD,eAAO,MAAM,QAAQ,SAAwB,CAAC;AAK9C,eAAO,MAAM,cAAc,SAAyB,CAAC;AAkDrD,eAAO,MAAM,WAAW,SAA6B,CAAC;AAItD,eAAO,MAAM,iBAAiB,SAA8B,CAAC;AAI7D,eAAO,MAAM,cAAc,SAA+B,CAAC;AAG3D,eAAO,MAAM,UAAU,EAAE,OAwBxB,CAAC"}
|