@manuscripts/track-changes-plugin 2.1.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/dist/cjs/ChangeSet.js +23 -9
  2. package/dist/cjs/actions.js +3 -1
  3. package/dist/cjs/{changes/applyChanges.js → applyChanges.js} +16 -16
  4. package/dist/cjs/{changes → changeHelpers}/revertChange.js +3 -4
  5. package/dist/cjs/{mutate/dropStructureChange.js → changeHelpers/structureChange.js} +23 -17
  6. package/dist/cjs/{changes → changeHelpers}/updateChangeAttrs.js +4 -5
  7. package/dist/cjs/{changes → changeHelpers}/updateChangesStatus.js +5 -5
  8. package/dist/cjs/{changes/findChanges.js → findChanges.js} +5 -5
  9. package/dist/cjs/helpers/attributes.js +157 -0
  10. package/dist/cjs/{compute/setFragmentAsInserted.js → helpers/fragment.js} +71 -79
  11. package/dist/cjs/helpers/mark.js +19 -0
  12. package/dist/cjs/plugin.js +13 -22
  13. package/dist/cjs/trackChanges.js +47 -0
  14. package/dist/cjs/{change-steps → tracking/change-step}/diffChangeSteps.js +23 -28
  15. package/dist/cjs/{utils/mapChangeStep.js → tracking/change-step/mapChangeSteps.js} +1 -1
  16. package/dist/cjs/{change-steps → tracking/change-step}/processChangeSteps.js +14 -48
  17. package/dist/cjs/tracking/fixAndHandleSelection.js +54 -0
  18. package/dist/cjs/{mutate → tracking/lib}/deleteAndMergeSplitNodes.js +7 -40
  19. package/dist/cjs/{mutate → tracking/lib}/deleteNode.js +8 -9
  20. package/dist/cjs/{mutate/deleteText.js → tracking/lib/deleteTextIfInserted.js} +4 -4
  21. package/dist/cjs/{change-steps → tracking/lib}/matchInserted.js +15 -23
  22. package/dist/cjs/{mutate → tracking/lib}/mergeTrackedMarks.js +3 -3
  23. package/dist/cjs/tracking/lib/processStepsBeforeTracking.js +17 -0
  24. package/dist/cjs/{steps/utils.js → tracking/steps-trackers/qualifiers.js} +37 -10
  25. package/dist/cjs/{steps/trackAttrsChange.js → tracking/steps-trackers/trackAttrsChangeStep.js} +3 -3
  26. package/dist/cjs/{steps → tracking/steps-trackers}/trackMarkSteps.js +14 -11
  27. package/dist/cjs/{steps → tracking/steps-trackers}/trackReplaceAroundStep.js +12 -46
  28. package/dist/cjs/tracking/steps-trackers/trackReplaceStep.js +85 -0
  29. package/dist/cjs/tracking/trackTransaction.js +93 -0
  30. package/dist/cjs/tracking/transactionProcessing.js +164 -0
  31. package/dist/cjs/tracking/types.js +17 -0
  32. package/dist/es/ChangeSet.js +23 -9
  33. package/dist/es/actions.js +1 -0
  34. package/dist/es/{changes/applyChanges.js → applyChanges.js} +10 -10
  35. package/dist/es/{changes → changeHelpers}/revertChange.js +1 -2
  36. package/dist/es/{mutate/dropStructureChange.js → changeHelpers/structureChange.js} +10 -5
  37. package/dist/es/{changes → changeHelpers}/updateChangeAttrs.js +2 -3
  38. package/dist/es/{changes → changeHelpers}/updateChangesStatus.js +4 -4
  39. package/dist/es/{changes/findChanges.js → findChanges.js} +3 -3
  40. package/dist/es/helpers/attributes.js +136 -0
  41. package/dist/es/{compute/setFragmentAsInserted.js → helpers/fragment.js} +66 -42
  42. package/dist/es/helpers/mark.js +15 -0
  43. package/dist/es/plugin.js +12 -21
  44. package/dist/es/trackChanges.js +44 -0
  45. package/dist/es/{change-steps → tracking/change-step}/diffChangeSteps.js +23 -28
  46. package/dist/es/{utils/mapChangeStep.js → tracking/change-step/mapChangeSteps.js} +1 -1
  47. package/dist/es/{change-steps → tracking/change-step}/processChangeSteps.js +10 -11
  48. package/dist/es/tracking/fixAndHandleSelection.js +49 -0
  49. package/dist/es/{mutate → tracking/lib}/deleteAndMergeSplitNodes.js +7 -7
  50. package/dist/es/{mutate → tracking/lib}/deleteNode.js +4 -5
  51. package/dist/es/{mutate/deleteText.js → tracking/lib/deleteTextIfInserted.js} +1 -1
  52. package/dist/es/{change-steps → tracking/lib}/matchInserted.js +15 -23
  53. package/dist/es/{mutate → tracking/lib}/mergeTrackedMarks.js +2 -2
  54. package/dist/es/tracking/lib/processStepsBeforeTracking.js +14 -0
  55. package/dist/es/{steps/utils.js → tracking/steps-trackers/qualifiers.js} +32 -7
  56. package/dist/es/{steps/trackAttrsChange.js → tracking/steps-trackers/trackAttrsChangeStep.js} +3 -3
  57. package/dist/es/{steps → tracking/steps-trackers}/trackMarkSteps.js +6 -3
  58. package/dist/es/{steps → tracking/steps-trackers}/trackReplaceAroundStep.js +9 -10
  59. package/dist/es/{steps → tracking/steps-trackers}/trackReplaceStep.js +34 -26
  60. package/dist/es/tracking/trackTransaction.js +87 -0
  61. package/dist/es/tracking/transactionProcessing.js +153 -0
  62. package/dist/es/tracking/types.js +16 -0
  63. package/dist/types/ChangeSet.d.ts +4 -1
  64. package/dist/types/actions.d.ts +1 -0
  65. package/dist/types/applyChanges.d.ts +6 -0
  66. package/dist/types/{mutate/dropStructureChange.d.ts → changeHelpers/structureChange.d.ts} +2 -1
  67. package/dist/types/{changes/findChanges.d.ts → findChanges.d.ts} +1 -1
  68. package/dist/types/helpers/attributes.d.ts +47 -0
  69. package/dist/types/{compute/setFragmentAsInserted.d.ts → helpers/fragment.d.ts} +3 -1
  70. package/dist/types/helpers/mark.d.ts +3 -0
  71. package/dist/types/trackChanges.d.ts +17 -0
  72. package/dist/types/tracking/change-step/diffChangeSteps.d.ts +17 -0
  73. package/dist/types/{utils/mapChangeStep.d.ts → tracking/change-step/mapChangeSteps.d.ts} +2 -2
  74. package/dist/types/tracking/change-step/processChangeSteps.d.ts +6 -0
  75. package/dist/types/tracking/fixAndHandleSelection.d.ts +20 -0
  76. package/dist/types/{mutate → tracking/lib}/deleteAndMergeSplitNodes.d.ts +4 -5
  77. package/dist/types/{mutate → tracking/lib}/deleteNode.d.ts +2 -2
  78. package/dist/types/{mutate/deleteText.d.ts → tracking/lib/deleteTextIfInserted.d.ts} +1 -1
  79. package/dist/types/tracking/lib/matchInserted.d.ts +18 -0
  80. package/dist/types/tracking/lib/processStepsBeforeTracking.d.ts +4 -0
  81. package/dist/types/{compute → tracking/lib}/splitSliceIntoMergedParts.d.ts +1 -1
  82. package/dist/types/{steps/utils.d.ts → tracking/steps-trackers/qualifiers.d.ts} +5 -3
  83. package/dist/types/{steps/trackAttrsChange.d.ts → tracking/steps-trackers/trackAttrsChangeStep.d.ts} +4 -4
  84. package/dist/types/{steps → tracking/steps-trackers}/trackMarkSteps.d.ts +1 -1
  85. package/dist/types/{steps → tracking/steps-trackers}/trackReplaceAroundStep.d.ts +2 -2
  86. package/dist/types/tracking/steps-trackers/trackReplaceStep.d.ts +5 -0
  87. package/dist/types/tracking/trackTransaction.d.ts +4 -0
  88. package/dist/types/tracking/transactionProcessing.d.ts +12 -0
  89. package/dist/types/tracking/types.d.ts +65 -0
  90. package/dist/types/types/change.d.ts +1 -1
  91. package/dist/types/types/track.d.ts +0 -30
  92. package/package.json +2 -2
  93. package/dist/cjs/compute/nodeHelpers.js +0 -83
  94. package/dist/cjs/steps/trackReplaceStep.js +0 -110
  95. package/dist/cjs/steps/trackTransaction.js +0 -162
  96. package/dist/cjs/types/step.js +0 -2
  97. package/dist/cjs/utils/track-utils.js +0 -239
  98. package/dist/es/compute/nodeHelpers.js +0 -73
  99. package/dist/es/steps/trackTransaction.js +0 -156
  100. package/dist/es/types/step.js +0 -1
  101. package/dist/es/utils/track-utils.js +0 -217
  102. package/dist/types/change-steps/diffChangeSteps.d.ts +0 -2
  103. package/dist/types/change-steps/matchInserted.d.ts +0 -3
  104. package/dist/types/change-steps/processChangeSteps.d.ts +0 -6
  105. package/dist/types/changes/applyChanges.d.ts +0 -6
  106. package/dist/types/compute/nodeHelpers.d.ts +0 -14
  107. package/dist/types/steps/trackReplaceStep.d.ts +0 -6
  108. package/dist/types/steps/trackTransaction.d.ts +0 -3
  109. package/dist/types/types/step.d.ts +0 -40
  110. package/dist/types/utils/track-utils.d.ts +0 -24
  111. /package/dist/cjs/{changes → changeHelpers}/fixInconsistentChanges.js +0 -0
  112. /package/dist/cjs/{mutate → tracking/lib}/mergeNode.js +0 -0
  113. /package/dist/cjs/{compute → tracking/lib}/splitSliceIntoMergedParts.js +0 -0
  114. /package/dist/es/{changes → changeHelpers}/fixInconsistentChanges.js +0 -0
  115. /package/dist/es/{mutate → tracking/lib}/mergeNode.js +0 -0
  116. /package/dist/es/{compute → tracking/lib}/splitSliceIntoMergedParts.js +0 -0
  117. /package/dist/types/{changes → changeHelpers}/fixInconsistentChanges.d.ts +0 -0
  118. /package/dist/types/{changes → changeHelpers}/revertChange.d.ts +0 -0
  119. /package/dist/types/{changes → changeHelpers}/updateChangeAttrs.d.ts +0 -0
  120. /package/dist/types/{changes → changeHelpers}/updateChangesStatus.d.ts +0 -0
  121. /package/dist/types/{mutate → tracking/lib}/mergeNode.d.ts +0 -0
  122. /package/dist/types/{mutate → tracking/lib}/mergeTrackedMarks.d.ts +0 -0
