@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
@@ -727,7 +727,7 @@
727
727
  globalVersion++;
728
728
  return;
729
729
  }
730
- const run = (dep) => {
730
+ const run2 = (dep) => {
731
731
  if (dep) {
732
732
  {
733
733
  dep.trigger();
@@ -736,7 +736,7 @@
736
736
  };
737
737
  startBatch();
738
738
  if (type2 === "clear") {
739
- depsMap.forEach(run);
739
+ depsMap.forEach(run2);
740
740
  } else {
741
741
  const targetIsArray = isArray$4(target);
742
742
  const isArrayIndex = targetIsArray && isIntegerKey(key);
@@ -744,38 +744,38 @@
744
744
  const newLength = Number(newValue);
745
745
  depsMap.forEach((dep, key2) => {
746
746
  if (key2 === "length" || key2 === ARRAY_ITERATE_KEY || !isSymbol$2(key2) && key2 >= newLength) {
747
- run(dep);
747
+ run2(dep);
748
748
  }
749
749
  });
750
750
  } else {
751
751
  if (key !== void 0 || depsMap.has(void 0)) {
752
- run(depsMap.get(key));
752
+ run2(depsMap.get(key));
753
753
  }
754
754
  if (isArrayIndex) {
755
- run(depsMap.get(ARRAY_ITERATE_KEY));
755
+ run2(depsMap.get(ARRAY_ITERATE_KEY));
756
756
  }
757
757
  switch (type2) {
758
758
  case "add":
759
759
  if (!targetIsArray) {
760
- run(depsMap.get(ITERATE_KEY));
760
+ run2(depsMap.get(ITERATE_KEY));
761
761
  if (isMap(target)) {
762
- run(depsMap.get(MAP_KEY_ITERATE_KEY));
762
+ run2(depsMap.get(MAP_KEY_ITERATE_KEY));
763
763
  }
764
764
  } else if (isArrayIndex) {
765
- run(depsMap.get("length"));
765
+ run2(depsMap.get("length"));
766
766
  }
767
767
  break;
768
768
  case "delete":
769
769
  if (!targetIsArray) {
770
- run(depsMap.get(ITERATE_KEY));
770
+ run2(depsMap.get(ITERATE_KEY));
771
771
  if (isMap(target)) {
772
- run(depsMap.get(MAP_KEY_ITERATE_KEY));
772
+ run2(depsMap.get(MAP_KEY_ITERATE_KEY));
773
773
  }
774
774
  }
775
775
  break;
776
776
  case "set":
777
777
  if (isMap(target)) {
778
- run(depsMap.get(ITERATE_KEY));
778
+ run2(depsMap.get(ITERATE_KEY));
779
779
  }
780
780
  break;
781
781
  }
@@ -26498,7 +26498,7 @@
26498
26498
  };
26499
26499
  function hasTextNode(elements) {
26500
26500
  const runs = elements.filter((el) => el.name === "w:r");
26501
- const runsHaveText = runs.some((run) => run.elements.some((el) => el.name === "w:t"));
26501
+ const runsHaveText = runs.some((run2) => run2.elements.some((el) => el.name === "w:t"));
26502
26502
  return runsHaveText;
26503
26503
  }
26504
26504
  const handleTrackChangeNode = (params2) => {
@@ -27397,8 +27397,8 @@
27397
27397
  };
27398
27398
  };
27399
27399
  const parseAnnotationMarks = (content = {}) => {
27400
- const run = content.elements?.find((el) => el.name === "w:r");
27401
- const rPr = run?.elements?.find((el) => el.name === "w:rPr");
27400
+ const run2 = content.elements?.find((el) => el.name === "w:r");
27401
+ const rPr = run2?.elements?.find((el) => el.name === "w:rPr");
27402
27402
  if (!rPr) return {};
27403
27403
  const unknownMarks = [];
27404
27404
  const marks = parseMarks(rPr, unknownMarks) || [];
@@ -28001,7 +28001,7 @@
28001
28001
  return;
28002
28002
  }
28003
28003
  }
28004
- static updateDocumentVersion(docx = this.convertedXml, version2 = "0.8.10") {
28004
+ static updateDocumentVersion(docx = this.convertedXml, version2 = "0.8.12") {
28005
28005
  const customLocation = "docProps/custom.xml";
28006
28006
  if (!docx[customLocation]) {
28007
28007
  docx[customLocation] = generateCustomXml();
@@ -28274,7 +28274,7 @@
28274
28274
  function generateCustomXml() {
28275
28275
  return DEFAULT_CUSTOM_XML;
28276
28276
  }
28277
- function generateSuperdocVersion(pid = 2, version2 = "0.8.10") {
28277
+ function generateSuperdocVersion(pid = 2, version2 = "0.8.12") {
28278
28278
  return {
28279
28279
  type: "element",
28280
28280
  name: "property",
@@ -38735,6 +38735,357 @@
38735
38735
  function getSchemaTypeByName(name, schema) {
38736
38736
  return schema.nodes[name] || schema.marks[name] || null;
38737
38737
  }
38738
+ function isExtensionRulesEnabled(extension, enabled) {
38739
+ if (Array.isArray(enabled)) {
38740
+ return enabled.some((enabledExtension) => {
38741
+ const name = typeof enabledExtension === "string" ? enabledExtension : enabledExtension.name;
38742
+ return name === extension.name;
38743
+ });
38744
+ }
38745
+ return enabled;
38746
+ }
38747
+ function chainableEditorState(transaction, state2) {
38748
+ let { selection, doc: doc2, storedMarks } = transaction;
38749
+ return {
38750
+ ...state2,
38751
+ apply: state2.apply.bind(state2),
38752
+ applyTransaction: state2.applyTransaction.bind(state2),
38753
+ plugins: state2.plugins,
38754
+ schema: state2.schema,
38755
+ reconfigure: state2.reconfigure.bind(state2),
38756
+ toJSON: state2.toJSON.bind(state2),
38757
+ get storedMarks() {
38758
+ return storedMarks;
38759
+ },
38760
+ get selection() {
38761
+ return selection;
38762
+ },
38763
+ get doc() {
38764
+ return doc2;
38765
+ },
38766
+ get tr() {
38767
+ selection = transaction.selection;
38768
+ doc2 = transaction.doc;
38769
+ storedMarks = transaction.storedMarks;
38770
+ return transaction;
38771
+ }
38772
+ };
38773
+ }
38774
+ class CommandService {
38775
+ constructor(props) {
38776
+ __publicField$1(this, "editor");
38777
+ __publicField$1(this, "rawCommands");
38778
+ this.editor = props.editor;
38779
+ this.rawCommands = this.editor.extensionService.commands;
38780
+ }
38781
+ /**
38782
+ * Static method for creating a service.
38783
+ * @param args Arguments for the constructor.
38784
+ */
38785
+ static create(...args) {
38786
+ return new CommandService(...args);
38787
+ }
38788
+ /**
38789
+ * Get editor state.
38790
+ */
38791
+ get state() {
38792
+ return this.editor.state;
38793
+ }
38794
+ /**
38795
+ * Get all commands with wrapped command method.
38796
+ */
38797
+ get commands() {
38798
+ const { editor, state: state2 } = this;
38799
+ const { view } = editor;
38800
+ const { tr } = state2;
38801
+ const props = this.createProps(tr);
38802
+ const entries = Object.entries(this.rawCommands).map(([name, command2]) => {
38803
+ const method = (...args) => {
38804
+ const fn2 = command2(...args)(props);
38805
+ if (!tr.getMeta("preventDispatch")) {
38806
+ view.dispatch(tr);
38807
+ }
38808
+ return fn2;
38809
+ };
38810
+ return [name, method];
38811
+ });
38812
+ return Object.fromEntries(entries);
38813
+ }
38814
+ /**
38815
+ * Create a chain of commands to call multiple commands at once.
38816
+ */
38817
+ get chain() {
38818
+ return () => this.createChain();
38819
+ }
38820
+ /**
38821
+ * Check if a command or a chain of commands can be executed. Without executing it.
38822
+ */
38823
+ get can() {
38824
+ return () => this.createCan();
38825
+ }
38826
+ /**
38827
+ * Creates a chain of commands.
38828
+ * @param startTr Start transaction.
38829
+ * @param shouldDispatch Should dispatch or not.
38830
+ */
38831
+ createChain(startTr, shouldDispatch = true) {
38832
+ const { editor, state: state2, rawCommands } = this;
38833
+ const { view } = editor;
38834
+ const callbacks2 = [];
38835
+ const hasStartTr = !!startTr;
38836
+ const tr = startTr || state2.tr;
38837
+ const run2 = () => {
38838
+ if (!hasStartTr && shouldDispatch && !tr.getMeta("preventDispatch")) {
38839
+ view.dispatch(tr);
38840
+ }
38841
+ return callbacks2.every((cb) => cb === true);
38842
+ };
38843
+ const entries = Object.entries(rawCommands).map(([name, command2]) => {
38844
+ const chainedCommand = (...args) => {
38845
+ const props = this.createProps(tr, shouldDispatch);
38846
+ const callback = command2(...args)(props);
38847
+ callbacks2.push(callback);
38848
+ return chain;
38849
+ };
38850
+ return [name, chainedCommand];
38851
+ });
38852
+ const chain = {
38853
+ ...Object.fromEntries(entries),
38854
+ run: run2
38855
+ };
38856
+ return chain;
38857
+ }
38858
+ /**
38859
+ * Creates a can check for commands.
38860
+ * @param startTr Start transaction.
38861
+ */
38862
+ createCan(startTr) {
38863
+ const { rawCommands, state: state2 } = this;
38864
+ const dispatch = false;
38865
+ const tr = startTr || state2.tr;
38866
+ const props = this.createProps(tr, dispatch);
38867
+ const commands2 = Object.fromEntries(
38868
+ Object.entries(rawCommands).map(([name, command2]) => {
38869
+ return [name, (...args) => command2(...args)({ ...props, dispatch: void 0 })];
38870
+ })
38871
+ );
38872
+ return {
38873
+ ...commands2,
38874
+ chain: () => this.createChain(tr, dispatch)
38875
+ };
38876
+ }
38877
+ /**
38878
+ * Creates default props for the command method.
38879
+ * @param {*} tr Transaction.
38880
+ * @param {*} shouldDispatch Check if should dispatch.
38881
+ * @returns Object with props.
38882
+ */
38883
+ createProps(tr, shouldDispatch = true) {
38884
+ const { editor, state: state2, rawCommands } = this;
38885
+ const { view } = editor;
38886
+ const props = {
38887
+ tr,
38888
+ editor,
38889
+ view,
38890
+ state: chainableEditorState(tr, state2),
38891
+ dispatch: shouldDispatch ? () => void 0 : void 0,
38892
+ chain: () => this.createChain(tr, shouldDispatch),
38893
+ can: () => this.createCan(tr),
38894
+ get commands() {
38895
+ return Object.fromEntries(
38896
+ Object.entries(rawCommands).map(([name, command2]) => {
38897
+ return [name, (...args) => command2(...args)(props)];
38898
+ })
38899
+ );
38900
+ }
38901
+ };
38902
+ return props;
38903
+ }
38904
+ }
38905
+ function getHTMLFromFragment(fragment, schema) {
38906
+ const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment);
38907
+ const temporaryDocument = document.implementation.createHTMLDocument();
38908
+ const container = temporaryDocument.createElement("div");
38909
+ container.appendChild(documentFragment);
38910
+ return container.innerHTML;
38911
+ }
38912
+ const getTextContentFromNodes = ($from, maxMatch = 500) => {
38913
+ let textBefore = "";
38914
+ const sliceEndPos = $from.parentOffset;
38915
+ $from.parent.nodesBetween(
38916
+ Math.max(0, sliceEndPos - maxMatch),
38917
+ sliceEndPos,
38918
+ (node2, pos, parent, index2) => {
38919
+ const chunk = node2.type.spec.toText?.({
38920
+ node: node2,
38921
+ pos,
38922
+ parent,
38923
+ index: index2
38924
+ }) || node2.textContent || "%leaf%";
38925
+ textBefore += node2.isAtom && !node2.isText ? chunk : chunk.slice(0, Math.max(0, sliceEndPos - pos));
38926
+ }
38927
+ );
38928
+ return textBefore;
38929
+ };
38930
+ class InputRule {
38931
+ constructor(config) {
38932
+ __publicField$1(this, "match");
38933
+ __publicField$1(this, "handler");
38934
+ this.match = config.match;
38935
+ this.handler = config.handler;
38936
+ }
38937
+ }
38938
+ const inputRuleMatcherHandler = (text, match2) => {
38939
+ if (isRegExp(match2)) {
38940
+ return match2.exec(text);
38941
+ }
38942
+ const inputRuleMatch = match2(text);
38943
+ if (!inputRuleMatch) {
38944
+ return null;
38945
+ }
38946
+ const result = [inputRuleMatch.text];
38947
+ result.index = inputRuleMatch.index;
38948
+ result.input = text;
38949
+ result.data = inputRuleMatch.data;
38950
+ if (inputRuleMatch.replaceWith) {
38951
+ if (!inputRuleMatch.text.includes(inputRuleMatch.replaceWith)) {
38952
+ console.warn(
38953
+ '[super-editor warn]: "inputRuleMatch.replaceWith" must be part of "inputRuleMatch.text".'
38954
+ );
38955
+ }
38956
+ result.push(inputRuleMatch.replaceWith);
38957
+ }
38958
+ return result;
38959
+ };
38960
+ const run = (config) => {
38961
+ const {
38962
+ editor,
38963
+ from: from2,
38964
+ to,
38965
+ text,
38966
+ rules,
38967
+ plugin: plugin2
38968
+ } = config;
38969
+ const { view } = editor;
38970
+ if (view.composing) {
38971
+ return false;
38972
+ }
38973
+ const $from = view.state.doc.resolve(from2);
38974
+ if ($from.parent.type.spec.code || !!($from.nodeBefore || $from.nodeAfter)?.marks.find((mark) => mark.type.spec.code)) {
38975
+ return false;
38976
+ }
38977
+ let matched = false;
38978
+ const textBefore = getTextContentFromNodes($from) + text;
38979
+ rules.forEach((rule) => {
38980
+ if (matched) {
38981
+ return;
38982
+ }
38983
+ const match2 = inputRuleMatcherHandler(textBefore, rule.match);
38984
+ if (!match2) {
38985
+ return;
38986
+ }
38987
+ const tr = view.state.tr;
38988
+ const state2 = chainableEditorState(tr, view.state);
38989
+ const range2 = {
38990
+ from: from2 - (match2[0].length - text.length),
38991
+ to
38992
+ };
38993
+ const { commands: commands2, chain, can } = new CommandService({
38994
+ editor,
38995
+ state: state2
38996
+ });
38997
+ const handler = rule.handler({
38998
+ state: state2,
38999
+ range: range2,
39000
+ match: match2,
39001
+ commands: commands2,
39002
+ chain,
39003
+ can
39004
+ });
39005
+ if (handler === null || !tr.steps.length) {
39006
+ return;
39007
+ }
39008
+ tr.setMeta(plugin2, {
39009
+ transform: tr,
39010
+ from: from2,
39011
+ to,
39012
+ text
39013
+ });
39014
+ view.dispatch(tr);
39015
+ matched = true;
39016
+ });
39017
+ return matched;
39018
+ };
39019
+ const inputRulesPlugin = ({ editor, rules }) => {
39020
+ const plugin2 = new Plugin({
39021
+ key: new PluginKey("inputRulesPlugin"),
39022
+ state: {
39023
+ init() {
39024
+ return null;
39025
+ },
39026
+ apply(tr, prev, state2) {
39027
+ const stored = tr.getMeta(plugin2);
39028
+ if (stored) {
39029
+ return stored;
39030
+ }
39031
+ const simulatedInputMeta = tr.getMeta("applyInputRules");
39032
+ const isSimulatedInput = !!simulatedInputMeta;
39033
+ if (isSimulatedInput) {
39034
+ setTimeout(() => {
39035
+ let { text } = simulatedInputMeta;
39036
+ if (typeof text !== "string") {
39037
+ text = getHTMLFromFragment(Fragment.from(text), state2.schema);
39038
+ }
39039
+ const { from: from2 } = simulatedInputMeta;
39040
+ const to = from2 + text.length;
39041
+ run({
39042
+ editor,
39043
+ from: from2,
39044
+ to,
39045
+ text,
39046
+ rules,
39047
+ plugin: plugin2
39048
+ });
39049
+ });
39050
+ }
39051
+ return tr.selectionSet || tr.docChanged ? null : prev;
39052
+ }
39053
+ },
39054
+ props: {
39055
+ handleTextInput(view, from2, to, text) {
39056
+ return run({
39057
+ editor,
39058
+ from: from2,
39059
+ to,
39060
+ text,
39061
+ rules,
39062
+ plugin: plugin2
39063
+ });
39064
+ },
39065
+ // add support for input rules to trigger on enter
39066
+ // this is useful for example for code blocks
39067
+ handleKeyDown(view, event) {
39068
+ if (event.key !== "Enter") {
39069
+ return false;
39070
+ }
39071
+ const { $cursor } = view.state.selection;
39072
+ if ($cursor) {
39073
+ return run({
39074
+ editor,
39075
+ from: $cursor.pos,
39076
+ to: $cursor.pos,
39077
+ text: "\n",
39078
+ rules,
39079
+ plugin: plugin2
39080
+ });
39081
+ }
39082
+ return false;
39083
+ }
39084
+ },
39085
+ isInputRules: true
39086
+ });
39087
+ return plugin2;
39088
+ };
38738
39089
  const _ExtensionService = class _ExtensionService2 {
38739
39090
  constructor(extensions, userExtensions, editor) {
38740
39091
  __privateAdd$1(this, _ExtensionService_instances);
@@ -38819,6 +39170,7 @@
38819
39170
  get plugins() {
38820
39171
  const editor = this.editor;
38821
39172
  const extensions = _ExtensionService2.sortByPriority([...this.extensions].reverse());
39173
+ const inputRules = [];
38822
39174
  const allPlugins = extensions.map((extension) => {
38823
39175
  const context = {
38824
39176
  name: extension.name,
@@ -38837,6 +39189,10 @@
38837
39189
  bindingsObject = { ...Object.fromEntries(entries) };
38838
39190
  }
38839
39191
  plugins.push(keymap(bindingsObject));
39192
+ const addInputRules = getExtensionConfigField(extension, "addInputRules", context);
39193
+ if (isExtensionRulesEnabled(extension, editor.options.enableInputRules) && addInputRules) {
39194
+ inputRules.push(...addInputRules());
39195
+ }
38840
39196
  const addPmPlugins = getExtensionConfigField(extension, "addPmPlugins", context);
38841
39197
  if (addPmPlugins) {
38842
39198
  const pmPlugins = addPmPlugins();
@@ -38844,7 +39200,13 @@
38844
39200
  }
38845
39201
  return plugins;
38846
39202
  }).flat();
38847
- return [...allPlugins];
39203
+ return [
39204
+ inputRulesPlugin({
39205
+ editor,
39206
+ rules: inputRules
39207
+ }),
39208
+ ...allPlugins
39209
+ ];
38848
39210
  }
38849
39211
  /**
38850
39212
  * Get all node views from the extensions.
@@ -38926,164 +39288,6 @@
38926
39288
  if (onDestroy2) this.editor.on("destroy", onDestroy2);
38927
39289
  };
38928
39290
  let ExtensionService = _ExtensionService;
38929
- function chainableEditorState(transaction, state2) {
38930
- let { selection, doc: doc2, storedMarks } = transaction;
38931
- return {
38932
- ...state2,
38933
- apply: state2.apply.bind(state2),
38934
- applyTransaction: state2.applyTransaction.bind(state2),
38935
- plugins: state2.plugins,
38936
- schema: state2.schema,
38937
- reconfigure: state2.reconfigure.bind(state2),
38938
- toJSON: state2.toJSON.bind(state2),
38939
- get storedMarks() {
38940
- return storedMarks;
38941
- },
38942
- get selection() {
38943
- return selection;
38944
- },
38945
- get doc() {
38946
- return doc2;
38947
- },
38948
- get tr() {
38949
- selection = transaction.selection;
38950
- doc2 = transaction.doc;
38951
- storedMarks = transaction.storedMarks;
38952
- return transaction;
38953
- }
38954
- };
38955
- }
38956
- class CommandService {
38957
- constructor(props) {
38958
- __publicField$1(this, "editor");
38959
- __publicField$1(this, "rawCommands");
38960
- this.editor = props.editor;
38961
- this.rawCommands = this.editor.extensionService.commands;
38962
- }
38963
- /**
38964
- * Static method for creating a service.
38965
- * @param args Arguments for the constructor.
38966
- */
38967
- static create(...args) {
38968
- return new CommandService(...args);
38969
- }
38970
- /**
38971
- * Get editor state.
38972
- */
38973
- get state() {
38974
- return this.editor.state;
38975
- }
38976
- /**
38977
- * Get all commands with wrapped command method.
38978
- */
38979
- get commands() {
38980
- const { editor, state: state2 } = this;
38981
- const { view } = editor;
38982
- const { tr } = state2;
38983
- const props = this.createProps(tr);
38984
- const entries = Object.entries(this.rawCommands).map(([name, command2]) => {
38985
- const method = (...args) => {
38986
- const fn2 = command2(...args)(props);
38987
- if (!tr.getMeta("preventDispatch")) {
38988
- view.dispatch(tr);
38989
- }
38990
- return fn2;
38991
- };
38992
- return [name, method];
38993
- });
38994
- return Object.fromEntries(entries);
38995
- }
38996
- /**
38997
- * Create a chain of commands to call multiple commands at once.
38998
- */
38999
- get chain() {
39000
- return () => this.createChain();
39001
- }
39002
- /**
39003
- * Check if a command or a chain of commands can be executed. Without executing it.
39004
- */
39005
- get can() {
39006
- return () => this.createCan();
39007
- }
39008
- /**
39009
- * Creates a chain of commands.
39010
- * @param startTr Start transaction.
39011
- * @param shouldDispatch Should dispatch or not.
39012
- */
39013
- createChain(startTr, shouldDispatch = true) {
39014
- const { editor, state: state2, rawCommands } = this;
39015
- const { view } = editor;
39016
- const callbacks2 = [];
39017
- const hasStartTr = !!startTr;
39018
- const tr = startTr || state2.tr;
39019
- const run = () => {
39020
- if (!hasStartTr && shouldDispatch && !tr.getMeta("preventDispatch")) {
39021
- view.dispatch(tr);
39022
- }
39023
- return callbacks2.every((cb) => cb === true);
39024
- };
39025
- const entries = Object.entries(rawCommands).map(([name, command2]) => {
39026
- const chainedCommand = (...args) => {
39027
- const props = this.createProps(tr, shouldDispatch);
39028
- const callback = command2(...args)(props);
39029
- callbacks2.push(callback);
39030
- return chain;
39031
- };
39032
- return [name, chainedCommand];
39033
- });
39034
- const chain = {
39035
- ...Object.fromEntries(entries),
39036
- run
39037
- };
39038
- return chain;
39039
- }
39040
- /**
39041
- * Creates a can check for commands.
39042
- * @param startTr Start transaction.
39043
- */
39044
- createCan(startTr) {
39045
- const { rawCommands, state: state2 } = this;
39046
- const dispatch = false;
39047
- const tr = startTr || state2.tr;
39048
- const props = this.createProps(tr, dispatch);
39049
- const commands2 = Object.fromEntries(
39050
- Object.entries(rawCommands).map(([name, command2]) => {
39051
- return [name, (...args) => command2(...args)({ ...props, dispatch: void 0 })];
39052
- })
39053
- );
39054
- return {
39055
- ...commands2,
39056
- chain: () => this.createChain(tr, dispatch)
39057
- };
39058
- }
39059
- /**
39060
- * Creates default props for the command method.
39061
- * @param {*} tr Transaction.
39062
- * @param {*} shouldDispatch Check if should dispatch.
39063
- * @returns Object with props.
39064
- */
39065
- createProps(tr, shouldDispatch = true) {
39066
- const { editor, state: state2, rawCommands } = this;
39067
- const { view } = editor;
39068
- const props = {
39069
- tr,
39070
- editor,
39071
- view,
39072
- state: chainableEditorState(tr, state2),
39073
- dispatch: shouldDispatch ? () => void 0 : void 0,
39074
- chain: () => this.createChain(tr, shouldDispatch),
39075
- can: () => this.createCan(tr),
39076
- get commands() {
39077
- return Object.fromEntries(
39078
- Object.entries(rawCommands).map(([name, command2]) => {
39079
- return [name, (...args) => command2(...args)(props)];
39080
- })
39081
- );
39082
- }
39083
- };
39084
- return props;
39085
- }
39086
- }
39087
39291
  const first = (commands2) => (props) => {
39088
39292
  const items = typeof commands2 === "function" ? commands2(props) : commands2;
39089
39293
  for (let i2 = 0; i2 < items.length; i2 += 1) {
@@ -40120,6 +40324,30 @@
40120
40324
  }
40121
40325
  return true;
40122
40326
  };
40327
+ const undoInputRule = () => ({ state: state2, dispatch }) => {
40328
+ const plugins = state2.plugins;
40329
+ for (let i2 = 0; i2 < plugins.length; i2 += 1) {
40330
+ const plugin2 = plugins[i2];
40331
+ let undoable;
40332
+ if (plugin2.spec.isInputRules && (undoable = plugin2.getState(state2))) {
40333
+ if (dispatch) {
40334
+ const tr = state2.tr;
40335
+ const toUndo = undoable.transform;
40336
+ for (let j = toUndo.steps.length - 1; j >= 0; j -= 1) {
40337
+ tr.step(toUndo.steps[j].invert(toUndo.docs[j]));
40338
+ }
40339
+ if (undoable.text) {
40340
+ const marks = tr.doc.resolve(undoable.from).marks();
40341
+ tr.replaceWith(undoable.from, undoable.to, state2.schema.text(undoable.text, marks));
40342
+ } else {
40343
+ tr.delete(undoable.from, undoable.to);
40344
+ }
40345
+ }
40346
+ return true;
40347
+ }
40348
+ }
40349
+ return false;
40350
+ };
40123
40351
  function wrapInList$1(listType, attrs = null) {
40124
40352
  return function(state2, dispatch) {
40125
40353
  let { $from, $to } = state2.selection;
@@ -40449,6 +40677,7 @@
40449
40677
  toggleList,
40450
40678
  toggleMark,
40451
40679
  toggleNode,
40680
+ undoInputRule,
40452
40681
  unsetAllMarks,
40453
40682
  unsetMark,
40454
40683
  updateAttributes,
@@ -40478,6 +40707,7 @@
40478
40707
  () => commands2.splitBlock()
40479
40708
  ]);
40480
40709
  const handleBackspace = () => this.editor.commands.first(({ commands: commands2, tr }) => [
40710
+ () => commands2.undoInputRule(),
40481
40711
  () => {
40482
40712
  tr.setMeta("inputType", "deleteContentBackward");
40483
40713
  return false;
@@ -41093,199 +41323,6 @@
41093
41323
  });
41094
41324
  return DecorationSet.create(state2.doc, decorations);
41095
41325
  };
41096
- const replaceStep = ({ state: state2, tr, step, newTr, map: map2, doc: doc2, user, date, originalStep, originalStepIndex }) => {
41097
- const deletionMarkSchema = state2.schema.marks[TrackDeleteMarkName];
41098
- const deletionMark = findMark(state2, deletionMarkSchema, false);
41099
- const positionTo = deletionMark ? deletionMark.to : step.to;
41100
- const newStep = new ReplaceStep(
41101
- positionTo,
41102
- // We insert all the same steps, but with "from"/"to" both set to "to" in order not to delete content. Mapped as needed.
41103
- positionTo,
41104
- step.slice,
41105
- step.structure
41106
- );
41107
- const invertStep = originalStep.invert(tr.docs[originalStepIndex]).map(map2);
41108
- map2.appendMap(invertStep.getMap());
41109
- const meta = {};
41110
- if (newStep) {
41111
- const trTemp = state2.apply(newTr).tr;
41112
- if (trTemp.maybeStep(newStep).failed) {
41113
- return;
41114
- }
41115
- const mappedNewStepTo = newStep.getMap().map(newStep.to);
41116
- const insertedMark = markInsertion({
41117
- tr: trTemp,
41118
- from: newStep.from,
41119
- to: mappedNewStepTo,
41120
- user,
41121
- date
41122
- });
41123
- const condensedStep = new ReplaceStep(newStep.from, newStep.to, trTemp.doc.slice(newStep.from, mappedNewStepTo));
41124
- newTr.step(condensedStep);
41125
- const mirrorIndex = map2.maps.length - 1;
41126
- map2.appendMap(condensedStep.getMap(), mirrorIndex);
41127
- if (newStep.from !== mappedNewStepTo) {
41128
- meta.insertedMark = insertedMark;
41129
- meta.step = condensedStep;
41130
- }
41131
- if (!newTr.selection.eq(trTemp.selection)) {
41132
- newTr.setSelection(trTemp.selection);
41133
- }
41134
- }
41135
- if (step.from !== step.to) {
41136
- const { deletionMark: deletionMark2, deletionMap, nodes: deletionNodes } = markDeletion({
41137
- tr: newTr,
41138
- from: step.from,
41139
- to: step.to,
41140
- user,
41141
- date
41142
- });
41143
- meta.deletionNodes = deletionNodes;
41144
- meta.deletionMark = deletionMark2;
41145
- map2.appendMapping(deletionMap);
41146
- }
41147
- newTr.setMeta(TrackChangesBasePluginKey, meta);
41148
- };
41149
- const markWrapping = () => {
41150
- };
41151
- const replaceAroundStep = () => {
41152
- };
41153
- const addMarkStep = ({ state: state2, tr, step, newTr, map: map2, doc: doc2, user, date }) => {
41154
- const meta = {};
41155
- doc2.nodesBetween(step.from, step.to, (node2, pos) => {
41156
- if (!node2.isInline) {
41157
- return;
41158
- }
41159
- if (node2.marks.find((mark) => mark.type.name === TrackDeleteMarkName)) {
41160
- return false;
41161
- }
41162
- const existingChangeMark = node2.marks.find((mark) => [TrackDeleteMarkName, TrackFormatMarkName].includes(mark.type.name));
41163
- const wid = existingChangeMark ? existingChangeMark.attrs.id : v4$1();
41164
- newTr.addMark(Math.max(step.from, pos), Math.min(step.to, pos + node2.nodeSize), step.mark);
41165
- const allowedMarks = ["bold", "italic", "strike", "underline", "textStyle"];
41166
- if (allowedMarks.includes(step.mark.type.name) && !node2.marks.find((mark) => mark.type === step.mark.type)) {
41167
- const formatChangeMark = node2.marks.find((mark) => mark.type.name === TrackFormatMarkName);
41168
- let after = [];
41169
- let before = [];
41170
- if (formatChangeMark) {
41171
- let foundBefore = formatChangeMark.attrs.before.find((mark) => {
41172
- if (mark.type === "textStyle") {
41173
- return mark.type === step.mark.type.name && objectIncludes(mark.attrs, step.mark.attrs);
41174
- }
41175
- return mark.type === step.mark.type.name;
41176
- });
41177
- if (foundBefore) {
41178
- before = [...formatChangeMark.attrs.before.filter((mark) => mark.type !== step.mark.type.name)];
41179
- after = [...formatChangeMark.attrs.after];
41180
- } else {
41181
- before = [...formatChangeMark.attrs.before];
41182
- after = [
41183
- ...formatChangeMark.attrs.after,
41184
- {
41185
- type: step.mark.type.name,
41186
- attrs: { ...step.mark.attrs }
41187
- }
41188
- ];
41189
- }
41190
- } else {
41191
- before = node2.marks.map((mark) => ({
41192
- type: mark.type.name,
41193
- attrs: { ...mark.attrs }
41194
- }));
41195
- after = [
41196
- {
41197
- type: step.mark.type.name,
41198
- attrs: { ...step.mark.attrs }
41199
- }
41200
- ];
41201
- }
41202
- if (after.length || before.length) {
41203
- const newFormatMark = state2.schema.marks[TrackFormatMarkName].create({
41204
- id: wid,
41205
- author: user.name,
41206
- authorEmail: user.email,
41207
- date,
41208
- before,
41209
- after
41210
- });
41211
- newTr.addMark(
41212
- step.from,
41213
- // Math.max(step.from, pos)
41214
- step.to,
41215
- // Math.min(step.to, pos + node.nodeSize),
41216
- newFormatMark
41217
- );
41218
- meta.formatMark = newFormatMark;
41219
- meta.step = step;
41220
- newTr.setMeta(TrackChangesBasePluginKey, meta);
41221
- } else if (formatChangeMark) {
41222
- newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node2.nodeSize), formatChangeMark);
41223
- }
41224
- }
41225
- });
41226
- };
41227
- const removeMarkStep = ({ state: state2, tr, step, newTr, map: map2, doc: doc2, user, date }) => {
41228
- const meta = {};
41229
- doc2.nodesBetween(step.from, step.to, (node2, pos) => {
41230
- if (!node2.isInline) {
41231
- return true;
41232
- }
41233
- if (node2.marks.find((mark) => mark.type.name === TrackDeleteMarkName)) {
41234
- return false;
41235
- }
41236
- newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node2.nodeSize), step.mark);
41237
- const allowedMarks = ["bold", "italic", "strike", "underline", "textStyle"];
41238
- if (allowedMarks.includes(step.mark.type.name) && node2.marks.find((mark) => mark.type === step.mark.type)) {
41239
- const formatChangeMark = node2.marks.find((mark) => mark.type.name === TrackFormatMarkName);
41240
- let after = [];
41241
- let before = [];
41242
- if (formatChangeMark) {
41243
- let foundAfter = formatChangeMark.attrs.after.find((mark) => mark.type === step.mark.type.name);
41244
- if (foundAfter) {
41245
- after = [...formatChangeMark.attrs.after.filter((mark) => mark.type !== step.mark.type.name)];
41246
- before = [...formatChangeMark.attrs.before];
41247
- } else {
41248
- after = [...formatChangeMark.attrs.after];
41249
- before = [
41250
- ...formatChangeMark.attrs.before,
41251
- {
41252
- type: step.mark.type.name,
41253
- attrs: { ...step.mark.attrs }
41254
- }
41255
- ];
41256
- }
41257
- } else {
41258
- after = [];
41259
- before = [
41260
- {
41261
- type: step.mark.type.name,
41262
- attrs: { ...step.mark.attrs }
41263
- }
41264
- ];
41265
- }
41266
- if (after.length || before.length) {
41267
- const newFormatMark = state2.schema.marks[TrackFormatMarkName].create({
41268
- id: v4$1(),
41269
- author: user.name,
41270
- authorEmail: user.email,
41271
- date,
41272
- before,
41273
- after
41274
- });
41275
- newTr.addMark(
41276
- Math.max(step.from, pos),
41277
- Math.min(step.to, pos + node2.nodeSize),
41278
- newFormatMark
41279
- );
41280
- meta.formatMark = newFormatMark;
41281
- meta.step = step;
41282
- newTr.setMeta(TrackChangesBasePluginKey, meta);
41283
- } else if (formatChangeMark) {
41284
- newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node2.nodeSize), formatChangeMark);
41285
- }
41286
- }
41287
- });
41288
- };
41289
41326
  const CommentMarkName = "commentMark";
41290
41327
  const removeCommentsById = ({ commentId, state: state2, tr, dispatch }) => {
41291
41328
  const positions = getCommentPositionsById(commentId, state2.doc);
@@ -41692,7 +41729,7 @@
41692
41729
  update(view, prevState) {
41693
41730
  const { state: state2 } = view;
41694
41731
  const { doc: doc2, tr } = state2;
41695
- if (prevDoc && prevDoc.eq(doc2)) shouldUpdate = true;
41732
+ if (prevDoc && !prevDoc.eq(doc2)) shouldUpdate = true;
41696
41733
  if (!shouldUpdate) return;
41697
41734
  prevDoc = doc2;
41698
41735
  shouldUpdate = false;
@@ -41726,10 +41763,14 @@
41726
41763
  if (hasActive && activeThreadId !== threadId) return;
41727
41764
  decorations.push(deco);
41728
41765
  });
41729
- const trackedChangeNode = getTrackedChangeNode(node2);
41730
- if (trackedChangeNode) {
41766
+ const trackedChangeMark = findTrackedMark({
41767
+ doc: doc2,
41768
+ from: pos,
41769
+ to: pos + node2.nodeSize
41770
+ });
41771
+ if (trackedChangeMark) {
41731
41772
  const currentBounds = view.coordsAtPos(pos);
41732
- const { id } = trackedChangeNode.attrs;
41773
+ const { id } = trackedChangeMark.mark.attrs;
41733
41774
  updatePosition({
41734
41775
  allCommentPositions,
41735
41776
  threadId: id,
@@ -41797,9 +41838,13 @@
41797
41838
  if ($from.pos !== $to.pos) return;
41798
41839
  const nodeAtPos = doc2.nodeAt($from.pos);
41799
41840
  if (!nodeAtPos) return;
41800
- const trackedChangeNode = getTrackedChangeNode(nodeAtPos);
41801
- if (trackedChangeNode) {
41802
- return trackedChangeNode.attrs.id;
41841
+ const trackedChangeMark = findTrackedMark({
41842
+ doc: doc2,
41843
+ from: $from.pos,
41844
+ to: $to.pos
41845
+ });
41846
+ if (trackedChangeMark) {
41847
+ return trackedChangeMark.mark.attrs.id;
41803
41848
  }
41804
41849
  const overlaps = [];
41805
41850
  let found2 = false;
@@ -41836,13 +41881,30 @@
41836
41881
  const closestCommentMark = closestMarks.find((mark) => mark.type.name === CommentMarkName);
41837
41882
  return closestCommentMark?.attrs?.commentId || closestCommentMark?.attrs?.importedId;
41838
41883
  };
41839
- const getTrackedChangeNode = (node2) => {
41840
- if (!node2) return;
41841
- const nodeMarks = node2.marks;
41842
- const trackedInsertMark = nodeMarks?.find((mark) => mark.type.name === TrackInsertMarkName);
41843
- const trackedDeleteMark = nodeMarks?.find((mark) => mark.type.name === TrackDeleteMarkName);
41844
- const trackedFormatMark = nodeMarks?.find((mark) => mark.type.name === TrackFormatMarkName);
41845
- return trackedInsertMark || trackedDeleteMark || trackedFormatMark;
41884
+ const findTrackedMark = ({
41885
+ doc: doc2,
41886
+ from: from2,
41887
+ to,
41888
+ offset: offset2 = 1
41889
+ // To get non-inclusive marks.
41890
+ }) => {
41891
+ const startPos = Math.max(from2 - offset2, 0);
41892
+ const endPos = Math.min(to + offset2, doc2.content.size);
41893
+ let markFound;
41894
+ doc2.nodesBetween(startPos, endPos, (node2, pos) => {
41895
+ if (!node2 || node2?.nodeSize === void 0) {
41896
+ return;
41897
+ }
41898
+ const mark = node2.marks.find((mark2) => TRACK_CHANGE_MARKS.includes(mark2.type.name));
41899
+ if (mark && !markFound) {
41900
+ markFound = {
41901
+ from: pos,
41902
+ to: pos + node2.nodeSize,
41903
+ mark
41904
+ };
41905
+ }
41906
+ });
41907
+ return markFound;
41846
41908
  };
41847
41909
  const handleTrackedChangeTransaction = (trackedChangeMeta, trackedChanges, newEditorState, editor) => {
41848
41910
  const {
@@ -41982,6 +42044,202 @@
41982
42044
  });
41983
42045
  return found2;
41984
42046
  }
42047
+ const replaceStep = ({ state: state2, tr, step, newTr, map: map2, doc: doc2, user, date, originalStep, originalStepIndex }) => {
42048
+ const deletionMarkSchema = state2.schema.marks[TrackDeleteMarkName];
42049
+ const deletionMark = findMark(state2, deletionMarkSchema, false);
42050
+ const positionTo = deletionMark ? deletionMark.to : step.to;
42051
+ const newStep = new ReplaceStep(
42052
+ positionTo,
42053
+ // We insert all the same steps, but with "from"/"to" both set to "to" in order not to delete content. Mapped as needed.
42054
+ positionTo,
42055
+ step.slice,
42056
+ step.structure
42057
+ );
42058
+ const invertStep = originalStep.invert(tr.docs[originalStepIndex]).map(map2);
42059
+ map2.appendMap(invertStep.getMap());
42060
+ const meta = {};
42061
+ if (newStep) {
42062
+ const trTemp = state2.apply(newTr).tr;
42063
+ if (trTemp.maybeStep(newStep).failed) {
42064
+ return;
42065
+ }
42066
+ const mappedNewStepTo = newStep.getMap().map(newStep.to);
42067
+ const insertedMark = markInsertion({
42068
+ tr: trTemp,
42069
+ from: newStep.from,
42070
+ to: mappedNewStepTo,
42071
+ user,
42072
+ date
42073
+ });
42074
+ const condensedStep = new ReplaceStep(newStep.from, newStep.to, trTemp.doc.slice(newStep.from, mappedNewStepTo));
42075
+ newTr.step(condensedStep);
42076
+ const mirrorIndex = map2.maps.length - 1;
42077
+ map2.appendMap(condensedStep.getMap(), mirrorIndex);
42078
+ if (newStep.from !== mappedNewStepTo) {
42079
+ meta.insertedMark = insertedMark;
42080
+ meta.step = condensedStep;
42081
+ }
42082
+ if (!newTr.selection.eq(trTemp.selection)) {
42083
+ newTr.setSelection(trTemp.selection);
42084
+ }
42085
+ }
42086
+ if (step.from !== step.to) {
42087
+ const { deletionMark: deletionMark2, deletionMap, nodes: deletionNodes } = markDeletion({
42088
+ tr: newTr,
42089
+ from: step.from,
42090
+ to: step.to,
42091
+ user,
42092
+ date
42093
+ });
42094
+ meta.deletionNodes = deletionNodes;
42095
+ meta.deletionMark = deletionMark2;
42096
+ map2.appendMapping(deletionMap);
42097
+ }
42098
+ newTr.setMeta(TrackChangesBasePluginKey, meta);
42099
+ newTr.setMeta(CommentsPluginKey, { type: "force" });
42100
+ };
42101
+ const markWrapping = () => {
42102
+ };
42103
+ const replaceAroundStep = () => {
42104
+ };
42105
+ const addMarkStep = ({ state: state2, tr, step, newTr, map: map2, doc: doc2, user, date }) => {
42106
+ const meta = {};
42107
+ doc2.nodesBetween(step.from, step.to, (node2, pos) => {
42108
+ if (!node2.isInline) {
42109
+ return;
42110
+ }
42111
+ if (node2.marks.find((mark) => mark.type.name === TrackDeleteMarkName)) {
42112
+ return false;
42113
+ }
42114
+ const existingChangeMark = node2.marks.find((mark) => [TrackDeleteMarkName, TrackFormatMarkName].includes(mark.type.name));
42115
+ const wid = existingChangeMark ? existingChangeMark.attrs.id : v4$1();
42116
+ newTr.addMark(Math.max(step.from, pos), Math.min(step.to, pos + node2.nodeSize), step.mark);
42117
+ const allowedMarks = ["bold", "italic", "strike", "underline", "textStyle"];
42118
+ if (allowedMarks.includes(step.mark.type.name) && !node2.marks.find((mark) => mark.type === step.mark.type)) {
42119
+ const formatChangeMark = node2.marks.find((mark) => mark.type.name === TrackFormatMarkName);
42120
+ let after = [];
42121
+ let before = [];
42122
+ if (formatChangeMark) {
42123
+ let foundBefore = formatChangeMark.attrs.before.find((mark) => {
42124
+ if (mark.type === "textStyle") {
42125
+ return mark.type === step.mark.type.name && objectIncludes(mark.attrs, step.mark.attrs);
42126
+ }
42127
+ return mark.type === step.mark.type.name;
42128
+ });
42129
+ if (foundBefore) {
42130
+ before = [...formatChangeMark.attrs.before.filter((mark) => mark.type !== step.mark.type.name)];
42131
+ after = [...formatChangeMark.attrs.after];
42132
+ } else {
42133
+ before = [...formatChangeMark.attrs.before];
42134
+ after = [
42135
+ ...formatChangeMark.attrs.after,
42136
+ {
42137
+ type: step.mark.type.name,
42138
+ attrs: { ...step.mark.attrs }
42139
+ }
42140
+ ];
42141
+ }
42142
+ } else {
42143
+ before = node2.marks.map((mark) => ({
42144
+ type: mark.type.name,
42145
+ attrs: { ...mark.attrs }
42146
+ }));
42147
+ after = [
42148
+ {
42149
+ type: step.mark.type.name,
42150
+ attrs: { ...step.mark.attrs }
42151
+ }
42152
+ ];
42153
+ }
42154
+ if (after.length || before.length) {
42155
+ const newFormatMark = state2.schema.marks[TrackFormatMarkName].create({
42156
+ id: wid,
42157
+ author: user.name,
42158
+ authorEmail: user.email,
42159
+ date,
42160
+ before,
42161
+ after
42162
+ });
42163
+ newTr.addMark(
42164
+ step.from,
42165
+ // Math.max(step.from, pos)
42166
+ step.to,
42167
+ // Math.min(step.to, pos + node.nodeSize),
42168
+ newFormatMark
42169
+ );
42170
+ meta.formatMark = newFormatMark;
42171
+ meta.step = step;
42172
+ newTr.setMeta(TrackChangesBasePluginKey, meta);
42173
+ newTr.setMeta(CommentsPluginKey, { type: "force" });
42174
+ } else if (formatChangeMark) {
42175
+ newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node2.nodeSize), formatChangeMark);
42176
+ }
42177
+ }
42178
+ });
42179
+ };
42180
+ const removeMarkStep = ({ state: state2, tr, step, newTr, map: map2, doc: doc2, user, date }) => {
42181
+ const meta = {};
42182
+ doc2.nodesBetween(step.from, step.to, (node2, pos) => {
42183
+ if (!node2.isInline) {
42184
+ return true;
42185
+ }
42186
+ if (node2.marks.find((mark) => mark.type.name === TrackDeleteMarkName)) {
42187
+ return false;
42188
+ }
42189
+ newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node2.nodeSize), step.mark);
42190
+ const allowedMarks = ["bold", "italic", "strike", "underline", "textStyle"];
42191
+ if (allowedMarks.includes(step.mark.type.name) && node2.marks.find((mark) => mark.type === step.mark.type)) {
42192
+ const formatChangeMark = node2.marks.find((mark) => mark.type.name === TrackFormatMarkName);
42193
+ let after = [];
42194
+ let before = [];
42195
+ if (formatChangeMark) {
42196
+ let foundAfter = formatChangeMark.attrs.after.find((mark) => mark.type === step.mark.type.name);
42197
+ if (foundAfter) {
42198
+ after = [...formatChangeMark.attrs.after.filter((mark) => mark.type !== step.mark.type.name)];
42199
+ before = [...formatChangeMark.attrs.before];
42200
+ } else {
42201
+ after = [...formatChangeMark.attrs.after];
42202
+ before = [
42203
+ ...formatChangeMark.attrs.before,
42204
+ {
42205
+ type: step.mark.type.name,
42206
+ attrs: { ...step.mark.attrs }
42207
+ }
42208
+ ];
42209
+ }
42210
+ } else {
42211
+ after = [];
42212
+ before = [
42213
+ {
42214
+ type: step.mark.type.name,
42215
+ attrs: { ...step.mark.attrs }
42216
+ }
42217
+ ];
42218
+ }
42219
+ if (after.length || before.length) {
42220
+ const newFormatMark = state2.schema.marks[TrackFormatMarkName].create({
42221
+ id: v4$1(),
42222
+ author: user.name,
42223
+ authorEmail: user.email,
42224
+ date,
42225
+ before,
42226
+ after
42227
+ });
42228
+ newTr.addMark(
42229
+ Math.max(step.from, pos),
42230
+ Math.min(step.to, pos + node2.nodeSize),
42231
+ newFormatMark
42232
+ );
42233
+ meta.formatMark = newFormatMark;
42234
+ meta.step = step;
42235
+ newTr.setMeta(TrackChangesBasePluginKey, meta);
42236
+ newTr.setMeta(CommentsPluginKey, { type: "force" });
42237
+ } else if (formatChangeMark) {
42238
+ newTr.removeMark(Math.max(step.from, pos), Math.min(step.to, pos + node2.nodeSize), formatChangeMark);
42239
+ }
42240
+ }
42241
+ });
42242
+ };
41985
42243
  const trackedTransaction = ({ tr, state: state2, user }) => {
41986
42244
  const onlyInputTypeMeta = ["inputType", "uiEvent", "paste", "pointer"];
41987
42245
  const notAllowedMeta = ["historyUndo", "historyRedo", "acceptReject"];
@@ -42140,6 +42398,7 @@
42140
42398
  editorProps: {},
42141
42399
  parseOptions: {},
42142
42400
  coreExtensionOptions: {},
42401
+ enableInputRules: true,
42143
42402
  isCommentsEnabled: false,
42144
42403
  isNewFile: false,
42145
42404
  scale: 1,
@@ -42578,7 +42837,7 @@
42578
42837
  * @returns {Y.Doc | undefined} Updated Y.Doc if any, otherwise undefined
42579
42838
  */
42580
42839
  processCollaborationMigrations() {
42581
- console.debug("[checkVersionMigrations] Current editor version", "0.8.10");
42840
+ console.debug("[checkVersionMigrations] Current editor version", "0.8.12");
42582
42841
  if (!this.options.ydoc) return;
42583
42842
  const metaMap = this.options.ydoc.getMap("meta");
42584
42843
  let docVersion = metaMap.get("version");
@@ -43923,6 +44182,45 @@
43923
44182
  };
43924
44183
  }
43925
44184
  });
