@atlaskit/editor-plugin-track-changes 2.3.0 → 2.4.1

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 (37) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/afm-cc/tsconfig.json +3 -0
  3. package/afm-jira/tsconfig.json +3 -0
  4. package/afm-post-office/tsconfig.json +3 -0
  5. package/afm-rovo-extension/tsconfig.json +3 -0
  6. package/afm-townsquare/tsconfig.json +3 -0
  7. package/dist/cjs/pm-plugins/filterSteps.js +49 -0
  8. package/dist/cjs/pm-plugins/invertableStep.js +15 -0
  9. package/dist/cjs/pm-plugins/main.js +28 -14
  10. package/dist/cjs/pm-plugins/maxSteps.js +9 -0
  11. package/dist/cjs/pm-plugins/types.js +1 -0
  12. package/dist/cjs/trackChangesPlugin.js +10 -0
  13. package/dist/es2019/pm-plugins/filterSteps.js +32 -0
  14. package/dist/es2019/pm-plugins/invertableStep.js +7 -0
  15. package/dist/es2019/pm-plugins/main.js +27 -10
  16. package/dist/es2019/pm-plugins/maxSteps.js +3 -0
  17. package/dist/es2019/pm-plugins/types.js +1 -0
  18. package/dist/es2019/trackChangesPlugin.js +11 -0
  19. package/dist/esm/pm-plugins/filterSteps.js +44 -0
  20. package/dist/esm/pm-plugins/invertableStep.js +8 -0
  21. package/dist/esm/pm-plugins/main.js +27 -13
  22. package/dist/esm/pm-plugins/maxSteps.js +3 -0
  23. package/dist/esm/pm-plugins/types.js +1 -0
  24. package/dist/esm/trackChangesPlugin.js +10 -0
  25. package/dist/types/pm-plugins/filterSteps.d.ts +8 -0
  26. package/dist/types/pm-plugins/invertableStep.d.ts +7 -0
  27. package/dist/types/pm-plugins/main.d.ts +4 -6
  28. package/dist/types/pm-plugins/maxSteps.d.ts +1 -0
  29. package/dist/types/pm-plugins/types.d.ts +2 -1
  30. package/dist/types/trackChangesPluginType.d.ts +9 -0
  31. package/dist/types-ts4.5/pm-plugins/filterSteps.d.ts +8 -0
  32. package/dist/types-ts4.5/pm-plugins/invertableStep.d.ts +7 -0
  33. package/dist/types-ts4.5/pm-plugins/main.d.ts +4 -6
  34. package/dist/types-ts4.5/pm-plugins/maxSteps.d.ts +1 -0
  35. package/dist/types-ts4.5/pm-plugins/types.d.ts +2 -1
  36. package/dist/types-ts4.5/trackChangesPluginType.d.ts +9 -0
  37. package/package.json +5 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @atlaskit/editor-plugin-track-changes
2
2
 
3
+ ## 2.4.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 2.4.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#193925](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/193925)
14
+ [`696d65f882441`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/696d65f882441) -
15
+ Implement `resetBaseline` command for track changes plugin which can be called to reset the diff
16
+ history.
17
+
3
18
  ## 2.3.0
4
19
 
5
20
  ### Minor Changes
@@ -25,6 +25,9 @@
25
25
  {
26
26
  "path": "../../../design-system/button/afm-cc/tsconfig.json"
27
27
  },
28
+ {
29
+ "path": "../../editor-plugin-history/afm-cc/tsconfig.json"
30
+ },
28
31
  {
29
32
  "path": "../../editor-plugin-primary-toolbar/afm-cc/tsconfig.json"
30
33
  },
@@ -25,6 +25,9 @@
25
25
  {
26
26
  "path": "../../../design-system/button/afm-jira/tsconfig.json"
27
27
  },
28
+ {
29
+ "path": "../../editor-plugin-history/afm-jira/tsconfig.json"
30
+ },
28
31
  {
29
32
  "path": "../../editor-plugin-primary-toolbar/afm-jira/tsconfig.json"
30
33
  },
@@ -25,6 +25,9 @@
25
25
  {
26
26
  "path": "../../../design-system/button/afm-post-office/tsconfig.json"
27
27
  },
28
+ {
29
+ "path": "../../editor-plugin-history/afm-post-office/tsconfig.json"
30
+ },
28
31
  {
29
32
  "path": "../../editor-plugin-primary-toolbar/afm-post-office/tsconfig.json"
30
33
  },
@@ -25,6 +25,9 @@
25
25
  {
26
26
  "path": "../../../design-system/button/afm-rovo-extension/tsconfig.json"
27
27
  },
28
+ {
29
+ "path": "../../editor-plugin-history/afm-rovo-extension/tsconfig.json"
30
+ },
28
31
  {
29
32
  "path": "../../editor-plugin-primary-toolbar/afm-rovo-extension/tsconfig.json"
30
33
  },
