@manuscripts/track-changes-plugin 1.7.0 → 1.7.1-LEAN-2832
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 +71 -33
- package/dist/index.js +71 -33
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -469,7 +469,7 @@ function deleteNode(node, pos, tr) {
|
|
|
469
469
|
*/
|
|
470
470
|
function deleteOrSetNodeDeleted(node, pos, newTr, deleteAttrs) {
|
|
471
471
|
const dataTracked = getBlockInlineTrackedData(node);
|
|
472
|
-
const inserted = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === exports.CHANGE_OPERATION.insert);
|
|
472
|
+
const inserted = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === exports.CHANGE_OPERATION.insert && d.status === exports.CHANGE_STATUS.pending);
|
|
473
473
|
const deleted = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === exports.CHANGE_OPERATION.delete);
|
|
474
474
|
const updated = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === exports.CHANGE_OPERATION.set_node_attributes);
|
|
475
475
|
if (inserted && inserted.authorID === deleteAttrs.authorID) {
|
|
@@ -531,9 +531,7 @@ function updateChangeAttrs(tr, change, trackedAttrs, schema) {
|
|
|
531
531
|
return tr;
|
|
532
532
|
}
|
|
533
533
|
const { operation } = trackedAttrs;
|
|
534
|
-
const oldTrackData = change.type === 'text-change'
|
|
535
|
-
? getTextNodeTrackedMarkData(node, schema)
|
|
536
|
-
: getBlockInlineTrackedData(node);
|
|
534
|
+
const oldTrackData = change.type === 'text-change' ? getTextNodeTrackedMarkData(node, schema) : getBlockInlineTrackedData(node);
|
|
537
535
|
if (!operation) {
|
|
538
536
|
log.warn('updateChangeAttrs: unable to determine operation of change ', change);
|
|
539
537
|
}
|
|
@@ -554,7 +552,15 @@ function updateChangeAttrs(tr, change, trackedAttrs, schema) {
|
|
|
554
552
|
tr.setNodeMarkup(change.from, undefined, { ...node.attrs, dataTracked: null }, node.marks);
|
|
555
553
|
}
|
|
556
554
|
else if (change.type === 'node-change' || change.type === 'node-attr-change') {
|
|
557
|
-
const
|
|
555
|
+
const trackedDataSource = getBlockInlineTrackedData(node) || [];
|
|
556
|
+
const targetDataTracked = trackedDataSource.find((t) => change.id === t.id);
|
|
557
|
+
const newDataTracked = trackedDataSource.map((oldTrack) => {
|
|
558
|
+
if (targetDataTracked) {
|
|
559
|
+
if (oldTrack.id === targetDataTracked.id) {
|
|
560
|
+
return { ...oldTrack, ...trackedAttrs };
|
|
561
|
+
}
|
|
562
|
+
return oldTrack;
|
|
563
|
+
}
|
|
558
564
|
if (oldTrack.operation === operation) {
|
|
559
565
|
return { ...oldTrack, ...trackedAttrs };
|
|
560
566
|
}
|
|
@@ -578,6 +584,13 @@ function updateChangeChildrenAttributes(changes, tr, mapping) {
|
|
|
578
584
|
});
|
|
579
585
|
}
|
|
580
586
|
|
|
587
|
+
function getUpdatedDataTracked(dataTracked, changeId) {
|
|
588
|
+
if (!dataTracked) {
|
|
589
|
+
return null;
|
|
590
|
+
}
|
|
591
|
+
const newDataTracked = dataTracked.filter((c) => c.id !== changeId);
|
|
592
|
+
return newDataTracked.length ? newDataTracked : null;
|
|
593
|
+
}
|
|
581
594
|
/**
|
|
582
595
|
* Applies the accepted/rejected changes in the current document and sets them untracked
|
|
583
596
|
*
|
|
@@ -587,10 +600,12 @@ function updateChangeChildrenAttributes(changes, tr, mapping) {
|
|
|
587
600
|
* @param deleteMap
|
|
588
601
|
*/
|
|
589
602
|
function applyAcceptedRejectedChanges(tr, schema, changes, deleteMap = new prosemirrorTransform.Mapping()) {
|
|
603
|
+
const attrsChangesLog = new Map(); // map of node ids and applied change updatedAt timestamp
|
|
604
|
+
function addAttrLog(nodeId, changeId) {
|
|
605
|
+
const arr = attrsChangesLog.get(nodeId) || attrsChangesLog.set(nodeId, []).get(nodeId);
|
|
606
|
+
arr.push(changeId);
|
|
607
|
+
}
|
|
590
608
|
changes.forEach((change) => {
|
|
591
|
-
if (change.dataTracked.status === exports.CHANGE_STATUS.pending) {
|
|
592
|
-
return;
|
|
593
|
-
}
|
|
594
609
|
// Map change.from and skip those which dont need to be applied
|
|
595
610
|
// or were already deleted by an applied block delete
|
|
596
611
|
const { pos: from, deleted } = deleteMap.mapResult(change.from), node = tr.doc.nodeAt(from), noChangeNeeded = deleted || !ChangeSet.shouldDeleteChange(change);
|
|
@@ -598,6 +613,22 @@ function applyAcceptedRejectedChanges(tr, schema, changes, deleteMap = new prose
|
|
|
598
613
|
!deleted && log.warn('no node found to update for change', change);
|
|
599
614
|
return;
|
|
600
615
|
}
|
|
616
|
+
if (change.dataTracked.status === exports.CHANGE_STATUS.pending) {
|
|
617
|
+
if (ChangeSet.isNodeAttrChange(change)) {
|
|
618
|
+
/*
|
|
619
|
+
Apply pending changes for attributes as well because applying accepted/rejected changes may override
|
|
620
|
+
pending because we store the most recent change directly on the node attributes. But in case of pending attributes
|
|
621
|
+
we don't need to remove dataTracked record. We need, however, to make sure we don't restore dataTracked records for
|
|
622
|
+
the previously applied changes. To check for already applied changes we log them into "attrsChangesLog" Map.
|
|
623
|
+
*/
|
|
624
|
+
const { dataTracked, ...attrs } = change.newAttrs;
|
|
625
|
+
const changeLog = attrsChangesLog.get(node.attrs.id);
|
|
626
|
+
const newDataTracked = changeLog && changeLog.length ? dataTracked.filter((c) => !changeLog.includes(c.id)) : dataTracked;
|
|
627
|
+
tr.setNodeMarkup(from, undefined, { ...attrs, dataTracked: newDataTracked.length ? newDataTracked : null }, node.marks);
|
|
628
|
+
// default is "null" for dataTracked in attrs in pm schema, so codebase generally relies on it being null when empty
|
|
629
|
+
}
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
601
632
|
if (ChangeSet.isTextChange(change) && noChangeNeeded) {
|
|
602
633
|
tr.removeMark(from, deleteMap.map(change.to), schema.marks.tracked_insert);
|
|
603
634
|
tr.removeMark(from, deleteMap.map(change.to), schema.marks.tracked_delete);
|
|
@@ -621,13 +652,13 @@ function applyAcceptedRejectedChanges(tr, schema, changes, deleteMap = new prose
|
|
|
621
652
|
}
|
|
622
653
|
deleteMap.appendMap(tr.steps[tr.steps.length - 1].getMap());
|
|
623
654
|
}
|
|
624
|
-
else if (ChangeSet.isNodeAttrChange(change) &&
|
|
625
|
-
change.dataTracked.
|
|
626
|
-
|
|
655
|
+
else if (ChangeSet.isNodeAttrChange(change) && change.dataTracked.status === exports.CHANGE_STATUS.accepted) {
|
|
656
|
+
tr.setNodeMarkup(from, undefined, { ...change.newAttrs, dataTracked: getUpdatedDataTracked(node.attrs.dataTracked, change.id) }, node.marks);
|
|
657
|
+
addAttrLog(node.attrs.id, change.dataTracked.id);
|
|
627
658
|
}
|
|
628
|
-
else if (ChangeSet.isNodeAttrChange(change) &&
|
|
629
|
-
change.dataTracked.
|
|
630
|
-
|
|
659
|
+
else if (ChangeSet.isNodeAttrChange(change) && change.dataTracked.status === exports.CHANGE_STATUS.rejected) {
|
|
660
|
+
tr.setNodeMarkup(from, undefined, { ...change.oldAttrs, dataTracked: getUpdatedDataTracked(node.attrs.dataTracked, change.id) }, node.marks);
|
|
661
|
+
addAttrLog(node.attrs.id, change.dataTracked.id);
|
|
631
662
|
}
|
|
632
663
|
});
|
|
633
664
|
return deleteMap;
|
|
@@ -952,7 +983,7 @@ function createNewUpdateAttrs(attrs, oldAttrs) {
|
|
|
952
983
|
return {
|
|
953
984
|
...attrs,
|
|
954
985
|
operation: exports.CHANGE_OPERATION.set_node_attributes,
|
|
955
|
-
oldAttrs: restAttrs,
|
|
986
|
+
oldAttrs: JSON.parse(JSON.stringify(restAttrs)),
|
|
956
987
|
};
|
|
957
988
|
}
|
|
958
989
|
|
|
@@ -1203,7 +1234,8 @@ function trackReplaceAroundStep(step, oldState, tr, newTr, attrs) {
|
|
|
1203
1234
|
*/
|
|
1204
1235
|
function trackReplaceStep(step, oldState, newTr, attrs, stepResult, currentStepDoc) {
|
|
1205
1236
|
log.info('###### ReplaceStep ######');
|
|
1206
|
-
let selectionPos = 0
|
|
1237
|
+
let selectionPos = 0;
|
|
1238
|
+
const changeSteps = [];
|
|
1207
1239
|
// Invert the transaction step to prevent it from actually deleting or inserting anything
|
|
1208
1240
|
step.getMap().forEach((fromA, toA, fromB, toB) => {
|
|
1209
1241
|
var _a, _b;
|
|
@@ -1427,15 +1459,29 @@ function processChangeSteps(changes, startPos, newTr, emptyAttrs, schema) {
|
|
|
1427
1459
|
}
|
|
1428
1460
|
else if (c.type === 'update-node-attrs') {
|
|
1429
1461
|
const oldDataTracked = getBlockInlineTrackedData(c.node) || [];
|
|
1430
|
-
const oldUpdate = oldDataTracked.find((d) =>
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1462
|
+
const oldUpdate = oldDataTracked.reverse().find((d) => {
|
|
1463
|
+
// reversing to start from the most recent change
|
|
1464
|
+
if (d.operation === exports.CHANGE_OPERATION.set_node_attributes &&
|
|
1465
|
+
(d.status === exports.CHANGE_STATUS.pending || d.status === exports.CHANGE_STATUS.rejected)) {
|
|
1466
|
+
return true;
|
|
1467
|
+
}
|
|
1468
|
+
return false;
|
|
1469
|
+
});
|
|
1470
|
+
// if the selected last change is with status "rejected" we need to use oldAttrs from it because
|
|
1471
|
+
// node's actual attributes represent the "rejected" values
|
|
1472
|
+
const lastChangeRejected = oldUpdate && oldUpdate.status === exports.CHANGE_STATUS.rejected;
|
|
1473
|
+
const sourceAttrs = (oldUpdate === null || oldUpdate === void 0 ? void 0 : oldUpdate.oldAttrs) || c.node.attrs;
|
|
1474
|
+
const { dataTracked, ...restAttrs } = sourceAttrs;
|
|
1475
|
+
const oldAttrs = lastChangeRejected ? oldUpdate.oldAttrs : restAttrs;
|
|
1476
|
+
const newDataTracked = [
|
|
1477
|
+
...oldDataTracked.filter((d) => !oldUpdate || d.id !== oldUpdate.id || lastChangeRejected),
|
|
1478
|
+
];
|
|
1479
|
+
const newUpdate = oldUpdate && oldUpdate.status !== exports.CHANGE_STATUS.rejected
|
|
1434
1480
|
? {
|
|
1435
1481
|
...oldUpdate,
|
|
1436
1482
|
updatedAt: emptyAttrs.updatedAt,
|
|
1437
1483
|
}
|
|
1438
|
-
: addTrackIdIfDoesntExist(createNewUpdateAttrs(emptyAttrs, c.node.attrs));
|
|
1484
|
+
: addTrackIdIfDoesntExist(createNewUpdateAttrs(emptyAttrs, lastChangeRejected ? oldAttrs : c.node.attrs));
|
|
1439
1485
|
// Dont add update changes if there exists already an insert change for this node
|
|
1440
1486
|
if (JSON.stringify(oldAttrs) !== JSON.stringify(c.newAttrs) &&
|
|
1441
1487
|
!oldDataTracked.find((d) => d.operation === exports.CHANGE_OPERATION.insert)) {
|
|
@@ -1849,9 +1895,7 @@ const trackChangesPlugin = (opts = { userID: 'anonymous:Anonymous' }) => {
|
|
|
1849
1895
|
},
|
|
1850
1896
|
appendTransaction(trs, oldState, newState) {
|
|
1851
1897
|
const pluginState = trackChangesPluginKey.getState(newState);
|
|
1852
|
-
if (!pluginState ||
|
|
1853
|
-
pluginState.status === exports.TrackChangesStatus.disabled ||
|
|
1854
|
-
!(editorView === null || editorView === void 0 ? void 0 : editorView.editable)) {
|
|
1898
|
+
if (!pluginState || pluginState.status === exports.TrackChangesStatus.disabled || !(editorView === null || editorView === void 0 ? void 0 : editorView.editable)) {
|
|
1855
1899
|
return null;
|
|
1856
1900
|
}
|
|
1857
1901
|
const { userID, changeSet } = pluginState;
|
|
@@ -1860,13 +1904,8 @@ const trackChangesPlugin = (opts = { userID: 'anonymous:Anonymous' }) => {
|
|
|
1860
1904
|
trs.forEach((tr) => {
|
|
1861
1905
|
const wasAppended = tr.getMeta('appendedTransaction');
|
|
1862
1906
|
const skipMetaUsed = skipTrsWithMetas.some((m) => tr.getMeta(m) || (wasAppended === null || wasAppended === void 0 ? void 0 : wasAppended.getMeta(m)));
|
|
1863
|
-
const skipTrackUsed = getAction(tr, TrackChangesAction.skipTrack) ||
|
|
1864
|
-
|
|
1865
|
-
if (tr.docChanged &&
|
|
1866
|
-
!skipMetaUsed &&
|
|
1867
|
-
!skipTrackUsed &&
|
|
1868
|
-
!tr.getMeta('history$') &&
|
|
1869
|
-
!(wasAppended && tr.getMeta('origin') === 'paragraphs')) {
|
|
1907
|
+
const skipTrackUsed = getAction(tr, TrackChangesAction.skipTrack) || (wasAppended && getAction(wasAppended, TrackChangesAction.skipTrack));
|
|
1908
|
+
if (tr.docChanged && !skipMetaUsed && !skipTrackUsed && !tr.getMeta('history$') && !(wasAppended && tr.getMeta('origin') === 'paragraphs')) {
|
|
1870
1909
|
createdTr = trackTransaction(tr, oldState, createdTr, userID);
|
|
1871
1910
|
}
|
|
1872
1911
|
docChanged = docChanged || tr.docChanged;
|
|
@@ -1886,8 +1925,7 @@ const trackChangesPlugin = (opts = { userID: 'anonymous:Anonymous' }) => {
|
|
|
1886
1925
|
setAction(createdTr, TrackChangesAction.refreshChanges, true);
|
|
1887
1926
|
}
|
|
1888
1927
|
});
|
|
1889
|
-
const changed = pluginState.changeSet.hasInconsistentData &&
|
|
1890
|
-
fixInconsistentChanges(pluginState.changeSet, userID, createdTr, oldState.schema);
|
|
1928
|
+
const changed = pluginState.changeSet.hasInconsistentData && fixInconsistentChanges(pluginState.changeSet, userID, createdTr, oldState.schema);
|
|
1891
1929
|
if (changed) {
|
|
1892
1930
|
log.warn('had to fix inconsistent changes in', createdTr);
|
|
1893
1931
|
}
|
package/dist/index.js
CHANGED
|
@@ -461,7 +461,7 @@ function deleteNode(node, pos, tr) {
|
|
|
461
461
|
*/
|
|
462
462
|
function deleteOrSetNodeDeleted(node, pos, newTr, deleteAttrs) {
|
|
463
463
|
const dataTracked = getBlockInlineTrackedData(node);
|
|
464
|
-
const inserted = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === CHANGE_OPERATION.insert);
|
|
464
|
+
const inserted = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === CHANGE_OPERATION.insert && d.status === CHANGE_STATUS.pending);
|
|
465
465
|
const deleted = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === CHANGE_OPERATION.delete);
|
|
466
466
|
const updated = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === CHANGE_OPERATION.set_node_attributes);
|
|
467
467
|
if (inserted && inserted.authorID === deleteAttrs.authorID) {
|
|
@@ -523,9 +523,7 @@ function updateChangeAttrs(tr, change, trackedAttrs, schema) {
|
|
|
523
523
|
return tr;
|
|
524
524
|
}
|
|
525
525
|
const { operation } = trackedAttrs;
|
|
526
|
-
const oldTrackData = change.type === 'text-change'
|
|
527
|
-
? getTextNodeTrackedMarkData(node, schema)
|
|
528
|
-
: getBlockInlineTrackedData(node);
|
|
526
|
+
const oldTrackData = change.type === 'text-change' ? getTextNodeTrackedMarkData(node, schema) : getBlockInlineTrackedData(node);
|
|
529
527
|
if (!operation) {
|
|
530
528
|
log.warn('updateChangeAttrs: unable to determine operation of change ', change);
|
|
531
529
|
}
|
|
@@ -546,7 +544,15 @@ function updateChangeAttrs(tr, change, trackedAttrs, schema) {
|
|
|
546
544
|
tr.setNodeMarkup(change.from, undefined, { ...node.attrs, dataTracked: null }, node.marks);
|
|
547
545
|
}
|
|
548
546
|
else if (change.type === 'node-change' || change.type === 'node-attr-change') {
|
|
549
|
-
const
|
|
547
|
+
const trackedDataSource = getBlockInlineTrackedData(node) || [];
|
|
548
|
+
const targetDataTracked = trackedDataSource.find((t) => change.id === t.id);
|
|
549
|
+
const newDataTracked = trackedDataSource.map((oldTrack) => {
|
|
550
|
+
if (targetDataTracked) {
|
|
551
|
+
if (oldTrack.id === targetDataTracked.id) {
|
|
552
|
+
return { ...oldTrack, ...trackedAttrs };
|
|
553
|
+
}
|
|
554
|
+
return oldTrack;
|
|
555
|
+
}
|
|
550
556
|
if (oldTrack.operation === operation) {
|
|
551
557
|
return { ...oldTrack, ...trackedAttrs };
|
|
552
558
|
}
|
|
@@ -570,6 +576,13 @@ function updateChangeChildrenAttributes(changes, tr, mapping) {
|
|
|
570
576
|
});
|
|
571
577
|
}
|
|
572
578
|
|
|
579
|
+
function getUpdatedDataTracked(dataTracked, changeId) {
|
|
580
|
+
if (!dataTracked) {
|
|
581
|
+
return null;
|
|
582
|
+
}
|
|
583
|
+
const newDataTracked = dataTracked.filter((c) => c.id !== changeId);
|
|
584
|
+
return newDataTracked.length ? newDataTracked : null;
|
|
585
|
+
}
|
|
573
586
|
/**
|
|
574
587
|
* Applies the accepted/rejected changes in the current document and sets them untracked
|
|
575
588
|
*
|
|
@@ -579,10 +592,12 @@ function updateChangeChildrenAttributes(changes, tr, mapping) {
|
|
|
579
592
|
* @param deleteMap
|
|
580
593
|
*/
|
|
581
594
|
function applyAcceptedRejectedChanges(tr, schema, changes, deleteMap = new Mapping()) {
|
|
595
|
+
const attrsChangesLog = new Map(); // map of node ids and applied change updatedAt timestamp
|
|
596
|
+
function addAttrLog(nodeId, changeId) {
|
|
597
|
+
const arr = attrsChangesLog.get(nodeId) || attrsChangesLog.set(nodeId, []).get(nodeId);
|
|
598
|
+
arr.push(changeId);
|
|
599
|
+
}
|
|
582
600
|
changes.forEach((change) => {
|
|
583
|
-
if (change.dataTracked.status === CHANGE_STATUS.pending) {
|
|
584
|
-
return;
|
|
585
|
-
}
|
|
586
601
|
// Map change.from and skip those which dont need to be applied
|
|
587
602
|
// or were already deleted by an applied block delete
|
|
588
603
|
const { pos: from, deleted } = deleteMap.mapResult(change.from), node = tr.doc.nodeAt(from), noChangeNeeded = deleted || !ChangeSet.shouldDeleteChange(change);
|
|
@@ -590,6 +605,22 @@ function applyAcceptedRejectedChanges(tr, schema, changes, deleteMap = new Mappi
|
|
|
590
605
|
!deleted && log.warn('no node found to update for change', change);
|
|
591
606
|
return;
|
|
592
607
|
}
|
|
608
|
+
if (change.dataTracked.status === CHANGE_STATUS.pending) {
|
|
609
|
+
if (ChangeSet.isNodeAttrChange(change)) {
|
|
610
|
+
/*
|
|
611
|
+
Apply pending changes for attributes as well because applying accepted/rejected changes may override
|
|
612
|
+
pending because we store the most recent change directly on the node attributes. But in case of pending attributes
|
|
613
|
+
we don't need to remove dataTracked record. We need, however, to make sure we don't restore dataTracked records for
|
|
614
|
+
the previously applied changes. To check for already applied changes we log them into "attrsChangesLog" Map.
|
|
615
|
+
*/
|
|
616
|
+
const { dataTracked, ...attrs } = change.newAttrs;
|
|
617
|
+
const changeLog = attrsChangesLog.get(node.attrs.id);
|
|
618
|
+
const newDataTracked = changeLog && changeLog.length ? dataTracked.filter((c) => !changeLog.includes(c.id)) : dataTracked;
|
|
619
|
+
tr.setNodeMarkup(from, undefined, { ...attrs, dataTracked: newDataTracked.length ? newDataTracked : null }, node.marks);
|
|
620
|
+
// default is "null" for dataTracked in attrs in pm schema, so codebase generally relies on it being null when empty
|
|
621
|
+
}
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
593
624
|
if (ChangeSet.isTextChange(change) && noChangeNeeded) {
|
|
594
625
|
tr.removeMark(from, deleteMap.map(change.to), schema.marks.tracked_insert);
|
|
595
626
|
tr.removeMark(from, deleteMap.map(change.to), schema.marks.tracked_delete);
|
|
@@ -613,13 +644,13 @@ function applyAcceptedRejectedChanges(tr, schema, changes, deleteMap = new Mappi
|
|
|
613
644
|
}
|
|
614
645
|
deleteMap.appendMap(tr.steps[tr.steps.length - 1].getMap());
|
|
615
646
|
}
|
|
616
|
-
else if (ChangeSet.isNodeAttrChange(change) &&
|
|
617
|
-
change.dataTracked.
|
|
618
|
-
|
|
647
|
+
else if (ChangeSet.isNodeAttrChange(change) && change.dataTracked.status === CHANGE_STATUS.accepted) {
|
|
648
|
+
tr.setNodeMarkup(from, undefined, { ...change.newAttrs, dataTracked: getUpdatedDataTracked(node.attrs.dataTracked, change.id) }, node.marks);
|
|
649
|
+
addAttrLog(node.attrs.id, change.dataTracked.id);
|
|
619
650
|
}
|
|
620
|
-
else if (ChangeSet.isNodeAttrChange(change) &&
|
|
621
|
-
change.dataTracked.
|
|
622
|
-
|
|
651
|
+
else if (ChangeSet.isNodeAttrChange(change) && change.dataTracked.status === CHANGE_STATUS.rejected) {
|
|
652
|
+
tr.setNodeMarkup(from, undefined, { ...change.oldAttrs, dataTracked: getUpdatedDataTracked(node.attrs.dataTracked, change.id) }, node.marks);
|
|
653
|
+
addAttrLog(node.attrs.id, change.dataTracked.id);
|
|
623
654
|
}
|
|
624
655
|
});
|
|
625
656
|
return deleteMap;
|
|
@@ -944,7 +975,7 @@ function createNewUpdateAttrs(attrs, oldAttrs) {
|
|
|
944
975
|
return {
|
|
945
976
|
...attrs,
|
|
946
977
|
operation: CHANGE_OPERATION.set_node_attributes,
|
|
947
|
-
oldAttrs: restAttrs,
|
|
978
|
+
oldAttrs: JSON.parse(JSON.stringify(restAttrs)),
|
|
948
979
|
};
|
|
949
980
|
}
|
|
950
981
|
|
|
@@ -1195,7 +1226,8 @@ function trackReplaceAroundStep(step, oldState, tr, newTr, attrs) {
|
|
|
1195
1226
|
*/
|
|
1196
1227
|
function trackReplaceStep(step, oldState, newTr, attrs, stepResult, currentStepDoc) {
|
|
1197
1228
|
log.info('###### ReplaceStep ######');
|
|
1198
|
-
let selectionPos = 0
|
|
1229
|
+
let selectionPos = 0;
|
|
1230
|
+
const changeSteps = [];
|
|
1199
1231
|
// Invert the transaction step to prevent it from actually deleting or inserting anything
|
|
1200
1232
|
step.getMap().forEach((fromA, toA, fromB, toB) => {
|
|
1201
1233
|
var _a, _b;
|
|
@@ -1419,15 +1451,29 @@ function processChangeSteps(changes, startPos, newTr, emptyAttrs, schema) {
|
|
|
1419
1451
|
}
|
|
1420
1452
|
else if (c.type === 'update-node-attrs') {
|
|
1421
1453
|
const oldDataTracked = getBlockInlineTrackedData(c.node) || [];
|
|
1422
|
-
const oldUpdate = oldDataTracked.find((d) =>
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1454
|
+
const oldUpdate = oldDataTracked.reverse().find((d) => {
|
|
1455
|
+
// reversing to start from the most recent change
|
|
1456
|
+
if (d.operation === CHANGE_OPERATION.set_node_attributes &&
|
|
1457
|
+
(d.status === CHANGE_STATUS.pending || d.status === CHANGE_STATUS.rejected)) {
|
|
1458
|
+
return true;
|
|
1459
|
+
}
|
|
1460
|
+
return false;
|
|
1461
|
+
});
|
|
1462
|
+
// if the selected last change is with status "rejected" we need to use oldAttrs from it because
|
|
1463
|
+
// node's actual attributes represent the "rejected" values
|
|
1464
|
+
const lastChangeRejected = oldUpdate && oldUpdate.status === CHANGE_STATUS.rejected;
|
|
1465
|
+
const sourceAttrs = (oldUpdate === null || oldUpdate === void 0 ? void 0 : oldUpdate.oldAttrs) || c.node.attrs;
|
|
1466
|
+
const { dataTracked, ...restAttrs } = sourceAttrs;
|
|
1467
|
+
const oldAttrs = lastChangeRejected ? oldUpdate.oldAttrs : restAttrs;
|
|
1468
|
+
const newDataTracked = [
|
|
1469
|
+
...oldDataTracked.filter((d) => !oldUpdate || d.id !== oldUpdate.id || lastChangeRejected),
|
|
1470
|
+
];
|
|
1471
|
+
const newUpdate = oldUpdate && oldUpdate.status !== CHANGE_STATUS.rejected
|
|
1426
1472
|
? {
|
|
1427
1473
|
...oldUpdate,
|
|
1428
1474
|
updatedAt: emptyAttrs.updatedAt,
|
|
1429
1475
|
}
|
|
1430
|
-
: addTrackIdIfDoesntExist(createNewUpdateAttrs(emptyAttrs, c.node.attrs));
|
|
1476
|
+
: addTrackIdIfDoesntExist(createNewUpdateAttrs(emptyAttrs, lastChangeRejected ? oldAttrs : c.node.attrs));
|
|
1431
1477
|
// Dont add update changes if there exists already an insert change for this node
|
|
1432
1478
|
if (JSON.stringify(oldAttrs) !== JSON.stringify(c.newAttrs) &&
|
|
1433
1479
|
!oldDataTracked.find((d) => d.operation === CHANGE_OPERATION.insert)) {
|
|
@@ -1841,9 +1887,7 @@ const trackChangesPlugin = (opts = { userID: 'anonymous:Anonymous' }) => {
|
|
|
1841
1887
|
},
|
|
1842
1888
|
appendTransaction(trs, oldState, newState) {
|
|
1843
1889
|
const pluginState = trackChangesPluginKey.getState(newState);
|
|
1844
|
-
if (!pluginState ||
|
|
1845
|
-
pluginState.status === TrackChangesStatus.disabled ||
|
|
1846
|
-
!(editorView === null || editorView === void 0 ? void 0 : editorView.editable)) {
|
|
1890
|
+
if (!pluginState || pluginState.status === TrackChangesStatus.disabled || !(editorView === null || editorView === void 0 ? void 0 : editorView.editable)) {
|
|
1847
1891
|
return null;
|
|
1848
1892
|
}
|
|
1849
1893
|
const { userID, changeSet } = pluginState;
|
|
@@ -1852,13 +1896,8 @@ const trackChangesPlugin = (opts = { userID: 'anonymous:Anonymous' }) => {
|
|
|
1852
1896
|
trs.forEach((tr) => {
|
|
1853
1897
|
const wasAppended = tr.getMeta('appendedTransaction');
|
|
1854
1898
|
const skipMetaUsed = skipTrsWithMetas.some((m) => tr.getMeta(m) || (wasAppended === null || wasAppended === void 0 ? void 0 : wasAppended.getMeta(m)));
|
|
1855
|
-
const skipTrackUsed = getAction(tr, TrackChangesAction.skipTrack) ||
|
|
1856
|
-
|
|
1857
|
-
if (tr.docChanged &&
|
|
1858
|
-
!skipMetaUsed &&
|
|
1859
|
-
!skipTrackUsed &&
|
|
1860
|
-
!tr.getMeta('history$') &&
|
|
1861
|
-
!(wasAppended && tr.getMeta('origin') === 'paragraphs')) {
|
|
1899
|
+
const skipTrackUsed = getAction(tr, TrackChangesAction.skipTrack) || (wasAppended && getAction(wasAppended, TrackChangesAction.skipTrack));
|
|
1900
|
+
if (tr.docChanged && !skipMetaUsed && !skipTrackUsed && !tr.getMeta('history$') && !(wasAppended && tr.getMeta('origin') === 'paragraphs')) {
|
|
1862
1901
|
createdTr = trackTransaction(tr, oldState, createdTr, userID);
|
|
1863
1902
|
}
|
|
1864
1903
|
docChanged = docChanged || tr.docChanged;
|
|
@@ -1878,8 +1917,7 @@ const trackChangesPlugin = (opts = { userID: 'anonymous:Anonymous' }) => {
|
|
|
1878
1917
|
setAction(createdTr, TrackChangesAction.refreshChanges, true);
|
|
1879
1918
|
}
|
|
1880
1919
|
});
|
|
1881
|
-
const changed = pluginState.changeSet.hasInconsistentData &&
|
|
1882
|
-
fixInconsistentChanges(pluginState.changeSet, userID, createdTr, oldState.schema);
|
|
1920
|
+
const changed = pluginState.changeSet.hasInconsistentData && fixInconsistentChanges(pluginState.changeSet, userID, createdTr, oldState.schema);
|
|
1883
1921
|
if (changed) {
|
|
1884
1922
|
log.warn('had to fix inconsistent changes in', createdTr);
|
|
1885
1923
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manuscripts/track-changes-plugin",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.1-LEAN-2832",
|
|
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",
|