@harbour-enterprises/superdoc 0.8.10 → 0.8.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/chunks/{super-editor.es-CnpejCPC.js → super-editor.es-D8IC7SPE.js} +719 -375
  2. package/dist/chunks/super-editor.es-D8IC7SPE.js.map +1 -0
  3. package/dist/super-editor/chunks/{converter-B5SRaBp5.js → converter-vMwuPcFT.js} +28 -27
  4. package/dist/super-editor/chunks/converter-vMwuPcFT.js.map +1 -0
  5. package/dist/super-editor/chunks/{docx-zipper-fdMcchlI.js → docx-zipper-CNguQWs9.js} +2 -2
  6. package/dist/super-editor/chunks/{docx-zipper-fdMcchlI.js.map → docx-zipper-CNguQWs9.js.map} +1 -1
  7. package/dist/super-editor/chunks/{editor-nlt5JeOJ.js → editor-aREw3zbp.js} +764 -420
  8. package/dist/super-editor/chunks/editor-aREw3zbp.js.map +1 -0
  9. package/dist/super-editor/chunks/{toolbar-COfngBDY.js → toolbar-BQJNZhd8.js} +3 -3
  10. package/dist/super-editor/chunks/{toolbar-COfngBDY.js.map → toolbar-BQJNZhd8.js.map} +1 -1
  11. package/dist/super-editor/converter.es.js +2 -2
  12. package/dist/super-editor/core/Editor.d.ts +1 -0
  13. package/dist/super-editor/core/Editor.d.ts.map +1 -1
  14. package/dist/super-editor/core/ExtensionService.d.ts.map +1 -1
  15. package/dist/super-editor/core/InputRule.d.ts +11 -0
  16. package/dist/super-editor/core/InputRule.d.ts.map +1 -0
  17. package/dist/super-editor/core/commands/index.d.ts +1 -0
  18. package/dist/super-editor/core/commands/undoInputRule.d.ts +5 -0
  19. package/dist/super-editor/core/commands/undoInputRule.d.ts.map +1 -0
  20. package/dist/super-editor/core/extensions/keymap.d.ts.map +1 -1
  21. package/dist/super-editor/core/helpers/getHTMLFromFragment.d.ts +2 -0
  22. package/dist/super-editor/core/helpers/getHTMLFromFragment.d.ts.map +1 -0
  23. package/dist/super-editor/core/helpers/getTextContentFromNodes.d.ts +2 -0
  24. package/dist/super-editor/core/helpers/getTextContentFromNodes.d.ts.map +1 -0
  25. package/dist/super-editor/core/helpers/isExtentionRulesEnabled.d.ts +2 -0
  26. package/dist/super-editor/core/helpers/isExtentionRulesEnabled.d.ts.map +1 -0
  27. package/dist/super-editor/core/inputRules/wrappingInputRule.d.ts +9 -0
  28. package/dist/super-editor/core/inputRules/wrappingInputRule.d.ts.map +1 -0
  29. package/dist/super-editor/core/utilities/isRegExp.d.ts +2 -0
  30. package/dist/super-editor/core/utilities/isRegExp.d.ts.map +1 -0
  31. package/dist/super-editor/core/utilities/objectIncludes.d.ts.map +1 -1
  32. package/dist/super-editor/docx-zipper.es.js +2 -2
  33. package/dist/super-editor/editor.es.js +3 -3
  34. package/dist/super-editor/extensions/bullet-list/bullet-list.d.ts.map +1 -1
  35. package/dist/super-editor/extensions/comment/comments-plugin.d.ts.map +1 -1
  36. package/dist/super-editor/extensions/ordered-list/ordered-list.d.ts.map +1 -1
  37. package/dist/super-editor/extensions/track-changes/trackChangesHelpers/addMarkStep.d.ts.map +1 -1
  38. package/dist/super-editor/extensions/track-changes/trackChangesHelpers/removeMarkStep.d.ts.map +1 -1
  39. package/dist/super-editor/extensions/track-changes/trackChangesHelpers/replaceStep.d.ts.map +1 -1
  40. package/dist/super-editor/file-zipper.es.js +1 -1
  41. package/dist/super-editor/super-editor.es.js +7 -7
  42. package/dist/super-editor/toolbar.es.js +2 -2
  43. package/dist/super-editor.es.js +1 -1
  44. package/dist/superdoc.es.js +3 -3
  45. package/dist/superdoc.umd.js +730 -386
  46. package/dist/superdoc.umd.js.map +1 -1
  47. package/package.json +1 -1
  48. package/dist/chunks/super-editor.es-CnpejCPC.js.map +0 -1
  49. package/dist/super-editor/chunks/converter-B5SRaBp5.js.map +0 -1
  50. package/dist/super-editor/chunks/editor-nlt5JeOJ.js.map +0 -1
@@ -19161,7 +19161,7 @@ const isPropertiesElement = (element) => {
19161
19161
  };
19162
19162
  function hasTextNode(elements) {
19163
19163
  const runs = elements.filter((el) => el.name === "w:r");
19164
- const runsHaveText = runs.some((run) => run.elements.some((el) => el.name === "w:t"));
19164
+ const runsHaveText = runs.some((run2) => run2.elements.some((el) => el.name === "w:t"));
19165
19165
  return runsHaveText;
19166
19166
  }
19167
19167
  const handleTrackChangeNode = (params2) => {
@@ -20060,8 +20060,8 @@ const handleAnnotationNode = (params2) => {
20060
20060
  };
20061
20061
  };
20062
20062
  const parseAnnotationMarks = (content = {}) => {
20063
- const run = content.elements?.find((el) => el.name === "w:r");
20064
- const rPr = run?.elements?.find((el) => el.name === "w:rPr");
20063
+ const run2 = content.elements?.find((el) => el.name === "w:r");
20064
+ const rPr = run2?.elements?.find((el) => el.name === "w:rPr");
20065
20065
  if (!rPr) return {};
20066
20066
  const unknownMarks = [];
20067
20067
  const marks = parseMarks(rPr, unknownMarks) || [];
@@ -20664,7 +20664,7 @@ const _SuperConverter = class _SuperConverter2 {
20664
20664
  return;
20665
20665
  }
20666
20666
  }