@@ -25,6 +25,9 @@
25
25
  {
26
26
  "path": "../../../design-system/button/afm-townsquare/tsconfig.json"
27
27
  },
28
+ {
29
+ "path": "../../editor-plugin-history/afm-townsquare/tsconfig.json"
30
+ },
28
31
  {
29
32
  "path": "../../editor-plugin-primary-toolbar/afm-townsquare/tsconfig.json"
30
33
  },
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.filterSteps = filterSteps;
7
+ var _maxSteps = require("./maxSteps");
8
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
9
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
10
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
11
+ /**
12
+ * Returns the filtered steps to ensure we don't track an entire document worth of changes
13
+ */
14
+ function filterSteps(steps, allocations) {
15
+ if (allocations.size <= _maxSteps.MAX_STEPS_FROM_BASELINE) {
16
+ return {
17
+ steps: steps,
18
+ allocations: allocations
19
+ };
20
+ }
21
+
22
+ // Create a new allocation, retaining only the most recent values
23
+ var elements = Array.from(allocations);
24
+ var newAllocation = new Set(elements.slice(-_maxSteps.MAX_STEPS_FROM_BASELINE));
25
+ var finalSteps = [];
26
+ var cutoffFound = false;
27
+ var _iterator = _createForOfIteratorHelper(steps),
28
+ _step;
29
+ try {
30
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
31
+ var step = _step.value;
32
+ if (newAllocation.has(step.allocation)) {
33
+ cutoffFound = true;
34
+ }
35
+ // Accept everything after this point otherwise we could have mis-ordered steps
36
+ if (cutoffFound) {
37
+ finalSteps.push(step);
38
+ }
39
+ }
40
+ } catch (err) {
41
+ _iterator.e(err);
42
+ } finally {
43
+ _iterator.f();
44
+ }
45
+ return {
46
+ steps: finalSteps,
47
+ allocations: newAllocation
48
+ };
49
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.InvertableStep = void 0;
8
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
9
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
10
+ var InvertableStep = exports.InvertableStep = /*#__PURE__*/(0, _createClass2.default)(function InvertableStep(step, inverted, allocation) {
11
+ (0, _classCallCheck2.default)(this, InvertableStep);
12
+ this.step = step;
13
+ this.inverted = inverted;
14
+ this.allocation = allocation;
15
+ });
@@ -4,14 +4,14 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.trackChangesPluginKey = exports.createTrackChangesPlugin = exports.InvertableStep = void 0;
7
+ exports.trackChangesPluginKey = exports.getBaselineFromSteps = exports.createTrackChangesPlugin = void 0;
8
8
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
9
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
- var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
11
- var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
12
10
  var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
13
11
  var _state = require("@atlaskit/editor-prosemirror/state");
14
12
  var _transform = require("@atlaskit/editor-prosemirror/transform");
13
+ var _filterSteps2 = require("./filterSteps");
14
+ var _invertableStep = require("./invertableStep");
15
15
  var _types = require("./types");
16
16
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
17
17
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
@@ -19,18 +19,14 @@ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol
19
19
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
20
20
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
21
21
  var trackChangesPluginKey = exports.trackChangesPluginKey = new _state.PluginKey('trackChangesPlugin');