44185
+ function wrappingInputRule(config) {
44186
+ return new InputRule({
44187
+ match: config.match,
44188
+ handler: ({
44189
+ state: state2,
44190
+ range: range2,
44191
+ match: match2,
44192
+ chain
44193
+ }) => {
44194
+ const attributes = callOrGet(config.getAttributes, null, match2) || {};
44195
+ const tr = state2.tr.delete(range2.from, range2.to);
44196
+ const $start = tr.doc.resolve(range2.from);
44197
+ const blockRange = $start.blockRange();
44198
+ const wrapping = blockRange && findWrapping(blockRange, config.type, attributes);
44199
+ if (!wrapping) {
44200
+ return null;
44201
+ }
44202
+ tr.wrap(blockRange, wrapping);
44203
+ if (config.keepMarks && config.editor) {
44204
+ const { selection, storedMarks } = state2;
44205
+ const { splittableMarks } = config.editor.extensionService;
44206
+ const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
44207
+ if (marks) {
44208
+ const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
44209
+ tr.ensureMarks(filteredMarks);
44210
+ }
44211
+ }
44212
+ if (config.keepAttributes) {
44213
+ const nodeType = config.type.name === "bulletList" || config.type.name === "orderedList" ? "listItem" : config.type.name;
44214
+ chain().updateAttributes(nodeType, attributes).run();
44215
+ }
44216
+ const before = tr.doc.resolve(range2.from - 1).nodeBefore;
44217
+ if (before && before.type === config.type && canJoin(tr.doc, range2.from - 1) && (!config.joinPredicate || config.joinPredicate(match2, before))) {
44218
+ tr.join(range2.from - 1);
44219
+ }
44220
+ }
44221
+ });
44222
+ }
44223
+ const inputRegex$1 = /^\s*([-+*])\s$/;
43926
44224
  const BulletList = Node$1.create({
43927
44225
  name: "bulletList",
43928
44226
  group: "block list",
@@ -43933,7 +44231,8 @@
43933
44231
  return {
43934
44232
  itemTypeName: "listItem",
43935
44233
  htmlAttributes: {},
43936
- keepMarks: true
44234
+ keepMarks: true,
44235
+ keepAttributes: false
43937
44236
  };
43938
44237
  },
43939
44238
  parseDOM() {
@@ -43971,8 +44270,29 @@
43971
44270
  return this.editor.commands.toggleBulletList();
43972
44271
  }
43973
44272
  };