20667
- static updateDocumentVersion(docx = this.convertedXml, version = "0.8.10") {
20667
+ static updateDocumentVersion(docx = this.convertedXml, version = "0.8.12") {
20668
20668
  const customLocation = "docProps/custom.xml";
20669
20669
  if (!docx[customLocation]) {
20670
20670
  docx[customLocation] = generateCustomXml();
@@ -20937,7 +20937,7 @@ function storeSuperdocVersion(docx) {
20937
20937
  function generateCustomXml() {
20938
20938
  return DEFAULT_CUSTOM_XML;
20939
20939
  }
20940
- function generateSuperdocVersion(pid = 2, version = "0.8.10") {
20940
+ function generateSuperdocVersion(pid = 2, version = "0.8.12") {
20941
20941
  return {
20942
20942
  type: "element",
20943
20943
  name: "property",
@@ -31398,6 +31398,357 @@ let Schema2 = _Schema;
31398
31398
  function getSchemaTypeByName(name, schema) {
31399
31399
  return schema.nodes[name] || schema.marks[name] || null;
31400
31400
  }
31401
+ function isExtensionRulesEnabled(extension, enabled) {
31402
+ if (Array.isArray(enabled)) {
31403
+ return enabled.some((enabledExtension) => {
31404
+ const name = typeof enabledExtension === "string" ? enabledExtension : enabledExtension.name;
31405
+ return name === extension.name;
31406
+ });
31407
+ }
31408
+ return enabled;
31409
+ }
31410
+ function chainableEditorState(transaction, state2) {
31411
+ let { selection, doc: doc2, storedMarks } = transaction;
31412
+ return {
31413
+ ...state2,
31414
+ apply: state2.apply.bind(state2),
31415
+ applyTransaction: state2.applyTransaction.bind(state2),
31416
+ plugins: state2.plugins,
31417
+ schema: state2.schema,
31418
+ reconfigure: state2.reconfigure.bind(state2),
31419
+ toJSON: state2.toJSON.bind(state2),
31420
+ get storedMarks() {
31421
+ return storedMarks;
31422
+ },
31423
+ get selection() {
31424
+ return selection;
31425
+ },
31426
+ get doc() {
31427
+ return doc2;
31428
+ },
31429
+ get tr() {
31430
+ selection = transaction.selection;
31431
+ doc2 = transaction.doc;
31432
+ storedMarks = transaction.storedMarks;
31433
+ return transaction;
31434
+ }
31435
+ };
31436
+ }
31437
+ class CommandService {
31438
+ constructor(props) {
31439
+ __publicField$1(this, "editor");
31440
+ __publicField$1(this, "rawCommands");
31441
+ this.editor = props.editor;
31442
+ this.rawCommands = this.editor.extensionService.commands;
31443
+ }
31444
+ /**
31445
+ * Static method for creating a service.
31446
+ * @param args Arguments for the constructor.
31447
+ */
31448
+ static create(...args) {
31449
+ return new CommandService(...args);
31450
+ }
31451
+ /**
31452
+ * Get editor state.
31453
+ */
31454
+ get state() {
31455
+ return this.editor.state;
31456
+ }
31457
+ /**
31458
+ * Get all commands with wrapped command method.
31459
+ */
31460
+ get commands() {
31461
+ const { editor, state: state2 } = this;
31462
+ const { view } = editor;
31463
+ const { tr } = state2;
31464
+ const props = this.createProps(tr);
31465
+ const entries = Object.entries(this.rawCommands).map(([name, command2]) => {
31466
+ const method = (...args) => {
31467
+ const fn2 = command2(...args)(props);
31468
+ if (!tr.getMeta("preventDispatch")) {
31469
+ view.dispatch(tr);
31470
+ }
31471
+ return fn2;
31472
+ };
31473
+ return [name, method];
31474
+ });
31475
+ return Object.fromEntries(entries);
31476
+ }
31477
+ /**
31478
+ * Create a chain of commands to call multiple commands at once.
31479
+ */
31480
+ get chain() {
31481
+ return () => this.createChain();
31482
+ }
31483
+ /**
31484
+ * Check if a command or a chain of commands can be executed. Without executing it.
31485
+ */
31486
+ get can() {
31487
+ return () => this.createCan();
31488
+ }
31489
+ /**
31490
+ * Creates a chain of commands.
31491
+ * @param startTr Start transaction.
31492
+ * @param shouldDispatch Should dispatch or not.
31493
+ */
31494
+ createChain(startTr, shouldDispatch = true) {
31495
+ const { editor, state: state2, rawCommands } = this;
31496
+ const { view } = editor;
31497
+ const callbacks2 = [];
31498
+ const hasStartTr = !!startTr;
31499
+ const tr = startTr || state2.tr;
31500
+ const run2 = () => {
31501
+ if (!hasStartTr && shouldDispatch && !tr.getMeta("preventDispatch")) {
31502
+ view.dispatch(tr);
31503
+ }
31504
+ return callbacks2.every((cb) => cb === true);
31505
+ };
31506
+ const entries = Object.entries(rawCommands).map(([name, command2]) => {
31507
+ const chainedCommand = (...args) => {
31508
+ const props = this.createProps(tr, shouldDispatch);
31509
+ const callback = command2(...args)(props);
31510
+ callbacks2.push(callback);
31511
+ return chain;
31512
+ };
31513
+ return [name, chainedCommand];
31514
+ });
31515
+ const chain = {
31516
+ ...Object.fromEntries(entries),
31517
+ run: run2
31518
+ };
31519
+ return chain;
31520
+ }
31521
+ /**
31522
+ * Creates a can check for commands.
31523
+ * @param startTr Start transaction.
31524
+ */
31525
+ createCan(startTr) {
31526
+ const { rawCommands, state: state2 } = this;
31527
+ const dispatch = false;
31528
+ const tr = startTr || state2.tr;
31529
+ const props = this.createProps(tr, dispatch);
31530
+ const commands2 = Object.fromEntries(
31531
+ Object.entries(rawCommands).map(([name, command2]) => {
31532
+ return [name, (...args) => command2(...args)({ ...props, dispatch: void 0 })];
31533
+ })
31534
+ );
31535
+ return {
31536
+ ...commands2,
31537
+ chain: () => this.createChain(tr, dispatch)
31538
+ };
31539
+ }
31540
+ /**
31541
+ * Creates default props for the command method.
31542
+ * @param {*} tr Transaction.
31543
+ * @param {*} shouldDispatch Check if should dispatch.
31544
+ * @returns Object with props.
31545
+ */
31546
+ createProps(tr, shouldDispatch = true) {
31547
+ const { editor, state: state2, rawCommands } = this;
31548
+ const { view } = editor;
31549
+ const props = {
31550
+ tr,
31551
+ editor,
31552
+ view,
31553
+ state: chainableEditorState(tr, state2),
31554
+ dispatch: shouldDispatch ? () => void 0 : void 0,
31555
+ chain: () => this.createChain(tr, shouldDispatch),
31556
+ can: () => this.createCan(tr),
31557
+ get commands() {
31558
+ return Object.fromEntries(
31559
+ Object.entries(rawCommands).map(([name, command2]) => {
31560
+ return [name, (...args) => command2(...args)(props)];
31561
+ })
31562
+ );
31563
+ }
31564
+ };
31565
+ return props;
31566
+ }
31567
+ }
31568
+ function getHTMLFromFragment(fragment, schema) {
31569
+ const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment);
31570
+ const temporaryDocument = document.implementation.createHTMLDocument();
31571
+ const container = temporaryDocument.createElement("div");
31572
+ container.appendChild(documentFragment);
31573
+ return container.innerHTML;
31574
+ }
31575
+ const getTextContentFromNodes = ($from, maxMatch = 500) => {
31576
+ let textBefore = "";
31577
+ const sliceEndPos = $from.parentOffset;
31578
+ $from.parent.nodesBetween(
31579
+ Math.max(0, sliceEndPos - maxMatch),
31580
+ sliceEndPos,
31581
+ (node2, pos, parent, index2) => {
31582
+ const chunk = node2.type.spec.toText?.({
31583
+ node: node2,
31584
+ pos,
31585
+ parent,
31586
+ index: index2
31587
+ }) || node2.textContent || "%leaf%";
31588
+ textBefore += node2.isAtom && !node2.isText ? chunk : chunk.slice(0, Math.max(0, sliceEndPos - pos));
31589
+ }
31590
+ );
31591
+ return textBefore;
31592
+ };
31593
+ class InputRule {
31594
+ constructor(config) {
31595
+ __publicField$1(this, "match");
31596
+ __publicField$1(this, "handler");
31597
+ this.match = config.match;
31598
+ this.handler = config.handler;
31599
+ }
31600
+ }
31601
+ const inputRuleMatcherHandler = (text, match) => {
31602
+ if (isRegExp(match)) {
31603
+ return match.exec(text);
31604
+ }
31605
+ const inputRuleMatch = match(text);
31606
+ if (!inputRuleMatch) {
31607
+ return null;
31608
+ }
31609
+ const result = [inputRuleMatch.text];
31610
+ result.index = inputRuleMatch.index;
31611
+ result.input = text;
31612
+ result.data = inputRuleMatch.data;
31613
+ if (inputRuleMatch.replaceWith) {
31614
+ if (!inputRuleMatch.text.includes(inputRuleMatch.replaceWith)) {
31615
+ console.warn(
31616
+ '[super-editor warn]: "inputRuleMatch.replaceWith" must be part of "inputRuleMatch.text".'
31617
+ );
31618
+ }
31619
+ result.push(inputRuleMatch.replaceWith);
31620
+ }
31621
+ return result;
31622
+ };
31623
+ const run = (config) => {
31624
+ const {
31625
+ editor,
31626
+ from: from2,
31627
+ to,
31628
+ text,
31629
+ rules,
31630
+ plugin: plugin2
31631
+ } = config;
31632
+ const { view } = editor;
31633
+ if (view.composing) {
31634
+ return false;
31635
+ }
31636
+ const $from = view.state.doc.resolve(from2);
31637
+ if ($from.parent.type.spec.code || !!($from.nodeBefore || $from.nodeAfter)?.marks.find((mark) => mark.type.spec.code)) {
31638
+ return false;
31639
+ }
31640
+ let matched = false;
31641
+ const textBefore = getTextContentFromNodes($from) + text;
31642
+ rules.forEach((rule) => {
31643
+ if (matched) {
31644
+ return;
31645
+ }
31646
+ const match = inputRuleMatcherHandler(textBefore, rule.match);
31647
+ if (!match) {
31648
+ return;
31649
+ }
31650
+ const tr = view.state.tr;
31651
+ const state2 = chainableEditorState(tr, view.state);
31652
+ const range2 = {
31653
+ from: from2 - (match[0].length - text.length),
31654
+ to
31655
+ };
31656
+ const { commands: commands2, chain, can } = new CommandService({
31657
+ editor,
31658
+ state: state2
31659
+ });
31660
+ const handler = rule.handler({
31661
+ state: state2,
31662
+ range: range2,
31663
+ match,
31664
+ commands: commands2,
31665
+ chain,
31666
+ can
31667
+ });
31668
+ if (handler === null || !tr.steps.length) {
31669
+ return;
31670
+ }
31671
+ tr.setMeta(plugin2, {
31672
+ transform: tr,
31673
+ from: from2,
31674
+ to,
31675
+ text
31676
+ });
31677
+ view.dispatch(tr);
31678
+ matched = true;
31679
+ });
31680
+ return matched;
31681
+ };
31682
+ const inputRulesPlugin = ({ editor, rules }) => {
31683
+ const plugin2 = new Plugin({
31684
+ key: new PluginKey("inputRulesPlugin"),
31685
+ state: {
31686
+ init() {
31687
+ return null;
31688
+ },
31689
+ apply(tr, prev, state2) {
31690
+ const stored = tr.getMeta(plugin2);
31691
+ if (stored) {
31692
+ return stored;
31693
+ }
31694
+ const simulatedInputMeta = tr.getMeta("applyInputRules");
31695
+ const isSimulatedInput = !!simulatedInputMeta;
31696
+ if (isSimulatedInput) {
31697
+ setTimeout(() => {
31698
+ let { text } = simulatedInputMeta;
31699
+ if (typeof text !== "string") {
31700
+ text = getHTMLFromFragment(Fragment.from(text), state2.schema);
31701
+ }
31702
+ const { from: from2 } = simulatedInputMeta;
31703
+ const to = from2 + text.length;
31704
+ run({
31705
+ editor,
31706
+ from: from2,
31707
+ to,
31708
+ text,
31709
+ rules,
31710
+ plugin: plugin2
31711
+ });
31712
+ });
31713
+ }
31714
+ return tr.selectionSet || tr.docChanged ? null : prev;
31715
+ }
31716
+ },
31717
+ props: {
31718
+ handleTextInput(view, from2, to, text) {
31719
+ return run({
31720
+ editor,
31721
+ from: from2,
31722
+ to,
31723
+ text,
31724
+ rules,
31725
+ plugin: plugin2
31726
+ });
31727
+ },
31728
+ // add support for input rules to trigger on enter
31729
+ // this is useful for example for code blocks
31730
+ handleKeyDown(view, event) {
31731
+ if (event.key !== "Enter") {
31732
+ return false;
31733
+ }
31734
+ const { $cursor } = view.state.selection;
31735
+ if ($cursor) {
31736
+ return run({
31737
+ editor,
31738
+ from: $cursor.pos,
31739
+ to: $cursor.pos,
31740
+ text: "\n",
31741
+ rules,
31742
+ plugin: plugin2
31743
+ });
31744
+ }
31745
+ return false;
31746
+ }
31747
+ },
31748
+ isInputRules: true
31749
+ });
31750
+ return plugin2;
31751
+ };
31401
31752
  const _ExtensionService = class _ExtensionService2 {
31402
31753
  constructor(extensions, userExtensions, editor) {
31403
31754
  __privateAdd$1(this, _ExtensionService_instances);
@@ -31482,6 +31833,7 @@ const _ExtensionService = class _ExtensionService2 {
31482
31833
  get plugins() {
31483
31834
  const editor = this.editor;
31484
31835
  const extensions = _ExtensionService2.sortByPriority([...this.extensions].reverse());
31836
+ const inputRules = [];
31485
31837
  const allPlugins = extensions.map((extension) => {
31486
31838
  const context = {
31487
31839
  name: extension.name,
@@ -31500,6 +31852,10 @@ const _ExtensionService = class _ExtensionService2 {
31500
31852
  bindingsObject = { ...Object.fromEntries(entries) };
31501
31853
  }
31502
31854
  plugins.push(keymap(bindingsObject));
31855
+ const addInputRules = getExtensionConfigField(extension, "addInputRules", context);
31856
+ if (isExtensionRulesEnabled(extension, editor.options.enableInputRules) && addInputRules) {
31857
+ inputRules.push(...addInputRules());
31858
+ }
31503
31859
  const addPmPlugins = getExtensionConfigField(extension, "addPmPlugins", context);
31504
31860
  if (addPmPlugins) {
31505
31861
  const pmPlugins = addPmPlugins();
@@ -31507,7 +31863,13 @@ const _ExtensionService = class _ExtensionService2 {
31507
31863
  }
31508
31864
  return plugins;
31509
31865
  }).flat();
31510
- return [...allPlugins];
31866
+ return [
31867
+ inputRulesPlugin({
31868
+ editor,
31869
+ rules: inputRules
31870
+ }),
31871
+ ...allPlugins
31872
+ ];
31511
31873
  }
31512
31874
  /**
31513
31875
  * Get all node views from the extensions.
@@ -31589,164 +31951,6 @@ attachEditorEvents_fn = function(extension) {
31589
31951
  if (onDestroy2) this.editor.on("destroy", onDestroy2);
31590
31952
  };
31591
31953
  let ExtensionService = _ExtensionService;
31592
- function chainableEditorState(transaction, state2) {
31593
- let { selection, doc: doc2, storedMarks } = transaction;
31594
- return {
31595
- ...state2,
31596
- apply: state2.apply.bind(state2),
31597
- applyTransaction: state2.applyTransaction.bind(state2),
31598
- plugins: state2.plugins,
31599
- schema: state2.schema,
31600
- reconfigure: state2.reconfigure.bind(state2),
31601
- toJSON: state2.toJSON.bind(state2),
31602
- get storedMarks() {
31603
- return storedMarks;
31604
- },
31605
- get selection() {
31606
- return selection;
31607
- },
31608
- get doc() {
31609
- return doc2;
31610
- },
31611
- get tr() {
31612
- selection = transaction.selection;
31613
- doc2 = transaction.doc;
31614
- storedMarks = transaction.storedMarks;
31615
- return transaction;
31616
- }
31617
- };
31618
- }
31619
- class CommandService {
31620
- constructor(props) {
31621
- __publicField$1(this, "editor");
31622
- __publicField$1(this, "rawCommands");
31623
- this.editor = props.editor;
31624
- this.rawCommands = this.editor.extensionService.commands;
31625
- }
31626
- /**
31627
- * Static method for creating a service.
31628
- * @param args Arguments for the constructor.
31629
- */
31630
- static create(...args) {
31631
- return new CommandService(...args);
31632
- }
31633
- /**
31634
- * Get editor state.
31635
- */
31636
- get state() {
31637
- return this.editor.state;
31638
- }
31639
- /**
31640
- * Get all commands with wrapped command method.
31641
- */
31642
- get commands() {
31643
- const { editor, state: state2 } = this;
31644
- const { view } = editor;
31645
- const { tr } = state2;
31646
- const props = this.createProps(tr);
31647
- const entries = Object.entries(this.rawCommands).map(([name, command2]) => {
31648
- const method = (...args) => {
31649
- const fn2 = command2(...args)(props);
31650
- if (!tr.getMeta("preventDispatch")) {
31651
- view.dispatch(tr);
31652
- }
31653
- return fn2;
31654
- };
31655
- return [name, method];
31656
- });
31657
- return Object.fromEntries(entries);
31658
- }
31659
- /**
31660
- * Create a chain of commands to call multiple commands at once.
31661
- */
31662
- get chain() {
31663
- return () => this.createChain();
31664
- }
31665
- /**
31666
- * Check if a command or a chain of commands can be executed. Without executing it.
31667
- */
31668
- get can() {
31669
- return () => this.createCan();
31670
- }
31671
- /**
31672
- * Creates a chain of commands.
31673
- * @param startTr Start transaction.
31674
- * @param shouldDispatch Should dispatch or not.
31675
- */
31676
- createChain(startTr, shouldDispatch = true) {
31677
- const { editor, state: state2, rawCommands } = this;
31678
- const { view } = editor;
31679
- const callbacks2 = [];
31680
- const hasStartTr = !!startTr;
31681
- const tr = startTr || state2.tr;
31682
- const run = () => {
31683
- if (!hasStartTr && shouldDispatch && !tr.getMeta("preventDispatch")) {
31684
- view.dispatch(tr);
31685
- }
31686
- return callbacks2.every((cb) => cb === true);
31687
- };
31688
- const entries = Object.entries(rawCommands).map(([name, command2]) => {
31689
- const chainedCommand = (...args) => {
31690
- const props = this.createProps(tr, shouldDispatch);
31691
- const callback = command2(...args)(props);
31692
- callbacks2.push(callback);
31693
- return chain;
31694
- };
31695
- return [name, chainedCommand];
31696
- });
31697
- const chain = {
31698
- ...Object.fromEntries(entries),
31699
- run
31700
- };
31701
- return chain;
31702
- }
31703
- /**
31704
- * Creates a can check for commands.
31705
- * @param startTr Start transaction.
31706
- */
31707
- createCan(startTr) {
31708
- const { rawCommands, state: state2 } = this;
31709
- const dispatch = false;
31710
- const tr = startTr || state2.tr;
31711
- const props = this.createProps(tr, dispatch);
31712
- const commands2 = Object.fromEntries(
31713
- Object.entries(rawCommands).map(([name, command2]) => {
31714
- return [name, (...args) => command2(...args)({ ...props, dispatch: void 0 })];
31715
- })
31716
- );
31717
- return {
31718
- ...commands2,
31719
- chain: () => this.createChain(tr, dispatch)
31720
- };
31721
- }
31722
- /**
31723
- * Creates default props for the command method.
31724
- * @param {*} tr Transaction.
31725
- * @param {*} shouldDispatch Check if should dispatch.
31726
- * @returns Object with props.
31727
- */
31728
- createProps(tr, shouldDispatch = true) {
31729
- const { editor, state: state2, rawCommands } = this;
31730
- const { view } = editor;
31731
- const props = {
31732
- tr,
31733
- editor,
31734
- view,
31735
- state: chainableEditorState(tr, state2),
31736
- dispatch: shouldDispatch ? () => void 0 : void 0,
31737
- chain: () => this.createChain(tr, shouldDispatch),
31738
- can: () => this.createCan(tr),
31739
- get commands() {
31740
- return Object.fromEntries(
31741
- Object.entries(rawCommands).map(([name, command2]) => {
31742
- return [name, (...args) => command2(...args)(props)];
31743
- })
31744
- );
31745
- }
31746
- };
31747
- return props;
31748
- }
31749
- }
31750
31954
  const first = (commands2) => (props) => {
31751
31955
  const items = typeof commands2 === "function" ? commands2(props) : commands2;
31752
31956
  for (let i = 0; i < items.length; i += 1) {
@@ -32783,6 +32987,30 @@ const insertContentAt = (position, value, options2) => ({ tr, dispatch, editor }
32783
32987
  }
32784
32988
  return true;
32785
32989
  };
32990
+ const undoInputRule = () => ({ state: state2, dispatch }) => {
32991
+ const plugins = state2.plugins;
32992
+ for (let i = 0; i < plugins.length; i += 1) {
32993
+ const plugin2 = plugins[i];
32994
+ let undoable;
32995
+ if (plugin2.spec.isInputRules && (undoable = plugin2.getState(state2))) {
32996
+ if (dispatch) {
32997
+ const tr = state2.tr;
32998
+ const toUndo = undoable.transform;
32999
+ for (let j = toUndo.steps.length - 1; j >= 0; j -= 1) {
33000
+ tr.step(toUndo.steps[j].invert(toUndo.docs[j]));
33001
+ }
33002
+ if (undoable.text) {
33003
+ const marks = tr.doc.resolve(undoable.from).marks();
33004
+ tr.replaceWith(undoable.from, undoable.to, state2.schema.text(undoable.text, marks));
33005
+ } else {
33006
+ tr.delete(undoable.from, undoable.to);
33007
+ }
33008
+ }
33009
+ return true;
33010
+ }
33011
+ }
33012
+ return false;
33013
+ };
32786
33014
  function wrapInList$1(listType, attrs = null) {
32787
33015
  return function(state2, dispatch) {
32788
33016
  let { $from, $to } = state2.selection;
@@ -33112,6 +33340,7 @@ const commands = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
33112
33340
  toggleList,
33113
33341
  toggleMark,
33114
33342
  toggleNode,
33343
+ undoInputRule,
33115
33344
  unsetAllMarks,
33116
33345
  unsetMark,
33117
33346
  updateAttributes,
@@ -33141,6 +33370,7 @@ const Keymap = Extension.create({
33141
33370
  () => commands2.splitBlock()
33142
33371
  ]);
33143
33372
  const handleBackspace = () => this.editor.commands.first(({ commands: commands2, tr }) => [
33373
+ () => commands2.undoInputRule(),
33144
33374
  () => {
33145
33375
  tr.setMeta("inputType", "deleteContentBackward");
33146
33376
  return false;
@@ -33756,199 +33986,6 @@ const getTrackChangesDecorations = (state2, onlyOriginalShown, onlyModifiedShown
33756
33986
  });
33757
33987
  return DecorationSet.create(state2.doc, decorations);
33758
33988
  };
33759
- const replaceStep = ({ state: state2, tr, step, newTr, map: map22, doc: doc2, user, date, originalStep, originalStepIndex }) => {
33760
- const deletionMarkSchema = state2.schema.marks[TrackDeleteMarkName];
33761
- const deletionMark = findMark(state2, deletionMarkSchema, false);
33762
- const positionTo = deletionMark ? deletionMark.to : step.to;
33763
- const newStep = new ReplaceStep(
33764
- positionTo,
33765
- // We insert all the same steps, but with "from"/"to" both set to "to" in order not to delete content. Mapped as needed.
33766
- positionTo,
33767
- step.slice,
33768
- step.structure
33769
- );
33770
- const invertStep = originalStep.invert(tr.docs[originalStepIndex]).map(map22);
33771
- map22.appendMap(invertStep.getMap());
33772
- const meta = {};
33773
- if (newStep) {
33774
- const trTemp = state2.apply(newTr).tr;
33775
- if (trTemp.maybeStep(newStep).failed) {
33776
- return;
33777
- }
33778
- const mappedNewStepTo = newStep.getMap().map(newStep.to);
33779
- const insertedMark = markInsertion({
33780
- tr: trTemp,
33781
- from: newStep.from,
33782
- to: mappedNewStepTo,
33783
- user,
33784
- date
33785
- });
33786
- const condensedStep = new ReplaceStep(newStep.from, newStep.to, trTemp.doc.slice(newStep.from, mappedNewStepTo));
33787
- newTr.step(condensedStep);
33788
- const mirrorIndex = map22.maps.length - 1;
33789
- map22.appendMap(condensedStep.getMap(), mirrorIndex);
33790
- if (newStep.from !== mappedNewStepTo) {
33791
- meta.insertedMark = insertedMark;
33792
- meta.step = condensedStep;
33793
- }
33794
- if (!newTr.selection.eq(trTemp.selection)) {
33795
- newTr.setSelection(trTemp.selection);
33796
- }
33797
- }
33798
- if (step.from !== step.to) {
33799
- const { deletionMark: deletionMark2, deletionMap, nodes: deletionNodes } = markDeletion({
33800
- tr: newTr,
33801
- from: step.from,
33802
- to: step.to,
33803
- user,
33804
- date
33805
- });
33806
- meta.deletionNodes = deletionNodes;
33807
- meta.deletionMark = deletionMark2;
33808
- map22.appendMapping(deletionMap);
33809
- }
33810
- newTr.setMeta(TrackChangesBasePluginKey, meta);
33811
- };
33812
- const markWrapping = () => {
33813
- };
33814
- const replaceAroundStep = () => {
33815
- };
33816
- const addMarkStep = ({ state: state2, tr, step, newTr, map: map22, doc: doc2, user, date }) => {
33817
- const meta = {};
33818
- doc2.nodesBetween(step.from, step.to, (node2, pos) => {
33819
- if (!node2.isInline) {
33820
- return;
33821
- }
33822
- if (node2.marks.find((mark) => mark.type.name === TrackDeleteMarkName)) {
33823
- return false;
33824
- }
33825
- const existingChangeMark = node2.marks.find((mark) => [TrackDeleteMarkName, TrackFormatMarkName].includes(mark.type.name));
33826
- const wid = existingChangeMark ? existingChangeMark.attrs.id : v4();
33827
- newTr.addMark(Math.max(step.from, pos), Math.min(step.to, pos + node2.nodeSize), step.mark);
33828
- const allowedMarks = ["bold", "italic", "strike", "underline", "textStyle"];
33829
- if (allowedMarks.includes(step.mark.type.name) && !node2.marks.find((mark) => mark.type === step.mark.type)) {
33830
- const formatChangeMark = node2.marks.find((mark) => mark.type.name === TrackFormatMarkName);
33831
- let after = [];
33832
- let before = [];
33833
- if (formatChangeMark) {
33834
- let foundBefore = formatChangeMark.attrs.before.find((mark) => {
33835
- if (mark.type === "textStyle") {
33836
- return mark.type === step.mark.type.name && objectIncludes(mark.attrs, step.mark.attrs);
33837
- }
33838
- return mark.type === step.mark.type.name;
33839
- });
33840
- if (foundBefore) {
33841
- before = [...formatChangeMark.attrs.before.filter((mark) => mark.type !== step.mark.type.name)];
33842
- after = [...formatChangeMark.attrs.after];
33843
- } else {
33844
- before = [...formatChangeMark.attrs.before];
33845
- after = [
33846
- ...formatChangeMark.attrs.after,
33847
- {
33848
- type: step.mark.type.name,
33849
- attrs: { ...step.mark.attrs }
33850
- }
33851
- ];
33852
- }
33853
- } else {
33854
- before = node2.marks.map((mark) => ({
33855
- type: mark.type.name,
33856
- attrs: { ...mark.attrs }
33857
- }));
33858
- after = [
33859
- {
33860
- type: step.mark.type.name,
33861
- attrs: { ...step.mark.attrs }
33862
- }
33863
- ];
33864
- }
33865
- if (after.length || before.length) {
33866
- const newFormatMark = state2.schema.marks[TrackFormatMarkName].create({
33867
- id: wid,
33868
- author: user.name,
33869
- authorEmail: user.email,
33870
- date,
33871
- before,
33872
- after
33873
- });
33874
- newTr.addMark(
33875
- step.from,
33876
- // Math.max(step.from, pos)
33877
- step.to,
33878
- // Math.min(step.to, pos + node.nodeSize),
33879
- newFormatMark
33880
- );
33881
- meta.formatMark = newFormatMark;
33882
- meta.step = step;
33883
- newTr.setMeta(TrackChangesBasePluginKey, meta);
33884
- } else if (formatChangeMark) {
33885
- newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node2.nodeSize), formatChangeMark);
33886
- }
33887
- }
33888
- });
33889
- };
33890
- const removeMarkStep = ({ state: state2, tr, step, newTr, map: map22, doc: doc2, user, date }) => {
33891
- const meta = {};
33892
- doc2.nodesBetween(step.from, step.to, (node2, pos) => {
33893
- if (!node2.isInline) {
33894
- return true;
33895
- }
33896
- if (node2.marks.find((mark) => mark.type.name === TrackDeleteMarkName)) {
33897
- return false;
33898
- }
33899
- newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node2.nodeSize), step.mark);
33900
- const allowedMarks = ["bold", "italic", "strike", "underline", "textStyle"];
33901
- if (allowedMarks.includes(step.mark.type.name) && node2.marks.find((mark) => mark.type === step.mark.type)) {
33902
- const formatChangeMark = node2.marks.find((mark) => mark.type.name === TrackFormatMarkName);
33903
- let after = [];
33904
- let before = [];
33905
- if (formatChangeMark) {
33906
- let foundAfter = formatChangeMark.attrs.after.find((mark) => mark.type === step.mark.type.name);
33907
- if (foundAfter) {
33908
- after = [...formatChangeMark.attrs.after.filter((mark) => mark.type !== step.mark.type.name)];
33909
- before = [...formatChangeMark.attrs.before];
33910
- } else {
33911
- after = [...formatChangeMark.attrs.after];
33912
- before = [
33913
- ...formatChangeMark.attrs.before,
33914
- {
33915
- type: step.mark.type.name,
33916
- attrs: { ...step.mark.attrs }
33917
- }
33918
- ];
33919
- }
33920
- } else {
33921
- after = [];
33922
- before = [
33923
- {
33924
- type: step.mark.type.name,
33925
- attrs: { ...step.mark.attrs }
33926
- }
33927
- ];
33928
- }
33929
- if (after.length || before.length) {
33930
- const newFormatMark = state2.schema.marks[TrackFormatMarkName].create({
33931
- id: v4(),
33932
- author: user.name,
33933
- authorEmail: user.email,
33934
- date,
33935
- before,
33936
- after
33937
- });
33938
- newTr.addMark(
33939
- Math.max(step.from, pos),
33940
- Math.min(step.to, pos + node2.nodeSize),
33941
- newFormatMark
33942
- );
33943
- meta.formatMark = newFormatMark;
33944
- meta.step = step;
33945
- newTr.setMeta(TrackChangesBasePluginKey, meta);
33946
- } else if (formatChangeMark) {
33947
- newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node2.nodeSize), formatChangeMark);
33948
- }
33949
- }
33950
- });
33951
- };
33952
33989
  const CommentMarkName = "commentMark";
33953
33990
  const removeCommentsById = ({ commentId, state: state2, tr, dispatch }) => {
33954
33991
  const positions = getCommentPositionsById(commentId, state2.doc);
@@ -34355,7 +34392,7 @@ const CommentsPlugin = Extension.create({
34355
34392
  update(view, prevState) {
34356
34393
  const { state: state2 } = view;
34357
34394
  const { doc: doc2, tr } = state2;
34358
- if (prevDoc && prevDoc.eq(doc2)) shouldUpdate = true;
34395
+ if (prevDoc && !prevDoc.eq(doc2)) shouldUpdate = true;
34359
34396
  if (!shouldUpdate) return;
34360
34397
  prevDoc = doc2;
34361
34398
  shouldUpdate = false;
@@ -34389,10 +34426,14 @@ const CommentsPlugin = Extension.create({
34389
34426
  if (hasActive && activeThreadId !== threadId) return;
34390
34427
  decorations.push(deco);
34391
34428
  });
34392
- const trackedChangeNode = getTrackedChangeNode(node2);
34393
- if (trackedChangeNode) {
34429
+ const trackedChangeMark = findTrackedMark({
34430
+ doc: doc2,
34431
+ from: pos,
34432
+ to: pos + node2.nodeSize
34433
+ });
34434
+ if (trackedChangeMark) {
34394
34435
  const currentBounds = view.coordsAtPos(pos);
34395
- const { id } = trackedChangeNode.attrs;
34436
+ const { id } = trackedChangeMark.mark.attrs;
34396
34437
  updatePosition({
34397
34438
  allCommentPositions,
34398
34439
  threadId: id,
@@ -34460,9 +34501,13 @@ const getActiveCommentId = (doc2, selection) => {
34460
34501
  if ($from.pos !== $to.pos) return;
34461
34502
  const nodeAtPos = doc2.nodeAt($from.pos);
34462
34503
  if (!nodeAtPos) return;
34463
- const trackedChangeNode = getTrackedChangeNode(nodeAtPos);
34464
- if (trackedChangeNode) {
34465
- return trackedChangeNode.attrs.id;
34504
+ const trackedChangeMark = findTrackedMark({
34505
+ doc: doc2,
34506
+ from: $from.pos,
34507
+ to: $to.pos
34508
+ });
34509
+ if (trackedChangeMark) {
34510
+ return trackedChangeMark.mark.attrs.id;
34466
34511
  }
34467
34512
  const overlaps = [];
34468
34513
  let found2 = false;
@@ -34499,13 +34544,30 @@ const getActiveCommentId = (doc2, selection) => {
34499
34544
  const closestCommentMark = closestMarks.find((mark) => mark.type.name === CommentMarkName);
34500
34545
  return closestCommentMark?.attrs?.commentId || closestCommentMark?.attrs?.importedId;
34501
34546
  };
34502
- const getTrackedChangeNode = (node2) => {
34503
- if (!node2) return;
34504
- const nodeMarks = node2.marks;
34505
- const trackedInsertMark = nodeMarks?.find((mark) => mark.type.name === TrackInsertMarkName);
34506
- const trackedDeleteMark = nodeMarks?.find((mark) => mark.type.name === TrackDeleteMarkName);
34507
- const trackedFormatMark = nodeMarks?.find((mark) => mark.type.name === TrackFormatMarkName);
34508
- return trackedInsertMark || trackedDeleteMark || trackedFormatMark;
34547
+ const findTrackedMark = ({
34548
+ doc: doc2,
34549
+ from: from2,
34550
+ to,
34551
+ offset: offset2 = 1
34552
+ // To get non-inclusive marks.
34553
+ }) => {
34554
+ const startPos = Math.max(from2 - offset2, 0);
34555
+ const endPos = Math.min(to + offset2, doc2.content.size);
34556
+ let markFound;
34557
+ doc2.nodesBetween(startPos, endPos, (node2, pos) => {
34558
+ if (!node2 || node2?.nodeSize === void 0) {
34559
+ return;
34560
+ }
34561
+ const mark = node2.marks.find((mark2) => TRACK_CHANGE_MARKS.includes(mark2.type.name));
34562
+ if (mark && !markFound) {
34563
+ markFound = {
34564
+ from: pos,
34565
+ to: pos + node2.nodeSize,
34566
+ mark
34567
+ };
34568
+ }
34569
+ });
34570
+ return markFound;
34509
34571
  };
34510
34572
  const handleTrackedChangeTransaction = (trackedChangeMeta, trackedChanges, newEditorState, editor) => {
34511
34573
  const {
@@ -34645,6 +34707,202 @@ function findNode$1(node2, predicate) {
34645
34707
  });
34646
34708
  return found2;
34647
34709
  }
34710
+ const replaceStep = ({ state: state2, tr, step, newTr, map: map22, doc: doc2, user, date, originalStep, originalStepIndex }) => {
34711
+ const deletionMarkSchema = state2.schema.marks[TrackDeleteMarkName];
34712
+ const deletionMark = findMark(state2, deletionMarkSchema, false);
34713
+ const positionTo = deletionMark ? deletionMark.to : step.to;
34714
+ const newStep = new ReplaceStep(
34715
+ positionTo,
34716
+ // We insert all the same steps, but with "from"/"to" both set to "to" in order not to delete content. Mapped as needed.
34717
+ positionTo,
34718
+ step.slice,
34719
+ step.structure
34720
+ );
34721
+ const invertStep = originalStep.invert(tr.docs[originalStepIndex]).map(map22);
34722
+ map22.appendMap(invertStep.getMap());
34723
+ const meta = {};
34724
+ if (newStep) {
34725
+ const trTemp = state2.apply(newTr).tr;
34726
+ if (trTemp.maybeStep(newStep).failed) {
34727
+ return;
34728
+ }
34729
+ const mappedNewStepTo = newStep.getMap().map(newStep.to);
34730
+ const insertedMark = markInsertion({
34731
+ tr: trTemp,
34732
+ from: newStep.from,
34733
+ to: mappedNewStepTo,
34734
+ user,
34735
+ date
34736
+ });
34737
+ const condensedStep = new ReplaceStep(newStep.from, newStep.to, trTemp.doc.slice(newStep.from, mappedNewStepTo));
34738
+ newTr.step(condensedStep);
34739
+ const mirrorIndex = map22.maps.length - 1;
34740
+ map22.appendMap(condensedStep.getMap(), mirrorIndex);
34741
+ if (newStep.from !== mappedNewStepTo) {
34742
+ meta.insertedMark = insertedMark;
34743
+ meta.step = condensedStep;
34744
+ }
34745
+ if (!newTr.selection.eq(trTemp.selection)) {
34746
+ newTr.setSelection(trTemp.selection);
34747
+ }
34748
+ }
34749
+ if (step.from !== step.to) {
34750
+ const { deletionMark: deletionMark2, deletionMap, nodes: deletionNodes } = markDeletion({
34751
+ tr: newTr,
34752
+ from: step.from,
34753
+ to: step.to,
34754
+ user,
34755
+ date
34756
+ });
34757
+ meta.deletionNodes = deletionNodes;
34758
+ meta.deletionMark = deletionMark2;
34759
+ map22.appendMapping(deletionMap);
34760
+ }
34761
+ newTr.setMeta(TrackChangesBasePluginKey, meta);
34762
+ newTr.setMeta(CommentsPluginKey, { type: "force" });
34763
+ };
34764
+ const markWrapping = () => {
34765
+ };
34766
+ const replaceAroundStep = () => {
34767
+ };
34768
+ const addMarkStep = ({ state: state2, tr, step, newTr, map: map22, doc: doc2, user, date }) => {
34769
+ const meta = {};
34770
+ doc2.nodesBetween(step.from, step.to, (node2, pos) => {
34771
+ if (!node2.isInline) {
34772
+ return;
34773
+ }
34774
+ if (node2.marks.find((mark) => mark.type.name === TrackDeleteMarkName)) {
34775
+ return false;
34776
+ }
34777
+ const existingChangeMark = node2.marks.find((mark) => [TrackDeleteMarkName, TrackFormatMarkName].includes(mark.type.name));
34778
+ const wid = existingChangeMark ? existingChangeMark.attrs.id : v4();
34779
+ newTr.addMark(Math.max(step.from, pos), Math.min(step.to, pos + node2.nodeSize), step.mark);
34780
+ const allowedMarks = ["bold", "italic", "strike", "underline", "textStyle"];
34781
+ if (allowedMarks.includes(step.mark.type.name) && !node2.marks.find((mark) => mark.type === step.mark.type)) {
34782
+ const formatChangeMark = node2.marks.find((mark) => mark.type.name === TrackFormatMarkName);
34783
+ let after = [];
34784
+ let before = [];
34785
+ if (formatChangeMark) {
34786
+ let foundBefore = formatChangeMark.attrs.before.find((mark) => {
34787
+ if (mark.type === "textStyle") {
34788
+ return mark.type === step.mark.type.name && objectIncludes(mark.attrs, step.mark.attrs);
34789
+ }
34790
+ return mark.type === step.mark.type.name;
34791
+ });
34792
+ if (foundBefore) {
34793
+ before = [...formatChangeMark.attrs.before.filter((mark) => mark.type !== step.mark.type.name)];
34794
+ after = [...formatChangeMark.attrs.after];
34795
+ } else {
34796
+ before = [...formatChangeMark.attrs.before];
34797
+ after = [
34798
+ ...formatChangeMark.attrs.after,
34799
+ {
34800
+ type: step.mark.type.name,
34801
+ attrs: { ...step.mark.attrs }
34802
+ }
34803
+ ];
34804
+ }
34805
+ } else {
34806
+ before = node2.marks.map((mark) => ({
34807
+ type: mark.type.name,
34808
+ attrs: { ...mark.attrs }
34809
+ }));
34810
+ after = [
34811
+ {
34812
+ type: step.mark.type.name,
34813
+ attrs: { ...step.mark.attrs }
34814
+ }
34815
+ ];
34816
+ }
34817
+ if (after.length || before.length) {
34818
+ const newFormatMark = state2.schema.marks[TrackFormatMarkName].create({
34819
+ id: wid,
34820
+ author: user.name,
34821
+ authorEmail: user.email,
34822
+ date,
34823
+ before,
34824
+ after
34825
+ });
34826
+ newTr.addMark(
34827
+ step.from,
34828
+ // Math.max(step.from, pos)
34829
+ step.to,
34830
+ // Math.min(step.to, pos + node.nodeSize),
34831
+ newFormatMark
34832
+ );
34833
+ meta.formatMark = newFormatMark;
34834
+ meta.step = step;
34835
+ newTr.setMeta(TrackChangesBasePluginKey, meta);
34836
+ newTr.setMeta(CommentsPluginKey, { type: "force" });
34837
+ } else if (formatChangeMark) {
34838
+ newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node2.nodeSize), formatChangeMark);
34839
+ }
34840
+ }
34841
+ });
34842
+ };
34843
+ const removeMarkStep = ({ state: state2, tr, step, newTr, map: map22, doc: doc2, user, date }) => {
34844
+ const meta = {};
34845
+ doc2.nodesBetween(step.from, step.to, (node2, pos) => {
34846
+ if (!node2.isInline) {
34847
+ return true;
34848
+ }
34849
+ if (node2.marks.find((mark) => mark.type.name === TrackDeleteMarkName)) {
34850
+ return false;
34851
+ }
34852
+ newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node2.nodeSize), step.mark);
34853
+ const allowedMarks = ["bold", "italic", "strike", "underline", "textStyle"];
34854
+ if (allowedMarks.includes(step.mark.type.name) && node2.marks.find((mark) => mark.type === step.mark.type)) {
34855
+ const formatChangeMark = node2.marks.find((mark) => mark.type.name === TrackFormatMarkName);
34856
+ let after = [];
34857
+ let before = [];
34858
+ if (formatChangeMark) {
34859
+ let foundAfter = formatChangeMark.attrs.after.find((mark) => mark.type === step.mark.type.name);
34860
+ if (foundAfter) {
34861
+ after = [...formatChangeMark.attrs.after.filter((mark) => mark.type !== step.mark.type.name)];
34862
+ before = [...formatChangeMark.attrs.before];
34863
+ } else {
34864
+ after = [...formatChangeMark.attrs.after];
34865
+ before = [
34866
+ ...formatChangeMark.attrs.before,
34867
+ {
34868
+ type: step.mark.type.name,
34869
+ attrs: { ...step.mark.attrs }
34870
+ }
34871
+ ];
34872
+ }
34873
+ } else {
34874
+ after = [];
34875
+ before = [
34876
+ {
34877
+ type: step.mark.type.name,
34878
+ attrs: { ...step.mark.attrs }
34879
+ }
34880
+ ];
34881
+ }
34882
+ if (after.length || before.length) {
34883
+ const newFormatMark = state2.schema.marks[TrackFormatMarkName].create({
34884
+ id: v4(),
34885
+ author: user.name,
34886
+ authorEmail: user.email,
34887
+ date,
34888
+ before,
34889
+ after
34890
+ });
34891
+ newTr.addMark(
34892
+ Math.max(step.from, pos),
34893
+ Math.min(step.to, pos + node2.nodeSize),
34894
+ newFormatMark
34895
+ );
34896
+ meta.formatMark = newFormatMark;
34897
+ meta.step = step;
34898
+ newTr.setMeta(TrackChangesBasePluginKey, meta);
34899
+ newTr.setMeta(CommentsPluginKey, { type: "force" });
34900
+ } else if (formatChangeMark) {
34901
+ newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node2.nodeSize), formatChangeMark);
34902
+ }
34903
+ }
34904
+ });
34905
+ };
34648
34906
  const trackedTransaction = ({ tr, state: state2, user }) => {
34649
34907
  const onlyInputTypeMeta = ["inputType", "uiEvent", "paste", "pointer"];
34650
34908
  const notAllowedMeta = ["historyUndo", "historyRedo", "acceptReject"];
@@ -34803,6 +35061,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
34803
35061
  editorProps: {},
34804
35062
  parseOptions: {},
34805
35063
  coreExtensionOptions: {},
35064
+ enableInputRules: true,
34806
35065
  isCommentsEnabled: false,
34807
35066
  isNewFile: false,
34808
35067
  scale: 1,
@@ -35241,7 +35500,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
35241
35500
  * @returns {Y.Doc | undefined} Updated Y.Doc if any, otherwise undefined
35242
35501
  */
35243
35502
  processCollaborationMigrations() {
35244
- console.debug("[checkVersionMigrations] Current editor version", "0.8.10");
35503
+ console.debug("[checkVersionMigrations] Current editor version", "0.8.12");
35245
35504
  if (!this.options.ydoc) return;
35246
35505
  const metaMap = this.options.ydoc.getMap("meta");
35247
35506
  let docVersion = metaMap.get("version");
@@ -36586,6 +36845,45 @@ const RunItem = Node2.create({
36586
36845
  };
36587
36846
  }
36588
36847
  });
36848
+ function wrappingInputRule(config) {
36849
+ return new InputRule({
36850
+ match: config.match,
36851
+ handler: ({
36852
+ state: state2,
36853
+ range: range2,
36854
+ match,
36855
+ chain
36856
+ }) => {
36857
+ const attributes = callOrGet(config.getAttributes, null, match) || {};
36858
+ const tr = state2.tr.delete(range2.from, range2.to);
36859
+ const $start = tr.doc.resolve(range2.from);
36860
+ const blockRange = $start.blockRange();
36861
+ const wrapping = blockRange && findWrapping(blockRange, config.type, attributes);
36862
+ if (!wrapping) {
36863
+ return null;
36864
+ }
36865
+ tr.wrap(blockRange, wrapping);
36866
+ if (config.keepMarks && config.editor) {
36867
+ const { selection, storedMarks } = state2;
36868
+ const { splittableMarks } = config.editor.extensionService;
36869
+ const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
36870
+ if (marks) {
36871
+ const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
36872
+ tr.ensureMarks(filteredMarks);
36873
+ }
36874
+ }
36875
+ if (config.keepAttributes) {
36876
+ const nodeType = config.type.name === "bulletList" || config.type.name === "orderedList" ? "listItem" : config.type.name;
36877
+ chain().updateAttributes(nodeType, attributes).run();
36878
+ }
36879
+ const before = tr.doc.resolve(range2.from - 1).nodeBefore;
36880
+ if (before && before.type === config.type && canJoin(tr.doc, range2.from - 1) && (!config.joinPredicate || config.joinPredicate(match, before))) {
36881
+ tr.join(range2.from - 1);
36882
+ }
36883
+ }
36884
+ });
36885
+ }
36886
+ const inputRegex$1 = /^\s*([-+*])\s$/;
36589
36887
  const BulletList = Node2.create({
36590
36888
  name: "bulletList",
36591
36889
  group: "block list",
@@ -36596,7 +36894,8 @@ const BulletList = Node2.create({
36596
36894
  return {
36597
36895
  itemTypeName: "listItem",
36598
36896
  htmlAttributes: {},
36599
- keepMarks: true
36897
+ keepMarks: true,
36898
+ keepAttributes: false
36600
36899
  };
36601
36900
  },
36602
36901
  parseDOM() {
@@ -36634,8 +36933,29 @@ const BulletList = Node2.create({
36634
36933
  return this.editor.commands.toggleBulletList();
36635
36934
  }
36636
36935
  };
36637
- }
36936
+ },
36638
36937
  // Input rules.
36938
+ addInputRules() {
36939
+ let inputRule = wrappingInputRule({
36940
+ match: inputRegex$1,
36941
+ type: this.type
36942
+ });
36943
+ if (this.options.keepMarks || this.options.keepAttributes) {
36944
+ inputRule = wrappingInputRule({
36945
+ match: inputRegex$1,
36946
+ type: this.type,
36947
+ keepMarks: this.options.keepMarks,
36948
+ keepAttributes: this.options.keepAttributes,
36949
+ getAttributes: () => {
36950
+ return this.editor.getAttributes("textStyle");
36951
+ },
36952
+ editor: this.editor
36953
+ });
36954
+ }
36955
+ return [
36956
+ inputRule
36957
+ ];
36958
+ }
36639
36959
  });
36640
36960
  function orderedListSync(options2 = {}) {
36641
36961
  return new Plugin({
@@ -36846,6 +37166,7 @@ function buildFirstListItemAttrs({ state: state2, listItems }) {
36846
37166
  listNumberingType
36847
37167
  };
36848
37168
  }
37169
+ const inputRegex = /^(\d+)\.\s$/;
36849
37170
  const OrderedList = Node2.create({
36850
37171
  name: "orderedList",
36851
37172
  group: "block list",
@@ -36857,6 +37178,7 @@ const OrderedList = Node2.create({
36857
37178
  itemTypeName: "listItem",
36858
37179
  htmlAttributes: {},
36859
37180
  keepMarks: true,
37181
+ keepAttributes: false,
36860
37182
  listStyleTypes: ["decimal", "lowerAlpha", "lowerRoman"]
36861
37183
  };
36862
37184
  },
@@ -37014,6 +37336,28 @@ const OrderedList = Node2.create({
37014
37336
  },
37015
37337
  addPmPlugins() {
37016
37338
  return [orderedListMarker(), orderedListSync()];
37339
+ },
37340
+ addInputRules() {
37341
+ let inputRule = wrappingInputRule({
37342
+ match: inputRegex,
37343
+ type: this.type,
37344
+ getAttributes: (match) => ({ start: +match[1] }),
37345
+ joinPredicate: (match, node2) => node2.childCount + node2.attrs.start === +match[1]
37346
+ });
37347
+ if (this.options.keepMarks || this.options.keepAttributes) {
37348
+ inputRule = wrappingInputRule({
37349
+ match: inputRegex,
37350
+ type: this.type,
37351
+ keepMarks: this.options.keepMarks,
37352
+ keepAttributes: this.options.keepAttributes,
37353
+ getAttributes: (match) => ({ start: +match[1], ...this.editor.getAttributes("textStyle") }),
37354
+ joinPredicate: (match, node2) => node2.childCount + node2.attrs.start === +match[1],
37355
+ editor: this.editor
37356
+ });
37357
+ }
37358
+ return [
37359
+ inputRule
37360
+ ];
37017
37361
  }
37018
37362
  });
37019
37363
  function randomId() {
@@ -58787,4 +59131,4 @@ export {
58787
59131
  helpers as m,
58788
59132
  index as n
58789
59133
  };
58790
- //# sourceMappingURL=super-editor.es-CnpejCPC.js.map
59134
+ //# sourceMappingURL=super-editor.es-D8IC7SPE.js.map