22
- var InvertableStep = exports.InvertableStep = /*#__PURE__*/(0, _createClass2.default)(function InvertableStep(step, inverted) {
23
- (0, _classCallCheck2.default)(this, InvertableStep);
24
- this.step = step;
25
- this.inverted = inverted;
26
- });
27
- var getBaselineFromSteps = function getBaselineFromSteps(doc, steps) {
22
+ // Exported for test purposes
23
+ var getBaselineFromSteps = exports.getBaselineFromSteps = function getBaselineFromSteps(doc, steps) {
28
24
  var _iterator = _createForOfIteratorHelper(steps.slice().reverse()),
29
25
  _step;
30
26
  try {
31
27
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
32
- var _step2 = _step.value;
33
- var result = _step2.inverted.apply(doc);
28
+ var step = _step.value;
29
+ var result = step.inverted.apply(doc);
34
30
  if (result.failed === null && result.doc) {
35
31
  doc = result.doc;
36
32
  }
@@ -52,11 +48,19 @@ var createTrackChangesPlugin = exports.createTrackChangesPlugin = function creat
52
48
  return {
53
49
  steps: [],
54
50
  shouldChangesBeDisplayed: false,
55
- isShowDiffAvailable: false
51
+ isShowDiffAvailable: false,
52
+ allocations: new Set()
56
53
  };
57
54
  },
58
55
  apply: function apply(tr, state) {
56
+ var _api$history, _state$steps$at$alloc, _state$steps$at;
59
57
  var metadata = tr.getMeta(trackChangesPluginKey);
58
+ if (metadata && metadata.action === _types.TOGGLE_TRACK_CHANGES_ACTION.RESET_BASELINE) {
59
+ return _objectSpread(_objectSpread({}, state), {}, {
60
+ steps: [],
61
+ isShowDiffAvailable: false
62
+ });
63
+ }
60
64
  if (metadata && metadata.action === _types.TOGGLE_TRACK_CHANGES_ACTION.TOGGLE_TRACK_CHANGES) {
61
65
  resetBaseline = true;
62
66
  return _objectSpread(_objectSpread({}, state), {}, {
@@ -70,14 +74,24 @@ var createTrackChangesPlugin = exports.createTrackChangesPlugin = function creat
70
74
  // If no document changes, return the old changeSet
71
75
  return state;
72
76
  }
77
+
78
+ // If we don't have the history plugin don't limit the change tracking
79
+ var historyState = api === null || api === void 0 || (_api$history = api.history) === null || _api$history === void 0 ? void 0 : _api$history.sharedState.currentState();
80
+ var currentAllocation = historyState ?
81
+ // Combine both done + undone so we have the total "distance".
82
+ historyState.done.eventCount + historyState.undone.eventCount : ((_state$steps$at$alloc = (_state$steps$at = state.steps.at(-1)) === null || _state$steps$at === void 0 ? void 0 : _state$steps$at.allocation) !== null && _state$steps$at$alloc !== void 0 ? _state$steps$at$alloc : 0) + 1;
73
83
  var newSteps = tr.steps.map(function (step, idx) {
74
- return new InvertableStep(step, step.invert(tr.docs[idx]));
84
+ return new _invertableStep.InvertableStep(step, step.invert(tr.docs[idx]), currentAllocation);
75
85
  });
76
- var steps = resetBaseline ? newSteps : [].concat((0, _toConsumableArray2.default)(state.steps), (0, _toConsumableArray2.default)(newSteps));
86
+ var concatSteps = resetBaseline ? newSteps : [].concat((0, _toConsumableArray2.default)(state.steps), (0, _toConsumableArray2.default)(newSteps));
77
87
  resetBaseline = false;
88
+ var _filterSteps = (0, _filterSteps2.filterSteps)(concatSteps, state.allocations.add(currentAllocation)),
89
+ allocations = _filterSteps.allocations,
90
+ steps = _filterSteps.steps;
78
91
 
79
92
  // Create a new ChangeSet based on document changes
80
93
  return _objectSpread(_objectSpread({}, state), {}, {
94
+ allocations: allocations,
81
95
  steps: steps,
82
96
  shouldChangesBeDisplayed: false,
83
97
  isShowDiffAvailable: true
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.MAX_STEPS_FROM_BASELINE = void 0;
7
+ // To be determined a suitable threshold
8
+ // Exported for testing
9
+ var MAX_STEPS_FROM_BASELINE = exports.MAX_STEPS_FROM_BASELINE = 10;
@@ -6,5 +6,6 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.TOGGLE_TRACK_CHANGES_ACTION = void 0;
7
7
  var TOGGLE_TRACK_CHANGES_ACTION = exports.TOGGLE_TRACK_CHANGES_ACTION = /*#__PURE__*/function (TOGGLE_TRACK_CHANGES_ACTION) {
8
8
  TOGGLE_TRACK_CHANGES_ACTION["TOGGLE_TRACK_CHANGES"] = "TOGGLE_TRACK_CHANGES";
9
+ TOGGLE_TRACK_CHANGES_ACTION["RESET_BASELINE"] = "RESET_BASELINE";
9
10
  return TOGGLE_TRACK_CHANGES_ACTION;
10
11
  }({});
@@ -40,6 +40,16 @@ var trackChangesPlugin = exports.trackChangesPlugin = function trackChangesPlugi
40
40
  return tr.setMeta(_main.trackChangesPluginKey, {
41
41
  action: _types.TOGGLE_TRACK_CHANGES_ACTION.TOGGLE_TRACK_CHANGES
42
42
  });
43
+ },
44
+ resetBaseline: function resetBaseline(_ref3) {
45
+ var _api$trackChanges;
46
+ var tr = _ref3.tr;
47
+ if (!(api !== null && api !== void 0 && (_api$trackChanges = api.trackChanges) !== null && _api$trackChanges !== void 0 && (_api$trackChanges = _api$trackChanges.sharedState.currentState()) !== null && _api$trackChanges !== void 0 && _api$trackChanges.isShowDiffAvailable)) {
48
+ return null;
49
+ }
50
+ return tr.setMeta(_main.trackChangesPluginKey, {
51
+ action: _types.TOGGLE_TRACK_CHANGES_ACTION.RESET_BASELINE
52
+ });
43
53
  }
44
54
  },
45
55
  getSharedState: function getSharedState(editorState) {
@@ -0,0 +1,32 @@
1
+ import { MAX_STEPS_FROM_BASELINE } from './maxSteps';
2
+
3
+ /**
4
+ * Returns the filtered steps to ensure we don't track an entire document worth of changes
5
+ */
6
+ export function filterSteps(steps, allocations) {
7
+ if (allocations.size <= MAX_STEPS_FROM_BASELINE) {
8
+ return {
9
+ steps,
10
+ allocations
11
+ };
12
+ }
13
+
14
+ // Create a new allocation, retaining only the most recent values
15
+ const elements = Array.from(allocations);
16
+ const newAllocation = new Set(elements.slice(-MAX_STEPS_FROM_BASELINE));
17
+ const finalSteps = [];
18
+ let cutoffFound = false;
19
+ for (const step of steps) {
20
+ if (newAllocation.has(step.allocation)) {
21
+ cutoffFound = true;
22
+ }
23
+ // Accept everything after this point otherwise we could have mis-ordered steps
24
+ if (cutoffFound) {
25
+ finalSteps.push(step);
26
+ }
27
+ }
28
+ return {
29
+ steps: finalSteps,
30
+ allocations: newAllocation
31
+ };
32
+ }
@@ -0,0 +1,7 @@
1
+ export class InvertableStep {
2
+ constructor(step, inverted, allocation) {
3
+ this.step = step;
4
+ this.inverted = inverted;
5
+ this.allocation = allocation;
6
+ }
7
+ }
@@ -1,15 +1,12 @@
1
1
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
2
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
3
3
  import { ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
4
+ import { filterSteps } from './filterSteps';
5
+ import { InvertableStep } from './invertableStep';
4
6
  import { TOGGLE_TRACK_CHANGES_ACTION as ACTION } from './types';
5
7
  export const trackChangesPluginKey = new PluginKey('trackChangesPlugin');
6
- export class InvertableStep {
7
- constructor(step, inverted) {
8
- this.step = step;
9
- this.inverted = inverted;
10
- }
11
- }
12
- const getBaselineFromSteps = (doc, steps) => {
8
+ // Exported for test purposes
9
+ export const getBaselineFromSteps = (doc, steps) => {
13
10
  for (const step of steps.slice().reverse()) {
14
11
  const result = step.inverted.apply(doc);
15
12
  if (result.failed === null && result.doc) {
@@ -28,11 +25,20 @@ export const createTrackChangesPlugin = api => {
28
25
  return {
29
26
  steps: [],
30
27
  shouldChangesBeDisplayed: false,
31
- isShowDiffAvailable: false
28
+ isShowDiffAvailable: false,
29
+ allocations: new Set()
32
30
  };
33
31
  },
34
32
  apply(tr, state) {
33
+ var _api$history, _state$steps$at$alloc, _state$steps$at;
35
34
  const metadata = tr.getMeta(trackChangesPluginKey);
35
+ if (metadata && metadata.action === ACTION.RESET_BASELINE) {
36
+ return {
37
+ ...state,
38
+ steps: [],
39
+ isShowDiffAvailable: false
40
+ };
41
+ }
36
42
  if (metadata && metadata.action === ACTION.TOGGLE_TRACK_CHANGES) {
37
43
  resetBaseline = true;
38
44
  return {
@@ -45,13 +51,24 @@ export const createTrackChangesPlugin = api => {
45
51
  // If no document changes, return the old changeSet
46
52
  return state;
47
53
  }
48
- const newSteps = tr.steps.map((step, idx) => new InvertableStep(step, step.invert(tr.docs[idx])));
49
- const steps = resetBaseline ? newSteps : [...state.steps, ...newSteps];
54
+
55
+ // If we don't have the history plugin don't limit the change tracking
56
+ const historyState = api === null || api === void 0 ? void 0 : (_api$history = api.history) === null || _api$history === void 0 ? void 0 : _api$history.sharedState.currentState();
57
+ const currentAllocation = historyState ?
58
+ // Combine both done + undone so we have the total "distance".
59
+ historyState.done.eventCount + historyState.undone.eventCount : ((_state$steps$at$alloc = (_state$steps$at = state.steps.at(-1)) === null || _state$steps$at === void 0 ? void 0 : _state$steps$at.allocation) !== null && _state$steps$at$alloc !== void 0 ? _state$steps$at$alloc : 0) + 1;
60
+ const newSteps = tr.steps.map((step, idx) => new InvertableStep(step, step.invert(tr.docs[idx]), currentAllocation));
61
+ const concatSteps = resetBaseline ? newSteps : [...state.steps, ...newSteps];
50
62
  resetBaseline = false;
63
+ const {
64
+ allocations,
65
+ steps
66
+ } = filterSteps(concatSteps, state.allocations.add(currentAllocation));
51
67
 
52
68
  // Create a new ChangeSet based on document changes
53
69
  return {
54
70
  ...state,
71
+ allocations,
55
72
  steps,
56
73
  shouldChangesBeDisplayed: false,
57
74
  isShowDiffAvailable: true
@@ -0,0 +1,3 @@
1
+ // To be determined a suitable threshold
2
+ // Exported for testing
3
+ export const MAX_STEPS_FROM_BASELINE = 10;
@@ -1,4 +1,5 @@
1
1
  export let TOGGLE_TRACK_CHANGES_ACTION = /*#__PURE__*/function (TOGGLE_TRACK_CHANGES_ACTION) {
2
2
  TOGGLE_TRACK_CHANGES_ACTION["TOGGLE_TRACK_CHANGES"] = "TOGGLE_TRACK_CHANGES";
3
+ TOGGLE_TRACK_CHANGES_ACTION["RESET_BASELINE"] = "RESET_BASELINE";
3
4
  return TOGGLE_TRACK_CHANGES_ACTION;
4
5
  }({});
@@ -33,6 +33,17 @@ export const trackChangesPlugin = ({
33
33
  return tr.setMeta(trackChangesPluginKey, {
34
34
  action: ACTION.TOGGLE_TRACK_CHANGES
35
35
  });
36
+ },
37
+ resetBaseline: ({
38
+ tr
39
+ }) => {
40
+ var _api$trackChanges, _api$trackChanges$sha;
41
+ if (!(api !== null && api !== void 0 && (_api$trackChanges = api.trackChanges) !== null && _api$trackChanges !== void 0 && (_api$trackChanges$sha = _api$trackChanges.sharedState.currentState()) !== null && _api$trackChanges$sha !== void 0 && _api$trackChanges$sha.isShowDiffAvailable)) {
42
+ return null;
43
+ }
44
+ return tr.setMeta(trackChangesPluginKey, {
45
+ action: ACTION.RESET_BASELINE
46
+ });
36
47
  }
37
48
  },
38
49
  getSharedState: editorState => {
@@ -0,0 +1,44 @@
1
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
2
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
3
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
4
+ import { MAX_STEPS_FROM_BASELINE } from './maxSteps';
5
+
6
+ /**
7
+ * Returns the filtered steps to ensure we don't track an entire document worth of changes
8
+ */
9
+ export function filterSteps(steps, allocations) {
10
+ if (allocations.size <= MAX_STEPS_FROM_BASELINE) {
11
+ return {
12
+ steps: steps,
13
+ allocations: allocations
14
+ };
15
+ }
16
+
17
+ // Create a new allocation, retaining only the most recent values
18
+ var elements = Array.from(allocations);
19
+ var newAllocation = new Set(elements.slice(-MAX_STEPS_FROM_BASELINE));
20
+ var finalSteps = [];
21
+ var cutoffFound = false;
22
+ var _iterator = _createForOfIteratorHelper(steps),
23
+ _step;
24
+ try {
25
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
26
+ var step = _step.value;
27
+ if (newAllocation.has(step.allocation)) {
28
+ cutoffFound = true;
29
+ }
30
+ // Accept everything after this point otherwise we could have mis-ordered steps
31
+ if (cutoffFound) {
32
+ finalSteps.push(step);
33
+ }
34
+ }
35
+ } catch (err) {
36
+ _iterator.e(err);
37
+ } finally {
38
+ _iterator.f();
39
+ }
40
+ return {
41
+ steps: finalSteps,
42
+ allocations: newAllocation
43
+ };
44
+ }
@@ -0,0 +1,8 @@
1
+ import _createClass from "@babel/runtime/helpers/createClass";
2
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
+ export var InvertableStep = /*#__PURE__*/_createClass(function InvertableStep(step, inverted, allocation) {
4
+ _classCallCheck(this, InvertableStep);
5
+ this.step = step;
6
+ this.inverted = inverted;
7
+ this.allocation = allocation;
8
+ });
@@ -1,7 +1,5 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
- import _createClass from "@babel/runtime/helpers/createClass";
4
- import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
5
3
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
6
4
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
7
5
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
@@ -10,20 +8,18 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
10
8
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
11
9
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
12
10
  import { ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
11
+ import { filterSteps } from './filterSteps';
12
+ import { InvertableStep } from './invertableStep';
13
13
  import { TOGGLE_TRACK_CHANGES_ACTION as ACTION } from './types';
14
14
  export var trackChangesPluginKey = new PluginKey('trackChangesPlugin');
15
- export var InvertableStep = /*#__PURE__*/_createClass(function InvertableStep(step, inverted) {
16
- _classCallCheck(this, InvertableStep);
17
- this.step = step;
18
- this.inverted = inverted;
19
- });
20
- var getBaselineFromSteps = function getBaselineFromSteps(doc, steps) {
15
+ // Exported for test purposes
16
+ export var getBaselineFromSteps = function getBaselineFromSteps(doc, steps) {
21
17
  var _iterator = _createForOfIteratorHelper(steps.slice().reverse()),
22
18
  _step;
23
19
  try {
24
20
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
25
- var _step2 = _step.value;
26
- var result = _step2.inverted.apply(doc);
21
+ var step = _step.value;
22
+ var result = step.inverted.apply(doc);
27
23
  if (result.failed === null && result.doc) {
28
24
  doc = result.doc;
29
25
  }
@@ -45,11 +41,19 @@ export var createTrackChangesPlugin = function createTrackChangesPlugin(api) {
45
41
  return {
46
42
  steps: [],
47
43
  shouldChangesBeDisplayed: false,
48
- isShowDiffAvailable: false
44
+ isShowDiffAvailable: false,
45
+ allocations: new Set()
49
46
  };
50
47
  },
51
48
  apply: function apply(tr, state) {
49
+ var _api$history, _state$steps$at$alloc, _state$steps$at;
52
50
  var metadata = tr.getMeta(trackChangesPluginKey);
51
+ if (metadata && metadata.action === ACTION.RESET_BASELINE) {
52
+ return _objectSpread(_objectSpread({}, state), {}, {
53
+ steps: [],
54
+ isShowDiffAvailable: false
55
+ });
56
+ }
53
57
  if (metadata && metadata.action === ACTION.TOGGLE_TRACK_CHANGES) {
54
58
  resetBaseline = true;
55
59
  return _objectSpread(_objectSpread({}, state), {}, {
@@ -63,14 +67,24 @@ export var createTrackChangesPlugin = function createTrackChangesPlugin(api) {
63
67
  // If no document changes, return the old changeSet
64
68
  return state;
65
69
  }
70
+
71
+ // If we don't have the history plugin don't limit the change tracking
72
+ var historyState = api === null || api === void 0 || (_api$history = api.history) === null || _api$history === void 0 ? void 0 : _api$history.sharedState.currentState();
73
+ var currentAllocation = historyState ?
74
+ // Combine both done + undone so we have the total "distance".
75
+ historyState.done.eventCount + historyState.undone.eventCount : ((_state$steps$at$alloc = (_state$steps$at = state.steps.at(-1)) === null || _state$steps$at === void 0 ? void 0 : _state$steps$at.allocation) !== null && _state$steps$at$alloc !== void 0 ? _state$steps$at$alloc : 0) + 1;
66
76
  var newSteps = tr.steps.map(function (step, idx) {
67
- return new InvertableStep(step, step.invert(tr.docs[idx]));
77
+ return new InvertableStep(step, step.invert(tr.docs[idx]), currentAllocation);
68
78
  });
69
- var steps = resetBaseline ? newSteps : [].concat(_toConsumableArray(state.steps), _toConsumableArray(newSteps));
79
+ var concatSteps = resetBaseline ? newSteps : [].concat(_toConsumableArray(state.steps), _toConsumableArray(newSteps));
70
80
  resetBaseline = false;
81
+ var _filterSteps = filterSteps(concatSteps, state.allocations.add(currentAllocation)),
82
+ allocations = _filterSteps.allocations,
83
+ steps = _filterSteps.steps;
71
84
 
72
85
  // Create a new ChangeSet based on document changes
73
86
  return _objectSpread(_objectSpread({}, state), {}, {
87
+ allocations: allocations,
74
88
  steps: steps,
75
89
  shouldChangesBeDisplayed: false,
76
90
  isShowDiffAvailable: true
@@ -0,0 +1,3 @@
1
+ // To be determined a suitable threshold
2
+ // Exported for testing
3
+ export var MAX_STEPS_FROM_BASELINE = 10;
@@ -1,4 +1,5 @@
1
1
  export var TOGGLE_TRACK_CHANGES_ACTION = /*#__PURE__*/function (TOGGLE_TRACK_CHANGES_ACTION) {
2
2
  TOGGLE_TRACK_CHANGES_ACTION["TOGGLE_TRACK_CHANGES"] = "TOGGLE_TRACK_CHANGES";
3
+ TOGGLE_TRACK_CHANGES_ACTION["RESET_BASELINE"] = "RESET_BASELINE";
3
4
  return TOGGLE_TRACK_CHANGES_ACTION;
4
5
  }({});
@@ -33,6 +33,16 @@ export var trackChangesPlugin = function trackChangesPlugin(_ref) {
33
33
  return tr.setMeta(trackChangesPluginKey, {
34
34
  action: ACTION.TOGGLE_TRACK_CHANGES
35
35
  });
36
+ },
37
+ resetBaseline: function resetBaseline(_ref3) {
38
+ var _api$trackChanges;
39
+ var tr = _ref3.tr;
40
+ if (!(api !== null && api !== void 0 && (_api$trackChanges = api.trackChanges) !== null && _api$trackChanges !== void 0 && (_api$trackChanges = _api$trackChanges.sharedState.currentState()) !== null && _api$trackChanges !== void 0 && _api$trackChanges.isShowDiffAvailable)) {
41
+ return null;
42
+ }
43
+ return tr.setMeta(trackChangesPluginKey, {
44
+ action: ACTION.RESET_BASELINE
45
+ });
36
46
  }
37
47
  },
38
48
  getSharedState: function getSharedState(editorState) {
@@ -0,0 +1,8 @@
1
+ import type { InvertableStep } from './invertableStep';
2
+ /**
3
+ * Returns the filtered steps to ensure we don't track an entire document worth of changes
4
+ */
5
+ export declare function filterSteps(steps: InvertableStep[], allocations: Set<number>): {
6
+ steps: InvertableStep[];
7
+ allocations: Set<number>;
8
+ };
@@ -0,0 +1,7 @@
1
+ import { type Step } from '@atlaskit/editor-prosemirror/transform';
2
+ export declare class InvertableStep {
3
+ readonly step: Step;
4
+ readonly inverted: Step;
5
+ readonly allocation: number;
6
+ constructor(step: Step, inverted: Step, allocation: number);
7
+ }
@@ -1,18 +1,16 @@
1
1
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
2
  import { type ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
4
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
4
- import { type Step } from '@atlaskit/editor-prosemirror/transform';
5
5
  import type { TrackChangesPlugin } from '../trackChangesPluginType';
6
+ import { InvertableStep } from './invertableStep';
6
7
  export declare const trackChangesPluginKey: PluginKey<TrackChangesPluginState>;
7
8
  type TrackChangesPluginState = {
8
9
  shouldChangesBeDisplayed: boolean;
9
10
  isShowDiffAvailable: boolean;
10
11
  steps: InvertableStep[];
12
+ allocations: Set<number>;
11
13
  };
12
- export declare class InvertableStep {
13
- readonly step: Step;
14
- readonly inverted: Step;
15
- constructor(step: Step, inverted: Step);
16
- }
14
+ export declare const getBaselineFromSteps: (doc: PMNode, steps: InvertableStep[]) => PMNode;
17
15
  export declare const createTrackChangesPlugin: (api: ExtractInjectionAPI<TrackChangesPlugin> | undefined) => SafePlugin<TrackChangesPluginState>;
18
16
  export {};
@@ -0,0 +1 @@
1
+ export declare const MAX_STEPS_FROM_BASELINE = 10;
@@ -1,3 +1,4 @@
1
1
  export declare enum TOGGLE_TRACK_CHANGES_ACTION {
2
- TOGGLE_TRACK_CHANGES = "TOGGLE_TRACK_CHANGES"
2
+ TOGGLE_TRACK_CHANGES = "TOGGLE_TRACK_CHANGES",
3
+ RESET_BASELINE = "RESET_BASELINE"
3
4
  }
@@ -1,4 +1,5 @@
1
1
  import type { EditorCommand, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
2
+ import type { HistoryPlugin } from '@atlaskit/editor-plugin-history';
2
3
  import { type PrimaryToolbarPlugin } from '@atlaskit/editor-plugin-primary-toolbar';
3
4
  import type { ShowDiffPlugin } from '@atlaskit/editor-plugin-show-diff';
4
5
  export type TrackChangesPlugin = NextEditorPlugin<'trackChanges', {
@@ -7,12 +8,20 @@ export type TrackChangesPlugin = NextEditorPlugin<'trackChanges', {
7
8
  * Toggles the displaying of changes in the editor.
8
9
  */
9
10
  toggleChanges: EditorCommand;
11
+ /**
12
+ * Resets the baseline used for tracking changes in the editor.
13
+ */
14
+ resetBaseline: EditorCommand;
10
15
  };
11
16
  dependencies: [
12
17
  /**
13
18
  * Primary toolbar plugin for registering the track changes button.
14
19
  */
15
20
  OptionalPlugin<PrimaryToolbarPlugin>,
21
+ /**
22
+ * For ensuring the tracked changes align with the history
23
+ */
24
+ OptionalPlugin<HistoryPlugin>,
16
25
  /**
17
26
  * Show diff plugin for showing the changes in a diff view.
18
27
  */
@@ -0,0 +1,8 @@
1
+ import type { InvertableStep } from './invertableStep';
2
+ /**
3
+ * Returns the filtered steps to ensure we don't track an entire document worth of changes
4
+ */
5
+ export declare function filterSteps(steps: InvertableStep[], allocations: Set<number>): {
6
+ steps: InvertableStep[];
7
+ allocations: Set<number>;
8
+ };
@@ -0,0 +1,7 @@
1
+ import { type Step } from '@atlaskit/editor-prosemirror/transform';
2
+ export declare class InvertableStep {
3
+ readonly step: Step;
4
+ readonly inverted: Step;
5
+ readonly allocation: number;
6
+ constructor(step: Step, inverted: Step, allocation: number);
7
+ }
@@ -1,18 +1,16 @@
1
1
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
2
  import { type ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
4
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
4
- import { type Step } from '@atlaskit/editor-prosemirror/transform';
5
5
  import type { TrackChangesPlugin } from '../trackChangesPluginType';
6
+ import { InvertableStep } from './invertableStep';
6
7
  export declare const trackChangesPluginKey: PluginKey<TrackChangesPluginState>;
7
8
  type TrackChangesPluginState = {
8
9
  shouldChangesBeDisplayed: boolean;
9
10
  isShowDiffAvailable: boolean;
10
11
  steps: InvertableStep[];
12
+ allocations: Set<number>;
11
13
  };
12
- export declare class InvertableStep {
13
- readonly step: Step;
14
- readonly inverted: Step;
15
- constructor(step: Step, inverted: Step);
16
- }
14
+ export declare const getBaselineFromSteps: (doc: PMNode, steps: InvertableStep[]) => PMNode;
17
15
  export declare const createTrackChangesPlugin: (api: ExtractInjectionAPI<TrackChangesPlugin> | undefined) => SafePlugin<TrackChangesPluginState>;
18
16
  export {};
@@ -0,0 +1 @@
1
+ export declare const MAX_STEPS_FROM_BASELINE = 10;
@@ -1,3 +1,4 @@
1
1
  export declare enum TOGGLE_TRACK_CHANGES_ACTION {
2
- TOGGLE_TRACK_CHANGES = "TOGGLE_TRACK_CHANGES"
2
+ TOGGLE_TRACK_CHANGES = "TOGGLE_TRACK_CHANGES",
3
+ RESET_BASELINE = "RESET_BASELINE"
3
4
  }
@@ -1,4 +1,5 @@
1
1
  import type { EditorCommand, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
2
+ import type { HistoryPlugin } from '@atlaskit/editor-plugin-history';
2
3
  import { type PrimaryToolbarPlugin } from '@atlaskit/editor-plugin-primary-toolbar';
3
4
  import type { ShowDiffPlugin } from '@atlaskit/editor-plugin-show-diff';
4
5
  export type TrackChangesPlugin = NextEditorPlugin<'trackChanges', {
@@ -7,12 +8,20 @@ export type TrackChangesPlugin = NextEditorPlugin<'trackChanges', {
7
8
  * Toggles the displaying of changes in the editor.
8
9
  */
9
10
  toggleChanges: EditorCommand;
11
+ /**
12
+ * Resets the baseline used for tracking changes in the editor.
13
+ */
14
+ resetBaseline: EditorCommand;
10
15
  };
11
16
  dependencies: [
12
17
  /**
13
18
  * Primary toolbar plugin for registering the track changes button.
14
19
  */
15
20
  OptionalPlugin<PrimaryToolbarPlugin>,
21
+ /**
22
+ * For ensuring the tracked changes align with the history
23
+ */
24
+ OptionalPlugin<HistoryPlugin>,
16
25
  /**
17
26
  * Show diff plugin for showing the changes in a diff view.
18
27
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-track-changes",
3
- "version": "2.3.0",
3
+ "version": "2.4.1",
4
4
  "description": "ShowDiff plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -32,15 +32,16 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "@atlaskit/button": "^23.3.0",
35
+ "@atlaskit/editor-plugin-history": "3.1.0",
35
36
  "@atlaskit/editor-plugin-primary-toolbar": "^4.1.0",
36
- "@atlaskit/editor-plugin-show-diff": "0.0.0",
37
+ "@atlaskit/editor-plugin-show-diff": "0.0.1",
37
38
  "@atlaskit/editor-prosemirror": "7.0.0",
38
- "@atlaskit/icon-lab": "^5.2.0",
39
+ "@atlaskit/icon-lab": "^5.3.0",
39
40
  "@babel/runtime": "^7.0.0",
40
41
  "react-intl-next": "npm:react-intl@^5.18.1"
41
42
  },
42
43
  "peerDependencies": {
43
- "@atlaskit/editor-common": "^107.14.0",
44
+ "@atlaskit/editor-common": "^107.16.0",
44
45
  "react": "^18.2.0"
45
46
  },
46
47
  "devDependencies": {