43974
- }
44273
+ },
43975
44274
  // Input rules.
44275
+ addInputRules() {
44276
+ let inputRule = wrappingInputRule({
44277
+ match: inputRegex$1,
44278
+ type: this.type
44279
+ });
44280
+ if (this.options.keepMarks || this.options.keepAttributes) {
44281
+ inputRule = wrappingInputRule({
44282
+ match: inputRegex$1,
44283
+ type: this.type,
44284
+ keepMarks: this.options.keepMarks,
44285
+ keepAttributes: this.options.keepAttributes,
44286
+ getAttributes: () => {
44287
+ return this.editor.getAttributes("textStyle");
44288
+ },
44289
+ editor: this.editor
44290
+ });
44291
+ }
44292
+ return [
44293
+ inputRule
44294
+ ];
44295
+ }
43976
44296
  });
43977
44297
  function orderedListSync(options2 = {}) {
43978
44298
  return new Plugin({
@@ -44183,6 +44503,7 @@
44183
44503
  listNumberingType
44184
44504
  };
44185
44505
  }
44506
+ const inputRegex = /^(\d+)\.\s$/;
44186
44507
  const OrderedList = Node$1.create({
44187
44508
  name: "orderedList",
44188
44509
  group: "block list",
@@ -44194,6 +44515,7 @@
44194
44515
  itemTypeName: "listItem",
44195
44516
  htmlAttributes: {},
44196
44517
  keepMarks: true,
44518
+ keepAttributes: false,
44197
44519
  listStyleTypes: ["decimal", "lowerAlpha", "lowerRoman"]
44198
44520
  };
44199
44521
  },
@@ -44351,6 +44673,28 @@
44351
44673
  },
