@atlaskit/editor-plugin-collab-edit 3.9.4 → 3.10.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/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # @atlaskit/editor-plugin-collab-edit
2
2
 
3
+ ## 3.10.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#171561](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/171561)
8
+ [`d0c41c462c511`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d0c41c462c511) -
9
+ [ux] Telepointers now stay expanded even if there are other transactions received which will
10
+ re-create their DOM elements.
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies
15
+
16
+ ## 3.9.5
17
+
18
+ ### Patch Changes
19
+
20
+ - [#171054](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/171054)
21
+ [`46a532280fd7c`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/46a532280fd7c) -
22
+ Filter out AnalyticsSteps from metric
23
+ - [#169039](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/169039)
24
+ [`d2488752fcad8`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d2488752fcad8) -
25
+ EDITOR-508 Part 1 of cleaning up `platform_editor_use_nested_table_pm_nodes`
26
+ - Updated dependencies
27
+
3
28
  ## 3.9.4
4
29
 
5
30
  ### Patch Changes
@@ -33,6 +33,7 @@ var PluginState = exports.PluginState = /*#__PURE__*/function () {
33
33
  function PluginState(decorations, participants, sessionId) {
34
34
  var collabInitalised = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
35
35
  var onError = arguments.length > 4 ? arguments[4] : undefined;
36
+ var nudgeAnimations = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : new Map();
36
37
  (0, _classCallCheck2.default)(this, PluginState);
37
38
  // eslint-disable-next-line no-console
38
39
  (0, _defineProperty2.default)(this, "onError", function (error) {
@@ -43,6 +44,7 @@ var PluginState = exports.PluginState = /*#__PURE__*/function () {
43
44
  this.sid = sessionId;
44
45
  this.isReady = collabInitalised;
45
46
  this.onError = onError || this.onError;
47
+ this.nudgeAnimations = nudgeAnimations;
46
48
  }
47
49
  return (0, _createClass2.default)(PluginState, [{
48
50
  key: "decorations",
@@ -158,7 +160,7 @@ var PluginState = exports.PluginState = /*#__PURE__*/function () {
158
160
  } catch (err) {
159
161
  this.onError(err);
160
162
  }
161
- add = add.concat((0, _utils.createTelepointers)(from, to, sessionId, isSelection, this.getInitial(sessionId), this.getPresenceId(sessionId), this.getFullName(sessionId)));
163
+ add = add.concat((0, _utils.createTelepointers)(from, to, sessionId, isSelection, this.getInitial(sessionId), this.getPresenceId(sessionId), this.getFullName(sessionId), (0, _platformFeatureFlags.fg)('confluence_team_presence_scroll_to_pointer') ? (0, _utils.hasExistingNudge)(sessionId, this.nudgeAnimations) : false));
162
164
  }
163
165
  }
164
166
  if (tr.docChanged) {
@@ -177,7 +179,7 @@ var PluginState = exports.PluginState = /*#__PURE__*/function () {
177
179
  size = _ref.slice.content.size,
178
180
  _from = _ref.from;
179
181
  var pos = getValidPos(tr, size ? Math.min(_from + size, tr.doc.nodeSize - 3) : Math.max(_from, 1));
180
- add = add.concat((0, _utils.createTelepointers)(pos, pos, _sessionId, false, _this.getInitial(_sessionId), presenceId, _this.getFullName(_sessionId)));
182
+ add = add.concat((0, _utils.createTelepointers)(pos, pos, _sessionId, false, _this.getInitial(_sessionId), presenceId, _this.getFullName(_sessionId), (0, _platformFeatureFlags.fg)('confluence_team_presence_scroll_to_pointer') ? (0, _utils.hasExistingNudge)(_sessionId, _this.nudgeAnimations) : false));
181
183
  }
182
184
  }
183
185
  }
@@ -239,9 +241,11 @@ var PluginState = exports.PluginState = /*#__PURE__*/function () {
239
241
  var _deco$spec, _deco$spec2;
240
242
  if (deco.type.toDOM && participants.get(nudgeSessionId) && ((_deco$spec = deco.spec) === null || _deco$spec === void 0 || (_deco$spec = _deco$spec.pointer) === null || _deco$spec === void 0 ? void 0 : _deco$spec.sessionId) === nudgeSessionId && ((_deco$spec2 = deco.spec) === null || _deco$spec2 === void 0 ? void 0 : _deco$spec2.key) === "telepointer-".concat(nudgeSessionId)) {
241
243
  // Restart animation by removing and re-adding the class
244
+ deco.type.toDOM.classList.remove(_collab.TELEPOINTER_PULSE_DURING_TR_CLASS);
242
245
  deco.type.toDOM.classList.remove(_collab.TELEPOINTER_PULSE_CLASS);
243
246
  void deco.type.toDOM.offsetWidth; // Force reflow
244
247
  deco.type.toDOM.classList.add(_collab.TELEPOINTER_PULSE_CLASS);
248
+ _this.nudgeAnimations.set(nudgeSessionId, Date.now());
245
249
  }
246
250
  });
247
251
  }
@@ -263,6 +267,10 @@ var PluginState = exports.PluginState = /*#__PURE__*/function () {
263
267
  }
264
268
  }
265
269
  }
270
+ if ((0, _platformFeatureFlags.fg)('confluence_team_presence_scroll_to_pointer')) {
271
+ var _nextState = new PluginState(this.decorationSet, participants, sid, collabInitialised, this.onError, this.nudgeAnimations);
272
+ return PluginState.eq(_nextState, this) ? this : _nextState;
273
+ }
266
274
  var nextState = new PluginState(this.decorationSet, participants, sid, collabInitialised);
267
275
  return PluginState.eq(nextState, this) ? this : nextState;
268
276
  }
@@ -10,6 +10,7 @@ var _steps = require("@atlaskit/adf-schema/steps");
10
10
  var _transform = require("@atlaskit/editor-prosemirror/transform");
11
11
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
12
12
  var _prosemirrorCollab = require("@atlaskit/prosemirror-collab");
13
+ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
13
14
  var _trackStepMetrics = require("./track-step-metrics");
14
15
  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; } } }; }
