@prosekit/extensions 0.7.1 → 0.7.3
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/_tsup-dts-rollup.d.ts +100 -120
- package/dist/chunk-GPSAJOJA.js +188 -0
- package/dist/{chunk-PYT3MOTF.js → chunk-LVMTQOWG.js} +31 -14
- package/dist/{chunk-2JYT2MT7.js → chunk-OJCMRVEY.js} +36 -21
- package/dist/list/style.css +9 -5
- package/dist/placeholder/style.css +1 -1
- package/dist/prosekit-extensions-autocomplete.js +62 -33
- package/dist/prosekit-extensions-blockquote.js +2 -2
- package/dist/prosekit-extensions-bold.js +7 -3
- package/dist/prosekit-extensions-code-block.js +77 -41
- package/dist/prosekit-extensions-code.js +1 -1
- package/dist/prosekit-extensions-commit.js +70 -30
- package/dist/prosekit-extensions-enter-rule.js +1 -1
- package/dist/prosekit-extensions-heading.d.ts +4 -4
- package/dist/prosekit-extensions-heading.js +66 -36
- package/dist/prosekit-extensions-image.js +14 -5
- package/dist/prosekit-extensions-input-rule.js +1 -1
- package/dist/prosekit-extensions-italic.js +1 -1
- package/dist/prosekit-extensions-link.js +27 -14
- package/dist/prosekit-extensions-list.d.ts +8 -2
- package/dist/prosekit-extensions-list.js +64 -35
- package/dist/prosekit-extensions-mark-rule.js +1 -1
- package/dist/prosekit-extensions-mention.js +6 -4
- package/dist/prosekit-extensions-placeholder.js +16 -7
- package/dist/prosekit-extensions-readonly.js +1 -1
- package/dist/prosekit-extensions-search.js +8 -5
- package/dist/prosekit-extensions-strike.js +1 -1
- package/dist/prosekit-extensions-table.js +68 -30
- package/dist/prosekit-extensions-text-align.js +4 -2
- package/dist/prosekit-extensions-virtual-selection.js +11 -6
- package/package.json +8 -8
- package/dist/chunk-ZPEMHYTU.js +0 -140
@@ -1,5 +1,5 @@
|
|
1
|
+
import { AddMarkOptions } from '@prosekit/core';
|
1
2
|
import { Attrs } from '@prosekit/pm/model';
|
2
|
-
import { Attrs as Attrs_2 } from 'prosemirror-model';
|
3
3
|
import { BundledLanguage } from 'shiki';
|
4
4
|
import { BundledLanguageInfo } from 'shiki';
|
5
5
|
import { bundledLanguagesInfo } from 'shiki';
|
@@ -18,28 +18,33 @@ import { getSingletonHighlighter } from 'shiki/bundle/full';
|
|
18
18
|
import type { Highlighter } from 'shiki';
|
19
19
|
import { IndentListOptions } from 'prosemirror-flat-list';
|
20
20
|
import { InputRule } from '@prosekit/pm/inputrules';
|
21
|
+
import { InsertNodeOptions } from '@prosekit/core';
|
21
22
|
import { ListAttributes } from 'prosemirror-flat-list';
|
22
23
|
import { ListDOMSerializer } from 'prosemirror-flat-list';
|
23
24
|
import { MarkBuilder } from '@prosekit/core';
|
24
25
|
import { MarkType } from '@prosekit/pm/model';
|
25
|
-
import { MarkType as MarkType_2 } from 'prosemirror-model';
|
26
|
-
import { Node as Node_2 } from 'prosemirror-model';
|
27
26
|
import { NodeBuilder } from '@prosekit/core';
|
28
27
|
import { NodeJSON } from '@prosekit/core';
|
29
|
-
import { NodeRange } from 'prosemirror-model';
|
30
28
|
import { NodeType } from '@prosekit/pm/model';
|
31
|
-
import { NodeType as NodeType_2 } from 'prosemirror-model';
|
32
29
|
import { Options } from 'tsup';
|
33
30
|
import { Parser } from 'prosemirror-highlight';
|
34
31
|
import { Plugin as Plugin_2 } from '@prosekit/pm/state';
|
35
32
|
import { PluginKey } from '@prosekit/pm/state';
|
36
33
|
import { ProseMirrorNode } from '@prosekit/pm/model';
|
34
|
+
import { RemoveMarkOptions } from '@prosekit/core';
|
35
|
+
import { RemoveNodeOptions } from '@prosekit/core';
|
36
|
+
import { SetBlockTypeOptions } from '@prosekit/core';
|
37
|
+
import { SetNodeAttrsOptions } from '@prosekit/core';
|
37
38
|
import type { SpecialLanguage } from 'shiki';
|
38
39
|
import { StepJSON } from '@prosekit/core';
|
39
40
|
import { TestEditor } from '@prosekit/core/test';
|
40
41
|
import { ToggleCollapsedOptions } from 'prosemirror-flat-list';
|
41
42
|
import { Transaction } from '@prosekit/pm/state';
|
43
|
+
import { UnsetBlockTypeOptions } from '@prosekit/core';
|
44
|
+
import { UnsetMarkOptions } from '@prosekit/core';
|
42
45
|
import { UnwrapListOptions } from 'prosemirror-flat-list';
|
46
|
+
import { WrapInListGetAttrs } from 'prosemirror-flat-list';
|
47
|
+
import { WrapOptions } from '@prosekit/core';
|
43
48
|
|
44
49
|
export declare function applyMarkRules(rules: MarkRuleOptions[], transactions: readonly Transaction[], oldState: EditorState, newState: EditorState): Transaction | null;
|
45
50
|
|
@@ -174,6 +179,8 @@ export declare function createLazyParser(highlighterOptions: HighlighterOptions)
|
|
174
179
|
*/
|
175
180
|
export declare function createMarkInputRule({ regex, type, attrs, }: MarkInputRuleOptions): InputRule;
|
176
181
|
|
182
|
+
export { DedentListOptions }
|
183
|
+
|
177
184
|
export declare const default_alias: Options | Options[] | ((overrideOptions: Options) => Options | Options[] | Promise<Options | Options[]>);
|
178
185
|
|
179
186
|
export { default_alias_1 }
|
@@ -412,7 +419,7 @@ toggleHeading: [attrs?: HeadingAttrs | undefined];
|
|
412
419
|
};
|
413
420
|
}>;
|
414
421
|
|
415
|
-
|
422
|
+
declare function defineHeadingCommands(): Extension< {
|
416
423
|
Commands: {
|
417
424
|
setHeading: [attrs?: HeadingAttrs | undefined];
|
418
425
|
insertHeading: [attrs?: HeadingAttrs | undefined];
|
@@ -421,20 +428,28 @@ toggleHeading: [attrs?: HeadingAttrs | undefined];
|
|
421
428
|
Nodes: never;
|
422
429
|
Marks: never;
|
423
430
|
}>;
|
431
|
+
export { defineHeadingCommands }
|
432
|
+
export { defineHeadingCommands as defineHeadingCommands_alias_1 }
|
424
433
|
|
425
434
|
/**
|
426
435
|
* Converts the text block to a heading when `#` is typed at the start of a new
|
427
436
|
* line followed by a space.
|
428
437
|
*/
|
429
|
-
|
438
|
+
declare function defineHeadingInputRule(): Extension<ExtensionTyping<any, any, any>>;
|
439
|
+
export { defineHeadingInputRule }
|
440
|
+
export { defineHeadingInputRule as defineHeadingInputRule_alias_1 }
|
430
441
|
|
431
|
-
|
442
|
+
declare function defineHeadingKeymap(): Extension<ExtensionTyping<any, any, any>>;
|
443
|
+
export { defineHeadingKeymap }
|
444
|
+
export { defineHeadingKeymap as defineHeadingKeymap_alias_1 }
|
432
445
|
|
433
|
-
|
446
|
+
declare function defineHeadingSpec(): Extension< {
|
434
447
|
Nodes: "heading";
|
435
448
|
Marks: never;
|
436
449
|
Commands: never;
|
437
450
|
}>;
|
451
|
+
export { defineHeadingSpec }
|
452
|
+
export { defineHeadingSpec as defineHeadingSpec_alias_1 }
|
438
453
|
|
439
454
|
/**
|
440
455
|
* @public
|
@@ -559,26 +574,31 @@ export declare function defineList(): Extension<{
|
|
559
574
|
toggleCollapsed: [(ToggleCollapsedOptions | undefined)?];
|
560
575
|
toggleList: [attrs: ListAttributes];
|
561
576
|
unwrapList: [options?: UnwrapListOptions | undefined];
|
562
|
-
wrapInList: [getAttrs: ListAttributes
|
577
|
+
wrapInList: [getAttrs: WrapInListGetAttrs<ListAttributes>];
|
563
578
|
insertList: [attrs?: ListAttributes | undefined];
|
564
579
|
};
|
565
580
|
}>;
|
566
581
|
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
582
|
+
/**
|
583
|
+
* Defines list commands
|
584
|
+
*/
|
585
|
+
declare function defineListCommands(): Extension< {
|
586
|
+
Commands: {
|
587
|
+
dedentList: [options?: DedentListOptions | undefined];
|
588
|
+
indentList: [options?: IndentListOptions | undefined];
|
589
|
+
moveList: [direction: "up" | "down"];
|
590
|
+
splitList: [];
|
591
|
+
toggleCollapsed: [(ToggleCollapsedOptions | undefined)?];
|
592
|
+
toggleList: [attrs: ListAttributes];
|
593
|
+
unwrapList: [options?: UnwrapListOptions | undefined];
|
594
|
+
wrapInList: [getAttrs: WrapInListGetAttrs<ListAttributes>];
|
595
|
+
insertList: [attrs?: ListAttributes | undefined];
|
596
|
+
};
|
597
|
+
Nodes: never;
|
598
|
+
Marks: never;
|
581
599
|
}>;
|
600
|
+
export { defineListCommands }
|
601
|
+
export { defineListCommands as defineListCommands_alias_1 }
|
582
602
|
|
583
603
|
export declare function defineListInputRules(): Extension;
|
584
604
|
|
@@ -587,7 +607,9 @@ export declare function defineListInputRules(): Extension;
|
|
587
607
|
*
|
588
608
|
* @public
|
589
609
|
*/
|
590
|
-
|
610
|
+
declare function defineListKeymap(): Extension<ExtensionTyping<any, any, any>>;
|
611
|
+
export { defineListKeymap }
|
612
|
+
export { defineListKeymap as defineListKeymap_alias_1 }
|
591
613
|
|
592
614
|
export declare function defineListPlugins(): Extension<ExtensionTyping<any, any, any>>;
|
593
615
|
|
@@ -803,58 +825,25 @@ export declare function defineTestExtension(): Extension<{
|
|
803
825
|
from?: number;
|
804
826
|
to?: number;
|
805
827
|
}];
|
806
|
-
insertNode: [options:
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
} | {
|
812
|
-
node?: undefined;
|
813
|
-
pos?: number;
|
814
|
-
type: string;
|
815
|
-
attrs?: Attrs_2;
|
816
|
-
}];
|
817
|
-
removeNode: [options: {
|
818
|
-
type: string | NodeType_2;
|
819
|
-
pos?: number;
|
820
|
-
}];
|
821
|
-
wrap: [{
|
822
|
-
nodeType: NodeType_2;
|
823
|
-
attrs?: Attrs_2 | null;
|
824
|
-
}];
|
825
|
-
setBlockType: [options: {
|
826
|
-
type: NodeType_2 | string;
|
827
|
-
attrs?: Attrs_2 | null;
|
828
|
-
from?: number;
|
829
|
-
to?: number;
|
830
|
-
}];
|
831
|
-
setNodeAttrs: [options: {
|
832
|
-
type: string | NodeType_2 | string[] | NodeType_2[];
|
833
|
-
attrs: Attrs_2;
|
834
|
-
pos?: number;
|
835
|
-
}];
|
828
|
+
insertNode: [options: InsertNodeOptions];
|
829
|
+
removeNode: [options: RemoveNodeOptions];
|
830
|
+
wrap: [WrapOptions];
|
831
|
+
setBlockType: [options: SetBlockTypeOptions];
|
832
|
+
setNodeAttrs: [options: SetNodeAttrsOptions];
|
836
833
|
selectAll: [];
|
837
|
-
addMark: [options:
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
removeMark: [options: {
|
844
|
-
type: string | MarkType_2;
|
845
|
-
attrs?: Attrs_2 | null;
|
846
|
-
from?: number;
|
847
|
-
to?: number;
|
848
|
-
}];
|
849
|
-
toggleItalic: [];
|
850
|
-
undo: [];
|
851
|
-
redo: [];
|
834
|
+
addMark: [options: AddMarkOptions];
|
835
|
+
removeMark: [options: RemoveMarkOptions];
|
836
|
+
unsetBlockType: [options?: UnsetBlockTypeOptions | undefined];
|
837
|
+
unsetMark: [options?: UnsetMarkOptions | undefined];
|
838
|
+
readonly undo: [];
|
839
|
+
readonly redo: [];
|
852
840
|
toggleBold: [];
|
853
841
|
toggleCode: [];
|
854
842
|
setHeading: [attrs?: HeadingAttrs | undefined];
|
855
843
|
insertHeading: [attrs?: HeadingAttrs | undefined];
|
856
844
|
toggleHeading: [attrs?: HeadingAttrs | undefined];
|
857
845
|
insertImage: [attrs?: ImageAttrs | undefined];
|
846
|
+
toggleItalic: [];
|
858
847
|
addLink: [attrs: LinkAttrs];
|
859
848
|
removeLink: [];
|
860
849
|
toggleLink: [attrs: LinkAttrs];
|
@@ -866,7 +855,7 @@ export declare function defineTestExtension(): Extension<{
|
|
866
855
|
toggleCollapsed: [(ToggleCollapsedOptions | undefined)?];
|
867
856
|
toggleList: [attrs: ListAttributes];
|
868
857
|
unwrapList: [options?: UnwrapListOptions | undefined];
|
869
|
-
wrapInList: [getAttrs: ListAttributes
|
858
|
+
wrapInList: [getAttrs: WrapInListGetAttrs<ListAttributes>];
|
870
859
|
insertList: [attrs?: ListAttributes | undefined];
|
871
860
|
toggleStrike: [];
|
872
861
|
insertTable: [{
|
@@ -1095,9 +1084,11 @@ export { getSingletonHighlighter }
|
|
1095
1084
|
|
1096
1085
|
export declare function getTrMeta(tr: Transaction): PredictionPluginState;
|
1097
1086
|
|
1098
|
-
|
1087
|
+
declare interface HeadingAttrs {
|
1099
1088
|
level: number;
|
1100
1089
|
}
|
1090
|
+
export { HeadingAttrs }
|
1091
|
+
export { HeadingAttrs as HeadingAttrs_alias_1 }
|
1101
1092
|
|
1102
1093
|
export declare type HighlighterOptions = {
|
1103
1094
|
themes: BundledTheme[];
|
@@ -1126,6 +1117,8 @@ export declare interface ImageAttrs {
|
|
1126
1117
|
src?: string | null;
|
1127
1118
|
}
|
1128
1119
|
|
1120
|
+
export { IndentListOptions }
|
1121
|
+
|
1129
1122
|
/**
|
1130
1123
|
* Insert a table node with the given number of rows and columns, and optionally
|
1131
1124
|
* a header row.
|
@@ -1151,6 +1144,8 @@ export declare interface LinkAttrs {
|
|
1151
1144
|
href: string;
|
1152
1145
|
}
|
1153
1146
|
|
1147
|
+
export { ListAttributes }
|
1148
|
+
|
1154
1149
|
export { ListDOMSerializer }
|
1155
1150
|
|
1156
1151
|
/**
|
@@ -1248,6 +1243,18 @@ export declare interface PredictionPluginState {
|
|
1248
1243
|
|
1249
1244
|
export declare function prepareHighlighter(options: HighlighterOptions): HighlighterResult;
|
1250
1245
|
|
1246
|
+
/**
|
1247
|
+
* @example
|
1248
|
+
*
|
1249
|
+
* ```ts
|
1250
|
+
* await pressKey('mod-1')
|
1251
|
+
* await pressKey('Backspace')
|
1252
|
+
* ```
|
1253
|
+
*
|
1254
|
+
* @internal
|
1255
|
+
*/
|
1256
|
+
export declare function pressKey(input: string): Promise<void>;
|
1257
|
+
|
1251
1258
|
/**
|
1252
1259
|
* Options for {@link defineSearchQuery}
|
1253
1260
|
*
|
@@ -1303,7 +1310,7 @@ export declare function setTrMeta(tr: Transaction, meta: PredictionPluginState):
|
|
1303
1310
|
/**
|
1304
1311
|
* @internal
|
1305
1312
|
*/
|
1306
|
-
export declare function
|
1313
|
+
export declare function setupTest(): {
|
1307
1314
|
editor: TestEditor<Extension<{
|
1308
1315
|
Nodes: "blockquote" | "table" | "text" | "doc" | "paragraph" | "heading" | "image" | "list" | "tableRow" | "tableCell" | "tableHeaderCell";
|
1309
1316
|
Marks: "code" | "link" | "bold" | "strike" | "italic" | "underline";
|
@@ -1313,58 +1320,25 @@ export declare function setupDefaultTest(): {
|
|
1313
1320
|
from?: number;
|
1314
1321
|
to?: number;
|
1315
1322
|
}];
|
1316
|
-
insertNode: [options:
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
} | {
|
1322
|
-
node?: undefined;
|
1323
|
-
pos?: number;
|
1324
|
-
type: string;
|
1325
|
-
attrs?: Attrs_2;
|
1326
|
-
}];
|
1327
|
-
removeNode: [options: {
|
1328
|
-
type: string | NodeType_2;
|
1329
|
-
pos?: number;
|
1330
|
-
}];
|
1331
|
-
wrap: [{
|
1332
|
-
nodeType: NodeType_2;
|
1333
|
-
attrs?: Attrs_2 | null;
|
1334
|
-
}];
|
1335
|
-
setBlockType: [options: {
|
1336
|
-
type: NodeType_2 | string;
|
1337
|
-
attrs?: Attrs_2 | null;
|
1338
|
-
from?: number;
|
1339
|
-
to?: number;
|
1340
|
-
}];
|
1341
|
-
setNodeAttrs: [options: {
|
1342
|
-
type: string | NodeType_2 | string[] | NodeType_2[];
|
1343
|
-
attrs: Attrs_2;
|
1344
|
-
pos?: number;
|
1345
|
-
}];
|
1323
|
+
insertNode: [options: InsertNodeOptions];
|
1324
|
+
removeNode: [options: RemoveNodeOptions];
|
1325
|
+
wrap: [WrapOptions];
|
1326
|
+
setBlockType: [options: SetBlockTypeOptions];
|
1327
|
+
setNodeAttrs: [options: SetNodeAttrsOptions];
|
1346
1328
|
selectAll: [];
|
1347
|
-
addMark: [options:
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
removeMark: [options: {
|
1354
|
-
type: string | MarkType_2;
|
1355
|
-
attrs?: Attrs_2 | null;
|
1356
|
-
from?: number;
|
1357
|
-
to?: number;
|
1358
|
-
}];
|
1359
|
-
toggleItalic: [];
|
1360
|
-
undo: [];
|
1361
|
-
redo: [];
|
1329
|
+
addMark: [options: AddMarkOptions];
|
1330
|
+
removeMark: [options: RemoveMarkOptions];
|
1331
|
+
unsetBlockType: [options?: UnsetBlockTypeOptions | undefined];
|
1332
|
+
unsetMark: [options?: UnsetMarkOptions | undefined];
|
1333
|
+
readonly undo: [];
|
1334
|
+
readonly redo: [];
|
1362
1335
|
toggleBold: [];
|
1363
1336
|
toggleCode: [];
|
1364
1337
|
setHeading: [attrs?: HeadingAttrs | undefined];
|
1365
1338
|
insertHeading: [attrs?: HeadingAttrs | undefined];
|
1366
1339
|
toggleHeading: [attrs?: HeadingAttrs | undefined];
|
1367
1340
|
insertImage: [attrs?: ImageAttrs | undefined];
|
1341
|
+
toggleItalic: [];
|
1368
1342
|
addLink: [attrs: LinkAttrs];
|
1369
1343
|
removeLink: [];
|
1370
1344
|
toggleLink: [attrs: LinkAttrs];
|
@@ -1376,7 +1350,7 @@ export declare function setupDefaultTest(): {
|
|
1376
1350
|
toggleCollapsed: [(ToggleCollapsedOptions | undefined)?];
|
1377
1351
|
toggleList: [attrs: ListAttributes];
|
1378
1352
|
unwrapList: [options?: UnwrapListOptions | undefined];
|
1379
|
-
wrapInList: [getAttrs: ListAttributes
|
1353
|
+
wrapInList: [getAttrs: WrapInListGetAttrs<ListAttributes>];
|
1380
1354
|
insertList: [attrs?: ListAttributes | undefined];
|
1381
1355
|
toggleStrike: [];
|
1382
1356
|
insertTable: [{
|
@@ -1395,7 +1369,7 @@ export declare function setupDefaultTest(): {
|
|
1395
1369
|
/**
|
1396
1370
|
* @internal
|
1397
1371
|
*/
|
1398
|
-
export declare function
|
1372
|
+
export declare function setupTestFromExtension<E extends Extension>(extension: E): {
|
1399
1373
|
editor: TestEditor<E>;
|
1400
1374
|
n: Record<ExtractNodes<E>, NodeBuilder>;
|
1401
1375
|
m: Record<ExtractMarks<E>, MarkBuilder>;
|
@@ -1445,4 +1419,10 @@ export declare type TextBlockEnterRuleOptions = {
|
|
1445
1419
|
stop?: boolean;
|
1446
1420
|
};
|
1447
1421
|
|
1422
|
+
export { ToggleCollapsedOptions }
|
1423
|
+
|
1424
|
+
export { UnwrapListOptions }
|
1425
|
+
|
1426
|
+
export { WrapInListGetAttrs }
|
1427
|
+
|
1448
1428
|
export { }
|
@@ -0,0 +1,188 @@
|
|
1
|
+
// src/mark-rule/extension.ts
|
2
|
+
import {
|
3
|
+
defineFacet,
|
4
|
+
defineFacetPayload,
|
5
|
+
pluginFacet
|
6
|
+
} from "@prosekit/core";
|
7
|
+
import {
|
8
|
+
PluginKey,
|
9
|
+
ProseMirrorPlugin
|
10
|
+
} from "@prosekit/pm/state";
|
11
|
+
|
12
|
+
// src/mark-rule/apply.ts
|
13
|
+
import {
|
14
|
+
OBJECT_REPLACEMENT_CHARACTER,
|
15
|
+
getMarkType,
|
16
|
+
maybeRun
|
17
|
+
} from "@prosekit/core";
|
18
|
+
import "@prosekit/pm/model";
|
19
|
+
import "@prosekit/pm/state";
|
20
|
+
|
21
|
+
// src/mark-rule/range.ts
|
22
|
+
import "@prosekit/pm/state";
|
23
|
+
function getSpanTextRanges($from, $to) {
|
24
|
+
const nodeRange = $from.blockRange($to);
|
25
|
+
if (!nodeRange) {
|
26
|
+
return [];
|
27
|
+
}
|
28
|
+
const stack = [];
|
29
|
+
let start = nodeRange.start;
|
30
|
+
for (let i = nodeRange.startIndex; i < nodeRange.endIndex; i++) {
|
31
|
+
const child = nodeRange.parent.child(i);
|
32
|
+
stack.push([start, child]);
|
33
|
+
start += child.nodeSize;
|
34
|
+
}
|
35
|
+
const ranges = [];
|
36
|
+
while (stack.length > 0) {
|
37
|
+
const [start2, node] = stack.pop();
|
38
|
+
if (node.type.spec.code) {
|
39
|
+
continue;
|
40
|
+
}
|
41
|
+
if (node.type.isTextblock) {
|
42
|
+
ranges.push([start2 + 1, start2 + 1 + node.content.size]);
|
43
|
+
continue;
|
44
|
+
}
|
45
|
+
node.forEach((child, offset) => {
|
46
|
+
stack.push([start2 + offset + 1, child]);
|
47
|
+
});
|
48
|
+
}
|
49
|
+
return ranges;
|
50
|
+
}
|
51
|
+
function getInlineTextRange($from, $to) {
|
52
|
+
return [$from.start(), $to.end()];
|
53
|
+
}
|
54
|
+
function getTextRanges(doc, from, to) {
|
55
|
+
const $from = doc.resolve(from);
|
56
|
+
const $to = doc.resolve(to);
|
57
|
+
if ($from.sameParent($to) && $from.parent.isTextblock) {
|
58
|
+
return [getInlineTextRange($from, $to)];
|
59
|
+
} else {
|
60
|
+
const nodeRange = $from.blockRange($to);
|
61
|
+
if (!nodeRange) {
|
62
|
+
return [];
|
63
|
+
}
|
64
|
+
return getSpanTextRanges($from, $to);
|
65
|
+
}
|
66
|
+
}
|
67
|
+
function getMapRange(transactions, oldState, newState) {
|
68
|
+
let lo = oldState.selection.from;
|
69
|
+
let hi = oldState.selection.to;
|
70
|
+
for (const tr of transactions) {
|
71
|
+
for (const map of tr.mapping.maps) {
|
72
|
+
lo = map.map(lo);
|
73
|
+
hi = map.map(hi);
|
74
|
+
map.forEach((_oldStart, _oldEnd, newStart, newEnd) => {
|
75
|
+
lo = Math.min(lo, hi, newStart);
|
76
|
+
hi = Math.max(lo, hi, newEnd);
|
77
|
+
});
|
78
|
+
}
|
79
|
+
}
|
80
|
+
lo = Math.min(lo, hi, newState.selection.from);
|
81
|
+
hi = Math.min(lo, hi, newState.selection.to);
|
82
|
+
return [lo, hi];
|
83
|
+
}
|
84
|
+
function getCheckRanges(transactions, oldState, newState) {
|
85
|
+
const [from, to] = getMapRange(transactions, oldState, newState);
|
86
|
+
return getTextRanges(newState.doc, from, to);
|
87
|
+
}
|
88
|
+
|
89
|
+
// src/mark-rule/apply.ts
|
90
|
+
function getExpectedMarkings(rules, doc, from, to) {
|
91
|
+
const text = doc.textBetween(from, to, null, OBJECT_REPLACEMENT_CHARACTER);
|
92
|
+
const ranges = [];
|
93
|
+
for (const rule of rules) {
|
94
|
+
rule.regex.lastIndex = 0;
|
95
|
+
const matches = text.matchAll(rule.regex);
|
96
|
+
const markType = getMarkType(doc.type.schema, rule.type);
|
97
|
+
for (const match of matches) {
|
98
|
+
const index = match.index;
|
99
|
+
if (index == null) continue;
|
100
|
+
const attrs = maybeRun(rule.attrs, match);
|
101
|
+
const mark = markType.create(attrs);
|
102
|
+
ranges.push([from + index, from + index + match[0].length, mark]);
|
103
|
+
}
|
104
|
+
}
|
105
|
+
ranges.sort((a, b) => a[0] - b[0] || b[1] - a[1]);
|
106
|
+
const result = [];
|
107
|
+
let freeIndex = 0;
|
108
|
+
for (const range of ranges) {
|
109
|
+
if (range[0] >= freeIndex) {
|
110
|
+
result.push(range);
|
111
|
+
freeIndex = range[1];
|
112
|
+
}
|
113
|
+
}
|
114
|
+
return result;
|
115
|
+
}
|
116
|
+
function getReceivedMarkings(rules, doc, from, to) {
|
117
|
+
const result = [];
|
118
|
+
const schema = doc.type.schema;
|
119
|
+
const markTypes = rules.map((rule) => getMarkType(schema, rule.type));
|
120
|
+
doc.nodesBetween(from, to, (node, pos) => {
|
121
|
+
if (!node.isInline) {
|
122
|
+
return;
|
123
|
+
}
|
124
|
+
for (const markType of markTypes) {
|
125
|
+
const mark = node.marks.find((mark2) => mark2.type === markType);
|
126
|
+
if (mark) {
|
127
|
+
result.push([pos, pos + node.nodeSize, mark]);
|
128
|
+
}
|
129
|
+
}
|
130
|
+
});
|
131
|
+
return result;
|
132
|
+
}
|
133
|
+
function markRangeEquals(a, b) {
|
134
|
+
return a[0] === b[0] && a[1] === b[1] && a[2].eq(b[2]);
|
135
|
+
}
|
136
|
+
function markRangeDiffs(a, b) {
|
137
|
+
return a.filter((x) => !b.some((y) => markRangeEquals(x, y)));
|
138
|
+
}
|
139
|
+
function applyMarkRules(rules, transactions, oldState, newState) {
|
140
|
+
if (transactions.length === 0 || transactions.every((tr2) => !tr2.docChanged)) {
|
141
|
+
return null;
|
142
|
+
}
|
143
|
+
const ranges = getCheckRanges(transactions, oldState, newState);
|
144
|
+
const toRemove = [];
|
145
|
+
const toCreate = [];
|
146
|
+
for (const [from, to] of ranges) {
|
147
|
+
const expected = getExpectedMarkings(rules, newState.doc, from, to);
|
148
|
+
const received = getReceivedMarkings(rules, newState.doc, from, to);
|
149
|
+
toRemove.push(...markRangeDiffs(received, expected));
|
150
|
+
toCreate.push(...markRangeDiffs(expected, received));
|
151
|
+
}
|
152
|
+
if (toCreate.length === 0 && toRemove.length === 0) {
|
153
|
+
return null;
|
154
|
+
}
|
155
|
+
const tr = newState.tr;
|
156
|
+
for (const [from, to, mark] of toRemove) {
|
157
|
+
tr.removeMark(from, to, mark);
|
158
|
+
}
|
159
|
+
for (const [from, to, mark] of toCreate) {
|
160
|
+
tr.addMark(from, to, mark);
|
161
|
+
}
|
162
|
+
return tr;
|
163
|
+
}
|
164
|
+
|
165
|
+
// src/mark-rule/extension.ts
|
166
|
+
function defineMarkRule(options) {
|
167
|
+
return defineFacetPayload(markRuleFacet, [options]);
|
168
|
+
}
|
169
|
+
var markRuleFacet = defineFacet({
|
170
|
+
reduce: () => {
|
171
|
+
let rules = [];
|
172
|
+
const plugin = new ProseMirrorPlugin({
|
173
|
+
key: new PluginKey("prosekit-mark-rule"),
|
174
|
+
appendTransaction: (transactions, oldState, newState) => {
|
175
|
+
return applyMarkRules(rules, transactions, oldState, newState);
|
176
|
+
}
|
177
|
+
});
|
178
|
+
return function reducer(input) {
|
179
|
+
rules = input;
|
180
|
+
return plugin;
|
181
|
+
};
|
182
|
+
},
|
183
|
+
parent: pluginFacet
|
184
|
+
});
|
185
|
+
|
186
|
+
export {
|
187
|
+
defineMarkRule
|
188
|
+
};
|
@@ -24,20 +24,35 @@ function createMarkInputRule({
|
|
24
24
|
type,
|
25
25
|
attrs = null
|
26
26
|
}) {
|
27
|
-
|
27
|
+
const rule = new InputRule(regex, (state, match, start, end) => {
|
28
28
|
var _a;
|
29
|
-
|
30
|
-
|
29
|
+
const { tr, schema } = state;
|
30
|
+
const [fullText, markText] = match;
|
31
|
+
if (!markText) {
|
31
32
|
return null;
|
32
|
-
|
33
|
-
|
33
|
+
}
|
34
|
+
const markStart = start + fullText.indexOf(markText);
|
35
|
+
const markEnd = markStart + markText.length;
|
36
|
+
if (!(start <= markStart && markStart < markEnd && markEnd <= end)) {
|
34
37
|
return null;
|
35
|
-
|
36
|
-
|
38
|
+
}
|
39
|
+
const markType = getMarkType(schema, type);
|
40
|
+
const mark = markType.create(maybeRun(attrs, match));
|
41
|
+
if (!isMarkAbsent(tr.doc, markStart, markEnd, markType, attrs)) {
|
37
42
|
return null;
|
38
|
-
|
39
|
-
|
43
|
+
}
|
44
|
+
const initialStoredMarks = (_a = tr.storedMarks) != null ? _a : [];
|
45
|
+
tr.addMark(markStart, markEnd, mark);
|
46
|
+
if (markEnd < end) {
|
47
|
+
tr.delete(markEnd, end);
|
48
|
+
}
|
49
|
+
if (start < markStart) {
|
50
|
+
tr.delete(start, markStart);
|
51
|
+
}
|
52
|
+
tr.setStoredMarks(initialStoredMarks);
|
53
|
+
return tr;
|
40
54
|
});
|
55
|
+
return rule;
|
41
56
|
}
|
42
57
|
function defineMarkInputRule(options) {
|
43
58
|
return defineInputRule(createMarkInputRule(options));
|
@@ -49,7 +64,7 @@ function defineTextBlockInputRule({
|
|
49
64
|
}) {
|
50
65
|
return defineFacetPayload(inputRuleFacet, [
|
51
66
|
({ schema }) => {
|
52
|
-
|
67
|
+
const nodeType = getNodeType(schema, type);
|
53
68
|
return textblockTypeInputRule(regex, nodeType, attrs);
|
54
69
|
}
|
55
70
|
]);
|
@@ -62,15 +77,17 @@ function defineWrappingInputRule({
|
|
62
77
|
}) {
|
63
78
|
return defineFacetPayload(inputRuleFacet, [
|
64
79
|
({ schema }) => {
|
65
|
-
|
80
|
+
const nodeType = getNodeType(schema, type);
|
66
81
|
return wrappingInputRule(regex, nodeType, attrs, join);
|
67
82
|
}
|
68
83
|
]);
|
69
84
|
}
|
70
85
|
var inputRuleFacet = defineFacet({
|
71
|
-
reducer: (inputs) =>
|
72
|
-
|
73
|
-
|
86
|
+
reducer: (inputs) => {
|
87
|
+
return (context) => {
|
88
|
+
const rules = inputs.flatMap((callback) => callback(context));
|
89
|
+
return [inputRules({ rules })];
|
90
|
+
};
|
74
91
|
},
|
75
92
|
parent: pluginFacet
|
76
93
|
});
|