@lofcz/platejs-core 52.3.4 → 53.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hotkeys-DI1HPO2Q.js +1 -2
- package/dist/{index-NTp--CEF.d.ts → index-C-LKDYK-.d.ts} +606 -1849
- package/dist/index.d.ts +2 -2
- package/dist/index.js +134 -3
- package/dist/react/index.d.ts +211 -196
- package/dist/react/index.js +49 -7
- package/dist/static/index.d.ts +1 -1
- package/dist/static/index.js +2 -2
- package/dist/{static-CVN6JhaR.js → static-HrbPXDQ1.js} +28 -16
- package/dist/{withSlate-1B0SfAWG.js → withSlate-DsAgt7dN.js} +940 -103
- package/package.json +7 -7
- package/dist/hotkeys-DI1HPO2Q.js.map +0 -1
- package/dist/index-NTp--CEF.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/react/index.d.ts.map +0 -1
- package/dist/react/index.js.map +0 -1
- package/dist/static-CVN6JhaR.js.map +0 -1
- package/dist/withSlate-1B0SfAWG.js.map +0 -1
|
@@ -112,6 +112,7 @@ function createSlatePlugin(config = {}) {
|
|
|
112
112
|
render: {},
|
|
113
113
|
rules: {},
|
|
114
114
|
shortcuts: {},
|
|
115
|
+
inputRules: [],
|
|
115
116
|
transforms: {}
|
|
116
117
|
}, config);
|
|
117
118
|
if (plugin.node.isLeaf && !isDefined(plugin.node.isDecoration)) plugin.node.isDecoration = true;
|
|
@@ -283,6 +284,11 @@ function getEditorPlugin(editor, p) {
|
|
|
283
284
|
|
|
284
285
|
//#endregion
|
|
285
286
|
//#region src/internal/plugin/resolvePlugin.ts
|
|
287
|
+
const normalizeConfiguredInputRules = (config) => {
|
|
288
|
+
if (config === void 0) return [];
|
|
289
|
+
if (Array.isArray(config)) return [...config];
|
|
290
|
+
throw new Error("inputRules config must be an array of explicit rule instances.");
|
|
291
|
+
};
|
|
286
292
|
/**
|
|
287
293
|
* Resolves and finalizes a plugin configuration for use in a Plate editor.
|
|
288
294
|
*
|
|
@@ -303,6 +309,11 @@ const resolvePlugin = (editor, _plugin) => {
|
|
|
303
309
|
plugin.__resolved = true;
|
|
304
310
|
if (plugin.__configuration) {
|
|
305
311
|
const configResult = plugin.__configuration(getEditorPlugin(editor, plugin));
|
|
312
|
+
if (configResult.inputRules !== void 0) {
|
|
313
|
+
const normalizedInputRules = normalizeConfiguredInputRules(configResult.inputRules);
|
|
314
|
+
plugin.__configuredInputRules = [...normalizeConfiguredInputRules(plugin.__configuredInputRules), ...normalizedInputRules];
|
|
315
|
+
configResult.inputRules = void 0;
|
|
316
|
+
}
|
|
306
317
|
plugin = mergePlugins(plugin, configResult);
|
|
307
318
|
plugin.__configuration = void 0;
|
|
308
319
|
}
|
|
@@ -361,11 +372,390 @@ const getPluginByType = (editor, type) => {
|
|
|
361
372
|
};
|
|
362
373
|
const getContainerTypes = (editor) => getPluginTypes(editor, editor.meta.pluginCache.node.isContainer);
|
|
363
374
|
|
|
375
|
+
//#endregion
|
|
376
|
+
//#region src/lib/plugins/input-rules/defineInputRule.ts
|
|
377
|
+
function defineInputRule(rule) {
|
|
378
|
+
return rule;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
//#endregion
|
|
382
|
+
//#region src/lib/plugins/input-rules/createInputRules.ts
|
|
383
|
+
const noWhiteSpaceRegex = /\S+/;
|
|
384
|
+
const isPreviousCharacterEmpty = (editor, at) => {
|
|
385
|
+
const range = editor.api.range("before", at);
|
|
386
|
+
if (!range) return true;
|
|
387
|
+
const text = editor.api.string(range);
|
|
388
|
+
return text ? !noWhiteSpaceRegex.exec(text) : true;
|
|
389
|
+
};
|
|
390
|
+
const getMarkMatch = (editor, { end = "", start }) => {
|
|
391
|
+
const { selection } = editor;
|
|
392
|
+
if (!selection) return;
|
|
393
|
+
let beforeEndMatchPoint = selection.anchor;
|
|
394
|
+
if (end) {
|
|
395
|
+
beforeEndMatchPoint = editor.api.before(selection, { matchString: end });
|
|
396
|
+
if (!beforeEndMatchPoint) return;
|
|
397
|
+
}
|
|
398
|
+
const afterStartMatchPoint = editor.api.before(beforeEndMatchPoint, {
|
|
399
|
+
afterMatch: true,
|
|
400
|
+
matchString: start,
|
|
401
|
+
skipInvalid: true
|
|
402
|
+
});
|
|
403
|
+
if (!afterStartMatchPoint) return;
|
|
404
|
+
const beforeStartMatchPoint = editor.api.before(beforeEndMatchPoint, {
|
|
405
|
+
matchString: start,
|
|
406
|
+
skipInvalid: true
|
|
407
|
+
});
|
|
408
|
+
if (!beforeStartMatchPoint) return;
|
|
409
|
+
if (!isPreviousCharacterEmpty(editor, beforeStartMatchPoint)) return;
|
|
410
|
+
return {
|
|
411
|
+
afterStartMatchPoint,
|
|
412
|
+
beforeEndMatchPoint,
|
|
413
|
+
beforeStartMatchPoint
|
|
414
|
+
};
|
|
415
|
+
};
|
|
416
|
+
const createMarkInputRule = (config) => defineInputRule({
|
|
417
|
+
enabled: config.enabled,
|
|
418
|
+
priority: config.priority,
|
|
419
|
+
target: "insertText",
|
|
420
|
+
trigger: config.trigger,
|
|
421
|
+
resolve: ({ editor, text }) => {
|
|
422
|
+
if (text !== config.trigger || !editor.selection || !editor.api.isCollapsed()) return;
|
|
423
|
+
const match = getMarkMatch(editor, {
|
|
424
|
+
end: config.end,
|
|
425
|
+
start: config.start
|
|
426
|
+
});
|
|
427
|
+
if (!match) return;
|
|
428
|
+
const range = {
|
|
429
|
+
anchor: match.afterStartMatchPoint,
|
|
430
|
+
focus: match.beforeEndMatchPoint
|
|
431
|
+
};
|
|
432
|
+
const matchText = editor.api.string(range);
|
|
433
|
+
if (config.trim !== "allow" && matchText.trim() !== matchText) return;
|
|
434
|
+
return {
|
|
435
|
+
...match,
|
|
436
|
+
end: config.end
|
|
437
|
+
};
|
|
438
|
+
},
|
|
439
|
+
apply: ({ editor, pluginKey }, match) => {
|
|
440
|
+
const marks = config.marks ? [...config.marks] : [config.mark ?? pluginKey];
|
|
441
|
+
if (match.beforeEndMatchPoint !== editor.selection?.anchor) editor.tf.delete({ at: {
|
|
442
|
+
anchor: match.beforeEndMatchPoint,
|
|
443
|
+
focus: editor.selection.anchor
|
|
444
|
+
} });
|
|
445
|
+
editor.tf.select({
|
|
446
|
+
anchor: match.afterStartMatchPoint,
|
|
447
|
+
focus: match.beforeEndMatchPoint
|
|
448
|
+
});
|
|
449
|
+
marks.forEach((mark) => {
|
|
450
|
+
editor.tf.addMark(editor.getType(mark), true);
|
|
451
|
+
});
|
|
452
|
+
editor.tf.collapse({ edge: "end" });
|
|
453
|
+
editor.tf.removeMarks(marks.map((mark) => editor.getType(mark)), { shouldChange: false });
|
|
454
|
+
editor.tf.delete({ at: {
|
|
455
|
+
anchor: match.beforeStartMatchPoint,
|
|
456
|
+
focus: match.afterStartMatchPoint
|
|
457
|
+
} });
|
|
458
|
+
return true;
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
const matchBlockStart = (context, config) => {
|
|
462
|
+
if (!context.isCollapsed) return;
|
|
463
|
+
const pattern = typeof config.match === "function" ? config.match(context) : config.match;
|
|
464
|
+
if (!pattern) return;
|
|
465
|
+
const range = context.getBlockStartRange();
|
|
466
|
+
const blockText = context.getBlockStartText();
|
|
467
|
+
if (!range || blockText === void 0) return;
|
|
468
|
+
const baseMatch = {
|
|
469
|
+
range,
|
|
470
|
+
text: blockText
|
|
471
|
+
};
|
|
472
|
+
if (typeof pattern === "string") {
|
|
473
|
+
if (blockText !== pattern) return;
|
|
474
|
+
if (config.resolveMatch) {
|
|
475
|
+
const resolved = config.resolveMatch({
|
|
476
|
+
match: pattern,
|
|
477
|
+
range,
|
|
478
|
+
text: blockText
|
|
479
|
+
});
|
|
480
|
+
if (resolved === void 0) return;
|
|
481
|
+
return {
|
|
482
|
+
...baseMatch,
|
|
483
|
+
...resolved
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
return baseMatch;
|
|
487
|
+
}
|
|
488
|
+
const regexMatch = blockText.match(pattern);
|
|
489
|
+
if (!regexMatch) return;
|
|
490
|
+
if (config.resolveMatch) {
|
|
491
|
+
const resolved = config.resolveMatch({
|
|
492
|
+
match: regexMatch,
|
|
493
|
+
range,
|
|
494
|
+
text: blockText
|
|
495
|
+
});
|
|
496
|
+
if (resolved === void 0) return;
|
|
497
|
+
return {
|
|
498
|
+
...baseMatch,
|
|
499
|
+
...resolved
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
return baseMatch;
|
|
503
|
+
};
|
|
504
|
+
const createBlockStartInputRule = (config) => defineInputRule({
|
|
505
|
+
enabled: config.enabled,
|
|
506
|
+
priority: config.priority,
|
|
507
|
+
target: "insertText",
|
|
508
|
+
trigger: config.trigger,
|
|
509
|
+
resolve: (context) => matchBlockStart(context, config),
|
|
510
|
+
apply: (context, match) => {
|
|
511
|
+
if (config.apply) return config.apply(context, match);
|
|
512
|
+
const { editor, pluginKey } = context;
|
|
513
|
+
const defaultMatch = match;
|
|
514
|
+
if (config.removeMatchedText !== false) editor.tf.delete({ at: defaultMatch.range });
|
|
515
|
+
const node = editor.getType(config.node ?? pluginKey);
|
|
516
|
+
if (config.mode === "wrap") {
|
|
517
|
+
editor.tf.toggleBlock(node, { wrap: true });
|
|
518
|
+
return true;
|
|
519
|
+
}
|
|
520
|
+
if (config.mode === "toggle") {
|
|
521
|
+
editor.tf.toggleBlock(node);
|
|
522
|
+
return true;
|
|
523
|
+
}
|
|
524
|
+
editor.tf.setNodes({ type: node }, { match: (entryNode) => editor.api.isBlock(entryNode) });
|
|
525
|
+
return true;
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
const matchBlockFence = (context, config) => {
|
|
529
|
+
const { editor } = context;
|
|
530
|
+
const { selection } = editor;
|
|
531
|
+
if (!context.isCollapsed || !selection) return;
|
|
532
|
+
const blockEntry = context.getBlockEntry();
|
|
533
|
+
if (!blockEntry) return;
|
|
534
|
+
const [blockNode, path] = blockEntry;
|
|
535
|
+
const endPoint = editor.api.end(path);
|
|
536
|
+
if (config.block && blockNode.type !== editor.getType(config.block)) return;
|
|
537
|
+
if (!endPoint || !editor.api.isEnd(selection.focus, path)) return;
|
|
538
|
+
const range = context.getBlockStartRange();
|
|
539
|
+
const blockText = context.getBlockStartText();
|
|
540
|
+
if (!range || blockText === void 0 || blockText !== config.fence) return;
|
|
541
|
+
return config.resolveMatch ? config.resolveMatch({
|
|
542
|
+
fence: config.fence,
|
|
543
|
+
path,
|
|
544
|
+
range,
|
|
545
|
+
text: blockText
|
|
546
|
+
}) : {
|
|
547
|
+
path,
|
|
548
|
+
range,
|
|
549
|
+
text: blockText
|
|
550
|
+
};
|
|
551
|
+
};
|
|
552
|
+
function createBlockFenceInputRule(config) {
|
|
553
|
+
if (config.on === "break") return defineInputRule({
|
|
554
|
+
priority: config.priority,
|
|
555
|
+
target: "insertBreak",
|
|
556
|
+
enabled: config.enabled,
|
|
557
|
+
resolve: (context) => matchBlockFence(context, {
|
|
558
|
+
block: config.block,
|
|
559
|
+
fence: config.fence,
|
|
560
|
+
resolveMatch: config.resolveMatch
|
|
561
|
+
}),
|
|
562
|
+
apply: config.apply
|
|
563
|
+
});
|
|
564
|
+
const trigger = config.fence.at(-1);
|
|
565
|
+
if (!trigger) throw new Error("createBlockFenceInputRule requires a non-empty fence.");
|
|
566
|
+
return defineInputRule({
|
|
567
|
+
priority: config.priority,
|
|
568
|
+
target: "insertText",
|
|
569
|
+
enabled: config.enabled,
|
|
570
|
+
trigger,
|
|
571
|
+
resolve: (context) => {
|
|
572
|
+
if (context.text !== trigger) return;
|
|
573
|
+
return matchBlockFence(context, {
|
|
574
|
+
block: config.block,
|
|
575
|
+
fence: config.fence.slice(0, -trigger.length),
|
|
576
|
+
resolveMatch: config.resolveMatch
|
|
577
|
+
});
|
|
578
|
+
},
|
|
579
|
+
apply: config.apply
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
const matchDelimitedInline = (context, { boundaryRe, close, followRe, open, requireClosingDelimiter = true, rejectRepeatedOpen = true, trim = "reject" }) => {
|
|
583
|
+
const { editor } = context;
|
|
584
|
+
const { selection } = editor;
|
|
585
|
+
if (!selection || !context.isCollapsed) return;
|
|
586
|
+
const blockRange = context.getBlockStartRange();
|
|
587
|
+
if (!blockRange) return;
|
|
588
|
+
const openingDelimiter = open;
|
|
589
|
+
const closingDelimiter = close ?? open;
|
|
590
|
+
const textBefore = editor.api.string(blockRange);
|
|
591
|
+
const beforeClose = requireClosingDelimiter ? (() => {
|
|
592
|
+
const closeLength = closingDelimiter.length;
|
|
593
|
+
if (textBefore.length < closeLength) return;
|
|
594
|
+
if (!textBefore.endsWith(closingDelimiter)) return;
|
|
595
|
+
return textBefore.slice(0, -closeLength);
|
|
596
|
+
})() : textBefore;
|
|
597
|
+
if (!beforeClose) return;
|
|
598
|
+
const openIndex = beforeClose.lastIndexOf(openingDelimiter);
|
|
599
|
+
if (openIndex < 0) return;
|
|
600
|
+
const prefix = beforeClose.slice(0, openIndex);
|
|
601
|
+
const content = beforeClose.slice(openIndex + openingDelimiter.length);
|
|
602
|
+
if (!content) return;
|
|
603
|
+
if (trim === "reject" && content.trim() !== content) return;
|
|
604
|
+
if (rejectRepeatedOpen && openingDelimiter === closingDelimiter && prefix.endsWith(openingDelimiter)) return;
|
|
605
|
+
const previousChar = prefix.at(-1);
|
|
606
|
+
if (previousChar && boundaryRe && !boundaryRe.test(previousChar)) return;
|
|
607
|
+
const nextPoint = editor.api.after(selection, {
|
|
608
|
+
distance: 1,
|
|
609
|
+
unit: "character"
|
|
610
|
+
});
|
|
611
|
+
if (nextPoint && followRe) {
|
|
612
|
+
const nextChar = editor.api.string({
|
|
613
|
+
anchor: selection.anchor,
|
|
614
|
+
focus: nextPoint
|
|
615
|
+
});
|
|
616
|
+
if (nextChar && !followRe.test(nextChar)) return;
|
|
617
|
+
}
|
|
618
|
+
const startPoint = editor.api.before(selection, {
|
|
619
|
+
distance: content.length + openingDelimiter.length,
|
|
620
|
+
unit: "character"
|
|
621
|
+
});
|
|
622
|
+
if (!startPoint) return;
|
|
623
|
+
return {
|
|
624
|
+
content,
|
|
625
|
+
deleteRange: {
|
|
626
|
+
anchor: startPoint,
|
|
627
|
+
focus: selection.anchor
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
};
|
|
631
|
+
const getTextSubstitutionMatchRange = ({ match, trigger }) => {
|
|
632
|
+
const start = match;
|
|
633
|
+
const reversed = start.split("").reverse().join("");
|
|
634
|
+
const triggers = trigger ? Array.isArray(trigger) ? [...trigger] : [trigger] : [reversed.slice(-1)];
|
|
635
|
+
return {
|
|
636
|
+
end: trigger ? reversed : reversed.slice(0, -1),
|
|
637
|
+
start,
|
|
638
|
+
triggers
|
|
639
|
+
};
|
|
640
|
+
};
|
|
641
|
+
const getTextSubstitutionMatchPoints = (editor, { end, start }) => {
|
|
642
|
+
const { selection } = editor;
|
|
643
|
+
if (!selection) return;
|
|
644
|
+
let beforeEndMatchPoint = selection.anchor;
|
|
645
|
+
if (end) {
|
|
646
|
+
beforeEndMatchPoint = editor.api.before(selection, { matchString: end });
|
|
647
|
+
if (!beforeEndMatchPoint) return;
|
|
648
|
+
}
|
|
649
|
+
let afterStartMatchPoint;
|
|
650
|
+
let beforeStartMatchPoint;
|
|
651
|
+
if (start) {
|
|
652
|
+
afterStartMatchPoint = editor.api.before(beforeEndMatchPoint, {
|
|
653
|
+
afterMatch: true,
|
|
654
|
+
matchString: start,
|
|
655
|
+
skipInvalid: true
|
|
656
|
+
});
|
|
657
|
+
if (!afterStartMatchPoint) return;
|
|
658
|
+
beforeStartMatchPoint = editor.api.before(beforeEndMatchPoint, {
|
|
659
|
+
matchString: start,
|
|
660
|
+
skipInvalid: true
|
|
661
|
+
});
|
|
662
|
+
if (!beforeStartMatchPoint) return;
|
|
663
|
+
if (!isPreviousCharacterEmpty(editor, beforeStartMatchPoint)) return;
|
|
664
|
+
}
|
|
665
|
+
return {
|
|
666
|
+
afterStartMatchPoint,
|
|
667
|
+
beforeEndMatchPoint,
|
|
668
|
+
beforeStartMatchPoint
|
|
669
|
+
};
|
|
670
|
+
};
|
|
671
|
+
const getTextSubstitutionTriggers = (patterns) => Array.from(new Set(patterns.flatMap((pattern) => {
|
|
672
|
+
return (Array.isArray(pattern.match) ? [...pattern.match] : [pattern.match]).flatMap((match) => getTextSubstitutionMatchRange({
|
|
673
|
+
match,
|
|
674
|
+
trigger: pattern.trigger
|
|
675
|
+
}).triggers);
|
|
676
|
+
})));
|
|
677
|
+
const resolveTextSubstitution = ({ editor, patterns, text }) => {
|
|
678
|
+
for (const pattern of patterns) {
|
|
679
|
+
const matches = Array.isArray(pattern.match) ? [...pattern.match] : [pattern.match];
|
|
680
|
+
for (const match of matches) {
|
|
681
|
+
const { end, start, triggers } = getTextSubstitutionMatchRange({
|
|
682
|
+
match,
|
|
683
|
+
trigger: pattern.trigger
|
|
684
|
+
});
|
|
685
|
+
if (!triggers.includes(text)) continue;
|
|
686
|
+
const points = getTextSubstitutionMatchPoints(editor, {
|
|
687
|
+
end: Array.isArray(pattern.format) ? "" : end,
|
|
688
|
+
start
|
|
689
|
+
});
|
|
690
|
+
if (!points) continue;
|
|
691
|
+
return {
|
|
692
|
+
end: Array.isArray(pattern.format) ? "" : end,
|
|
693
|
+
pattern,
|
|
694
|
+
points
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
};
|
|
699
|
+
const applyTextSubstitution = (editor, match) => {
|
|
700
|
+
const selection = editor.selection;
|
|
701
|
+
if (!selection || !match) return false;
|
|
702
|
+
if (match.end) editor.tf.delete({ at: {
|
|
703
|
+
anchor: match.points.beforeEndMatchPoint,
|
|
704
|
+
focus: selection.anchor
|
|
705
|
+
} });
|
|
706
|
+
const formatEnd = Array.isArray(match.pattern.format) ? match.pattern.format[1] : match.pattern.format;
|
|
707
|
+
editor.tf.insertText(formatEnd);
|
|
708
|
+
if (match.points.beforeStartMatchPoint && match.points.afterStartMatchPoint) {
|
|
709
|
+
const formatStart = Array.isArray(match.pattern.format) ? match.pattern.format[0] : match.pattern.format;
|
|
710
|
+
editor.tf.delete({ at: {
|
|
711
|
+
anchor: match.points.beforeStartMatchPoint,
|
|
712
|
+
focus: match.points.afterStartMatchPoint
|
|
713
|
+
} });
|
|
714
|
+
editor.tf.insertText(formatStart, { at: match.points.beforeStartMatchPoint });
|
|
715
|
+
}
|
|
716
|
+
return true;
|
|
717
|
+
};
|
|
718
|
+
const createTextSubstitutionInputRule = ({ enabled, patterns, priority }) => defineInputRule({
|
|
719
|
+
enabled,
|
|
720
|
+
priority,
|
|
721
|
+
target: "insertText",
|
|
722
|
+
trigger: getTextSubstitutionTriggers(patterns),
|
|
723
|
+
resolve: ({ editor, text }) => {
|
|
724
|
+
if (!editor.selection || !editor.api.isCollapsed()) return;
|
|
725
|
+
return resolveTextSubstitution({
|
|
726
|
+
editor,
|
|
727
|
+
patterns,
|
|
728
|
+
text
|
|
729
|
+
});
|
|
730
|
+
},
|
|
731
|
+
apply: ({ editor }, match) => applyTextSubstitution(editor, match)
|
|
732
|
+
});
|
|
733
|
+
|
|
734
|
+
//#endregion
|
|
735
|
+
//#region src/lib/plugins/input-rules/internal/createInputRuleBuilder.ts
|
|
736
|
+
const createInputRuleBuilder = () => ({
|
|
737
|
+
blockFence: (config) => createBlockFenceInputRule(config),
|
|
738
|
+
blockStart: (config) => createBlockStartInputRule(config),
|
|
739
|
+
insertBreak: (rule) => defineInputRule(rule),
|
|
740
|
+
insertData: (rule) => defineInputRule(rule),
|
|
741
|
+
insertText: (rule) => defineInputRule(rule),
|
|
742
|
+
mark: (config) => createMarkInputRule(config)
|
|
743
|
+
});
|
|
744
|
+
|
|
364
745
|
//#endregion
|
|
365
746
|
//#region src/internal/plugin/resolvePlugins.ts
|
|
366
747
|
const resolvePlugins = (editor, plugins = [], createStore = createVanillaStore) => {
|
|
367
748
|
editor.plugins = {};
|
|
368
749
|
editor.meta.pluginList = [];
|
|
750
|
+
editor.meta.inputRules = {
|
|
751
|
+
insertBreak: [],
|
|
752
|
+
insertData: [],
|
|
753
|
+
insertText: {
|
|
754
|
+
all: [],
|
|
755
|
+
byTrigger: {}
|
|
756
|
+
},
|
|
757
|
+
plugins: {}
|
|
758
|
+
};
|
|
369
759
|
editor.meta.shortcuts = {};
|
|
370
760
|
editor.meta.components = {};
|
|
371
761
|
editor.meta.pluginCache = {
|
|
@@ -435,6 +825,8 @@ const resolvePlugins = (editor, plugins = [], createStore = createVanillaStore)
|
|
|
435
825
|
if (plugin.handlers?.onTextChange) editor.meta.pluginCache.handlers.onTextChange.push(plugin.key);
|
|
436
826
|
});
|
|
437
827
|
resolvePluginShortcuts(editor);
|
|
828
|
+
resolvePluginInputRules(editor);
|
|
829
|
+
validateRemovedRuntimePlugins(editor);
|
|
438
830
|
return editor;
|
|
439
831
|
};
|
|
440
832
|
const resolvePluginStores = (editor, createStore) => {
|
|
@@ -512,6 +904,68 @@ const resolvePluginShortcuts = (editor) => {
|
|
|
512
904
|
});
|
|
513
905
|
});
|
|
514
906
|
};
|
|
907
|
+
const resolvePluginInputRules = (editor) => {
|
|
908
|
+
const resolvedMeta = {
|
|
909
|
+
insertBreak: [],
|
|
910
|
+
insertData: [],
|
|
911
|
+
insertText: {
|
|
912
|
+
all: [],
|
|
913
|
+
byTrigger: {}
|
|
914
|
+
},
|
|
915
|
+
plugins: {}
|
|
916
|
+
};
|
|
917
|
+
editor.meta.pluginList.forEach((plugin, pluginIndex) => {
|
|
918
|
+
const pluginKey = plugin.key;
|
|
919
|
+
const inputRulesDefinition = plugin.inputRules;
|
|
920
|
+
const definitionRules = typeof inputRulesDefinition === "function" ? inputRulesDefinition({ rule: createInputRuleBuilder() }) : inputRulesDefinition ?? [];
|
|
921
|
+
const configuredRules = plugin.__configuredInputRules ?? [];
|
|
922
|
+
const ruleDefinitions = [...definitionRules, ...configuredRules];
|
|
923
|
+
resolvedMeta.plugins[pluginKey] = { rules: [] };
|
|
924
|
+
ruleDefinitions.forEach((definition, ruleIndex) => {
|
|
925
|
+
if (!definition) return;
|
|
926
|
+
const mergedRule = mergePlugins({}, definition);
|
|
927
|
+
const resolvedRule = {
|
|
928
|
+
...mergedRule,
|
|
929
|
+
id: `${pluginKey}.${ruleIndex}`,
|
|
930
|
+
pluginIndex,
|
|
931
|
+
pluginKey,
|
|
932
|
+
priority: mergedRule.priority ?? plugin.priority,
|
|
933
|
+
ruleIndex
|
|
934
|
+
};
|
|
935
|
+
resolvedMeta.plugins[pluginKey].rules.push(resolvedRule);
|
|
936
|
+
if (resolvedRule.target === "insertText") {
|
|
937
|
+
const triggers = Array.isArray(resolvedRule.trigger) ? [...resolvedRule.trigger] : [resolvedRule.trigger];
|
|
938
|
+
resolvedMeta.insertText.all.push(resolvedRule);
|
|
939
|
+
triggers.forEach((trigger) => {
|
|
940
|
+
if (!resolvedMeta.insertText.byTrigger[trigger]) resolvedMeta.insertText.byTrigger[trigger] = [];
|
|
941
|
+
resolvedMeta.insertText.byTrigger[trigger].push(resolvedRule);
|
|
942
|
+
});
|
|
943
|
+
} else if (resolvedRule.target === "insertBreak") resolvedMeta.insertBreak.push(resolvedRule);
|
|
944
|
+
else if (resolvedRule.target === "insertData") resolvedMeta.insertData.push(resolvedRule);
|
|
945
|
+
});
|
|
946
|
+
});
|
|
947
|
+
const sortRules = (a, b) => {
|
|
948
|
+
if (b.priority !== a.priority) return b.priority - a.priority;
|
|
949
|
+
if (a.pluginIndex !== b.pluginIndex) return a.pluginIndex - b.pluginIndex;
|
|
950
|
+
return a.ruleIndex - b.ruleIndex;
|
|
951
|
+
};
|
|
952
|
+
resolvedMeta.insertBreak.sort(sortRules);
|
|
953
|
+
resolvedMeta.insertData.sort(sortRules);
|
|
954
|
+
resolvedMeta.insertText.all.sort(sortRules);
|
|
955
|
+
Object.values(resolvedMeta.insertText.byTrigger).forEach((rules) => {
|
|
956
|
+
rules.sort(sortRules);
|
|
957
|
+
});
|
|
958
|
+
editor.meta.inputRules = resolvedMeta;
|
|
959
|
+
};
|
|
960
|
+
const validateRemovedRuntimePlugins = (editor) => {
|
|
961
|
+
const hasAutoformatPlugin = !!editor.plugins.autoformat;
|
|
962
|
+
const hasResolvedInputRules = editor.meta.inputRules.insertBreak.length > 0 || editor.meta.inputRules.insertData.length > 0 || editor.meta.inputRules.insertText.all.length > 0;
|
|
963
|
+
if (hasAutoformatPlugin && hasResolvedInputRules) throw new Error([
|
|
964
|
+
"AutoformatPlugin cannot be used with plugin-owned input rules.",
|
|
965
|
+
"Remove AutoformatPlugin from your editor plugins.",
|
|
966
|
+
"Enable inputRules on the feature plugins you use instead."
|
|
967
|
+
].join(" "));
|
|
968
|
+
};
|
|
515
969
|
const flattenAndResolvePlugins = (editor, plugins) => {
|
|
516
970
|
const pluginMap = /* @__PURE__ */ new Map();
|
|
517
971
|
const processPlugin = (plugin) => {
|
|
@@ -643,11 +1097,11 @@ const withBreakRules = (ctx) => {
|
|
|
643
1097
|
node: blockNode,
|
|
644
1098
|
path: blockPath,
|
|
645
1099
|
rule
|
|
646
|
-
})) return overridePlugin
|
|
1100
|
+
})) return overridePlugin;
|
|
647
1101
|
}
|
|
648
1102
|
return null;
|
|
649
1103
|
};
|
|
650
|
-
const executeBreakAction = (action, blockPath) => {
|
|
1104
|
+
const executeBreakAction = (action, blockPath, type) => {
|
|
651
1105
|
if (action === "reset") {
|
|
652
1106
|
editor.tf.resetBlock({ at: blockPath });
|
|
653
1107
|
return true;
|
|
@@ -665,30 +1119,40 @@ const withBreakRules = (ctx) => {
|
|
|
665
1119
|
editor.tf.insertSoftBreak();
|
|
666
1120
|
return true;
|
|
667
1121
|
}
|
|
1122
|
+
if (action === "lift" && type) return !!editor.tf.liftBlock({
|
|
1123
|
+
at: blockPath,
|
|
1124
|
+
match: { type }
|
|
1125
|
+
});
|
|
668
1126
|
return false;
|
|
669
1127
|
};
|
|
670
1128
|
return { transforms: { insertBreak() {
|
|
671
|
-
if (editor.selection
|
|
1129
|
+
if (editor.selection) {
|
|
672
1130
|
const block = editor.api.block();
|
|
673
1131
|
if (block) {
|
|
674
1132
|
const [blockNode, blockPath] = block;
|
|
675
1133
|
const breakRules = getPluginByType(editor, blockNode.type)?.rules.break;
|
|
676
|
-
if (editor.api.isEmpty(editor.selection, { block: true })) {
|
|
677
|
-
const
|
|
678
|
-
|
|
1134
|
+
if (editor.api.isCollapsed() && editor.api.isEmpty(editor.selection, { block: true })) {
|
|
1135
|
+
const overridePlugin = checkMatchRulesOverride("break.empty", blockNode, blockPath);
|
|
1136
|
+
const emptyAction = (overridePlugin?.rules.break ?? breakRules)?.empty;
|
|
1137
|
+
const actionType = overridePlugin?.node.type;
|
|
1138
|
+
if (executeBreakAction(emptyAction, blockPath, actionType)) return;
|
|
679
1139
|
}
|
|
680
|
-
if (!editor.api.isEmpty(editor.selection, { block: true }) && editor.api.isAt({ end: true })) {
|
|
1140
|
+
if (editor.api.isCollapsed() && !editor.api.isEmpty(editor.selection, { block: true }) && editor.api.isAt({ end: true })) {
|
|
681
1141
|
const range = editor.api.range("before", editor.selection);
|
|
682
1142
|
if (range) {
|
|
683
1143
|
if (editor.api.string(range) === "\n") {
|
|
684
|
-
const
|
|
685
|
-
|
|
1144
|
+
const overridePlugin = checkMatchRulesOverride("break.emptyLineEnd", blockNode, blockPath);
|
|
1145
|
+
const emptyLineEndAction = (overridePlugin?.rules.break ?? breakRules)?.emptyLineEnd;
|
|
1146
|
+
const actionType = overridePlugin?.node.type;
|
|
1147
|
+
if (executeBreakAction(emptyLineEndAction, blockPath, actionType)) return;
|
|
686
1148
|
}
|
|
687
1149
|
}
|
|
688
1150
|
}
|
|
689
|
-
const
|
|
690
|
-
|
|
691
|
-
|
|
1151
|
+
const overrideDefaultPlugin = checkMatchRulesOverride("break.default", blockNode, blockPath);
|
|
1152
|
+
const defaultAction = (overrideDefaultPlugin?.rules.break ?? breakRules)?.default;
|
|
1153
|
+
const defaultActionType = overrideDefaultPlugin?.node.type;
|
|
1154
|
+
if (executeBreakAction(defaultAction, blockPath, defaultActionType)) return;
|
|
1155
|
+
if ((checkMatchRulesOverride("break.splitReset", blockNode, blockPath)?.rules.break?.splitReset ?? breakRules?.splitReset) && !editor.api.isAt({ blocks: true })) {
|
|
692
1156
|
const isAtStart = editor.api.isAt({ start: true });
|
|
693
1157
|
insertBreak();
|
|
694
1158
|
editor.tf.resetBlock({ at: isAtStart ? blockPath : PathApi.next(blockPath) });
|
|
@@ -716,15 +1180,19 @@ const withDeleteRules = (ctx) => {
|
|
|
716
1180
|
node: blockNode,
|
|
717
1181
|
path: blockPath,
|
|
718
1182
|
rule
|
|
719
|
-
})) return overridePlugin
|
|
1183
|
+
})) return overridePlugin;
|
|
720
1184
|
}
|
|
721
1185
|
return null;
|
|
722
1186
|
};
|
|
723
|
-
const executeDeleteAction = (action, blockPath) => {
|
|
1187
|
+
const executeDeleteAction = (action, blockPath, type) => {
|
|
724
1188
|
if (action === "reset") {
|
|
725
1189
|
editor.tf.resetBlock({ at: blockPath });
|
|
726
1190
|
return true;
|
|
727
1191
|
}
|
|
1192
|
+
if (action === "lift" && type) return !!editor.tf.liftBlock({
|
|
1193
|
+
at: blockPath,
|
|
1194
|
+
match: { type }
|
|
1195
|
+
});
|
|
728
1196
|
return false;
|
|
729
1197
|
};
|
|
730
1198
|
return { transforms: {
|
|
@@ -735,12 +1203,16 @@ const withDeleteRules = (ctx) => {
|
|
|
735
1203
|
const [blockNode, blockPath] = block;
|
|
736
1204
|
const deleteRules = getPluginByType(editor, blockNode.type)?.rules.delete;
|
|
737
1205
|
if (editor.api.isAt({ start: true })) {
|
|
738
|
-
const
|
|
739
|
-
|
|
1206
|
+
const overridePlugin = checkMatchRulesOverride("delete.start", blockNode, blockPath);
|
|
1207
|
+
const startAction = (overridePlugin?.rules.delete ?? deleteRules)?.start;
|
|
1208
|
+
const actionType = overridePlugin?.node.type;
|
|
1209
|
+
if (executeDeleteAction(startAction, blockPath, actionType)) return;
|
|
740
1210
|
}
|
|
741
1211
|
if (editor.api.isEmpty(editor.selection, { block: true })) {
|
|
742
|
-
const
|
|
743
|
-
|
|
1212
|
+
const overridePlugin = checkMatchRulesOverride("delete.empty", blockNode, blockPath);
|
|
1213
|
+
const emptyAction = (overridePlugin?.rules.delete ?? deleteRules)?.empty;
|
|
1214
|
+
const actionType = overridePlugin?.node.type;
|
|
1215
|
+
if (executeDeleteAction(emptyAction, blockPath, actionType)) return;
|
|
744
1216
|
}
|
|
745
1217
|
}
|
|
746
1218
|
if (PointApi.equals(editor.selection.anchor, editor.api.start([]))) {
|
|
@@ -994,6 +1466,7 @@ const getInjectMatch = (editor, plugin) => {
|
|
|
994
1466
|
if (targetPlugins && !targetPlugins.includes(getPluginKey(editor, element.type))) return false;
|
|
995
1467
|
}
|
|
996
1468
|
if (excludeBelowPlugins || maxLevel) {
|
|
1469
|
+
if (!path) return false;
|
|
997
1470
|
if (maxLevel && path.length > maxLevel) return false;
|
|
998
1471
|
if (excludeBelowPlugins) {
|
|
999
1472
|
const excludeTypes = getPluginKeys(editor, excludeBelowPlugins);
|
|
@@ -1328,16 +1801,28 @@ const withScrolling = (editor, fn, options) => {
|
|
|
1328
1801
|
const prevOptions = editor.getOptions(DOMPlugin);
|
|
1329
1802
|
const prevAutoScroll = AUTO_SCROLL.get(editor) ?? false;
|
|
1330
1803
|
if (options) {
|
|
1804
|
+
const scrollOptions = typeof options.scrollOptions === "object" && options.scrollOptions ? {
|
|
1805
|
+
...typeof prevOptions.scrollOptions === "object" ? prevOptions.scrollOptions : {},
|
|
1806
|
+
...omitBy(options.scrollOptions, isUndefined)
|
|
1807
|
+
} : options.scrollOptions ?? prevOptions.scrollOptions;
|
|
1331
1808
|
const ops = {
|
|
1332
1809
|
...prevOptions,
|
|
1333
|
-
|
|
1810
|
+
scrollOperations: {
|
|
1811
|
+
...prevOptions.scrollOperations,
|
|
1812
|
+
...omitBy(options.operations ?? {}, isUndefined)
|
|
1813
|
+
},
|
|
1814
|
+
scrollOptions,
|
|
1815
|
+
...omitBy({ scrollMode: options.mode }, isUndefined)
|
|
1334
1816
|
};
|
|
1335
1817
|
editor.setOptions(DOMPlugin, ops);
|
|
1336
1818
|
}
|
|
1337
1819
|
AUTO_SCROLL.set(editor, true);
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1820
|
+
try {
|
|
1821
|
+
fn();
|
|
1822
|
+
} finally {
|
|
1823
|
+
AUTO_SCROLL.set(editor, prevAutoScroll);
|
|
1824
|
+
editor.setOptions(DOMPlugin, prevOptions);
|
|
1825
|
+
}
|
|
1341
1826
|
};
|
|
1342
1827
|
|
|
1343
1828
|
//#endregion
|
|
@@ -2055,6 +2540,182 @@ const LengthPlugin = createTSlatePlugin({ key: "length" }).overrideEditor(({ edi
|
|
|
2055
2540
|
});
|
|
2056
2541
|
} } }));
|
|
2057
2542
|
|
|
2543
|
+
//#endregion
|
|
2544
|
+
//#region src/lib/plugins/navigation-feedback/types.ts
|
|
2545
|
+
const NAVIGATION_FEEDBACK_KEY = "navigationFeedback";
|
|
2546
|
+
const NavigationFeedbackPluginKey = { key: NAVIGATION_FEEDBACK_KEY };
|
|
2547
|
+
|
|
2548
|
+
//#endregion
|
|
2549
|
+
//#region src/lib/plugins/navigation-feedback/transforms/flashTarget.ts
|
|
2550
|
+
const NAVIGATION_FEEDBACK_TIMEOUT = /* @__PURE__ */ new WeakMap();
|
|
2551
|
+
const NAVIGATION_FEEDBACK_PULSE = /* @__PURE__ */ new WeakMap();
|
|
2552
|
+
const NAVIGATION_FEEDBACK_ATTRIBUTES = [
|
|
2553
|
+
"data-nav-cycle",
|
|
2554
|
+
"data-nav-highlight",
|
|
2555
|
+
"data-nav-pulse",
|
|
2556
|
+
"data-nav-target"
|
|
2557
|
+
];
|
|
2558
|
+
const clearNavigationPathRef = (target) => {
|
|
2559
|
+
target?.pathRef.unref();
|
|
2560
|
+
};
|
|
2561
|
+
const resolveNavigationFeedbackTarget = (target) => {
|
|
2562
|
+
const path = target?.pathRef.current;
|
|
2563
|
+
if (!target || !path) return null;
|
|
2564
|
+
const { pathRef: _pathRef, ...rest } = target;
|
|
2565
|
+
return {
|
|
2566
|
+
...rest,
|
|
2567
|
+
path
|
|
2568
|
+
};
|
|
2569
|
+
};
|
|
2570
|
+
const getNavigationElement = (editor, target) => {
|
|
2571
|
+
const node = NodeApi.get(editor, target.path);
|
|
2572
|
+
if (!node) return;
|
|
2573
|
+
try {
|
|
2574
|
+
return editor.api.toDOMNode(node);
|
|
2575
|
+
} catch {
|
|
2576
|
+
return;
|
|
2577
|
+
}
|
|
2578
|
+
};
|
|
2579
|
+
const clearNavigationElement = (editor, target) => {
|
|
2580
|
+
if (!target) return;
|
|
2581
|
+
const element = getNavigationElement(editor, target);
|
|
2582
|
+
if (!element) return;
|
|
2583
|
+
for (const attribute of NAVIGATION_FEEDBACK_ATTRIBUTES) element.removeAttribute(attribute);
|
|
2584
|
+
element.style.removeProperty("--plate-nav-feedback-duration");
|
|
2585
|
+
};
|
|
2586
|
+
const setNavigationElement = (editor, target) => {
|
|
2587
|
+
const element = getNavigationElement(editor, target);
|
|
2588
|
+
if (!element) return;
|
|
2589
|
+
element.setAttribute("data-nav-cycle", String(target.cycle));
|
|
2590
|
+
element.setAttribute("data-nav-highlight", target.variant);
|
|
2591
|
+
element.setAttribute("data-nav-pulse", String(target.pulse));
|
|
2592
|
+
element.setAttribute("data-nav-target", "true");
|
|
2593
|
+
element.style.setProperty("--plate-nav-feedback-duration", `${target.duration}ms`);
|
|
2594
|
+
};
|
|
2595
|
+
const clearNavigationTimeout = (editor) => {
|
|
2596
|
+
const timeoutId = NAVIGATION_FEEDBACK_TIMEOUT.get(editor);
|
|
2597
|
+
if (timeoutId) {
|
|
2598
|
+
clearTimeout(timeoutId);
|
|
2599
|
+
NAVIGATION_FEEDBACK_TIMEOUT.delete(editor);
|
|
2600
|
+
}
|
|
2601
|
+
};
|
|
2602
|
+
const nextPulse = (editor) => {
|
|
2603
|
+
const pulse = (NAVIGATION_FEEDBACK_PULSE.get(editor) ?? 0) + 1;
|
|
2604
|
+
NAVIGATION_FEEDBACK_PULSE.set(editor, pulse);
|
|
2605
|
+
return pulse;
|
|
2606
|
+
};
|
|
2607
|
+
const clearNavigationFeedbackTarget = (editor, pulse) => {
|
|
2608
|
+
const storedTarget = editor.getOption(NavigationFeedbackPluginKey, "activeTarget");
|
|
2609
|
+
const activeTarget = resolveNavigationFeedbackTarget(storedTarget);
|
|
2610
|
+
if (!storedTarget) return false;
|
|
2611
|
+
if (pulse !== void 0 && storedTarget.pulse !== pulse) return false;
|
|
2612
|
+
clearNavigationTimeout(editor);
|
|
2613
|
+
clearNavigationElement(editor, activeTarget);
|
|
2614
|
+
clearNavigationPathRef(storedTarget);
|
|
2615
|
+
editor.setOption(NavigationFeedbackPluginKey, "activeTarget", null);
|
|
2616
|
+
return true;
|
|
2617
|
+
};
|
|
2618
|
+
const flashTarget = (editor, { duration, target, variant = "navigated" }) => {
|
|
2619
|
+
if (!editor.api.node(target.path)) return false;
|
|
2620
|
+
const pulse = nextPulse(editor);
|
|
2621
|
+
const timeoutMs = duration ?? editor.getOption(NavigationFeedbackPluginKey, "duration") ?? 800;
|
|
2622
|
+
const previousTarget = editor.getOption(NavigationFeedbackPluginKey, "activeTarget");
|
|
2623
|
+
clearNavigationTimeout(editor);
|
|
2624
|
+
clearNavigationElement(editor, resolveNavigationFeedbackTarget(previousTarget));
|
|
2625
|
+
clearNavigationPathRef(previousTarget);
|
|
2626
|
+
const pathRef = editor.api.pathRef(target.path);
|
|
2627
|
+
const activeTarget = {
|
|
2628
|
+
cycle: pulse % 2,
|
|
2629
|
+
duration: timeoutMs,
|
|
2630
|
+
pathRef,
|
|
2631
|
+
pulse,
|
|
2632
|
+
type: target.type,
|
|
2633
|
+
variant
|
|
2634
|
+
};
|
|
2635
|
+
editor.setOption(NavigationFeedbackPluginKey, "activeTarget", activeTarget);
|
|
2636
|
+
setNavigationElement(editor, resolveNavigationFeedbackTarget(activeTarget) ?? {
|
|
2637
|
+
cycle: activeTarget.cycle,
|
|
2638
|
+
duration: activeTarget.duration,
|
|
2639
|
+
path: target.path,
|
|
2640
|
+
pulse: activeTarget.pulse,
|
|
2641
|
+
type: activeTarget.type,
|
|
2642
|
+
variant: activeTarget.variant
|
|
2643
|
+
});
|
|
2644
|
+
const timeoutId = setTimeout(() => {
|
|
2645
|
+
clearNavigationFeedbackTarget(editor, pulse);
|
|
2646
|
+
}, timeoutMs);
|
|
2647
|
+
NAVIGATION_FEEDBACK_TIMEOUT.set(editor, timeoutId);
|
|
2648
|
+
return true;
|
|
2649
|
+
};
|
|
2650
|
+
|
|
2651
|
+
//#endregion
|
|
2652
|
+
//#region src/lib/plugins/navigation-feedback/transforms/navigate.ts
|
|
2653
|
+
const getScrollTarget = (editor, { scrollTarget, select, target }) => {
|
|
2654
|
+
if (scrollTarget) return scrollTarget;
|
|
2655
|
+
if (select && "focus" in select && select.focus) return select.focus;
|
|
2656
|
+
if (select && "anchor" in select && select.anchor) return select.anchor;
|
|
2657
|
+
if (select && "path" in select) return select;
|
|
2658
|
+
return editor.api.start(target.path);
|
|
2659
|
+
};
|
|
2660
|
+
const navigate = (editor, { flash, focus = true, scroll = true, scrollTarget, select, target }) => {
|
|
2661
|
+
if (!editor.api.node(target.path)) return false;
|
|
2662
|
+
if (select) if ("focus" in select) editor.tf.select(select);
|
|
2663
|
+
else editor.tf.select({
|
|
2664
|
+
anchor: select,
|
|
2665
|
+
focus: select
|
|
2666
|
+
});
|
|
2667
|
+
if (focus) editor.tf.focus();
|
|
2668
|
+
if (scroll) {
|
|
2669
|
+
const point = getScrollTarget(editor, {
|
|
2670
|
+
flash,
|
|
2671
|
+
focus,
|
|
2672
|
+
scroll,
|
|
2673
|
+
scrollTarget,
|
|
2674
|
+
select,
|
|
2675
|
+
target
|
|
2676
|
+
});
|
|
2677
|
+
if (point) editor.api.scrollIntoView(point);
|
|
2678
|
+
}
|
|
2679
|
+
if (flash !== false) flashTarget(editor, {
|
|
2680
|
+
duration: flash?.duration,
|
|
2681
|
+
target,
|
|
2682
|
+
variant: flash?.variant
|
|
2683
|
+
});
|
|
2684
|
+
return true;
|
|
2685
|
+
};
|
|
2686
|
+
|
|
2687
|
+
//#endregion
|
|
2688
|
+
//#region src/lib/plugins/navigation-feedback/NavigationFeedbackPlugin.ts
|
|
2689
|
+
const NavigationFeedbackPlugin = createTSlatePlugin({
|
|
2690
|
+
key: NAVIGATION_FEEDBACK_KEY,
|
|
2691
|
+
options: {
|
|
2692
|
+
activeTarget: null,
|
|
2693
|
+
duration: 1600
|
|
2694
|
+
}
|
|
2695
|
+
}).extendEditorApi(({ editor }) => {
|
|
2696
|
+
const getActiveTarget = () => {
|
|
2697
|
+
const storedTarget = editor.getOption(NavigationFeedbackPluginKey, "activeTarget");
|
|
2698
|
+
const activeTarget = resolveNavigationFeedbackTarget(storedTarget);
|
|
2699
|
+
if (!activeTarget && storedTarget) {
|
|
2700
|
+
clearNavigationFeedbackTarget(editor);
|
|
2701
|
+
return null;
|
|
2702
|
+
}
|
|
2703
|
+
return activeTarget;
|
|
2704
|
+
};
|
|
2705
|
+
return { navigation: {
|
|
2706
|
+
activeTarget: getActiveTarget,
|
|
2707
|
+
clear: () => clearNavigationFeedbackTarget(editor),
|
|
2708
|
+
isTarget: (path) => {
|
|
2709
|
+
const activeTarget = getActiveTarget();
|
|
2710
|
+
return !!activeTarget && PathApi.equals(activeTarget.path, path);
|
|
2711
|
+
}
|
|
2712
|
+
} };
|
|
2713
|
+
}).extendEditorTransforms(({ editor }) => ({ navigation: {
|
|
2714
|
+
clear: () => clearNavigationFeedbackTarget(editor),
|
|
2715
|
+
flashTarget: (options) => flashTarget(editor, options),
|
|
2716
|
+
navigate: (options) => navigate(editor, options)
|
|
2717
|
+
} }));
|
|
2718
|
+
|
|
2058
2719
|
//#endregion
|
|
2059
2720
|
//#region src/lib/plugins/node-id/withNodeId.ts
|
|
2060
2721
|
/** Enables support for inserting nodes with an id key. */
|
|
@@ -2390,18 +3051,45 @@ const insertExitBreak = (editor, { match, reverse } = {}) => {
|
|
|
2390
3051
|
return true;
|
|
2391
3052
|
};
|
|
2392
3053
|
|
|
3054
|
+
//#endregion
|
|
3055
|
+
//#region src/lib/plugins/slate-extension/transforms/liftBlock.ts
|
|
3056
|
+
/**
|
|
3057
|
+
* Lift the current block out of the nearest matching ancestor container.
|
|
3058
|
+
*
|
|
3059
|
+
* This unwraps only the current block and splits the ancestor around it when
|
|
3060
|
+
* needed, so one keypress changes one structural level instead of exploding the
|
|
3061
|
+
* whole container.
|
|
3062
|
+
*/
|
|
3063
|
+
const liftBlock = (editor, { at, match } = {}) => {
|
|
3064
|
+
const block = editor.api.block({ at });
|
|
3065
|
+
if (!block || !match) return;
|
|
3066
|
+
const [, blockPath] = block;
|
|
3067
|
+
if (!editor.api.above({
|
|
3068
|
+
at: blockPath,
|
|
3069
|
+
match: combineMatchOptions(editor, (_node, path) => path.length < blockPath.length, { match })
|
|
3070
|
+
})) return;
|
|
3071
|
+
editor.tf.unwrapNodes({
|
|
3072
|
+
at: blockPath,
|
|
3073
|
+
match,
|
|
3074
|
+
split: true
|
|
3075
|
+
});
|
|
3076
|
+
return true;
|
|
3077
|
+
};
|
|
3078
|
+
|
|
2393
3079
|
//#endregion
|
|
2394
3080
|
//#region src/lib/plugins/slate-extension/transforms/resetBlock.ts
|
|
2395
3081
|
/**
|
|
2396
|
-
* Reset the current block to a paragraph, removing all properties except
|
|
2397
|
-
* type.
|
|
3082
|
+
* Reset the current block to a paragraph, removing all properties except the
|
|
3083
|
+
* configured node id key and type.
|
|
2398
3084
|
*/
|
|
2399
3085
|
const resetBlock = (editor, { at } = {}) => {
|
|
2400
3086
|
const entry = editor.api.block({ at });
|
|
2401
3087
|
if (!entry?.[0]) return;
|
|
2402
3088
|
const [block, path] = entry;
|
|
3089
|
+
const idKey = editor.getOptions(NodeIdPlugin).idKey ?? "id";
|
|
2403
3090
|
editor.tf.withoutNormalizing(() => {
|
|
2404
|
-
const {
|
|
3091
|
+
const { type, ...otherProps } = NodeApi.extractProps(block);
|
|
3092
|
+
delete otherProps[idKey];
|
|
2405
3093
|
Object.keys(otherProps).forEach((key) => {
|
|
2406
3094
|
editor.tf.unsetNodes(key, { at: path });
|
|
2407
3095
|
});
|
|
@@ -2425,93 +3113,99 @@ const setValue = (editor, value) => {
|
|
|
2425
3113
|
|
|
2426
3114
|
//#endregion
|
|
2427
3115
|
//#region src/lib/plugins/slate-extension/SlateExtensionPlugin.ts
|
|
3116
|
+
const NOOP_ON_NODE_CHANGE = () => {};
|
|
3117
|
+
const NOOP_ON_TEXT_CHANGE = () => {};
|
|
2428
3118
|
/** Opinionated extension of slate default behavior. */
|
|
2429
3119
|
const SlateExtensionPlugin = createTSlatePlugin({
|
|
3120
|
+
api: { redecorate: () => {} },
|
|
2430
3121
|
key: "slateExtension",
|
|
2431
3122
|
options: {
|
|
2432
|
-
onNodeChange:
|
|
2433
|
-
onTextChange:
|
|
3123
|
+
onNodeChange: NOOP_ON_NODE_CHANGE,
|
|
3124
|
+
onTextChange: NOOP_ON_TEXT_CHANGE
|
|
2434
3125
|
}
|
|
2435
|
-
}).extendEditorTransforms(({ editor, getOption, tf
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
node = operation.node;
|
|
2457
|
-
break;
|
|
2458
|
-
case "merge_node":
|
|
2459
|
-
case "move_node":
|
|
2460
|
-
case "set_node":
|
|
2461
|
-
case "split_node":
|
|
2462
|
-
prevNode = NodeApi.get(editor, operation.path);
|
|
2463
|
-
break;
|
|
2464
|
-
case "remove_node":
|
|
2465
|
-
prevNode = operation.node;
|
|
2466
|
-
node = operation.node;
|
|
2467
|
-
break;
|
|
2468
|
-
}
|
|
2469
|
-
else if (OperationApi.isTextOperation(operation) && hasTextHandlers) {
|
|
2470
|
-
const parentPath = PathApi.parent(operation.path);
|
|
2471
|
-
parentNode = NodeApi.get(editor, parentPath);
|
|
2472
|
-
prevText = NodeApi.get(editor, operation.path).text;
|
|
2473
|
-
}
|
|
2474
|
-
apply(operation);
|
|
2475
|
-
if (OperationApi.isNodeOperation(operation) && hasNodeHandlers) {
|
|
2476
|
-
switch (operation.type) {
|
|
3126
|
+
}).extendEditorTransforms(({ editor, getOption, tf }) => {
|
|
3127
|
+
const apply = tf?.apply ?? editor.tf.apply;
|
|
3128
|
+
return {
|
|
3129
|
+
init: bindFirst(init, editor),
|
|
3130
|
+
insertExitBreak: bindFirst(insertExitBreak, editor),
|
|
3131
|
+
liftBlock: bindFirst(liftBlock, editor),
|
|
3132
|
+
resetBlock: bindFirst(resetBlock, editor),
|
|
3133
|
+
setValue: bindFirst(setValue, editor),
|
|
3134
|
+
apply(operation) {
|
|
3135
|
+
const hasNodeHandlers = editor.meta.pluginCache.handlers.onNodeChange.length > 0 || getOption("onNodeChange") !== NOOP_ON_NODE_CHANGE;
|
|
3136
|
+
const hasTextHandlers = editor.meta.pluginCache.handlers.onTextChange.length > 0 || getOption("onTextChange") !== NOOP_ON_TEXT_CHANGE;
|
|
3137
|
+
if (!hasNodeHandlers && !hasTextHandlers) {
|
|
3138
|
+
apply(operation);
|
|
3139
|
+
return;
|
|
3140
|
+
}
|
|
3141
|
+
let prevNode;
|
|
3142
|
+
let node;
|
|
3143
|
+
let prevText;
|
|
3144
|
+
let text;
|
|
3145
|
+
let parentNode;
|
|
3146
|
+
if (OperationApi.isNodeOperation(operation) && hasNodeHandlers) switch (operation.type) {
|
|
2477
3147
|
case "insert_node":
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
const prevPath = PathApi.previous(operation.path);
|
|
2481
|
-
if (prevPath) node = NodeApi.get(editor, prevPath);
|
|
3148
|
+
prevNode = operation.node;
|
|
3149
|
+
node = operation.node;
|
|
2482
3150
|
break;
|
|
2483
|
-
|
|
3151
|
+
case "merge_node":
|
|
2484
3152
|
case "move_node":
|
|
2485
|
-
node = NodeApi.get(editor, operation.newPath);
|
|
2486
|
-
break;
|
|
2487
3153
|
case "set_node":
|
|
2488
|
-
node = NodeApi.get(editor, operation.path);
|
|
2489
|
-
break;
|
|
2490
3154
|
case "split_node":
|
|
2491
|
-
|
|
3155
|
+
prevNode = NodeApi.get(editor, operation.path);
|
|
3156
|
+
break;
|
|
3157
|
+
case "remove_node":
|
|
3158
|
+
prevNode = operation.node;
|
|
3159
|
+
node = operation.node;
|
|
2492
3160
|
break;
|
|
2493
3161
|
}
|
|
2494
|
-
if (
|
|
2495
|
-
|
|
2496
|
-
editor,
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
3162
|
+
else if (OperationApi.isTextOperation(operation) && hasTextHandlers) {
|
|
3163
|
+
const parentPath = PathApi.parent(operation.path);
|
|
3164
|
+
parentNode = NodeApi.get(editor, parentPath);
|
|
3165
|
+
prevText = NodeApi.get(editor, operation.path).text;
|
|
3166
|
+
}
|
|
3167
|
+
apply(operation);
|
|
3168
|
+
if (OperationApi.isNodeOperation(operation) && hasNodeHandlers) {
|
|
3169
|
+
switch (operation.type) {
|
|
3170
|
+
case "insert_node":
|
|
3171
|
+
case "remove_node": break;
|
|
3172
|
+
case "merge_node": {
|
|
3173
|
+
const prevPath = PathApi.previous(operation.path);
|
|
3174
|
+
if (prevPath) node = NodeApi.get(editor, prevPath);
|
|
3175
|
+
break;
|
|
3176
|
+
}
|
|
3177
|
+
case "move_node":
|
|
3178
|
+
node = NodeApi.get(editor, operation.newPath);
|
|
3179
|
+
break;
|
|
3180
|
+
case "set_node":
|
|
3181
|
+
node = NodeApi.get(editor, operation.path);
|
|
3182
|
+
break;
|
|
3183
|
+
case "split_node":
|
|
3184
|
+
node = NodeApi.get(editor, operation.path);
|
|
3185
|
+
break;
|
|
3186
|
+
}
|
|
3187
|
+
if (!node) node = prevNode;
|
|
3188
|
+
if (!pipeOnNodeChange(editor, node, prevNode, operation)) getOption("onNodeChange")({
|
|
3189
|
+
editor,
|
|
3190
|
+
node,
|
|
3191
|
+
operation,
|
|
3192
|
+
prevNode
|
|
3193
|
+
});
|
|
3194
|
+
}
|
|
3195
|
+
if (OperationApi.isTextOperation(operation) && hasTextHandlers) {
|
|
3196
|
+
const textNodeAfter = NodeApi.get(editor, operation.path);
|
|
3197
|
+
if (textNodeAfter) text = textNodeAfter.text;
|
|
3198
|
+
if (!pipeOnTextChange(editor, parentNode, text, prevText, operation)) getOption("onTextChange")({
|
|
3199
|
+
editor,
|
|
3200
|
+
node: parentNode,
|
|
3201
|
+
operation,
|
|
3202
|
+
prevText,
|
|
3203
|
+
text
|
|
3204
|
+
});
|
|
3205
|
+
}
|
|
2512
3206
|
}
|
|
2513
|
-
}
|
|
2514
|
-
})
|
|
3207
|
+
};
|
|
3208
|
+
});
|
|
2515
3209
|
|
|
2516
3210
|
//#endregion
|
|
2517
3211
|
//#region src/lib/utils/normalizeDescendantsToDocumentFragment.ts
|
|
@@ -2637,16 +3331,159 @@ const ParserPlugin = createSlatePlugin({ key: "parser" }).overrideEditor(({ edit
|
|
|
2637
3331
|
insertData(dataTransfer);
|
|
2638
3332
|
} } }));
|
|
2639
3333
|
|
|
3334
|
+
//#endregion
|
|
3335
|
+
//#region src/lib/plugins/input-rules/internal/InputRulesPlugin.ts
|
|
3336
|
+
const createCachedGetter = (compute) => {
|
|
3337
|
+
let hasValue = false;
|
|
3338
|
+
let value;
|
|
3339
|
+
return () => {
|
|
3340
|
+
if (!hasValue) {
|
|
3341
|
+
value = compute();
|
|
3342
|
+
hasValue = true;
|
|
3343
|
+
}
|
|
3344
|
+
return value;
|
|
3345
|
+
};
|
|
3346
|
+
};
|
|
3347
|
+
const createSelectionContext = ({ editor }) => {
|
|
3348
|
+
const { selection } = editor;
|
|
3349
|
+
const isCollapsed = !!selection && editor.api.isCollapsed();
|
|
3350
|
+
const getBlockStartRange = createCachedGetter(() => {
|
|
3351
|
+
if (!selection) return;
|
|
3352
|
+
return editor.api.range("start", selection);
|
|
3353
|
+
});
|
|
3354
|
+
const getBlockStartText = createCachedGetter(() => {
|
|
3355
|
+
const range = getBlockStartRange();
|
|
3356
|
+
return range ? editor.api.string(range) : void 0;
|
|
3357
|
+
});
|
|
3358
|
+
return {
|
|
3359
|
+
editor,
|
|
3360
|
+
getBlockEntry: createCachedGetter(() => {
|
|
3361
|
+
if (!selection) return;
|
|
3362
|
+
return editor.api.block({ at: selection });
|
|
3363
|
+
}),
|
|
3364
|
+
getBlockStartRange,
|
|
3365
|
+
getBlockStartText,
|
|
3366
|
+
getBlockTextBeforeSelection: createCachedGetter(() => getBlockStartText() ?? ""),
|
|
3367
|
+
getCharAfter: createCachedGetter(() => {
|
|
3368
|
+
if (!selection || !isCollapsed) return;
|
|
3369
|
+
const afterPoint = editor.api.after(selection, {
|
|
3370
|
+
distance: 1,
|
|
3371
|
+
unit: "character"
|
|
3372
|
+
});
|
|
3373
|
+
if (!afterPoint) return;
|
|
3374
|
+
return editor.api.string({
|
|
3375
|
+
anchor: selection.anchor,
|
|
3376
|
+
focus: afterPoint
|
|
3377
|
+
}) || void 0;
|
|
3378
|
+
}),
|
|
3379
|
+
getCharBefore: createCachedGetter(() => {
|
|
3380
|
+
if (!selection || !isCollapsed) return;
|
|
3381
|
+
const beforePoint = editor.api.before(selection, {
|
|
3382
|
+
distance: 1,
|
|
3383
|
+
unit: "character"
|
|
3384
|
+
});
|
|
3385
|
+
if (!beforePoint) return;
|
|
3386
|
+
return editor.api.string({
|
|
3387
|
+
anchor: beforePoint,
|
|
3388
|
+
focus: selection.anchor
|
|
3389
|
+
}) || void 0;
|
|
3390
|
+
}),
|
|
3391
|
+
isCollapsed
|
|
3392
|
+
};
|
|
3393
|
+
};
|
|
3394
|
+
const isTriggerMatch = (trigger, text) => Array.isArray(trigger) ? trigger.includes(text) : trigger === text;
|
|
3395
|
+
const InputRulesPlugin = createTSlatePlugin({
|
|
3396
|
+
editOnly: true,
|
|
3397
|
+
key: "inputRules"
|
|
3398
|
+
}).overrideEditor(({ editor, tf: { insertBreak, insertData, insertText } }) => ({ transforms: {
|
|
3399
|
+
insertBreak() {
|
|
3400
|
+
const selectionContext = createSelectionContext({ editor });
|
|
3401
|
+
let handled = false;
|
|
3402
|
+
for (const rule of editor.meta.inputRules.insertBreak) {
|
|
3403
|
+
const context = {
|
|
3404
|
+
cause: "insertBreak",
|
|
3405
|
+
insertBreak,
|
|
3406
|
+
pluginKey: rule.pluginKey,
|
|
3407
|
+
...selectionContext
|
|
3408
|
+
};
|
|
3409
|
+
if (rule.enabled?.(context) === false) continue;
|
|
3410
|
+
const match = rule.resolve ? rule.resolve(context) : true;
|
|
3411
|
+
if (match === void 0) continue;
|
|
3412
|
+
if (rule.apply(context, match) !== false) {
|
|
3413
|
+
handled = true;
|
|
3414
|
+
break;
|
|
3415
|
+
}
|
|
3416
|
+
}
|
|
3417
|
+
if (handled) return;
|
|
3418
|
+
insertBreak();
|
|
3419
|
+
},
|
|
3420
|
+
insertData(data) {
|
|
3421
|
+
const text = data.getData("text/plain") || null;
|
|
3422
|
+
const selectionContext = createSelectionContext({ editor });
|
|
3423
|
+
let handled = false;
|
|
3424
|
+
for (const rule of editor.meta.inputRules.insertData) {
|
|
3425
|
+
const context = {
|
|
3426
|
+
cause: "insertData",
|
|
3427
|
+
data,
|
|
3428
|
+
insertData,
|
|
3429
|
+
pluginKey: rule.pluginKey,
|
|
3430
|
+
text,
|
|
3431
|
+
...selectionContext
|
|
3432
|
+
};
|
|
3433
|
+
if (rule.enabled?.(context) === false) continue;
|
|
3434
|
+
if (rule.mimeTypes && rule.mimeTypes.length > 0 && !rule.mimeTypes.some((type) => !!context.data.getData(type))) continue;
|
|
3435
|
+
const match = rule.resolve ? rule.resolve(context) : true;
|
|
3436
|
+
if (match === void 0) continue;
|
|
3437
|
+
if (rule.apply(context, match) !== false) {
|
|
3438
|
+
handled = true;
|
|
3439
|
+
break;
|
|
3440
|
+
}
|
|
3441
|
+
}
|
|
3442
|
+
if (handled) return;
|
|
3443
|
+
insertData(data);
|
|
3444
|
+
},
|
|
3445
|
+
insertText(text, options) {
|
|
3446
|
+
const rules = editor.meta.inputRules.insertText.byTrigger[text] ?? [];
|
|
3447
|
+
const selectionContext = createSelectionContext({ editor });
|
|
3448
|
+
let handled = false;
|
|
3449
|
+
for (const rule of rules) {
|
|
3450
|
+
const context = {
|
|
3451
|
+
cause: "insertText",
|
|
3452
|
+
insertText,
|
|
3453
|
+
options,
|
|
3454
|
+
pluginKey: rule.pluginKey,
|
|
3455
|
+
text,
|
|
3456
|
+
...selectionContext
|
|
3457
|
+
};
|
|
3458
|
+
if (!isTriggerMatch(rule.trigger, context.text)) continue;
|
|
3459
|
+
if (rule.enabled?.(context) === false) continue;
|
|
3460
|
+
const match = rule.resolve ? rule.resolve(context) : true;
|
|
3461
|
+
if (match === void 0) continue;
|
|
3462
|
+
if (rule.apply(context, match) !== false) {
|
|
3463
|
+
handled = true;
|
|
3464
|
+
break;
|
|
3465
|
+
}
|
|
3466
|
+
}
|
|
3467
|
+
if (handled) return;
|
|
3468
|
+
insertText(text, options);
|
|
3469
|
+
}
|
|
3470
|
+
} }));
|
|
3471
|
+
|
|
2640
3472
|
//#endregion
|
|
2641
3473
|
//#region src/lib/plugins/getCorePlugins.ts
|
|
2642
|
-
const getCorePlugins = ({ affinity, chunking, maxLength, nodeId, plugins = [] }) => {
|
|
3474
|
+
const getCorePlugins = ({ affinity, chunking, maxLength, navigationFeedback, nodeId, plugins = [] }) => {
|
|
2643
3475
|
let resolvedNodeId = nodeId;
|
|
2644
3476
|
if (process.env.NODE_ENV === "test" && nodeId === void 0) resolvedNodeId = false;
|
|
2645
3477
|
let corePlugins = [
|
|
2646
3478
|
DebugPlugin,
|
|
2647
3479
|
SlateExtensionPlugin,
|
|
2648
3480
|
DOMPlugin,
|
|
3481
|
+
NavigationFeedbackPlugin.configure({
|
|
3482
|
+
enabled: navigationFeedback !== false,
|
|
3483
|
+
options: typeof navigationFeedback === "boolean" ? void 0 : navigationFeedback
|
|
3484
|
+
}),
|
|
2649
3485
|
HistoryPlugin,
|
|
3486
|
+
InputRulesPlugin,
|
|
2650
3487
|
OverridePlugin,
|
|
2651
3488
|
ParserPlugin,
|
|
2652
3489
|
maxLength ? LengthPlugin.configure({ options: { maxLength } }) : LengthPlugin,
|
|
@@ -2689,7 +3526,7 @@ const getCorePlugins = ({ affinity, chunking, maxLength, nodeId, plugins = [] })
|
|
|
2689
3526
|
* @see {@link usePlateEditor} for a memoized React version.
|
|
2690
3527
|
* @see {@link withPlate} for the React-specific enhancement function.
|
|
2691
3528
|
*/
|
|
2692
|
-
const withSlate = (e, { id, affinity = true, autoSelect, chunking = true, maxLength, nodeId, optionsStoreFactory, plugins = [], readOnly = false, rootPlugin, selection, shouldNormalizeEditor, skipInitialization, userId, value, onReady, ...pluginConfig } = {}) => {
|
|
3529
|
+
const withSlate = (e, { id, affinity = true, autoSelect, chunking = true, maxLength, navigationFeedback, nodeId, optionsStoreFactory, plugins = [], readOnly = false, rootPlugin, selection, shouldNormalizeEditor, skipInitialization, userId, value, onReady, ...pluginConfig } = {}) => {
|
|
2693
3530
|
const editor = e;
|
|
2694
3531
|
editor.id = id ?? editor.id ?? nanoid();
|
|
2695
3532
|
editor.meta.key = editor.meta.key ?? nanoid();
|
|
@@ -2747,6 +3584,7 @@ const withSlate = (e, { id, affinity = true, autoSelect, chunking = true, maxLen
|
|
|
2747
3584
|
affinity,
|
|
2748
3585
|
chunking,
|
|
2749
3586
|
maxLength,
|
|
3587
|
+
navigationFeedback,
|
|
2750
3588
|
nodeId,
|
|
2751
3589
|
plugins
|
|
2752
3590
|
});
|
|
@@ -2819,5 +3657,4 @@ const withSlate = (e, { id, affinity = true, autoSelect, chunking = true, maxLen
|
|
|
2819
3657
|
const createSlateEditor = ({ editor = createEditor(), ...options } = {}) => withSlate(editor, options);
|
|
2820
3658
|
|
|
2821
3659
|
//#endregion
|
|
2822
|
-
export {
|
|
2823
|
-
//# sourceMappingURL=withSlate-1B0SfAWG.js.map
|
|
3660
|
+
export { isHtmlBlockElement as $, defineInputRule as $t, htmlStringToDOMNode as A, isSlatePluginElement as At, htmlBrToNewLine as B, withDeleteRules as Bt, resolveNavigationFeedbackTarget as C, getInjectMatch as Ct, HtmlPlugin as D, isSlateElement as Dt, LengthPlugin as E, isSlateEditor as Et, pipeDeserializeHtmlLeaf as F, applyDeepToNodes as Ft, inferWhiteSpaceRule as G, AstPlugin as Gt, deserializeHtmlNodeChildren as H, BaseParagraphPlugin as Ht, htmlElementToElement as I, OverridePlugin as It, collapseWhiteSpaceText as J, createMarkInputRule as Jt, collapseWhiteSpaceChildren as K, createBlockFenceInputRule as Kt, pipeDeserializeHtmlElement as L, withOverrides as Lt, deserializeHtmlNode as M, isSlateString as Mt, htmlTextNodeToString as N, isSlateText as Nt, parseHtmlDocument as O, isSlateLeaf as Ot, htmlElementToLeaf as P, isSlateVoid as Pt, collapseString as Q, matchDelimitedInline as Qt, pluginDeserializeHtml as R, withNormalizeRules as Rt, flashTarget as S, getInjectedPlugins as St, NavigationFeedbackPluginKey as T, getSlateElements as Tt, collapseWhiteSpace as U, HistoryPlugin as Ut, htmlBodyToFragment as V, withBreakRules as Vt, collapseWhiteSpaceElement as W, withPlateHistory as Wt, upsertInlineFormattingContext as X, matchBlockFence as Xt, endInlineFormattingContext as Y, createTextSubstitutionInputRule as Yt, isLastNonEmptyTextOfInlineFormattingContext as Z, matchBlockStart as Zt, normalizeNodeId as _, mergeDeepToNodes as _t, pipeInsertDataQuery as a, getPluginTypes as an, DOMPlugin as at, navigate as b, getNodeDataAttributeKeys as bt, setValue as c, createSlatePlugin as cn, PlateError as ct, insertExitBreak as d, AffinityPlugin as dt, getContainerTypes as en, isHtmlInlineElement as et, init as f, setAffinitySelection as ft, NodeIdPlugin as g, getEdgeNodes as gt, pipeOnNodeChange as h, getMarkBoundaryAffinity as ht, ParserPlugin as i, getPluginType as in, AUTO_SCROLL as it, deserializeHtmlElement as j, isSlatePluginNode as jt, deserializeHtml as k, isSlateNode as kt, resetBlock as l, createTSlatePlugin as ln, ChunkingPlugin as lt, pipeOnTextChange as m, isNodesAffinity as mt, withSlate as n, getPluginKey as nn, isHtmlText as nt, normalizeDescendantsToDocumentFragment as o, getSlatePlugin as on, withScrolling as ot, isEditOnly as p, isNodeAffinity as pt, collapseWhiteSpaceNode as q, createBlockStartInputRule as qt, getCorePlugins as r, getPluginKeys as rn, isHtmlElement as rt, SlateExtensionPlugin as s, getEditorPlugin as sn, DebugPlugin as st, createSlateEditor as t, getPluginByType as tn, inlineTagNames as tt, liftBlock as u, withChunking as ut, withNodeId as v, getSlateClass as vt, NAVIGATION_FEEDBACK_KEY as w, defaultsDeepToNodes as wt, clearNavigationFeedbackTarget as x, keyToDataAttribute as xt, NavigationFeedbackPlugin as y, getPluginNodeProps as yt, getDataNodeProps as z, withMergeRules as zt };
|