@@ -0,0 +1,15 @@
1
+ export function isValidTrackableMark(mark) {
2
+ var _a, _b;
3
+ const spec = mark.type.spec;
4
+ const name = mark.type.name;
5
+ if (!name.startsWith('tracked_') &&
6
+ ((_a = spec.attrs) === null || _a === void 0 ? void 0 : _a.dataTracked) &&
7
+ typeof ((_b = spec.attrs) === null || _b === void 0 ? void 0 : _b.dataTracked) === 'object') {
8
+ return true;
9
+ }
10
+ return false;
11
+ }
12
+ export function equalMarks(n1, n2) {
13
+ return (n1.marks.length === n2.marks.length &&
14
+ n1.marks.every((mark) => n1.marks.find((m) => m.type === mark.type)));
15
+ }
package/dist/es/plugin.js CHANGED
@@ -11,14 +11,14 @@ var __rest = (this && this.__rest) || function (s, e) {
11
11
  };
12
12
  import { Plugin, PluginKey } from 'prosemirror-state';
13
13
  import { getAction, hasAction, setAction, TrackChangesAction } from './actions';
14
- import { findChanges } from './changes/findChanges';
15
- import { fixInconsistentChanges } from './changes/fixInconsistentChanges';
16
- import { updateChangesStatus } from './changes/updateChangesStatus';
14
+ import { fixInconsistentChanges } from './changeHelpers/fixInconsistentChanges';
15
+ import { updateChangesStatus } from './changeHelpers/updateChangesStatus';
17
16
  import { ChangeSet } from './ChangeSet';