15
16
  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; } }
@@ -179,7 +180,9 @@ var track = exports.track = function track(_ref3) {
179
180
  if ((0, _platformFeatureFlags.fg)('platform_enable_ncs_step_metrics')) {
180
181
  (0, _trackStepMetrics.updateNcsSessionStepMetrics)({
181
182
  api: api,
182
- steps: newSteps
183
+ steps: (0, _experiments.editorExperiment)('platform_editor_reduce_noisy_steps_ncs', true) ? newSteps.filter(function (step) {
184
+ return !(step instanceof _steps.AnalyticsStep);
185
+ }) : newSteps
183
186
  });
184
187
  }
185
188
  scheduler.postTask(function () {
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.findPointers = exports.createTelepointers = exports._findPointers = void 0;
8
8
  exports.getAvatarColor = getAvatarColor;
9
- exports.scrollToCollabCursor = exports.replaceDocument = exports.originalTransactionHasMeta = exports.isReplaceStep = exports.isOrganicChange = exports.getPositionOfTelepointer = void 0;
9
+ exports.scrollToCollabCursor = exports.replaceDocument = exports.originalTransactionHasMeta = exports.isReplaceStep = exports.isOrganicChange = exports.hasExistingNudge = exports.getPositionOfTelepointer = void 0;
10
10
  var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
11
11
  var _steps = require("@atlaskit/adf-schema/steps");
12
12
  var _analytics = require("@atlaskit/editor-common/analytics");
@@ -46,7 +46,7 @@ function getAvatarColor(str) {
46
46
  textColor: participantColor.color.textColor
47
47
  };
48
48
  }
49
- var createTelepointers = exports.createTelepointers = function createTelepointers(from, to, sessionId, isSelection, initial, presenceId, fullName) {
49
+ var createTelepointers = exports.createTelepointers = function createTelepointers(from, to, sessionId, isSelection, initial, presenceId, fullName, isNudged) {
50
50
  var decorations = [];
51
51
  var avatarColor = getAvatarColor(presenceId);
52
52
  var color = avatarColor.index.toString();
@@ -78,6 +78,12 @@ var createTelepointers = exports.createTelepointers = function createTelepointer
78
78
  cursor.setAttribute('data-initial', initial);
79
79
  if ((0, _platformFeatureFlags.fg)('confluence_team_presence_scroll_to_pointer')) {
80
80
  cursor.setAttribute(_collab.TELEPOINTER_DATA_SESSION_ID_ATTR, sessionId);
81
+ // If there is an ongoing expand animation, we'll keep the telepointer expanded
82
+ // until the keyframe animation is complete. Please note that this will restart the anim timer
83
+ // from 0 everytime it's re-added.
84
+ if (isNudged) {
85
+ cursor.classList.add(_collab.TELEPOINTER_PULSE_DURING_TR_CLASS);
86
+ }
81
87
  var fullNameEl = document.createElement('span');
82
88
  fullNameEl.textContent = fullName;
83
89
  fullNameEl.className = 'telepointer-fullname';
@@ -121,20 +127,9 @@ var createTelepointers = exports.createTelepointers = function createTelepointer
121
127
  var replaceDocument = exports.replaceDocument = function replaceDocument(doc, state, version, options, reserveCursor, editorAnalyticsAPI) {
122
128
  var schema = state.schema,
123
129
  tr = state.tr;
124
- var hasContent;
125
- var content;
126
- if ((0, _platformFeatureFlags.fg)('platform_editor_use_nested_table_pm_nodes')) {
127
- var parsedDoc = (0, _processRawValue.processRawValueWithoutValidation)(schema, doc, editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.fireAnalyticsEvent);
128
- hasContent = !!(parsedDoc !== null && parsedDoc !== void 0 && parsedDoc.childCount);
129
- content = parsedDoc === null || parsedDoc === void 0 ? void 0 : parsedDoc.content;
130
- } else {
131
- // Ignored via go/ees005
132
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
133
- content = (doc.content || []).map(function (child) {
134
- return schema.nodeFromJSON(child);
135
- });
136
- hasContent = Array.isArray(content) && !!content.length;
137
- }
130
+ var parsedDoc = (0, _processRawValue.processRawValueWithoutValidation)(schema, doc, editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.fireAnalyticsEvent);
131
+ var hasContent = !!(parsedDoc !== null && parsedDoc !== void 0 && parsedDoc.childCount);
132
+ var content = parsedDoc === null || parsedDoc === void 0 ? void 0 : parsedDoc.content;
138
133
  if (hasContent) {
139
134
  tr.setMeta('addToHistory', false);
140
135
  // Ignored via go/ees005
@@ -250,4 +245,18 @@ var isOrganicChange = exports.isOrganicChange = function isOrganicChange(tr) {
250
245
  }
251
246
  }) && !tr.doc.eq(tr.before);
252
247
  });
248
+ };
249
+
250
+ // If we receive a transaction while there is an ongoing CSS expand animation in the telepointer,
251
+ // it will be cut off due to the removal of the element. We'll persist the animation state in the plugin,
252
+ // so we can keep the expanded version showing even when the telepointer element is recreated.
253
+
254
+ var hasExistingNudge = exports.hasExistingNudge = function hasExistingNudge(sessionId, nudgeAnimations) {
255
+ var nudgeAnimStartTime = nudgeAnimations.get(sessionId);
256
+ var hasExistingNudge = false;
257
+ if (nudgeAnimStartTime) {
258
+ var timeElapsed = Date.now() - nudgeAnimStartTime;
259
+ hasExistingNudge = timeElapsed < _collab.TELEPOINTER_PULSE_DURING_TR_DURATION_MS;
260
+ }
261
+ return hasExistingNudge;
253
262
  };
@@ -1,11 +1,11 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import { browser } from '@atlaskit/editor-common/browser';
3
- import { TELEPOINTER_DIM_CLASS, TELEPOINTER_PULSE_CLASS } from '@atlaskit/editor-common/collab';
3
+ import { TELEPOINTER_DIM_CLASS, TELEPOINTER_PULSE_CLASS, TELEPOINTER_PULSE_DURING_TR_CLASS } from '@atlaskit/editor-common/collab';
4
4
  import { Selection } from '@atlaskit/editor-prosemirror/state';
5
5
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
6
6
  import { fg } from '@atlaskit/platform-feature-flags';
7
7
  import { Participants } from '../participants';
8
- import { createTelepointers, _findPointers, findPointers, getPositionOfTelepointer, isReplaceStep } from '../utils';
8
+ import { createTelepointers, _findPointers, findPointers, getPositionOfTelepointer, isReplaceStep, hasExistingNudge } from '../utils';
9
9
 
10
10
  /**
11
11
  * Returns position where it's possible to place a decoration.
@@ -31,7 +31,7 @@ export class PluginState {
31
31
  get sessionId() {
32
32
  return this.sid;
33
33
  }
34
- constructor(decorations, participants, sessionId, collabInitalised = false, onError) {
34
+ constructor(decorations, participants, sessionId, collabInitalised = false, onError, nudgeAnimations = new Map()) {
35
35
  // eslint-disable-next-line no-console
36
36
  _defineProperty(this, "onError", error => console.error(error));
37
37
  this.decorationSet = decorations;
@@ -39,6 +39,7 @@ export class PluginState {
39
39
  this.sid = sessionId;
40
40
  this.isReady = collabInitalised;
41
41
  this.onError = onError || this.onError;
42
+ this.nudgeAnimations = nudgeAnimations;
42
43
  }
43
44
  getFullName(sessionId) {
44
45
  const participant = this.participants.get(sessionId);
@@ -132,7 +133,7 @@ export class PluginState {
132
133
  } catch (err) {
133
134
  this.onError(err);
134
135
  }
135
- add = add.concat(createTelepointers(from, to, sessionId, isSelection, this.getInitial(sessionId), this.getPresenceId(sessionId), this.getFullName(sessionId)));
136
+ add = add.concat(createTelepointers(from, to, sessionId, isSelection, this.getInitial(sessionId), this.getPresenceId(sessionId), this.getFullName(sessionId), fg('confluence_team_presence_scroll_to_pointer') ? hasExistingNudge(sessionId, this.nudgeAnimations) : false));
136
137
  }
137
138
  }
138
139
  if (tr.docChanged) {
@@ -159,7 +160,7 @@ export class PluginState {
159
160
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
160
161
  } = step;
161
162
  const pos = getValidPos(tr, size ? Math.min(from + size, tr.doc.nodeSize - 3) : Math.max(from, 1));
162
- add = add.concat(createTelepointers(pos, pos, sessionId, false, this.getInitial(sessionId), presenceId, this.getFullName(sessionId)));
163
+ add = add.concat(createTelepointers(pos, pos, sessionId, false, this.getInitial(sessionId), presenceId, this.getFullName(sessionId), fg('confluence_team_presence_scroll_to_pointer') ? hasExistingNudge(sessionId, this.nudgeAnimations) : false));
163
164
  }
164
165
  }
165
166
  }
@@ -224,9 +225,11 @@ export class PluginState {
224
225
  var _deco$spec, _deco$spec$pointer, _deco$spec2;
225
226
  if (deco.type.toDOM && participants.get(nudgeSessionId) && ((_deco$spec = deco.spec) === null || _deco$spec === void 0 ? void 0 : (_deco$spec$pointer = _deco$spec.pointer) === null || _deco$spec$pointer === void 0 ? void 0 : _deco$spec$pointer.sessionId) === nudgeSessionId && ((_deco$spec2 = deco.spec) === null || _deco$spec2 === void 0 ? void 0 : _deco$spec2.key) === `telepointer-${nudgeSessionId}`) {
226
227
  // Restart animation by removing and re-adding the class
228
+ deco.type.toDOM.classList.remove(TELEPOINTER_PULSE_DURING_TR_CLASS);
227
229
  deco.type.toDOM.classList.remove(TELEPOINTER_PULSE_CLASS);
228
230
  void deco.type.toDOM.offsetWidth; // Force reflow
229
231
  deco.type.toDOM.classList.add(TELEPOINTER_PULSE_CLASS);
232
+ this.nudgeAnimations.set(nudgeSessionId, Date.now());
230
233
  }
231
234
  });
232
235
  }
@@ -250,6 +253,10 @@ export class PluginState {
250
253
  }
251
254
  }
252
255
  }
256
+ if (fg('confluence_team_presence_scroll_to_pointer')) {
257
+ const nextState = new PluginState(this.decorationSet, participants, sid, collabInitialised, this.onError, this.nudgeAnimations);
258
+ return PluginState.eq(nextState, this) ? this : nextState;
259
+ }
253
260
  const nextState = new PluginState(this.decorationSet, participants, sid, collabInitialised);
254
261
  return PluginState.eq(nextState, this) ? this : nextState;
255
262
  }
@@ -1,7 +1,8 @@
1
- import { SetAttrsStep } from '@atlaskit/adf-schema/steps';
1
+ import { AnalyticsStep, SetAttrsStep } from '@atlaskit/adf-schema/steps';
2
2
  import { AddMarkStep, AddNodeMarkStep, AttrStep, DocAttrStep, RemoveMarkStep, RemoveNodeMarkStep } from '@atlaskit/editor-prosemirror/transform';
3
3
  import { fg } from '@atlaskit/platform-feature-flags';
4
4
  import { sendableSteps } from '@atlaskit/prosemirror-collab';
5
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
5
6
  import { updateNcsSessionStepMetrics } from './track-step-metrics';
6
7
  function groupBy(array, keyGetter) {
7
8
  // Check group by exists, and that it's a function. If so, use the native browser code
@@ -157,7 +158,7 @@ export const track = ({
157
158
  if (fg('platform_enable_ncs_step_metrics')) {
158
159
  updateNcsSessionStepMetrics({
159
160
  api,
160
- steps: newSteps
161
+ steps: editorExperiment('platform_editor_reduce_noisy_steps_ncs', true) ? newSteps.filter(step => !(step instanceof AnalyticsStep)) : newSteps
161
162
  });
162
163
  }
163
164
  scheduler.postTask(() => {
@@ -1,6 +1,6 @@
1
1
  import { AnalyticsStep, SetAttrsStep } from '@atlaskit/adf-schema/steps';
2
2
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
3
- import { TELEPOINTER_DATA_SESSION_ID_ATTR } from '@atlaskit/editor-common/collab';
3
+ import { TELEPOINTER_DATA_SESSION_ID_ATTR, TELEPOINTER_PULSE_DURING_TR_CLASS, TELEPOINTER_PULSE_DURING_TR_DURATION_MS } from '@atlaskit/editor-common/collab';
4
4
  import { processRawValueWithoutValidation } from '@atlaskit/editor-common/process-raw-value';
5
5
  import { ZERO_WIDTH_JOINER } from '@atlaskit/editor-common/whitespace';
6
6
  import { Transaction, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
@@ -28,7 +28,7 @@ export function getAvatarColor(str) {
28
28
  textColor: participantColor.color.textColor
29
29
  };
30
30
  }
31
- export const createTelepointers = (from, to, sessionId, isSelection, initial, presenceId, fullName) => {
31
+ export const createTelepointers = (from, to, sessionId, isSelection, initial, presenceId, fullName, isNudged) => {
32
32
  const decorations = [];
33
33
  const avatarColor = getAvatarColor(presenceId);
34
34
  const color = avatarColor.index.toString();
@@ -60,6 +60,12 @@ export const createTelepointers = (from, to, sessionId, isSelection, initial, pr
60
60
  cursor.setAttribute('data-initial', initial);
61
61
  if (fg('confluence_team_presence_scroll_to_pointer')) {
62
62
  cursor.setAttribute(TELEPOINTER_DATA_SESSION_ID_ATTR, sessionId);
63
+ // If there is an ongoing expand animation, we'll keep the telepointer expanded
64
+ // until the keyframe animation is complete. Please note that this will restart the anim timer
65
+ // from 0 everytime it's re-added.
66
+ if (isNudged) {
67
+ cursor.classList.add(TELEPOINTER_PULSE_DURING_TR_CLASS);
68
+ }
63
69
  const fullNameEl = document.createElement('span');
64
70
  fullNameEl.textContent = fullName;
65
71
  fullNameEl.className = 'telepointer-fullname';
@@ -105,18 +111,9 @@ export const replaceDocument = (doc, state, version, options, reserveCursor, edi
105
111
  schema,
106
112
  tr
107
113
  } = state;
108
- let hasContent;
109
- let content;
110
- if (fg('platform_editor_use_nested_table_pm_nodes')) {
111
- const parsedDoc = processRawValueWithoutValidation(schema, doc, editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.fireAnalyticsEvent);
112
- hasContent = !!(parsedDoc !== null && parsedDoc !== void 0 && parsedDoc.childCount);
113
- content = parsedDoc === null || parsedDoc === void 0 ? void 0 : parsedDoc.content;
114
- } else {
115
- // Ignored via go/ees005
116
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
117
- content = (doc.content || []).map(child => schema.nodeFromJSON(child));
118
- hasContent = Array.isArray(content) && !!content.length;
119
- }
114
+ const parsedDoc = processRawValueWithoutValidation(schema, doc, editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.fireAnalyticsEvent);
115
+ const hasContent = !!(parsedDoc !== null && parsedDoc !== void 0 && parsedDoc.childCount);
116
+ const content = parsedDoc === null || parsedDoc === void 0 ? void 0 : parsedDoc.content;
120
117
  if (hasContent) {
121
118
  tr.setMeta('addToHistory', false);
122
119
  // Ignored via go/ees005
@@ -232,4 +229,18 @@ export const isOrganicChange = tr => {
232
229
  }
233
230
  }) && !tr.doc.eq(tr.before);
234
231
  });
232
+ };
233
+
234
+ // If we receive a transaction while there is an ongoing CSS expand animation in the telepointer,
235
+ // it will be cut off due to the removal of the element. We'll persist the animation state in the plugin,
236
+ // so we can keep the expanded version showing even when the telepointer element is recreated.
237
+
238
+ export const hasExistingNudge = (sessionId, nudgeAnimations) => {
239
+ const nudgeAnimStartTime = nudgeAnimations.get(sessionId);
240
+ let hasExistingNudge = false;
241
+ if (nudgeAnimStartTime) {
242
+ const timeElapsed = Date.now() - nudgeAnimStartTime;
243
+ hasExistingNudge = timeElapsed < TELEPOINTER_PULSE_DURING_TR_DURATION_MS;
244
+ }
245
+ return hasExistingNudge;
235
246
  };
@@ -2,12 +2,12 @@ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
2
  import _createClass from "@babel/runtime/helpers/createClass";
3
3
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
4
  import { browser } from '@atlaskit/editor-common/browser';
5
- import { TELEPOINTER_DIM_CLASS, TELEPOINTER_PULSE_CLASS } from '@atlaskit/editor-common/collab';
5
+ import { TELEPOINTER_DIM_CLASS, TELEPOINTER_PULSE_CLASS, TELEPOINTER_PULSE_DURING_TR_CLASS } from '@atlaskit/editor-common/collab';
6
6
  import { Selection } from '@atlaskit/editor-prosemirror/state';
7
7
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
8
8
  import { fg } from '@atlaskit/platform-feature-flags';
9
9
  import { Participants } from '../participants';
10
- import { createTelepointers, _findPointers, findPointers, getPositionOfTelepointer, isReplaceStep } from '../utils';
10
+ import { createTelepointers, _findPointers, findPointers, getPositionOfTelepointer, isReplaceStep, hasExistingNudge } from '../utils';
11
11
 
12
12
  /**
13
13
  * Returns position where it's possible to place a decoration.
@@ -27,6 +27,7 @@ export var PluginState = /*#__PURE__*/function () {
27
27
  function PluginState(decorations, participants, sessionId) {
28
28
  var collabInitalised = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
29
29
  var onError = arguments.length > 4 ? arguments[4] : undefined;
30
+ var nudgeAnimations = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : new Map();
30
31
  _classCallCheck(this, PluginState);
31
32
  // eslint-disable-next-line no-console
32
33
  _defineProperty(this, "onError", function (error) {
@@ -37,6 +38,7 @@ export var PluginState = /*#__PURE__*/function () {
37
38
  this.sid = sessionId;
38
39
  this.isReady = collabInitalised;
39
40
  this.onError = onError || this.onError;
41
+ this.nudgeAnimations = nudgeAnimations;
40
42
  }
41
43
  return _createClass(PluginState, [{
42
44
  key: "decorations",
@@ -152,7 +154,7 @@ export var PluginState = /*#__PURE__*/function () {
152
154
  } catch (err) {
153
155
  this.onError(err);
154
156
  }
155
- add = add.concat(createTelepointers(from, to, sessionId, isSelection, this.getInitial(sessionId), this.getPresenceId(sessionId), this.getFullName(sessionId)));
157
+ add = add.concat(createTelepointers(from, to, sessionId, isSelection, this.getInitial(sessionId), this.getPresenceId(sessionId), this.getFullName(sessionId), fg('confluence_team_presence_scroll_to_pointer') ? hasExistingNudge(sessionId, this.nudgeAnimations) : false));
156
158
  }
157
159
  }
158
160
  if (tr.docChanged) {
@@ -171,7 +173,7 @@ export var PluginState = /*#__PURE__*/function () {
171
173
  size = _ref.slice.content.size,
172
174
  _from = _ref.from;
173
175
  var pos = getValidPos(tr, size ? Math.min(_from + size, tr.doc.nodeSize - 3) : Math.max(_from, 1));
174
- add = add.concat(createTelepointers(pos, pos, _sessionId, false, _this.getInitial(_sessionId), presenceId, _this.getFullName(_sessionId)));
176
+ add = add.concat(createTelepointers(pos, pos, _sessionId, false, _this.getInitial(_sessionId), presenceId, _this.getFullName(_sessionId), fg('confluence_team_presence_scroll_to_pointer') ? hasExistingNudge(_sessionId, _this.nudgeAnimations) : false));
175
177
  }
176
178
  }
177
179
  }
@@ -233,9 +235,11 @@ export var PluginState = /*#__PURE__*/function () {
233
235
  var _deco$spec, _deco$spec2;
234
236
  if (deco.type.toDOM && participants.get(nudgeSessionId) && ((_deco$spec = deco.spec) === null || _deco$spec === void 0 || (_deco$spec = _deco$spec.pointer) === null || _deco$spec === void 0 ? void 0 : _deco$spec.sessionId) === nudgeSessionId && ((_deco$spec2 = deco.spec) === null || _deco$spec2 === void 0 ? void 0 : _deco$spec2.key) === "telepointer-".concat(nudgeSessionId)) {
235
237
  // Restart animation by removing and re-adding the class
238
+ deco.type.toDOM.classList.remove(TELEPOINTER_PULSE_DURING_TR_CLASS);
236
239
  deco.type.toDOM.classList.remove(TELEPOINTER_PULSE_CLASS);
237
240
  void deco.type.toDOM.offsetWidth; // Force reflow
238
241
  deco.type.toDOM.classList.add(TELEPOINTER_PULSE_CLASS);
242
+ _this.nudgeAnimations.set(nudgeSessionId, Date.now());
239
243
  }
240
244
  });
241
245
  }
@@ -257,6 +261,10 @@ export var PluginState = /*#__PURE__*/function () {
257
261
  }
258
262
  }
259
263
  }
264
+ if (fg('confluence_team_presence_scroll_to_pointer')) {
265
+ var _nextState = new PluginState(this.decorationSet, participants, sid, collabInitialised, this.onError, this.nudgeAnimations);
266
+ return PluginState.eq(_nextState, this) ? this : _nextState;
267
+ }
260
268
  var nextState = new PluginState(this.decorationSet, participants, sid, collabInitialised);
261
269
  return PluginState.eq(nextState, this) ? this : nextState;
262
270
  }
@@ -2,10 +2,11 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
2
  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; } } }; }
