@atlaskit/editor-plugin-show-diff 12.1.3 → 13.0.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 (32) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/compass.yml +3 -3
  3. package/dist/cjs/pm-plugins/calculateDiff/attrAwareTokenEncoder.js +76 -0
  4. package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +6 -1
  5. package/dist/cjs/pm-plugins/calculateDiff/computeDiffChanges.js +8 -1
  6. package/dist/cjs/pm-plugins/calculateDiff/diffBySteps.js +2 -1
  7. package/dist/cjs/pm-plugins/calculateDiff/smart/classifySmartChanges.js +9 -0
  8. package/dist/cjs/pm-plugins/decorations/colorSchemes/factory.js +678 -0
  9. package/dist/cjs/pm-plugins/decorations/colorSchemes/schemes.js +39 -0
  10. package/dist/cjs/pm-plugins/decorations/colorSchemes/types.js +1 -0
  11. package/dist/es2019/pm-plugins/calculateDiff/attrAwareTokenEncoder.js +64 -0
  12. package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +6 -1
  13. package/dist/es2019/pm-plugins/calculateDiff/computeDiffChanges.js +8 -1
  14. package/dist/es2019/pm-plugins/calculateDiff/diffBySteps.js +2 -1
  15. package/dist/es2019/pm-plugins/calculateDiff/smart/classifySmartChanges.js +9 -0
  16. package/dist/es2019/pm-plugins/decorations/colorSchemes/factory.js +625 -0
  17. package/dist/es2019/pm-plugins/decorations/colorSchemes/schemes.js +33 -0
  18. package/dist/es2019/pm-plugins/decorations/colorSchemes/types.js +0 -0
  19. package/dist/esm/pm-plugins/calculateDiff/attrAwareTokenEncoder.js +70 -0
  20. package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +6 -1
  21. package/dist/esm/pm-plugins/calculateDiff/computeDiffChanges.js +8 -1
  22. package/dist/esm/pm-plugins/calculateDiff/diffBySteps.js +2 -1
  23. package/dist/esm/pm-plugins/calculateDiff/smart/classifySmartChanges.js +9 -0
  24. package/dist/esm/pm-plugins/decorations/colorSchemes/factory.js +622 -0
  25. package/dist/esm/pm-plugins/decorations/colorSchemes/schemes.js +33 -0
  26. package/dist/esm/pm-plugins/decorations/colorSchemes/types.js +0 -0
  27. package/dist/types/pm-plugins/calculateDiff/attrAwareTokenEncoder.d.ts +7 -0
  28. package/dist/types/pm-plugins/decorations/colorSchemes/factory.d.ts +101 -0
  29. package/dist/types/pm-plugins/decorations/colorSchemes/schemes.d.ts +5 -0
  30. package/dist/types/pm-plugins/decorations/colorSchemes/types.d.ts +38 -0
  31. package/package.json +6 -6
  32. package/editor-plugin-show-diff.docs.tsx +0 -43
@@ -0,0 +1,70 @@
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
+ var 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
+ var encodeNodeWithAttrs = function encodeNodeWithAttrs(node, attrNames) {
25
+ var _node$attrs;
26
+ var attrs = (_node$attrs = node.attrs) !== null && _node$attrs !== void 0 ? _node$attrs : {};
27
+ // Deterministic order: iterate the allow-list, not `Object.keys(attrs)`.
28
+ var parts = attrNames.map(function (name) {
29
+ var _attrs$name;
30
+ return "".concat(name, "=").concat(JSON.stringify((_attrs$name = attrs[name]) !== null && _attrs$name !== void 0 ? _attrs$name : null));
31
+ });
32
+ return "".concat(node.type.name, "|").concat(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 var attrAwareTokenEncoder = {
41
+ encodeCharacter: function encodeCharacter(char, _marks) {
42
+ return char;
43
+ },
44
+ encodeNodeStart: function encodeNodeStart(node) {
45
+ var attrNames = DIFFED_ATTRS_BY_NODE_TYPE[node.type.name];
46
+ if (attrNames) {
47
+ return encodeNodeWithAttrs(node, attrNames);
48
+ }
49
+ return node.type.name;
50
+ },
51
+ encodeNodeEnd: function encodeNodeEnd(node) {
52
+ return -typeID(node.type);
53
+ },
54
+ compareTokens: function compareTokens(a, b) {
55
+ return a === b;
56
+ }
57
+ };
58
+
59
+ /**
60
+ * Mirrors the library's private `typeID` so node-end tokens match the default
61
+ * encoding exactly. Reimplemented here because it is not exported.
62
+ */
63
+ function typeID(type) {
64
+ var cache = type.schema.cached.changeSetIDs || (type.schema.cached.changeSetIDs = Object.create(null));
65
+ var id = cache[type.name];
66
+ if (id == null) {
67
+ cache[type.name] = id = Object.keys(type.schema.nodes).indexOf(type.name) + 1;
68
+ }
69
+ return id;
70
+ }
@@ -24,6 +24,7 @@ import { extractDiffDescriptors } from '../decorations/decorationKeys';
24
24
  import { getAttrChangeRanges, stepIsValidAttrChange } from '../decorations/utils/getAttrChangeRanges';
25
25
  import { getMarkChangeRanges } from '../decorations/utils/getMarkChangeRanges';
26
26
  import { isExtendedEnabled } from '../isExtendedEnabled';
27
+ import { attrAwareTokenEncoder } from './attrAwareTokenEncoder';
27
28
  import { diffBySteps } from './diffBySteps';
28
29
  import { groupChangesByBlock } from './groupChangesByBlock';
29
30
  import { optimizeChanges } from './optimizeChanges';
@@ -231,7 +232,11 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref4
231
232
  };
232
233
  }