18
- import { trackTransaction } from './steps/trackTransaction';
17
+ import { findChanges } from './findChanges';
18
+ import { trackChanges } from './trackChanges';
19
+ import { trFromHistory } from './tracking/transactionProcessing';
19
20
  import { TrackChangesStatus } from './types/track';
20
21
  import { enableDebug, log } from './utils/logger';
21
- import { trFromHistory } from './utils/track-utils';
22
22
  export const trackChangesPluginKey = new PluginKey('track-changes');
23
23
  export const trackChangesPlugin = (opts = { userID: 'anonymous:Anonymous', initialStatus: TrackChangesStatus.enabled }) => {
24
24
  const { userID, debug, skipTrsWithMetas = [] } = opts;
@@ -80,31 +80,22 @@ export const trackChangesPlugin = (opts = { userID: 'anonymous:Anonymous', initi
80
80
  let createdTr = newState.tr, docChanged = false;
81
81
  log.info('TRS', trs);
82
82
  trs.forEach((tr) => {
83
- const wasAppended = tr.getMeta('appendedTransaction');
84
- const skipMetaUsed = skipTrsWithMetas.some((m) => tr.getMeta(m) || (wasAppended === null || wasAppended === void 0 ? void 0 : wasAppended.getMeta(m)));
85
83
  const collabRebased = tr.getMeta('rebased');
86
84
  if (collabRebased !== undefined) {
87
85
  setAction(createdTr, TrackChangesAction.refreshChanges, true);
88
86
  docChanged = true;
89
87
  return;
90
88
  }
91
- const setChangeStatuses = getAction(tr, TrackChangesAction.setChangeStatuses);
92
- const skipTrackUsed = getAction(tr, TrackChangesAction.skipTrack) ||
93
- (wasAppended && getAction(wasAppended, TrackChangesAction.skipTrack));
94
- if (!setChangeStatuses &&
95
- tr.docChanged &&
96
- !skipMetaUsed &&
97
- !skipTrackUsed &&
98
- !trFromHistory(tr) &&
99
- !(wasAppended && tr.getMeta('origin') === 'paragraphs')) {
100
- createdTr = trackTransaction(tr, oldState, createdTr, userID, changeSet);
101
- }
102
- docChanged = docChanged || tr.docChanged;
103
- if (setChangeStatuses) {
104
- const { status, ids } = setChangeStatuses;
89
+ const setsChangeStatus = getAction(tr, TrackChangesAction.setChangeStatuses);
90
+ if (setsChangeStatus) {
91
+ const { status, ids } = setsChangeStatus;
105
92
  updateChangesStatus(createdTr, changeSet, ids, status, userID, oldState);
106
93
  setAction(createdTr, TrackChangesAction.refreshChanges, true);
107
94
  }
95
+ else {
96
+ createdTr = trackChanges(tr, createdTr, oldState, userID, skipTrsWithMetas) || createdTr;
97
+ }
98
+ docChanged = docChanged || tr.docChanged;
108
99
  });
109
100
  const changed = pluginState.changeSet.hasInconsistentData &&
110
101
  fixInconsistentChanges(pluginState.changeSet, userID, createdTr, oldState.schema);
@@ -0,0 +1,44 @@
1
+ /*!
2
+ * © 2025 Atypon Systems LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { getAction, TrackChangesAction } from './actions';
17
+ import { processStepsBeforeTracking } from './tracking/lib/processStepsBeforeTracking';
18
+ import { trackTransaction } from './tracking/trackTransaction';
19
+ import { changeMovedToInsertsOnSourceDeletion, filterMeaninglessMoveSteps, getIndentationOperationSteps, getMoveOperationsSteps, trFromHistory, } from './tracking/transactionProcessing';
20
+ export function trackChanges(tr, createdTr, oldState, userID, skipTrsWithMetas) {
21
+ var _a;
22
+ const wasAppended = tr.getMeta('appendedTransaction');
23
+ const skipMetaUsed = skipTrsWithMetas.some((m) => tr.getMeta(m) || (wasAppended === null || wasAppended === void 0 ? void 0 : wasAppended.getMeta(m)));
24
+ const skipTrackUsed = getAction(tr, TrackChangesAction.skipTrack) ||
25
+ (wasAppended && getAction(wasAppended, TrackChangesAction.skipTrack));
26
+ if (tr.docChanged &&
27
+ !skipMetaUsed &&
28
+ !skipTrackUsed &&
29
+ !trFromHistory(tr) &&
30
+ !(wasAppended && tr.getMeta('origin') === 'paragraphs')) {
31
+ const action = (_a = getAction(tr, TrackChangesAction.indentationAction)) === null || _a === void 0 ? void 0 : _a.action;
32
+ const trContext = {
33
+ action,
34
+ stepsByGroupIDMap: new Map(),
35
+ };
36
+ const clearedSteps = processStepsBeforeTracking(tr, trContext, [
37
+ getMoveOperationsSteps,
38
+ getIndentationOperationSteps,
39
+ filterMeaninglessMoveSteps,
40
+ ]);
41
+ changeMovedToInsertsOnSourceDeletion(tr, createdTr, trContext);
42
+ return trackTransaction(tr, oldState, createdTr, userID, clearedSteps, trContext);
43
+ }
44
+ }
@@ -1,31 +1,26 @@
1
- import { Fragment, Slice } from 'prosemirror-model';
2
- import { log } from '../utils/logger';
3
- import { matchInserted } from './matchInserted';
4
- function cutFragment(matched, deleted, content) {
5
- const newContent = [];
6
- for (let i = 0; matched <= deleted && i < content.childCount; i += 1) {
7
- const child = content.child(i);
8
- if (!child.isText && child.content.size > 0) {
9
- const cut = cutFragment(matched + 1, deleted, child.content);
10
- matched = cut[0];
11
- newContent.push(...cut[1].content);
12
- }
13
- else if (child.isText && matched + child.nodeSize > deleted) {
14
- if (deleted - matched > 0) {
15
- newContent.push(child.cut(deleted - matched));
16
- }
17
- else {
18
- newContent.push(child);
19
- }
20
- matched = deleted + 1;
21
- }
22
- else {
23
- matched += child.nodeSize;
24
- }
25
- }
26
- return [matched, Fragment.fromArray(newContent)];
27
- }
28
- export function diffChangeSteps(deleted, inserted) {
1
+ /*!
2
+ * © 2025 Atypon Systems LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { Slice } from 'prosemirror-model';
17
+ import { cutFragment } from '../../helpers/fragment';
18
+ import { log } from '../../utils/logger';
19
+ import { matchInserted } from '../lib/matchInserted';
20
+ export function diffChangeSteps(steps) {
21
+ const deleted = steps.filter((s) => s.type !== 'insert-slice');
22
+ const inserted = steps.filter((s) => s.type === 'insert-slice');
23
+ log.info('INSERT STEPS: ', inserted);
29
24
  const updated = [];
30
25
  let updatedDeleted = [...deleted];
31
26
  inserted.forEach((ins) => {
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * © 2023 Atypon Systems LLC
2
+ * © 2025 Atypon Systems LLC
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -10,17 +10,16 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  import { Mapping, ReplaceStep } from 'prosemirror-transform';
13
- import { addTrackIdIfDoesntExist, getBlockInlineTrackedData } from '../compute/nodeHelpers';
14
- import { deleteOrSetNodeDeleted } from '../mutate/deleteNode';
15
- import { deleteTextIfInserted } from '../mutate/deleteText';
16
- import { mergeTrackedMarks } from '../mutate/mergeTrackedMarks';
17
- import { CHANGE_OPERATION, CHANGE_STATUS } from '../types/change';
18
- import { log } from '../utils/logger';
19
- import * as trackUtils from '../utils/track-utils';
20
- export function processChangeSteps(changes, startPos, newTr, emptyAttrs, schema, deletedNodeMapping) {
13
+ import { addTrackIdIfDoesntExist, createNewDeleteAttrs, createNewUpdateAttrs, getBlockInlineTrackedData, } from '../../helpers/attributes';
14
+ import { CHANGE_OPERATION, CHANGE_STATUS } from '../../types/change';
15
+ import { log } from '../../utils/logger';
16
+ import { deleteOrSetNodeDeleted } from '../lib/deleteNode';
17
+ import { deleteTextIfInserted } from '../lib/deleteTextIfInserted';
18
+ import { mergeTrackedMarks } from '../lib/mergeTrackedMarks';
19
+ export function processChangeSteps(changes, newTr, emptyAttrs, schema, deletedNodeMapping) {
21
20
  const mapping = new Mapping();
22
- const deleteAttrs = trackUtils.createNewDeleteAttrs(emptyAttrs);
23
- let selectionPos = startPos;
21
+ const deleteAttrs = createNewDeleteAttrs(emptyAttrs);
22
+ let selectionPos = undefined;
24
23
  let deletesCounter = 0;
25
24
  let isInserted = false;
26
25
  let prevDelete;
@@ -130,7 +129,7 @@ export function processChangeSteps(changes, startPos, newTr, emptyAttrs, schema,
130
129
  const oldAttrs = restAttrs;
131
130
  const newDataTracked = [...oldDataTracked.filter((d) => !oldUpdate || d.id !== oldUpdate.id)];
132
131
  const newUpdate = oldUpdate && oldUpdate.status !== CHANGE_STATUS.rejected
133
- ? Object.assign(Object.assign({}, oldUpdate), { updatedAt: emptyAttrs.updatedAt }) : addTrackIdIfDoesntExist(trackUtils.createNewUpdateAttrs(emptyAttrs, c.node.attrs));
132
+ ? Object.assign(Object.assign({}, oldUpdate), { updatedAt: emptyAttrs.updatedAt }) : addTrackIdIfDoesntExist(createNewUpdateAttrs(emptyAttrs, c.node.attrs));
134
133
  if ((JSON.stringify(oldAttrs) !== JSON.stringify(c.newAttrs) ||
135
134
  c.node.type === c.node.type.schema.nodes.citation) &&
136
135
  !oldDataTracked.find((d) => (d.operation === CHANGE_OPERATION.insert || d.operation === CHANGE_OPERATION.wrap_with_node) &&
@@ -0,0 +1,49 @@
1
+ /*!
2
+ * © 2025 Atypon Systems LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { NodeSelection as NodeSelectionClass, TextSelection } from 'prosemirror-state';
17
+ import { Mapping, ReplaceStep } from 'prosemirror-transform';
18
+ import { isStructuralChange } from '../changeHelpers/structureChange';
19
+ export const getSelectionStaticConstructor = (sel) => Object.getPrototypeOf(sel).constructor;
20
+ export function fixAndSetSelectionAfterTracking(newTr, oldTr, deletedNodeMapping, trContext) {
21
+ const wasNodeSelection = oldTr.selection instanceof NodeSelectionClass;
22
+ if (!wasNodeSelection && !oldTr.selectionSet && trContext.selectionPosFromInsertion) {
23
+ const sel = getSelectionStaticConstructor(oldTr.selection);
24
+ const near = sel.near(newTr.doc.resolve(trContext.selectionPosFromInsertion), -1);
25
+ newTr.setSelection(near);
26
+ }
27
+ if (oldTr.selectionSet && oldTr.selection instanceof TextSelection) {
28
+ let from = oldTr.selection.from;
29
+ if (isStructuralChange(oldTr)) {
30
+ const selectionMapping = new Mapping();
31
+ oldTr.steps.map((step) => {
32
+ const isDeleteStep = step instanceof ReplaceStep && step.from !== step.to && step.slice.size === 0;
33
+ if (isDeleteStep) {
34
+ selectionMapping.appendMap(step.getMap().invert());
35
+ }
36
+ });
37
+ selectionMapping.appendMapping(deletedNodeMapping);
38
+ from = selectionMapping.map(oldTr.selection.from);
39
+ }
40
+ const newPos = newTr.doc.resolve(from);
41
+ newTr.setSelection(new TextSelection(newPos));
42
+ }
43
+ if (wasNodeSelection) {
44
+ const mappedPos = newTr.mapping.map(oldTr.selection.from, -1);
45
+ const sel = getSelectionStaticConstructor(oldTr.selection);
46
+ newTr.setSelection(sel.create(newTr.doc, mappedPos));
47
+ }
48
+ return newTr;
49
+ }
@@ -1,9 +1,9 @@
1
1
  import { Fragment } from 'prosemirror-model';
2
- import { setFragmentAsInserted } from '../compute/setFragmentAsInserted';
3
- import { splitSliceIntoMergedParts } from '../compute/splitSliceIntoMergedParts';
4
- import { stepIsLift } from '../steps/utils';
5
- import * as trackUtils from '../utils/track-utils';
6
- export function deleteAndMergeSplitNodes(from, to, gap, startDoc, newTr, schema, trackAttrs, insertSlice) {
2
+ import { createNewInsertAttrs } from '../../helpers/attributes';
3
+ import { setFragmentAsInserted } from '../../helpers/fragment';
4
+ import { isLiftStepForGap } from '../steps-trackers/qualifiers';
5
+ import { splitSliceIntoMergedParts } from './splitSliceIntoMergedParts';
6
+ export function deleteAndMergeSplitNodes(from, to, gap, startDoc, schema, trackAttrs, insertSlice) {
7
7
  const steps = [];
8
8
  if (from === to) {
9
9
  return {
@@ -34,7 +34,7 @@ export function deleteAndMergeSplitNodes(from, to, gap, startDoc, newTr, schema,
34
34
  const mergeEndNode = startTokenDeleted && openEnd > 0 && depth === openEnd && mergeContent;
35
35
  const mergeEndNodeNotEmpty = mergeEndNode && mergeContent.size;
36
36
  if (mergeEndNode && !mergeEndNodeNotEmpty && gap) {
37
- if (stepIsLift(gap, node, to)) {
37
+ if (isLiftStepForGap(gap, node, to)) {
38
38
  gap.slice.content.forEach((node, offset) => {
39
39
  steps.push({
40
40
  type: 'delete-node',
@@ -53,7 +53,7 @@ export function deleteAndMergeSplitNodes(from, to, gap, startDoc, newTr, schema,
53
53
  from,
54
54
  to,
55
55
  node,
56
- fragment: setFragmentAsInserted(mergeContent, trackUtils.createNewInsertAttrs(trackAttrs), schema),
56
+ fragment: setFragmentAsInserted(mergeContent, createNewInsertAttrs(trackAttrs), schema),
57
57
  });
58
58
  }
59
59
  else if (node.isText) {
@@ -1,11 +1,10 @@
1
1
  import { Fragment } from 'prosemirror-model';
2
- import { addTrackIdIfDoesntExist, getBlockInlineTrackedData } from '../compute/nodeHelpers';
3
- import { CHANGE_OPERATION, CHANGE_STATUS } from '../types/change';
4
- import { log } from '../utils/logger';
5
- import { dropStructuralChangeShadow } from './dropStructureChange';
2
+ import { dropStructuralChangeShadow } from '../../changeHelpers/structureChange';
3
+ import { addTrackIdIfDoesntExist, getBlockInlineTrackedData } from '../../helpers/attributes';
4
+ import { CHANGE_OPERATION, CHANGE_STATUS } from '../../types/change';
5
+ import { log } from '../../utils/logger';
6
6
  export function deleteNode(node, pos, tr) {
7
7
  var _a;
8
- const startPos = tr.doc.resolve(pos + 1);
9
8
  const resPos = tr.doc.resolve(pos);
10
9
  const canMergeToNodeAbove = resPos.parent !== tr.doc && resPos.nodeBefore && node.isBlock && ((_a = node.firstChild) === null || _a === void 0 ? void 0 : _a.isText);
11
10
  if (canMergeToNodeAbove) {
@@ -1,5 +1,5 @@
1
1
  import { Fragment } from 'prosemirror-model';
2
- import { addTrackIdIfDoesntExist, getMergeableMarkTrackedAttrs } from '../compute/nodeHelpers';
2
+ import { addTrackIdIfDoesntExist, getMergeableMarkTrackedAttrs, } from '../../helpers/attributes';
3
3
  export function deleteTextIfInserted(node, pos, newTr, schema, deleteAttrs, from, to) {
4
4
  const start = from ? Math.max(pos, from) : pos;
5
5
  const nodeEnd = pos + node.nodeSize;
@@ -1,3 +1,18 @@
1
+ /*!
2
+ * © 2023 Atypon Systems LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
1
16
  var __rest = (this && this.__rest) || function (s, e) {
2
17
  var t = {};
3
18
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -9,29 +24,6 @@ var __rest = (this && this.__rest) || function (s, e) {
9
24
  }
10
25
  return t;
11
26
  };
12
- function matchText(adjDeleted, insNode, offset, matchedDeleted, deleted) {
13
- const { pos, from, to, node: delNode } = adjDeleted;
14
- let j = offset, d = from - pos, maxSteps = to - Math.max(pos, from);
15
- for (; maxSteps !== j && insNode.text[j] !== undefined && insNode.text[j] === delNode.text[d]; j += 1, d += 1) {
16
- matchedDeleted += 1;
17
- }
18
- deleted = deleted.filter((d) => d !== adjDeleted);
19
- if (maxSteps !== j) {
20
- deleted.push({
21
- pos,
22
- from: from + j - offset,
23
- to,
24
- type: 'delete-text',
25
- node: delNode,
26
- });
27
- return [matchedDeleted, deleted];
28
- }
29
- const nextTextDelete = deleted.find((d) => d.type === 'delete-text' && d.pos === to);
30
- if (nextTextDelete) {
31
- return matchText(nextTextDelete, insNode, j, matchedDeleted, deleted);
32
- }
33
- return [matchedDeleted, deleted];
34
- }
35
27
  export function matchInserted(matchedDeleted, deleted, inserted) {
36
28
  var _a;
37
29
  let matched = [matchedDeleted, deleted];
@@ -1,5 +1,5 @@
1
- import { shouldMergeTrackedAttributes } from '../compute/nodeHelpers';
2
- import { uuidv4 } from '../utils/uuidv4';
1
+ import { shouldMergeTrackedAttributes } from '../../helpers/attributes';
2
+ import { uuidv4 } from '../../utils/uuidv4';
3
3
  const assignId = (attrs, leftDataTracked, rightDataTracked) => {
4
4
  if (attrs.id === leftDataTracked.id || attrs.id === rightDataTracked.id) {
5
5
  return Object.assign(Object.assign({}, attrs), { id: uuidv4() });
@@ -0,0 +1,14 @@
1
+ import { log } from '../../utils/logger';
2
+ export function processStepsBeforeTracking(tr, trContext, processors) {
3
+ let steps = [];
4
+ processors.forEach((p) => {
5
+ const res = p(tr, trContext);
6
+ if (res) {
7
+ steps = res;
8
+ if (steps.length < tr.steps.length) {
9
+ log.warn('Bug! A processor function filtered steps incorrectly. Filtered out steps should be replaced with null and not popped out of the array. Length and order has to be preserved');
10
+ }
11
+ }
12
+ });
13
+ return steps;
14
+ }
@@ -13,8 +13,9 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { ReplaceStep } from 'prosemirror-transform';
17
- import { TrackChangesAction } from '../actions';
16
+ import { ChangeSet } from '../../ChangeSet';
17
+ import { CHANGE_OPERATION, CHANGE_STATUS } from '../../types/change';
18
+ export const isDeleteStep = (step) => step.from !== step.to && step.slice.content.size < step.to - step.from;
18
19
  export const isSplitStep = (step, selection, uiEvent) => {
19
20
  var _a, _b, _c, _d;
20
21
  const { from, to, slice } = step;
@@ -53,10 +54,34 @@ export const isLiftStep = (step) => {
53
54
  }
54
55
  return false;
55
56
  };
56
- export function stepIsLift(gap, node, to) {
57
+ export function isLiftStepForGap(gap, node, to) {
57
58
  return gap.start < gap.end && gap.insert === 0 && gap.end === to && !node.isText;
58
59
  }
59
- export const isStructureSteps = (tr) => tr.getMeta(TrackChangesAction.structuralChangeAction) &&
60
- tr.steps.length === 2 &&
61
- tr.steps[0] instanceof ReplaceStep &&
62
- tr.steps[1] instanceof ReplaceStep;
60
+ export const isDirectPendingMoveDeletion = (step, doc, movingSteps) => {
61
+ if (step.from === step.to || step.slice.content.size > 0) {
62
+ return false;
63
+ }
64
+ if (movingSteps.has(step)) {
65
+ return false;
66
+ }
67
+ const node = doc.nodeAt(step.from);
68
+ if (!node) {
69
+ return false;
70
+ }
71
+ return ChangeSet.isPendingChange(node.attrs.dataTracked, CHANGE_OPERATION.move);
72
+ };
73
+ export const isDeletingPendingMovedNode = (step, doc) => {
74
+ if (!step.slice || step.from === step.to || step.slice.content.size > 0) {
75
+ return undefined;
76
+ }
77
+ const node = doc.nodeAt(step.from);
78
+ if (!node) {
79
+ return undefined;
80
+ }
81
+ const trackedAttrs = node.attrs.dataTracked;
82
+ const found = trackedAttrs === null || trackedAttrs === void 0 ? void 0 : trackedAttrs.find((tracked) => tracked.operation === CHANGE_OPERATION.move && tracked.status === CHANGE_STATUS.pending);
83
+ if (found === null || found === void 0 ? void 0 : found.moveNodeId) {
84
+ return found.moveNodeId;
85
+ }
86
+ return undefined;
87
+ };
@@ -24,8 +24,8 @@ var __rest = (this && this.__rest) || function (s, e) {
24
24
  }
25
25
  return t;
26
26
  };
27
- import { log } from '../utils/logger';
28
- function trackAttrsChange(step, oldState, tr, newTr, attrs, currentStepDoc) {
27
+ import { log } from '../../utils/logger';
28
+ function trackAttrsChangeStep(step, oldState, tr, newTr, attrs, currentStepDoc) {
29
29
  const newStep = step.invert(currentStepDoc);
30
30
  const stepResult = newTr.maybeStep(newStep);
31
31
  if (stepResult.failed) {
@@ -45,4 +45,4 @@ function trackAttrsChange(step, oldState, tr, newTr, attrs, currentStepDoc) {
45
45
  };
46
46
  return [changeStep];
47
47
  }
48
- export default trackAttrsChange;
48
+ export default trackAttrsChangeStep;
@@ -1,7 +1,8 @@
1
1
  import { AddMarkStep, AddNodeMarkStep, RemoveMarkStep } from 'prosemirror-transform';
2
- import { CHANGE_OPERATION } from '../types/change';
3
- import { createNewDeleteAttrs, createNewInsertAttrs, isValidTrackableMark } from '../utils/track-utils';
4
- import { uuidv4 } from '../utils/uuidv4';
2
+ import { createNewDeleteAttrs, createNewInsertAttrs } from '../../helpers/attributes';
3
+ import { isValidTrackableMark } from '../../helpers/mark';
4
+ import { CHANGE_OPERATION } from '../../types/change';
5
+ import { uuidv4 } from '../../utils/uuidv4';
5
6
  function markHasOp(mark, operation) {
6
7
  if (mark.attrs.dataTracked && Array.isArray(mark.attrs.dataTracked)) {
7
8
  const dtAttrs = mark.attrs.dataTracked;
@@ -88,6 +89,8 @@ export function trackRemoveNodeMarkStep(step, emptyAttrs, newTr, doc) {
88
89
  }
89
90
  }
90
91
  try {
92
+ const inverted = step.invert(doc);
93
+ newTr.step(inverted);
91
94
  newTr.step(newStep);
92
95
  }
93
96
  catch (e) {
@@ -1,10 +1,10 @@
1
1
  import { Slice } from 'prosemirror-model';
2
- import { TrackChangesAction } from '../actions';
3
- import { setFragmentAsInserted, setFragmentAsWrapChange } from '../compute/setFragmentAsInserted';
4
- import { deleteAndMergeSplitNodes } from '../mutate/deleteAndMergeSplitNodes';
5
- import { log } from '../utils/logger';
6
- import * as trackUtils from '../utils/track-utils';
7
- import { isLiftStep, isWrapStep } from './utils';
2
+ import { TrackChangesAction } from '../../actions';
3
+ import { createNewInsertAttrs } from '../../helpers/attributes';
4
+ import { setFragmentAsInserted, setFragmentAsWrapChange } from '../../helpers/fragment';
5
+ import { log } from '../../utils/logger';
6
+ import { deleteAndMergeSplitNodes } from '../lib/deleteAndMergeSplitNodes';
7
+ import { isLiftStep, isWrapStep } from './qualifiers';
8
8
  function preserveDataTrackedFromPreviousStep(newTr, step, newStep) {
9
9
  const prevDoc = newTr.docs[newTr.docs.length - 2];
10
10
  if (prevDoc && (step.slice.openEnd || step.slice.openStart)) {
@@ -30,16 +30,15 @@ export function trackReplaceAroundStep(step, oldState, tr, newTr, attrs, current
30
30
  preserveDataTrackedFromPreviousStep(newTr, step, newStep);
31
31
  const gap = currentStepDoc.slice(gapFrom, gapTo);
32
32
  log.info('RETAINED GAP CONTENT', gap);
33
- let { sliceWasSplit, newSliceContent, steps: deleteSteps, } = deleteAndMergeSplitNodes(from, to, { start: gapFrom, end: gapTo, slice: gap, insert }, newTr.doc, newTr, oldState.schema, attrs, slice);
33
+ let { sliceWasSplit, newSliceContent, steps: deleteSteps, } = deleteAndMergeSplitNodes(from, to, { start: gapFrom, end: gapTo, slice: gap, insert }, newTr.doc, oldState.schema, attrs, slice);
34
34
  let fragment;
35
35
  if (isWrapStep(step)) {
36
36
  fragment = setFragmentAsWrapChange(newSliceContent, attrs, oldState.schema);
37
37
  }
38
38
  else {
39
- fragment = setFragmentAsInserted(newSliceContent, trackUtils.createNewInsertAttrs(attrs), oldState.schema);
39
+ fragment = setFragmentAsInserted(newSliceContent, createNewInsertAttrs(attrs), oldState.schema);
40
40
  }
41
41
  let steps = deleteSteps;
42
- log.info('TR: new steps after applying delete', [...newTr.steps]);
43
42
  log.info('DELETE STEPS: ', deleteSteps);
44
43
  let liftStep = isLiftStep(step);
45
44
  if (liftStep) {
@@ -71,7 +70,7 @@ export function trackReplaceAroundStep(step, oldState, tr, newTr, attrs, current
71
70
  ? insertedSlice.content.append(trContext.liftFragment)
72
71
  : insertedSlice.content;
73
72
  if (tr.steps.indexOf(step) === 0) {
74
- const fragmentTracked = setFragmentAsInserted(trContext.liftFragment, trackUtils.createNewInsertAttrs(attrs), oldState.schema);
73
+ const fragmentTracked = setFragmentAsInserted(trContext.liftFragment, createNewInsertAttrs(attrs), oldState.schema);
75
74
  steps.push({
76
75
  type: 'insert-slice',
77
76
  from: from,