@atlaskit/editor-plugin-show-diff 12.1.3 → 12.1.4
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/CHANGELOG.md +34 -0
- package/compass.yml +3 -3
- package/dist/cjs/pm-plugins/calculateDiff/attrAwareTokenEncoder.js +76 -0
- package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +6 -1
- package/dist/cjs/pm-plugins/calculateDiff/computeDiffChanges.js +8 -1
- package/dist/cjs/pm-plugins/calculateDiff/diffBySteps.js +2 -1
- package/dist/cjs/pm-plugins/calculateDiff/smart/classifySmartChanges.js +9 -0
- package/dist/cjs/pm-plugins/decorations/colorSchemes/factory.js +678 -0
- package/dist/cjs/pm-plugins/decorations/colorSchemes/schemes.js +39 -0
- package/dist/cjs/pm-plugins/decorations/colorSchemes/types.js +1 -0
- package/dist/es2019/pm-plugins/calculateDiff/attrAwareTokenEncoder.js +64 -0
- package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +6 -1
- package/dist/es2019/pm-plugins/calculateDiff/computeDiffChanges.js +8 -1
- package/dist/es2019/pm-plugins/calculateDiff/diffBySteps.js +2 -1
- package/dist/es2019/pm-plugins/calculateDiff/smart/classifySmartChanges.js +9 -0
- package/dist/es2019/pm-plugins/decorations/colorSchemes/factory.js +625 -0
- package/dist/es2019/pm-plugins/decorations/colorSchemes/schemes.js +33 -0
- package/dist/es2019/pm-plugins/decorations/colorSchemes/types.js +0 -0
- package/dist/esm/pm-plugins/calculateDiff/attrAwareTokenEncoder.js +70 -0
- package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +6 -1
- package/dist/esm/pm-plugins/calculateDiff/computeDiffChanges.js +8 -1
- package/dist/esm/pm-plugins/calculateDiff/diffBySteps.js +2 -1
- package/dist/esm/pm-plugins/calculateDiff/smart/classifySmartChanges.js +9 -0
- package/dist/esm/pm-plugins/decorations/colorSchemes/factory.js +622 -0
- package/dist/esm/pm-plugins/decorations/colorSchemes/schemes.js +33 -0
- package/dist/esm/pm-plugins/decorations/colorSchemes/types.js +0 -0
- package/dist/types/pm-plugins/calculateDiff/attrAwareTokenEncoder.d.ts +7 -0
- package/dist/types/pm-plugins/decorations/colorSchemes/factory.d.ts +101 -0
- package/dist/types/pm-plugins/decorations/colorSchemes/schemes.d.ts +5 -0
- package/dist/types/pm-plugins/decorations/colorSchemes/types.d.ts +38 -0
- package/package.json +4 -4
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.traditionalScheme = exports.standardScheme = void 0;
|
|
7
|
+
/** Green insertions, red deletions. */
|
|
8
|
+
var traditionalScheme = exports.traditionalScheme = {
|
|
9
|
+
insertColor: 'green',
|
|
10
|
+
insertUnderlineStyle: 'solid',
|
|
11
|
+
insertActiveColor: 'green',
|
|
12
|
+
deleteColor: 'red',
|
|
13
|
+
deleteActiveColor: 'red',
|
|
14
|
+
deletedCellColor: 'gray',
|
|
15
|
+
insertedCellOpacity: 0.5,
|
|
16
|
+
deletedQuoteNodeShape: 'ring',
|
|
17
|
+
deletedCellBorderProminence: 'subtle',
|
|
18
|
+
deletedRowTreatment: 'strikeColor',
|
|
19
|
+
deletedBlockOutlineActiveEmphasis: 'background',
|
|
20
|
+
addedCellOverlayZIndex: 1,
|
|
21
|
+
roundedAddedCellOverlayInheritsBorder: true
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/** Purple insertions, gray deletions (red on active). */
|
|
25
|
+
var standardScheme = exports.standardScheme = {
|
|
26
|
+
insertColor: 'purple',
|
|
27
|
+
insertUnderlineStyle: 'dotted',
|
|
28
|
+
insertActiveColor: 'purple',
|
|
29
|
+
deleteColor: 'gray',
|
|
30
|
+
deleteActiveColor: 'red',
|
|
31
|
+
deletedCellColor: 'gray',
|
|
32
|
+
insertedCellOpacity: 0.2,
|
|
33
|
+
deletedQuoteNodeShape: 'borderLeft',
|
|
34
|
+
deletedCellBorderProminence: 'accent',
|
|
35
|
+
deletedRowTreatment: 'textTint',
|
|
36
|
+
deletedBlockOutlineActiveEmphasis: 'border',
|
|
37
|
+
addedCellOverlayZIndex: 2,
|
|
38
|
+
roundedAddedCellOverlayInheritsBorder: false
|
|
39
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attribute-aware token encoder for `prosemirror-changeset`.
|
|
3
|
+
*
|
|
4
|
+
* The library's default encoder reduces a node's open token to `node.type.name`,
|
|
5
|
+
* ignoring attributes. An attribute-only change (e.g. recolouring a table cell's
|
|
6
|
+
* `background`) therefore tokenises identically on both sides and reports no
|
|
7
|
+
* change at all.
|
|
8
|
+
*
|
|
9
|
+
* This encoder folds an allow-listed set of attributes into the open token so
|
|
10
|
+
* such changes register. Everything else encodes exactly as the default. The
|
|
11
|
+
* allow-list is deliberately narrow — folding in ephemeral attrs like `localId`
|
|
12
|
+
* would produce phantom diffs.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const DIFFED_ATTRS_BY_NODE_TYPE = {
|
|
16
|
+
tableCell: ['background', 'colspan', 'rowspan'],
|
|
17
|
+
tableHeader: ['background', 'colspan', 'rowspan']
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Builds a stable composite token. Iterates the allow-list rather than
|
|
22
|
+
* `Object.keys` so ordering is deterministic for string comparison.
|
|
23
|
+
*/
|
|
24
|
+
const encodeNodeWithAttrs = (node, attrNames) => {
|
|
25
|
+
var _node$attrs;
|
|
26
|
+
const attrs = (_node$attrs = node.attrs) !== null && _node$attrs !== void 0 ? _node$attrs : {};
|
|
27
|
+
// Deterministic order: iterate the allow-list, not `Object.keys(attrs)`.
|
|
28
|
+
const parts = attrNames.map(name => {
|
|
29
|
+
var _attrs$name;
|
|
30
|
+
return `${name}=${JSON.stringify((_attrs$name = attrs[name]) !== null && _attrs$name !== void 0 ? _attrs$name : null)}`;
|
|
31
|
+
});
|
|
32
|
+
return `${node.type.name}|${parts.join('|')}`;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Identical to the library default except that allow-listed node types encode
|
|
37
|
+
* their allow-listed attributes into the open token. Characters and node-end
|
|
38
|
+
* tokens are left as-is, hence the `string | number` token type.
|
|
39
|
+
*/
|
|
40
|
+
export const attrAwareTokenEncoder = {
|
|
41
|
+
encodeCharacter: (char, _marks) => char,
|
|
42
|
+
encodeNodeStart: node => {
|
|
43
|
+
const attrNames = DIFFED_ATTRS_BY_NODE_TYPE[node.type.name];
|
|
44
|
+
if (attrNames) {
|
|
45
|
+
return encodeNodeWithAttrs(node, attrNames);
|
|
46
|
+
}
|
|
47
|
+
return node.type.name;
|
|
48
|
+
},
|
|
49
|
+
encodeNodeEnd: node => -typeID(node.type),
|
|
50
|
+
compareTokens: (a, b) => a === b
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Mirrors the library's private `typeID` so node-end tokens match the default
|
|
55
|
+
* encoding exactly. Reimplemented here because it is not exported.
|
|
56
|
+
*/
|
|
57
|
+
function typeID(type) {
|
|
58
|
+
const cache = type.schema.cached.changeSetIDs || (type.schema.cached.changeSetIDs = Object.create(null));
|
|
59
|
+
let id = cache[type.name];
|
|
60
|
+
if (id == null) {
|
|
61
|
+
cache[type.name] = id = Object.keys(type.schema.nodes).indexOf(type.name) + 1;
|
|
62
|
+
}
|
|
63
|
+
return id;
|
|
64
|
+
}
|
|
@@ -16,6 +16,7 @@ import { extractDiffDescriptors } from '../decorations/decorationKeys';
|
|
|
16
16
|
import { getAttrChangeRanges, stepIsValidAttrChange } from '../decorations/utils/getAttrChangeRanges';
|
|
17
17
|
import { getMarkChangeRanges } from '../decorations/utils/getMarkChangeRanges';
|
|
18
18
|
import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
19
|
+
import { attrAwareTokenEncoder } from './attrAwareTokenEncoder';
|
|
19
20
|
import { diffBySteps } from './diffBySteps';
|
|
20
21
|
import { groupChangesByBlock } from './groupChangesByBlock';
|
|
21
22
|
import { optimizeChanges } from './optimizeChanges';
|
|
@@ -212,7 +213,11 @@ const calculateDiffDecorationsInner = ({
|
|
|
212
213
|
};
|
|
213
214
|
}
|
|
214
215
|
}
|
|
215
|
-
|
|
216
|
+
// The attribute-aware encoder is only needed by the smart classifier and is
|
|
217
|
+
// gated with it; other diff types keep the library default so their output is
|
|
218
|
+
// unchanged.
|
|
219
|
+
const tokenEncoder = diffType === 'smart' && fg('platform_editor_ai_smart_diff') ? attrAwareTokenEncoder : undefined;
|
|
220
|
+
const changeset = ChangeSet.create(originalDoc, undefined, tokenEncoder).addSteps(steppedDoc, stepMaps, tr.doc);
|
|
216
221
|
const changes = getChanges({
|
|
217
222
|
changeset,
|
|
218
223
|
originalDoc,
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* reconstructed by applying the (simplified) steps to `originalDoc`.
|
|
15
15
|
*/
|
|
16
16
|
import { ChangeSet, simplifyChanges } from 'prosemirror-changeset';
|
|
17
|
+
import { attrAwareTokenEncoder } from './attrAwareTokenEncoder';
|
|
17
18
|
import { diffBySteps } from './diffBySteps';
|
|
18
19
|
import { groupChangesByBlock } from './groupChangesByBlock';
|
|
19
20
|
import { optimizeChanges } from './optimizeChanges';
|
|
@@ -62,7 +63,13 @@ export const computeDiffChanges = ({
|
|
|
62
63
|
newDoc: originalDoc
|
|
63
64
|
};
|
|
64
65
|
}
|
|
65
|
-
|
|
66
|
+
|
|
67
|
+
// The attribute-aware encoder only affects the `smart` classification, so it is
|
|
68
|
+
// applied only for that type. (This utility intentionally applies no feature
|
|
69
|
+
// gate — see the file docstring — but a caller requesting `smart` is already
|
|
70
|
+
// behind the smart-diff gate.)
|
|
71
|
+
const tokenEncoder = diffType === 'smart' ? attrAwareTokenEncoder : undefined;
|
|
72
|
+
const changeset = ChangeSet.create(originalDoc, undefined, tokenEncoder).addSteps(steppedDoc, stepMaps, steppedDoc);
|
|
66
73
|
if (diffType === 'smart') {
|
|
67
74
|
return {
|
|
68
75
|
changes: classifySmartChanges({
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { simplifyChanges, ChangeSet } from 'prosemirror-changeset';
|
|
2
2
|
import { Mark } from '@atlaskit/editor-prosemirror/model';
|
|
3
3
|
import { Mapping, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
4
|
+
import { attrAwareTokenEncoder } from './attrAwareTokenEncoder';
|
|
4
5
|
import { optimizeChanges } from './optimizeChanges';
|
|
5
6
|
|
|
6
7
|
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
@@ -292,7 +293,7 @@ export const diffBySteps = (originalDoc, steps) => {
|
|
|
292
293
|
const fromB = mapPosition(afterStepToFinal, fromAfterStep);
|
|
293
294
|
const toB = mapPosition(afterStepToFinal, toAfterStep);
|
|
294
295
|
if (shouldCheckGranularDiff(rangedStep.step, rangedStep.before, rangedStep.from, rangedStep.to)) {
|
|
295
|
-
const granularStepChanges = ChangeSet.create(rangedStep.before).addSteps(rangedStep.doc, [rangedStep.stepMap], null);
|
|
296
|
+
const granularStepChanges = ChangeSet.create(rangedStep.before, undefined, attrAwareTokenEncoder).addSteps(rangedStep.doc, [rangedStep.stepMap], null);
|
|
296
297
|
|
|
297
298
|
// `simplifyChanges` reads text using `Change.fromB`/`toB`, which are
|
|
298
299
|
// positions in the post-step doc (the "B" doc). Passing the pre-step
|
|
@@ -635,6 +635,15 @@ const classifyChild = (childA, childB, changes, originalDoc, newDoc, locale, thr
|
|
|
635
635
|
const childrenB = childRefs(blockB);
|
|
636
636
|
const childrenA = wrapperA ? childRefs(wrapperA) : [];
|
|
637
637
|
const out = [];
|
|
638
|
+
|
|
639
|
+
// An attribute-only change on the wrapper itself (e.g. a table cell's
|
|
640
|
+
// `background`) sits on the node boundary, not inside any inner child, so the
|
|
641
|
+
// recursion below would emit nothing and the change would be dropped. Emit a
|
|
642
|
+
// whole-wrapper change instead, which also subsumes any inner content change.
|
|
643
|
+
if (wrapperA && !wrapperA.node.sameMarkup(blockB.node)) {
|
|
644
|
+
out.push(makePromotedChange(wrapperA.from, wrapperA.to, blockB.from, blockB.to, 'node'));
|
|
645
|
+
return out;
|
|
646
|
+
}
|
|
638
647
|
// LCS-align inner children (mirrors classifyContainer) so a paragraph inserted/deleted
|
|
639
648
|
// inside the cell/column does not mis-pair every subsequent inner child by index. We never
|
|
640
649
|
// promote the wrapper itself here — we only classify each inner child.
|