3
3
  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; } }
4
4
  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; }
5
- import { SetAttrsStep } from '@atlaskit/adf-schema/steps';
5
+ import { AnalyticsStep, SetAttrsStep } from '@atlaskit/adf-schema/steps';
6
6
  import { AddMarkStep, AddNodeMarkStep, AttrStep, DocAttrStep, RemoveMarkStep, RemoveNodeMarkStep } from '@atlaskit/editor-prosemirror/transform';
7
7
  import { fg } from '@atlaskit/platform-feature-flags';
8
8
  import { sendableSteps } from '@atlaskit/prosemirror-collab';
9
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
9
10
  import { updateNcsSessionStepMetrics } from './track-step-metrics';
10
11
  function groupBy(array, keyGetter) {
11
12
  // Check group by exists, and that it's a function. If so, use the native browser code
@@ -172,7 +173,9 @@ export var track = function track(_ref3) {
172
173
  if (fg('platform_enable_ncs_step_metrics')) {
173
174
  updateNcsSessionStepMetrics({
174
175
  api: api,
175
- steps: newSteps
176
+ steps: editorExperiment('platform_editor_reduce_noisy_steps_ncs', true) ? newSteps.filter(function (step) {
177
+ return !(step instanceof AnalyticsStep);
178
+ }) : newSteps
176
179
  });
177
180
  }
178
181
  scheduler.postTask(function () {
@@ -1,7 +1,7 @@
1
1
  import _typeof from "@babel/runtime/helpers/typeof";
2
2
  import { AnalyticsStep, SetAttrsStep } from '@atlaskit/adf-schema/steps';
3
3
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
4
- import { TELEPOINTER_DATA_SESSION_ID_ATTR } from '@atlaskit/editor-common/collab';
4
+ import { TELEPOINTER_DATA_SESSION_ID_ATTR, TELEPOINTER_PULSE_DURING_TR_CLASS, TELEPOINTER_PULSE_DURING_TR_DURATION_MS } from '@atlaskit/editor-common/collab';
5
5
  import { processRawValueWithoutValidation } from '@atlaskit/editor-common/process-raw-value';
6
6
  import { ZERO_WIDTH_JOINER } from '@atlaskit/editor-common/whitespace';
7
7
  import { Transaction, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
@@ -37,7 +37,7 @@ export function getAvatarColor(str) {
37
37
  textColor: participantColor.color.textColor
38
38
  };
39
39
  }
40
- export var createTelepointers = function createTelepointers(from, to, sessionId, isSelection, initial, presenceId, fullName) {
40
+ export var createTelepointers = function createTelepointers(from, to, sessionId, isSelection, initial, presenceId, fullName, isNudged) {
41
41
  var decorations = [];
42
42
  var avatarColor = getAvatarColor(presenceId);
43
43
  var color = avatarColor.index.toString();
@@ -69,6 +69,12 @@ export var createTelepointers = function createTelepointers(from, to, sessionId,
69
69
  cursor.setAttribute('data-initial', initial);
70
70
  if (fg('confluence_team_presence_scroll_to_pointer')) {
71
71
  cursor.setAttribute(TELEPOINTER_DATA_SESSION_ID_ATTR, sessionId);
72
+ // If there is an ongoing expand animation, we'll keep the telepointer expanded
73
+ // until the keyframe animation is complete. Please note that this will restart the anim timer
74
+ // from 0 everytime it's re-added.
75
+ if (isNudged) {
76
+ cursor.classList.add(TELEPOINTER_PULSE_DURING_TR_CLASS);
77
+ }
72
78
  var fullNameEl = document.createElement('span');
73
79
  fullNameEl.textContent = fullName;
74
80
  fullNameEl.className = 'telepointer-fullname';
@@ -112,20 +118,9 @@ export var createTelepointers = function createTelepointers(from, to, sessionId,
112
118
  export var replaceDocument = function replaceDocument(doc, state, version, options, reserveCursor, editorAnalyticsAPI) {
113
119
  var schema = state.schema,
114
120
  tr = state.tr;
115
- var hasContent;
116
- var content;
117
- if (fg('platform_editor_use_nested_table_pm_nodes')) {
118
- var parsedDoc = processRawValueWithoutValidation(schema, doc, editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.fireAnalyticsEvent);
119
- hasContent = !!(parsedDoc !== null && parsedDoc !== void 0 && parsedDoc.childCount);
120
- content = parsedDoc === null || parsedDoc === void 0 ? void 0 : parsedDoc.content;
121
- } else {
122
- // Ignored via go/ees005
123
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
124
- content = (doc.content || []).map(function (child) {
125
- return schema.nodeFromJSON(child);
126
- });
127
- hasContent = Array.isArray(content) && !!content.length;
128
- }
121
+ var parsedDoc = processRawValueWithoutValidation(schema, doc, editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.fireAnalyticsEvent);
122
+ var hasContent = !!(parsedDoc !== null && parsedDoc !== void 0 && parsedDoc.childCount);
123
+ var content = parsedDoc === null || parsedDoc === void 0 ? void 0 : parsedDoc.content;
129
124
  if (hasContent) {
130
125
  tr.setMeta('addToHistory', false);
131
126
  // Ignored via go/ees005
@@ -242,4 +237,18 @@ export var isOrganicChange = function isOrganicChange(tr) {
242
237
  }
243
238
  }) && !tr.doc.eq(tr.before);
244
239
  });
240
+ };
241
+
242
+ // If we receive a transaction while there is an ongoing CSS expand animation in the telepointer,
243
+ // it will be cut off due to the removal of the element. We'll persist the animation state in the plugin,
244
+ // so we can keep the expanded version showing even when the telepointer element is recreated.
245
+
246
+ export var hasExistingNudge = function hasExistingNudge(sessionId, nudgeAnimations) {
247
+ var nudgeAnimStartTime = nudgeAnimations.get(sessionId);
248
+ var hasExistingNudge = false;
249
+ if (nudgeAnimStartTime) {
250
+ var timeElapsed = Date.now() - nudgeAnimStartTime;
251
+ hasExistingNudge = timeElapsed < TELEPOINTER_PULSE_DURING_TR_DURATION_MS;
252
+ }
253
+ return hasExistingNudge;
245
254
  };
@@ -2,6 +2,7 @@ import type { ReadonlyTransaction } from '@atlaskit/editor-prosemirror/state';
2
2
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
3
3
  import type { ReadOnlyParticipants } from '../../types';
4
4
  import { Participants } from '../participants';
5
+ import { type NudgeAnimationsMap } from '../utils';
5
6
  /**
6
7
  * Returns position where it's possible to place a decoration.
7
8
  */
@@ -9,13 +10,14 @@ export declare const getValidPos: (tr: ReadonlyTransaction, pos: number) => numb
9
10
  export declare class PluginState {
10
11
  private decorationSet;
11
12
  private participants;
13
+ private nudgeAnimations;
12
14
  private onError;
13
15
  private sid?;
14
16
  isReady: boolean;
15
17
  get decorations(): DecorationSet;
16
18
  get activeParticipants(): ReadOnlyParticipants;
17
19
  get sessionId(): string | undefined;
18
- constructor(decorations: DecorationSet, participants: Participants, sessionId?: string, collabInitalised?: boolean, onError?: (err: Error) => void);
20
+ constructor(decorations: DecorationSet, participants: Participants, sessionId?: string, collabInitalised?: boolean, onError?: (err: Error) => void, nudgeAnimations?: NudgeAnimationsMap);
19
21
  getFullName(sessionId: string): string;
20
22
  getInitial(sessionId: string): string;
21
23
  getPresenceId(sessionId: string): string;
@@ -1,6 +1,6 @@
1
- import { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
1
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
2
  import type { Step } from '@atlaskit/editor-prosemirror/transform';
3
- import { CollabEditPlugin } from '../collabEditPluginType';
3
+ import type { CollabEditPlugin } from '../collabEditPluginType';
4
4
  type StepSessionMetrics = {
5
5
  totalStepSize: number;
6
6
  numberOfSteps: number;
@@ -1,7 +1,7 @@
1
- import { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
1
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
2
  import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
3
3
  import type { Step } from '@atlaskit/editor-prosemirror/transform';
4
- import { CollabEditPlugin } from '../collabEditPluginType';
4
+ import type { CollabEditPlugin } from '../collabEditPluginType';
5
5
  export type SanitizedStep = {
6
6
  stepType: string;
7
7
  attr?: string;
@@ -11,7 +11,7 @@ export declare function getAvatarColor(str: string): {
11
11
  backgroundColor: string;
12
12
  textColor: string;
13
13
  };
14
- export declare const createTelepointers: (from: number, to: number, sessionId: string, isSelection: boolean, initial: string, presenceId: string, fullName: string) => Decoration[];
14
+ export declare const createTelepointers: (from: number, to: number, sessionId: string, isSelection: boolean, initial: string, presenceId: string, fullName: string, isNudged: boolean) => Decoration[];
15
15
  export declare const replaceDocument: (doc: any, state: EditorState, version?: number, options?: CollabEditOptions, reserveCursor?: boolean, editorAnalyticsAPI?: EditorAnalyticsAPI) => Transaction;
16
16
  export declare const scrollToCollabCursor: (editorView: EditorView, participants: CollabParticipant[], sessionId: string | undefined, index: number, editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => void;
17
17
  export declare const getPositionOfTelepointer: (sessionId: string, decorationSet: DecorationSet) => undefined | number;
@@ -23,3 +23,5 @@ export declare const originalTransactionHasMeta: (transaction: Transaction | Rea
23
23
  * @returns boolean
24
24
  */
25
25
  export declare const isOrganicChange: (tr: ReadonlyTransaction) => boolean;
26
+ export type NudgeAnimationsMap = Map<string, number>;
27
+ export declare const hasExistingNudge: (sessionId: string, nudgeAnimations: NudgeAnimationsMap) => boolean;
@@ -2,6 +2,7 @@ import type { ReadonlyTransaction } from '@atlaskit/editor-prosemirror/state';
2
2
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
3
3
  import type { ReadOnlyParticipants } from '../../types';
4
4
  import { Participants } from '../participants';
5
+ import { type NudgeAnimationsMap } from '../utils';
5
6
  /**
6
7
  * Returns position where it's possible to place a decoration.
7
8
  */
@@ -9,13 +10,14 @@ export declare const getValidPos: (tr: ReadonlyTransaction, pos: number) => numb
9
10
  export declare class PluginState {
10
11
  private decorationSet;
11
12
  private participants;
13
+ private nudgeAnimations;
12
14
  private onError;
13
15
  private sid?;
14
16
  isReady: boolean;
15
17
  get decorations(): DecorationSet;
16
18
  get activeParticipants(): ReadOnlyParticipants;
17
19
  get sessionId(): string | undefined;
18
- constructor(decorations: DecorationSet, participants: Participants, sessionId?: string, collabInitalised?: boolean, onError?: (err: Error) => void);
20
+ constructor(decorations: DecorationSet, participants: Participants, sessionId?: string, collabInitalised?: boolean, onError?: (err: Error) => void, nudgeAnimations?: NudgeAnimationsMap);
19
21
  getFullName(sessionId: string): string;
20
22
  getInitial(sessionId: string): string;
21
23
  getPresenceId(sessionId: string): string;
@@ -1,6 +1,6 @@
1
- import { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
1
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
2
  import type { Step } from '@atlaskit/editor-prosemirror/transform';
3
- import { CollabEditPlugin } from '../collabEditPluginType';
3
+ import type { CollabEditPlugin } from '../collabEditPluginType';
4
4
  type StepSessionMetrics = {
5
5
  totalStepSize: number;
6
6
  numberOfSteps: number;
@@ -1,7 +1,7 @@
1
- import { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
1
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
2
  import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
3
3
  import type { Step } from '@atlaskit/editor-prosemirror/transform';
4
- import { CollabEditPlugin } from '../collabEditPluginType';
4
+ import type { CollabEditPlugin } from '../collabEditPluginType';
5
5
  export type SanitizedStep = {
6
6
  stepType: string;
7
7
  attr?: string;
@@ -11,7 +11,7 @@ export declare function getAvatarColor(str: string): {
11
11
  backgroundColor: string;
12
12
  textColor: string;
13
13
  };
14
- export declare const createTelepointers: (from: number, to: number, sessionId: string, isSelection: boolean, initial: string, presenceId: string, fullName: string) => Decoration[];
14
+ export declare const createTelepointers: (from: number, to: number, sessionId: string, isSelection: boolean, initial: string, presenceId: string, fullName: string, isNudged: boolean) => Decoration[];
15
15
  export declare const replaceDocument: (doc: any, state: EditorState, version?: number, options?: CollabEditOptions, reserveCursor?: boolean, editorAnalyticsAPI?: EditorAnalyticsAPI) => Transaction;
16
16
  export declare const scrollToCollabCursor: (editorView: EditorView, participants: CollabParticipant[], sessionId: string | undefined, index: number, editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => void;
17
17
  export declare const getPositionOfTelepointer: (sessionId: string, decorationSet: DecorationSet) => undefined | number;
@@ -23,3 +23,5 @@ export declare const originalTransactionHasMeta: (transaction: Transaction | Rea
23
23
  * @returns boolean
24
24
  */
25
25
  export declare const isOrganicChange: (tr: ReadonlyTransaction) => boolean;
26
+ export type NudgeAnimationsMap = Map<string, number>;
27
+ export declare const hasExistingNudge: (sessionId: string, nudgeAnimations: NudgeAnimationsMap) => boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-collab-edit",
3
- "version": "3.9.4",
3
+ "version": "3.10.0",
4
4
  "description": "Collab Edit plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -33,7 +33,7 @@
33
33
  "dependencies": {
34
34
  "@atlaskit/adf-schema": "^47.6.0",
35
35
  "@atlaskit/custom-steps": "^0.11.0",
36
- "@atlaskit/editor-common": "^106.6.0",
36
+ "@atlaskit/editor-common": "^106.8.0",
37
37
  "@atlaskit/editor-json-transformer": "^8.24.0",
38
38
  "@atlaskit/editor-plugin-analytics": "^2.3.0",
39
39
  "@atlaskit/editor-plugin-connectivity": "^2.0.0",
@@ -56,7 +56,7 @@
56
56
  "@af/integration-testing": "workspace:^",
57
57
  "@af/visual-regression": "workspace:^",
58
58
  "@atlaskit/editor-plugin-mentions": "^4.7.0",
59
- "@atlaskit/editor-plugin-text-formatting": "^2.2.0",
59
+ "@atlaskit/editor-plugin-text-formatting": "^2.3.0",
60
60
  "@atlaskit/editor-plugin-type-ahead": "^2.7.0",
61
61
  "@atlaskit/editor-plugin-unsupported-content": "^2.1.0",
62
62
  "@atlaskit/editor-test-helpers": "workspace:^",
@@ -105,9 +105,6 @@
105
105
  }
106
106
  },
107
107
  "platform-feature-flags": {
108
- "platform_editor_use_nested_table_pm_nodes": {
109
- "type": "boolean"
110
- },
111
108
  "platform_editor_selection_without_left_shift": {
112
109
  "type": "boolean"
113
110
  },