233
234
  }
234
- var changeset = ChangeSet.create(originalDoc).addSteps(steppedDoc, stepMaps, tr.doc);
235
+ // The attribute-aware encoder is only needed by the smart classifier and is
236
+ // gated with it; other diff types keep the library default so their output is
237
+ // unchanged.
238
+ var tokenEncoder = diffType === 'smart' && fg('platform_editor_ai_smart_diff') ? attrAwareTokenEncoder : undefined;
239
+ var changeset = ChangeSet.create(originalDoc, undefined, tokenEncoder).addSteps(steppedDoc, stepMaps, tr.doc);
235
240
  var changes = getChanges({
236
241
  changeset: changeset,
237
242
  originalDoc: originalDoc,
@@ -17,6 +17,7 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
17
17
  * reconstructed by applying the (simplified) steps to `originalDoc`.
18
18
  */
19
19
  import { ChangeSet, simplifyChanges } from 'prosemirror-changeset';
20
+ import { attrAwareTokenEncoder } from './attrAwareTokenEncoder';
20
21
  import { diffBySteps } from './diffBySteps';
21
22
  import { groupChangesByBlock } from './groupChangesByBlock';
22
23
  import { optimizeChanges } from './optimizeChanges';
@@ -75,7 +76,13 @@ export var computeDiffChanges = function computeDiffChanges(_ref) {
75
76
  newDoc: originalDoc
76
77
  };
77
78
  }
78
- var changeset = ChangeSet.create(originalDoc).addSteps(steppedDoc, stepMaps, steppedDoc);
79
+
80
+ // The attribute-aware encoder only affects the `smart` classification, so it is
81
+ // applied only for that type. (This utility intentionally applies no feature
82
+ // gate — see the file docstring — but a caller requesting `smart` is already
83
+ // behind the smart-diff gate.)
84
+ var tokenEncoder = diffType === 'smart' ? attrAwareTokenEncoder : undefined;
85
+ var changeset = ChangeSet.create(originalDoc, undefined, tokenEncoder).addSteps(steppedDoc, stepMaps, steppedDoc);
79
86
  if (diffType === 'smart') {
80
87
  return {
81
88
  changes: classifySmartChanges({
@@ -8,6 +8,7 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
8
8
  import { simplifyChanges, ChangeSet } from 'prosemirror-changeset';
9
9
  import { Mark } from '@atlaskit/editor-prosemirror/model';
10
10
  import { Mapping, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
11
+ import { attrAwareTokenEncoder } from './attrAwareTokenEncoder';
11
12
  import { optimizeChanges } from './optimizeChanges';
12
13
 
13
14
  // @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
@@ -322,7 +323,7 @@ export var diffBySteps = function diffBySteps(originalDoc, steps) {
322
323
  var fromB = mapPosition(afterStepToFinal, fromAfterStep);
323
324
  var toB = mapPosition(afterStepToFinal, toAfterStep);
324
325
  if (shouldCheckGranularDiff(rangedStep.step, rangedStep.before, rangedStep.from, rangedStep.to)) {
325
- var granularStepChanges = ChangeSet.create(rangedStep.before).addSteps(rangedStep.doc, [rangedStep.stepMap], null);
326
+ var granularStepChanges = ChangeSet.create(rangedStep.before, undefined, attrAwareTokenEncoder).addSteps(rangedStep.doc, [rangedStep.stepMap], null);
326
327
 
327
328
  // `simplifyChanges` reads text using `Change.fromB`/`toB`, which are
328
329
  // positions in the post-step doc (the "B" doc). Passing the pre-step
@@ -765,6 +765,15 @@ var _classifyChild = function classifyChild(childA, childB, changes, originalDoc
765
765
  var childrenB = childRefs(blockB);
766
766
  var childrenA = wrapperA ? childRefs(wrapperA) : [];
767
767
  var out = [];
768
+
769
+ // An attribute-only change on the wrapper itself (e.g. a table cell's
770
+ // `background`) sits on the node boundary, not inside any inner child, so the
771
+ // recursion below would emit nothing and the change would be dropped. Emit a
772
+ // whole-wrapper change instead, which also subsumes any inner content change.
773
+ if (wrapperA && !wrapperA.node.sameMarkup(blockB.node)) {
774
+ out.push(makePromotedChange(wrapperA.from, wrapperA.to, blockB.from, blockB.to, 'node'));
775
+ return out;
776
+ }
768
777
  // LCS-align inner children (mirrors classifyContainer) so a paragraph inserted/deleted
769
778
  // inside the cell/column does not mis-pair every subsequent inner child by index. We never
770
779
  // promote the wrapper itself here — we only classify each inner child.