@manuscripts/track-changes-plugin 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1195,23 +1195,21 @@ function trackReplaceAroundStep(step, oldState, newTr, attrs) {
1195
1195
  * See the License for the specific language governing permissions and
1196
1196
  * limitations under the License.
1197
1197
  */
1198
- function trackReplaceStep(step, oldState, newTr, attrs) {
1198
+ function trackReplaceStep(step, oldState, newTr, attrs, stepResult, currentStepDoc) {
1199
1199
  log.info('###### ReplaceStep ######');
1200
1200
  let selectionPos = 0, changeSteps = [];
1201
+ // Invert the transaction step to prevent it from actually deleting or inserting anything
1201
1202
  step.getMap().forEach((fromA, toA, fromB, toB) => {
1202
1203
  log.info(`changed ranges: ${fromA} ${toA} ${fromB} ${toB}`);
1203
1204
  const { slice } = step;
1204
- // Invert the transaction step to prevent it from actually deleting or inserting anything
1205
- const newStep = step.invert(oldState.doc);
1206
- const stepResult = newTr.maybeStep(newStep);
1207
- if (stepResult.failed) {
1208
- log.error(`invert ReplaceStep failed: "${stepResult.failed}"`, newStep);
1209
- return;
1210
- }
1211
1205
  log.info('TR: steps before applying delete', [...newTr.steps]);
1212
1206
  // First apply the deleted range and update the insert slice to not include content that was deleted,
1213
1207
  // eg partial nodes in an open-ended slice
1214
- const { sliceWasSplit, newSliceContent, steps: deleteSteps, } = deleteAndMergeSplitNodes(fromA, toA, undefined, oldState.doc, newTr, oldState.schema, attrs, slice);
1208
+ if (stepResult.failed) {
1209
+ log.error(`invert ReplaceStep failed: "${stepResult.failed}"`);
1210
+ return;
1211
+ }
1212
+ const { sliceWasSplit, newSliceContent, steps: deleteSteps, } = deleteAndMergeSplitNodes(fromA, toA, undefined, currentStepDoc, newTr, oldState.schema, attrs, slice);
1215
1213
  changeSteps.push(...deleteSteps);
1216
1214
  log.info('TR: steps after applying delete', [...newTr.steps]);
1217
1215
  log.info('DELETE STEPS: ', changeSteps);
@@ -1635,6 +1633,7 @@ const isHighlightMarkerNode = (node) => node && node.type === node.type.schema.n
1635
1633
  * @returns newTr that inverts the initial tr and applies track attributes/marks
1636
1634
  */
1637
1635
  function trackTransaction(tr, oldState, newTr, authorID) {
1636
+ var _a, _b, _c, _d;
1638
1637
  const emptyAttrs = {
1639
1638
  authorID,
1640
1639
  reviewedByID: null,
@@ -1647,33 +1646,35 @@ function trackTransaction(tr, oldState, newTr, authorID) {
1647
1646
  const wasNodeSelection = tr.selection instanceof prosemirrorState.NodeSelection;
1648
1647
  let iters = 0;
1649
1648
  log.info('ORIGINAL transaction', tr);
1650
- tr.steps.forEach((step) => {
1651
- var _a, _b, _c, _d;
1649
+ for (let i = tr.steps.length - 1; i >= 0; i--) {
1650
+ const step = tr.steps[i];
1652
1651
  log.info('transaction step', step);
1653
1652
  iters += 1;
1654
1653
  if (iters > 20) {
1655
1654
  console.error('@manuscripts/track-changes-plugin: Possible infinite loop in iterating tr.steps, tracking skipped!\n' +
1656
1655
  'This is probably an error with the library, please report back to maintainers with a reproduction if possible', newTr);
1657
- return;
1656
+ continue;
1658
1657
  }
1659
1658
  else if (!(step instanceof prosemirrorTransform.ReplaceStep) && step.constructor.name === 'ReplaceStep') {
1660
1659
  console.error('@manuscripts/track-changes-plugin: Multiple prosemirror-transform packages imported, alias/dedupe them ' +
1661
1660
  'or instanceof checks fail as well as creating new steps');
1662
- return;
1661
+ continue;
1663
1662
  }
1664
1663
  else if (step instanceof prosemirrorTransform.ReplaceStep) {
1665
1664
  const { slice } = step;
1666
1665
  if (((_b = (_a = slice === null || slice === void 0 ? void 0 : slice.content) === null || _a === void 0 ? void 0 : _a.content) === null || _b === void 0 ? void 0 : _b.length) === 1 &&
1667
1666
  isHighlightMarkerNode(slice.content.content[0])) {
1668
1667
  // don't track highlight marker nodes
1669
- return;
1668
+ continue;
1670
1669
  }
1671
- let [steps, startPos] = trackReplaceStep(step, oldState, newTr, emptyAttrs);
1670
+ const newStep = step.invert(tr.docs[i]);
1671
+ const stepResult = newTr.maybeStep(newStep);
1672
+ let [steps, startPos] = trackReplaceStep(step, oldState, newTr, emptyAttrs, stepResult, tr.docs[i]);
1672
1673
  if (steps.length === 1) {
1673
1674
  const step = steps[0]; // eslint-disable-line @typescript-eslint/no-explicit-any
1674
1675
  if (isHighlightMarkerNode((step === null || step === void 0 ? void 0 : step.node) || ((_d = (_c = step === null || step === void 0 ? void 0 : step.slice) === null || _c === void 0 ? void 0 : _c.content) === null || _d === void 0 ? void 0 : _d.content[0]))) {
1675
1676
  // don't track deleted highlight marker nodes
1676
- return;
1677
+ continue;
1677
1678
  }
1678
1679
  }
1679
1680
  log.info('CHANGES: ', steps);
@@ -1713,10 +1714,11 @@ function trackTransaction(tr, oldState, newTr, authorID) {
1713
1714
  // after track-changes plugin.
1714
1715
  tr.getMeta('inputType') && newTr.setMeta('inputType', tr.getMeta('inputType'));
1715
1716
  tr.getMeta('uiEvent') && newTr.setMeta('uiEvent', tr.getMeta('uiEvent'));
1716
- });
1717
+ }
1717
1718
  // This is kinda hacky solution at the moment to maintain NodeSelections over transactions
1718
1719
  // These are required by at least cross-references and links to activate their selector pop-ups
1719
1720
  if (wasNodeSelection) {
1721
+ console.log('%c Getting into node select! ', 'background: #222; color: #bada55');
1720
1722
  // And -1 here is necessary to keep the selection pointing at the start of the node
1721
1723
  // (or something, breaks with cross-references otherwise)
1722
1724
  const mappedPos = newTr.mapping.map(tr.selection.from, -1);
package/dist/index.js CHANGED
@@ -1187,23 +1187,21 @@ function trackReplaceAroundStep(step, oldState, newTr, attrs) {
1187
1187
  * See the License for the specific language governing permissions and
1188
1188
  * limitations under the License.
1189
1189
  */
1190
- function trackReplaceStep(step, oldState, newTr, attrs) {
1190
+ function trackReplaceStep(step, oldState, newTr, attrs, stepResult, currentStepDoc) {
1191
1191
  log.info('###### ReplaceStep ######');
1192
1192
  let selectionPos = 0, changeSteps = [];
1193
+ // Invert the transaction step to prevent it from actually deleting or inserting anything
1193
1194
  step.getMap().forEach((fromA, toA, fromB, toB) => {
1194
1195
  log.info(`changed ranges: ${fromA} ${toA} ${fromB} ${toB}`);
1195
1196
  const { slice } = step;
1196
- // Invert the transaction step to prevent it from actually deleting or inserting anything
1197
- const newStep = step.invert(oldState.doc);
1198
- const stepResult = newTr.maybeStep(newStep);
1199
- if (stepResult.failed) {
1200
- log.error(`invert ReplaceStep failed: "${stepResult.failed}"`, newStep);
1201
- return;
1202
- }
1203
1197
  log.info('TR: steps before applying delete', [...newTr.steps]);
1204
1198
  // First apply the deleted range and update the insert slice to not include content that was deleted,
1205
1199
  // eg partial nodes in an open-ended slice
1206
- const { sliceWasSplit, newSliceContent, steps: deleteSteps, } = deleteAndMergeSplitNodes(fromA, toA, undefined, oldState.doc, newTr, oldState.schema, attrs, slice);
1200
+ if (stepResult.failed) {
1201
+ log.error(`invert ReplaceStep failed: "${stepResult.failed}"`);
1202
+ return;
1203
+ }
1204
+ const { sliceWasSplit, newSliceContent, steps: deleteSteps, } = deleteAndMergeSplitNodes(fromA, toA, undefined, currentStepDoc, newTr, oldState.schema, attrs, slice);
1207
1205
  changeSteps.push(...deleteSteps);
1208
1206
  log.info('TR: steps after applying delete', [...newTr.steps]);
1209
1207
  log.info('DELETE STEPS: ', changeSteps);
@@ -1627,6 +1625,7 @@ const isHighlightMarkerNode = (node) => node && node.type === node.type.schema.n
1627
1625
  * @returns newTr that inverts the initial tr and applies track attributes/marks
1628
1626
  */
1629
1627
  function trackTransaction(tr, oldState, newTr, authorID) {
1628
+ var _a, _b, _c, _d;
1630
1629
  const emptyAttrs = {
1631
1630
  authorID,
1632
1631
  reviewedByID: null,
@@ -1639,33 +1638,35 @@ function trackTransaction(tr, oldState, newTr, authorID) {
1639
1638
  const wasNodeSelection = tr.selection instanceof NodeSelection;
1640
1639
  let iters = 0;
1641
1640
  log.info('ORIGINAL transaction', tr);
1642
- tr.steps.forEach((step) => {
1643
- var _a, _b, _c, _d;
1641
+ for (let i = tr.steps.length - 1; i >= 0; i--) {
1642
+ const step = tr.steps[i];
1644
1643
  log.info('transaction step', step);
1645
1644
  iters += 1;
1646
1645
  if (iters > 20) {
1647
1646
  console.error('@manuscripts/track-changes-plugin: Possible infinite loop in iterating tr.steps, tracking skipped!\n' +
1648
1647
  'This is probably an error with the library, please report back to maintainers with a reproduction if possible', newTr);
1649
- return;
1648
+ continue;
1650
1649
  }
1651
1650
  else if (!(step instanceof ReplaceStep) && step.constructor.name === 'ReplaceStep') {
1652
1651
  console.error('@manuscripts/track-changes-plugin: Multiple prosemirror-transform packages imported, alias/dedupe them ' +
1653
1652
  'or instanceof checks fail as well as creating new steps');
1654
- return;
1653
+ continue;
1655
1654
  }
1656
1655
  else if (step instanceof ReplaceStep) {
1657
1656
  const { slice } = step;
1658
1657
  if (((_b = (_a = slice === null || slice === void 0 ? void 0 : slice.content) === null || _a === void 0 ? void 0 : _a.content) === null || _b === void 0 ? void 0 : _b.length) === 1 &&
1659
1658
  isHighlightMarkerNode(slice.content.content[0])) {
1660
1659
  // don't track highlight marker nodes
1661
- return;
1660
+ continue;
1662
1661
  }
1663
- let [steps, startPos] = trackReplaceStep(step, oldState, newTr, emptyAttrs);
1662
+ const newStep = step.invert(tr.docs[i]);
1663
+ const stepResult = newTr.maybeStep(newStep);
1664
+ let [steps, startPos] = trackReplaceStep(step, oldState, newTr, emptyAttrs, stepResult, tr.docs[i]);
1664
1665
  if (steps.length === 1) {
1665
1666
  const step = steps[0]; // eslint-disable-line @typescript-eslint/no-explicit-any
1666
1667
  if (isHighlightMarkerNode((step === null || step === void 0 ? void 0 : step.node) || ((_d = (_c = step === null || step === void 0 ? void 0 : step.slice) === null || _c === void 0 ? void 0 : _c.content) === null || _d === void 0 ? void 0 : _d.content[0]))) {
1667
1668
  // don't track deleted highlight marker nodes
1668
- return;
1669
+ continue;
1669
1670
  }
1670
1671
  }
1671
1672
  log.info('CHANGES: ', steps);
@@ -1705,10 +1706,11 @@ function trackTransaction(tr, oldState, newTr, authorID) {
1705
1706
  // after track-changes plugin.
1706
1707
  tr.getMeta('inputType') && newTr.setMeta('inputType', tr.getMeta('inputType'));
1707
1708
  tr.getMeta('uiEvent') && newTr.setMeta('uiEvent', tr.getMeta('uiEvent'));
1708
- });
1709
+ }
1709
1710
  // This is kinda hacky solution at the moment to maintain NodeSelections over transactions
1710
1711
  // These are required by at least cross-references and links to activate their selector pop-ups
1711
1712
  if (wasNodeSelection) {
1713
+ console.log('%c Getting into node select! ', 'background: #222; color: #bada55');
1712
1714
  // And -1 here is necessary to keep the selection pointing at the start of the node
1713
1715
  // (or something, breaks with cross-references otherwise)
1714
1716
  const mappedPos = newTr.mapping.map(tr.selection.from, -1);
@@ -1,5 +1,21 @@
1
+ /*!
2
+ * © 2021 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 { Node as PMNode } from 'prosemirror-model';
1
17
  import type { EditorState, Transaction } from 'prosemirror-state';
2
- import { ReplaceStep } from 'prosemirror-transform';
18
+ import { ReplaceStep, StepResult } from 'prosemirror-transform';
3
19
  import { NewEmptyAttrs } from '../types/track';
4
20
  import { ChangeStep } from '../types/step';
5
- export declare function trackReplaceStep(step: ReplaceStep, oldState: EditorState, newTr: Transaction, attrs: NewEmptyAttrs): [ChangeStep[], number];
21
+ export declare function trackReplaceStep(step: ReplaceStep, oldState: EditorState, newTr: Transaction, attrs: NewEmptyAttrs, stepResult: StepResult, currentStepDoc: PMNode): [ChangeStep[], number];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@manuscripts/track-changes-plugin",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "author": "Atypon Systems LLC",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/Atypon-OpenSource/manuscripts-quarterback/tree/main/quarterback-packages/track-changes-plugin",