44352
44674
  addPmPlugins() {
44353
44675
  return [orderedListMarker(), orderedListSync()];
44676
+ },
44677
+ addInputRules() {
44678
+ let inputRule = wrappingInputRule({
44679
+ match: inputRegex,
44680
+ type: this.type,
44681
+ getAttributes: (match2) => ({ start: +match2[1] }),
44682
+ joinPredicate: (match2, node2) => node2.childCount + node2.attrs.start === +match2[1]
44683
+ });
44684
+ if (this.options.keepMarks || this.options.keepAttributes) {
44685
+ inputRule = wrappingInputRule({
44686
+ match: inputRegex,
44687
+ type: this.type,
44688
+ keepMarks: this.options.keepMarks,
44689
+ keepAttributes: this.options.keepAttributes,
44690
+ getAttributes: (match2) => ({ start: +match2[1], ...this.editor.getAttributes("textStyle") }),
44691
+ joinPredicate: (match2, node2) => node2.childCount + node2.attrs.start === +match2[1],
44692
+ editor: this.editor
44693
+ });
44694
+ }
44695
+ return [
44696
+ inputRule
44697
+ ];
44354
44698
  }
44355
44699
  });
44356
44700
  function randomId() {
@@ -110962,7 +111306,7 @@ ${style2}
110962
111306
  this.config.colors = shuffleArray(this.config.colors);
110963
111307
  this.userColorMap = /* @__PURE__ */ new Map();
110964
111308
  this.colorIndex = 0;
110965
- this.version = "0.8.10";
111309
+ this.version = "0.8.12";
110966
111310
  console.debug("🦋 [superdoc] Using SuperDoc version:", this.version);
110967
111311
  this.superdocId = config.superdocId || v4();
110968
111312
  this.colors = this.config.colors;