@atlaskit/editor-plugin-collab-edit 1.11.2 → 1.13.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 +22 -0
- package/dist/cjs/plugin.js +15 -3
- package/dist/cjs/pm-plugins/main/plugin-state.js +2 -6
- package/dist/cjs/pm-plugins/track-last-organic-change.js +39 -0
- package/dist/cjs/pm-plugins/track-ncs-initialization.js +3 -13
- package/dist/cjs/utils.js +60 -1
- package/dist/es2019/plugin.js +15 -3
- package/dist/es2019/pm-plugins/main/plugin-state.js +1 -3
- package/dist/es2019/pm-plugins/track-last-organic-change.js +33 -0
- package/dist/es2019/pm-plugins/track-ncs-initialization.js +2 -12
- package/dist/es2019/utils.js +58 -0
- package/dist/esm/plugin.js +15 -3
- package/dist/esm/pm-plugins/main/plugin-state.js +1 -5
- package/dist/esm/pm-plugins/track-last-organic-change.js +33 -0
- package/dist/esm/pm-plugins/track-ncs-initialization.js +2 -12
- package/dist/esm/utils.js +60 -0
- package/dist/types/pm-plugins/track-last-organic-change.d.ts +5 -0
- package/dist/types/types.d.ts +3 -0
- package/dist/types/utils.d.ts +11 -2
- package/dist/types-ts4.5/pm-plugins/track-last-organic-change.d.ts +5 -0
- package/dist/types-ts4.5/types.d.ts +3 -0
- package/dist/types-ts4.5/utils.d.ts +11 -2
- package/package.json +14 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-collab-edit
|
|
2
2
|
|
|
3
|
+
## 1.13.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#128347](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/128347)
|
|
8
|
+
[`e33566cebd5d1`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/e33566cebd5d1) -
|
|
9
|
+
[ED-24175] bump @atlaskit/adf-schema to 40.8.1 and @atlassian/adf-schema-json to 1.22.0 to
|
|
10
|
+
promotecodeblocks & media in quotes, and nested expands in expands to full schema, and allow
|
|
11
|
+
quotes in panels and decisions in lists in stage0 schema, and a validator spec change
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies
|
|
16
|
+
|
|
17
|
+
## 1.12.0
|
|
18
|
+
|
|
19
|
+
### Minor Changes
|
|
20
|
+
|
|
21
|
+
- [#127757](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/127757)
|
|
22
|
+
[`7ebfdd4e7821d`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/7ebfdd4e7821d) -
|
|
23
|
+
Added logic to track the timestamp of when last organic change happened
|
|
24
|
+
|
|
3
25
|
## 1.11.2
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
package/dist/cjs/plugin.js
CHANGED
|
@@ -11,12 +11,14 @@ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers
|
|
|
11
11
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
12
12
|
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
13
13
|
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
14
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
14
15
|
var _prosemirrorCollab = require("@atlaskit/prosemirror-collab");
|
|
15
16
|
var _analytics2 = require("./analytics");
|
|
16
17
|
var _sendTransaction = require("./events/send-transaction");
|
|
17
18
|
var _main = require("./pm-plugins/main");
|
|
18
19
|
var _pluginKey = require("./pm-plugins/main/plugin-key");
|
|
19
20
|
var _nativeCollabProviderPlugin = require("./pm-plugins/native-collab-provider-plugin");
|
|
21
|
+
var _trackLastOrganicChange = require("./pm-plugins/track-last-organic-change");
|
|
20
22
|
var _trackNcsInitialization = require("./pm-plugins/track-ncs-initialization");
|
|
21
23
|
var _trackSteps = require("./track-steps");
|
|
22
24
|
var _utils = require("./utils");
|
|
@@ -109,7 +111,8 @@ var collabEditPlugin = exports.collabEditPlugin = function collabEditPlugin(_ref
|
|
|
109
111
|
initialised: {
|
|
110
112
|
collabInitialisedAt: null,
|
|
111
113
|
firstChangeAfterInitAt: null,
|
|
112
|
-
firstContentBodyChangeAfterInitAt: null
|
|
114
|
+
firstContentBodyChangeAfterInitAt: null,
|
|
115
|
+
lastOrganicChangeAt: null
|
|
113
116
|
},
|
|
114
117
|
activeParticipants: undefined,
|
|
115
118
|
sessionId: undefined
|
|
@@ -117,13 +120,15 @@ var collabEditPlugin = exports.collabEditPlugin = function collabEditPlugin(_ref
|
|
|
117
120
|
}
|
|
118
121
|
var collabPluginState = _pluginKey.pluginKey.getState(state);
|
|
119
122
|
var metadata = _trackNcsInitialization.trackNCSInitializationPluginKey.getState(state);
|
|
123
|
+
var lastOrganicChangeState = _trackLastOrganicChange.trackLastOrganicChangePluginKey.getState(state);
|
|
120
124
|
return {
|
|
121
125
|
activeParticipants: collabPluginState === null || collabPluginState === void 0 ? void 0 : collabPluginState.activeParticipants,
|
|
122
126
|
sessionId: collabPluginState === null || collabPluginState === void 0 ? void 0 : collabPluginState.sessionId,
|
|
123
127
|
initialised: {
|
|
124
128
|
collabInitialisedAt: (metadata === null || metadata === void 0 ? void 0 : metadata.collabInitialisedAt) || null,
|
|
125
129
|
firstChangeAfterInitAt: (metadata === null || metadata === void 0 ? void 0 : metadata.firstChangeAfterInitAt) || null,
|
|
126
|
-
firstContentBodyChangeAfterInitAt: (metadata === null || metadata === void 0 ? void 0 : metadata.firstContentBodyChangeAfterInitAt) || null
|
|
130
|
+
firstContentBodyChangeAfterInitAt: (metadata === null || metadata === void 0 ? void 0 : metadata.firstContentBodyChangeAfterInitAt) || null,
|
|
131
|
+
lastOrganicChangeAt: (lastOrganicChangeState === null || lastOrganicChangeState === void 0 ? void 0 : lastOrganicChangeState.lastOrganicChangeAt) || null
|
|
127
132
|
}
|
|
128
133
|
};
|
|
129
134
|
},
|
|
@@ -141,7 +146,7 @@ var collabEditPlugin = exports.collabEditPlugin = function collabEditPlugin(_ref
|
|
|
141
146
|
useNativePlugin = _ref5$useNativePlugin === void 0 ? false : _ref5$useNativePlugin,
|
|
142
147
|
_ref5$userId = _ref5.userId,
|
|
143
148
|
userId = _ref5$userId === void 0 ? null : _ref5$userId;
|
|
144
|
-
|
|
149
|
+
var plugins = [].concat((0, _toConsumableArray2.default)(useNativePlugin ? [{
|
|
145
150
|
name: 'pmCollab',
|
|
146
151
|
plugin: function plugin() {
|
|
147
152
|
return (0, _prosemirrorCollab.collab)({
|
|
@@ -166,6 +171,13 @@ var collabEditPlugin = exports.collabEditPlugin = function collabEditPlugin(_ref
|
|
|
166
171
|
name: 'collabTrackNCSInitializationPlugin',
|
|
167
172
|
plugin: _trackNcsInitialization.createPlugin
|
|
168
173
|
}]);
|
|
174
|
+
if ((0, _platformFeatureFlags.fg)('platform_editor_last_organic_change')) {
|
|
175
|
+
plugins.push({
|
|
176
|
+
name: 'collabTrackLastOrganicChangePlugin',
|
|
177
|
+
plugin: _trackLastOrganicChange.createPlugin
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
return plugins;
|
|
169
181
|
},
|
|
170
182
|
onEditorViewStateUpdated: function onEditorViewStateUpdated(props) {
|
|
171
183
|
var _api$analytics, _api$editorViewMode, _options$useNativePlu;
|
|
@@ -18,13 +18,9 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
|
|
|
18
18
|
var _collab = require("@atlaskit/editor-common/collab");
|
|
19
19
|
var _utils = require("@atlaskit/editor-common/utils");
|
|
20
20
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
21
|
-
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
22
21
|
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
23
22
|
var _participants = require("../../participants");
|
|
24
23
|
var _utils2 = require("../../utils");
|
|
25
|
-
var isReplaceStep = function isReplaceStep(step) {
|
|
26
|
-
return step instanceof _transform.ReplaceStep;
|
|
27
|
-
};
|
|
28
24
|
/**
|
|
29
25
|
* Returns position where it's possible to place a decoration.
|
|
30
26
|
*/
|
|
@@ -149,7 +145,7 @@ var PluginState = exports.PluginState = /*#__PURE__*/function () {
|
|
|
149
145
|
// Reapplies decorators those got removed by the state change
|
|
150
146
|
onRemove: function onRemove(spec) {
|
|
151
147
|
if (spec.pointer && spec.pointer.sessionId && spec.key === "telepointer-".concat(spec.pointer.sessionId)) {
|
|
152
|
-
var step = tr.steps.filter(isReplaceStep)[0];
|
|
148
|
+
var step = tr.steps.filter(_utils2.isReplaceStep)[0];
|
|
153
149
|
if (step) {
|
|
154
150
|
var _sessionId = spec.pointer.sessionId;
|
|
155
151
|
var _ref = step,
|
|
@@ -167,7 +163,7 @@ var PluginState = exports.PluginState = /*#__PURE__*/function () {
|
|
|
167
163
|
|
|
168
164
|
// Remove any selection decoration within the change range,
|
|
169
165
|
// takes care of the issue when after pasting we end up with a dead selection
|
|
170
|
-
tr.steps.filter(isReplaceStep).forEach(function (s) {
|
|
166
|
+
tr.steps.filter(_utils2.isReplaceStep).forEach(function (s) {
|
|
171
167
|
var _ref2 = s,
|
|
172
168
|
from = _ref2.from,
|
|
173
169
|
to = _ref2.to;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.trackLastOrganicChangePluginKey = exports.createPlugin = void 0;
|
|
7
|
+
var _collab = require("@atlaskit/editor-common/collab");
|
|
8
|
+
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
9
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
10
|
+
var _utils = require("../utils");
|
|
11
|
+
var trackLastOrganicChangePluginKey = exports.trackLastOrganicChangePluginKey = new _state.PluginKey('collabTrackLastOrganicChangePlugin');
|
|
12
|
+
var createPlugin = exports.createPlugin = function createPlugin() {
|
|
13
|
+
return new _safePlugin.SafePlugin({
|
|
14
|
+
key: trackLastOrganicChangePluginKey,
|
|
15
|
+
state: {
|
|
16
|
+
init: function init() {
|
|
17
|
+
return {
|
|
18
|
+
lastOrganicChangeAt: null
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
apply: function apply(transaction, prevPluginState) {
|
|
22
|
+
var isRemote = (0, _utils.originalTransactionHasMeta)(transaction, 'isRemote');
|
|
23
|
+
var isDocumentReplaceFromRemote = isRemote && (0, _utils.originalTransactionHasMeta)(transaction, 'replaceDocument');
|
|
24
|
+
if (isDocumentReplaceFromRemote) {
|
|
25
|
+
return prevPluginState;
|
|
26
|
+
}
|
|
27
|
+
if (isRemote || (0, _collab.isDirtyTransaction)(transaction)) {
|
|
28
|
+
return prevPluginState;
|
|
29
|
+
}
|
|
30
|
+
if ((0, _utils.isOrganicChange)(transaction)) {
|
|
31
|
+
return {
|
|
32
|
+
lastOrganicChangeAt: Date.now()
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return prevPluginState;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
};
|
|
@@ -10,18 +10,8 @@ var _collab = require("@atlaskit/editor-common/collab");
|
|
|
10
10
|
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
11
11
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
12
12
|
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
13
|
+
var _utils = require("../utils");
|
|
13
14
|
var trackNCSInitializationPluginKey = exports.trackNCSInitializationPluginKey = new _state.PluginKey('collabTrackNCSInitializationPlugin');
|
|
14
|
-
var originalTransactionHasMeta = function originalTransactionHasMeta(transaction, metaTag) {
|
|
15
|
-
var hasMetaTag = Boolean(transaction.getMeta(metaTag));
|
|
16
|
-
if (hasMetaTag) {
|
|
17
|
-
return true;
|
|
18
|
-
}
|
|
19
|
-
var appendedTransaction = transaction.getMeta('appendedTransaction');
|
|
20
|
-
if (appendedTransaction instanceof _state.Transaction) {
|
|
21
|
-
return originalTransactionHasMeta(appendedTransaction, metaTag);
|
|
22
|
-
}
|
|
23
|
-
return false;
|
|
24
|
-
};
|
|
25
15
|
var createPlugin = exports.createPlugin = function createPlugin() {
|
|
26
16
|
return new _safePlugin.SafePlugin({
|
|
27
17
|
key: trackNCSInitializationPluginKey,
|
|
@@ -45,8 +35,8 @@ var createPlugin = exports.createPlugin = function createPlugin() {
|
|
|
45
35
|
if (!shouldCheckDocument) {
|
|
46
36
|
return prevPluginState;
|
|
47
37
|
}
|
|
48
|
-
var isRemote = originalTransactionHasMeta(transaction, 'isRemote');
|
|
49
|
-
var isDocumentReplaceFromRemote = isRemote && originalTransactionHasMeta(transaction, 'replaceDocument');
|
|
38
|
+
var isRemote = (0, _utils.originalTransactionHasMeta)(transaction, 'isRemote');
|
|
39
|
+
var isDocumentReplaceFromRemote = isRemote && (0, _utils.originalTransactionHasMeta)(transaction, 'replaceDocument');
|
|
50
40
|
if (isDocumentReplaceFromRemote) {
|
|
51
41
|
return prevPluginState;
|
|
52
42
|
}
|
package/dist/cjs/utils.js
CHANGED
|
@@ -6,11 +6,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
});
|
|
7
7
|
exports.findPointers = exports.createTelepointers = void 0;
|
|
8
8
|
exports.getAvatarColor = getAvatarColor;
|
|
9
|
-
exports.scrollToCollabCursor = exports.replaceDocument = exports.getPositionOfTelepointer = void 0;
|
|
9
|
+
exports.scrollToCollabCursor = exports.replaceDocument = exports.originalTransactionHasMeta = exports.isReplaceStep = exports.isOrganicChange = exports.getPositionOfTelepointer = void 0;
|
|
10
10
|
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
11
|
+
var _steps = require("@atlaskit/adf-schema/steps");
|
|
11
12
|
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
12
13
|
var _whitespace = require("@atlaskit/editor-common/whitespace");
|
|
13
14
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
15
|
+
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
14
16
|
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
15
17
|
var _consts = require("@atlaskit/editor-shared-styles/consts");
|
|
16
18
|
var findPointers = exports.findPointers = function findPointers(id, decorations) {
|
|
@@ -140,4 +142,61 @@ var getPositionOfTelepointer = exports.getPositionOfTelepointer = function getPo
|
|
|
140
142
|
}
|
|
141
143
|
});
|
|
142
144
|
return scrollPosition;
|
|
145
|
+
};
|
|
146
|
+
var isReplaceStep = exports.isReplaceStep = function isReplaceStep(step) {
|
|
147
|
+
return step instanceof _transform.ReplaceStep;
|
|
148
|
+
};
|
|
149
|
+
var originalTransactionHasMeta = exports.originalTransactionHasMeta = function originalTransactionHasMeta(transaction, metaTag) {
|
|
150
|
+
var hasMetaTag = Boolean(transaction.getMeta(metaTag));
|
|
151
|
+
if (hasMetaTag) {
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
var appendedTransaction = transaction.getMeta('appendedTransaction');
|
|
155
|
+
if (appendedTransaction instanceof _state.Transaction) {
|
|
156
|
+
return originalTransactionHasMeta(appendedTransaction, metaTag);
|
|
157
|
+
}
|
|
158
|
+
return false;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* This list contains step attributes that do not result from a user action.
|
|
163
|
+
* All steps that contain ONLY the blocked attribute are considered automated steps
|
|
164
|
+
* and should not be recognised as organic change.
|
|
165
|
+
*
|
|
166
|
+
* `attr_colwidth` is an exception to above explanation. Resizing the column
|
|
167
|
+
* currently creates too many steps and is therefore also on this list.
|
|
168
|
+
*
|
|
169
|
+
* Steps analycs dashboard: https://atlassian-discover.cloud.databricks.com/dashboardsv3/01ef4d3c8aa916c8b0cb5332a9f37caf/published?o=4482001201517624
|
|
170
|
+
*/
|
|
171
|
+
var blockedAttrsList = ['__contextId', 'localId', '__autoSize', 'attr_colwidth'];
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Takes the transaction and editor state and checks if the transaction is considered organic change
|
|
175
|
+
* @param tr Transaction
|
|
176
|
+
* @returns boolean
|
|
177
|
+
*/
|
|
178
|
+
var isOrganicChange = exports.isOrganicChange = function isOrganicChange(tr) {
|
|
179
|
+
// If document has not been marked as `docChanged` by PM, skip the rest of the logic
|
|
180
|
+
if (!tr.docChanged) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
return tr.steps.some(function (step) {
|
|
184
|
+
// If a step is an instance of AnalyticsStep, it is not considered organic
|
|
185
|
+
if (step instanceof _steps.AnalyticsStep) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
// If a step is not an instance of SetAttrsStep, it is considered organic
|
|
189
|
+
if (!(step instanceof _steps.SetAttrsStep)) {
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
var allAttributes = Object.keys(step.attrs);
|
|
193
|
+
// If a step is an instance of SetAttrsStep, it checks if the attributes in the step
|
|
194
|
+
// are not in the `blockedAttributes`. If one of the attributes not on the list, it considers the change
|
|
195
|
+
// organic but only if the entire document is not equal to the previous state.
|
|
196
|
+
return allAttributes.some(function (attr) {
|
|
197
|
+
if (!blockedAttrsList.includes(attr)) {
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
}) && !tr.doc.eq(tr.before);
|
|
201
|
+
});
|
|
143
202
|
};
|
package/dist/es2019/plugin.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
2
2
|
import { AddMarkStep, AddNodeMarkStep } from '@atlaskit/editor-prosemirror/transform';
|
|
3
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
4
|
import { collab } from '@atlaskit/prosemirror-collab';
|
|
4
5
|
import { addSynchronyErrorAnalytics } from './analytics';
|
|
5
6
|
import { sendTransaction } from './events/send-transaction';
|
|
6
7
|
import { createPlugin } from './pm-plugins/main';
|
|
7
8
|
import { pluginKey as mainPluginKey } from './pm-plugins/main/plugin-key';
|
|
8
9
|
import { nativeCollabProviderPlugin } from './pm-plugins/native-collab-provider-plugin';
|
|
10
|
+
import { createPlugin as createLastOrganicChangePlugin, trackLastOrganicChangePluginKey } from './pm-plugins/track-last-organic-change';
|
|
9
11
|
import { createPlugin as createTrackNCSInitializationPlugin, trackNCSInitializationPluginKey } from './pm-plugins/track-ncs-initialization';
|
|
10
12
|
import { track } from './track-steps';
|
|
11
13
|
import { getAvatarColor } from './utils';
|
|
@@ -70,7 +72,8 @@ export const collabEditPlugin = ({
|
|
|
70
72
|
initialised: {
|
|
71
73
|
collabInitialisedAt: null,
|
|
72
74
|
firstChangeAfterInitAt: null,
|
|
73
|
-
firstContentBodyChangeAfterInitAt: null
|
|
75
|
+
firstContentBodyChangeAfterInitAt: null,
|
|
76
|
+
lastOrganicChangeAt: null
|
|
74
77
|
},
|
|
75
78
|
activeParticipants: undefined,
|
|
76
79
|
sessionId: undefined
|
|
@@ -78,13 +81,15 @@ export const collabEditPlugin = ({
|
|
|
78
81
|
}
|
|
79
82
|
const collabPluginState = mainPluginKey.getState(state);
|
|
80
83
|
const metadata = trackNCSInitializationPluginKey.getState(state);
|
|
84
|
+
const lastOrganicChangeState = trackLastOrganicChangePluginKey.getState(state);
|
|
81
85
|
return {
|
|
82
86
|
activeParticipants: collabPluginState === null || collabPluginState === void 0 ? void 0 : collabPluginState.activeParticipants,
|
|
83
87
|
sessionId: collabPluginState === null || collabPluginState === void 0 ? void 0 : collabPluginState.sessionId,
|
|
84
88
|
initialised: {
|
|
85
89
|
collabInitialisedAt: (metadata === null || metadata === void 0 ? void 0 : metadata.collabInitialisedAt) || null,
|
|
86
90
|
firstChangeAfterInitAt: (metadata === null || metadata === void 0 ? void 0 : metadata.firstChangeAfterInitAt) || null,
|
|
87
|
-
firstContentBodyChangeAfterInitAt: (metadata === null || metadata === void 0 ? void 0 : metadata.firstContentBodyChangeAfterInitAt) || null
|
|
91
|
+
firstContentBodyChangeAfterInitAt: (metadata === null || metadata === void 0 ? void 0 : metadata.firstContentBodyChangeAfterInitAt) || null,
|
|
92
|
+
lastOrganicChangeAt: (lastOrganicChangeState === null || lastOrganicChangeState === void 0 ? void 0 : lastOrganicChangeState.lastOrganicChangeAt) || null
|
|
88
93
|
}
|
|
89
94
|
};
|
|
90
95
|
},
|
|
@@ -99,7 +104,7 @@ export const collabEditPlugin = ({
|
|
|
99
104
|
useNativePlugin = false,
|
|
100
105
|
userId = null
|
|
101
106
|
} = options || {};
|
|
102
|
-
|
|
107
|
+
const plugins = [...(useNativePlugin ? [{
|
|
103
108
|
name: 'pmCollab',
|
|
104
109
|
plugin: () => collab({
|
|
105
110
|
clientID: userId
|
|
@@ -121,6 +126,13 @@ export const collabEditPlugin = ({
|
|
|
121
126
|
name: 'collabTrackNCSInitializationPlugin',
|
|
122
127
|
plugin: createTrackNCSInitializationPlugin
|
|
123
128
|
}];
|
|
129
|
+
if (fg('platform_editor_last_organic_change')) {
|
|
130
|
+
plugins.push({
|
|
131
|
+
name: 'collabTrackLastOrganicChangePlugin',
|
|
132
|
+
plugin: createLastOrganicChangePlugin
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return plugins;
|
|
124
136
|
},
|
|
125
137
|
onEditorViewStateUpdated(props) {
|
|
126
138
|
var _api$analytics, _api$editorViewMode, _api$editorViewMode$s, _options$useNativePlu;
|
|
@@ -2,11 +2,9 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
2
2
|
import { TELEPOINTER_DIM_CLASS } from '@atlaskit/editor-common/collab';
|
|
3
3
|
import { browser } from '@atlaskit/editor-common/utils';
|
|
4
4
|
import { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
5
|
-
import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
6
5
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
7
6
|
import { Participants } from '../../participants';
|
|
8
|
-
import { createTelepointers, findPointers, getPositionOfTelepointer } from '../../utils';
|
|
9
|
-
const isReplaceStep = step => step instanceof ReplaceStep;
|
|
7
|
+
import { createTelepointers, findPointers, getPositionOfTelepointer, isReplaceStep } from '../../utils';
|
|
10
8
|
export { TELEPOINTER_DIM_CLASS };
|
|
11
9
|
|
|
12
10
|
/**
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { isDirtyTransaction } from '@atlaskit/editor-common/collab';
|
|
2
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
4
|
+
import { isOrganicChange, originalTransactionHasMeta } from '../utils';
|
|
5
|
+
export const trackLastOrganicChangePluginKey = new PluginKey('collabTrackLastOrganicChangePlugin');
|
|
6
|
+
export const createPlugin = () => {
|
|
7
|
+
return new SafePlugin({
|
|
8
|
+
key: trackLastOrganicChangePluginKey,
|
|
9
|
+
state: {
|
|
10
|
+
init() {
|
|
11
|
+
return {
|
|
12
|
+
lastOrganicChangeAt: null
|
|
13
|
+
};
|
|
14
|
+
},
|
|
15
|
+
apply(transaction, prevPluginState) {
|
|
16
|
+
const isRemote = originalTransactionHasMeta(transaction, 'isRemote');
|
|
17
|
+
const isDocumentReplaceFromRemote = isRemote && originalTransactionHasMeta(transaction, 'replaceDocument');
|
|
18
|
+
if (isDocumentReplaceFromRemote) {
|
|
19
|
+
return prevPluginState;
|
|
20
|
+
}
|
|
21
|
+
if (isRemote || isDirtyTransaction(transaction)) {
|
|
22
|
+
return prevPluginState;
|
|
23
|
+
}
|
|
24
|
+
if (isOrganicChange(transaction)) {
|
|
25
|
+
return {
|
|
26
|
+
lastOrganicChangeAt: Date.now()
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return prevPluginState;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
};
|
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
import { isDirtyTransaction } from '@atlaskit/editor-common/collab';
|
|
2
2
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
|
-
import { PluginKey
|
|
3
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
4
4
|
import { AddMarkStep } from '@atlaskit/editor-prosemirror/transform';
|
|
5
|
+
import { originalTransactionHasMeta } from '../utils';
|
|
5
6
|
export const trackNCSInitializationPluginKey = new PluginKey('collabTrackNCSInitializationPlugin');
|
|
6
|
-
const originalTransactionHasMeta = (transaction, metaTag) => {
|
|
7
|
-
const hasMetaTag = Boolean(transaction.getMeta(metaTag));
|
|
8
|
-
if (hasMetaTag) {
|
|
9
|
-
return true;
|
|
10
|
-
}
|
|
11
|
-
const appendedTransaction = transaction.getMeta('appendedTransaction');
|
|
12
|
-
if (appendedTransaction instanceof Transaction) {
|
|
13
|
-
return originalTransactionHasMeta(appendedTransaction, metaTag);
|
|
14
|
-
}
|
|
15
|
-
return false;
|
|
16
|
-
};
|
|
17
7
|
export const createPlugin = () => {
|
|
18
8
|
return new SafePlugin({
|
|
19
9
|
key: trackNCSInitializationPluginKey,
|
package/dist/es2019/utils.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { AnalyticsStep, SetAttrsStep } from '@atlaskit/adf-schema/steps';
|
|
1
2
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
2
3
|
import { ZERO_WIDTH_JOINER } from '@atlaskit/editor-common/whitespace';
|
|
4
|
+
import { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
3
5
|
import { Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
6
|
+
import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
4
7
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
5
8
|
import { avatarColors } from '@atlaskit/editor-shared-styles/consts';
|
|
6
9
|
export const findPointers = (id, decorations) => decorations.find().reduce((arr, deco) => deco.spec.pointer.sessionId === id ? arr.concat(deco) : arr, []);
|
|
@@ -128,4 +131,59 @@ export const getPositionOfTelepointer = (sessionId, decorationSet) => {
|
|
|
128
131
|
}
|
|
129
132
|
});
|
|
130
133
|
return scrollPosition;
|
|
134
|
+
};
|
|
135
|
+
export const isReplaceStep = step => step instanceof ReplaceStep;
|
|
136
|
+
export const originalTransactionHasMeta = (transaction, metaTag) => {
|
|
137
|
+
const hasMetaTag = Boolean(transaction.getMeta(metaTag));
|
|
138
|
+
if (hasMetaTag) {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
const appendedTransaction = transaction.getMeta('appendedTransaction');
|
|
142
|
+
if (appendedTransaction instanceof Transaction) {
|
|
143
|
+
return originalTransactionHasMeta(appendedTransaction, metaTag);
|
|
144
|
+
}
|
|
145
|
+
return false;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* This list contains step attributes that do not result from a user action.
|
|
150
|
+
* All steps that contain ONLY the blocked attribute are considered automated steps
|
|
151
|
+
* and should not be recognised as organic change.
|
|
152
|
+
*
|
|
153
|
+
* `attr_colwidth` is an exception to above explanation. Resizing the column
|
|
154
|
+
* currently creates too many steps and is therefore also on this list.
|
|
155
|
+
*
|
|
156
|
+
* Steps analycs dashboard: https://atlassian-discover.cloud.databricks.com/dashboardsv3/01ef4d3c8aa916c8b0cb5332a9f37caf/published?o=4482001201517624
|
|
157
|
+
*/
|
|
158
|
+
const blockedAttrsList = ['__contextId', 'localId', '__autoSize', 'attr_colwidth'];
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Takes the transaction and editor state and checks if the transaction is considered organic change
|
|
162
|
+
* @param tr Transaction
|
|
163
|
+
* @returns boolean
|
|
164
|
+
*/
|
|
165
|
+
export const isOrganicChange = tr => {
|
|
166
|
+
// If document has not been marked as `docChanged` by PM, skip the rest of the logic
|
|
167
|
+
if (!tr.docChanged) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
return tr.steps.some(step => {
|
|
171
|
+
// If a step is an instance of AnalyticsStep, it is not considered organic
|
|
172
|
+
if (step instanceof AnalyticsStep) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
// If a step is not an instance of SetAttrsStep, it is considered organic
|
|
176
|
+
if (!(step instanceof SetAttrsStep)) {
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
const allAttributes = Object.keys(step.attrs);
|
|
180
|
+
// If a step is an instance of SetAttrsStep, it checks if the attributes in the step
|
|
181
|
+
// are not in the `blockedAttributes`. If one of the attributes not on the list, it considers the change
|
|
182
|
+
// organic but only if the entire document is not equal to the previous state.
|
|
183
|
+
return allAttributes.some(attr => {
|
|
184
|
+
if (!blockedAttrsList.includes(attr)) {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
}) && !tr.doc.eq(tr.before);
|
|
188
|
+
});
|
|
131
189
|
};
|
package/dist/esm/plugin.js
CHANGED
|
@@ -6,12 +6,14 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
6
6
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
7
7
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
8
8
|
import { AddMarkStep, AddNodeMarkStep } from '@atlaskit/editor-prosemirror/transform';
|
|
9
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
9
10
|
import { collab } from '@atlaskit/prosemirror-collab';
|
|
10
11
|
import { addSynchronyErrorAnalytics } from './analytics';
|
|
11
12
|
import { sendTransaction } from './events/send-transaction';
|
|
12
13
|
import { createPlugin } from './pm-plugins/main';
|
|
13
14
|
import { pluginKey as mainPluginKey } from './pm-plugins/main/plugin-key';
|
|
14
15
|
import { nativeCollabProviderPlugin } from './pm-plugins/native-collab-provider-plugin';
|
|
16
|
+
import { createPlugin as createLastOrganicChangePlugin, trackLastOrganicChangePluginKey } from './pm-plugins/track-last-organic-change';
|
|
15
17
|
import { createPlugin as createTrackNCSInitializationPlugin, trackNCSInitializationPluginKey } from './pm-plugins/track-ncs-initialization';
|
|
16
18
|
import { track } from './track-steps';
|
|
17
19
|
import { getAvatarColor } from './utils';
|
|
@@ -102,7 +104,8 @@ export var collabEditPlugin = function collabEditPlugin(_ref4) {
|
|
|
102
104
|
initialised: {
|
|
103
105
|
collabInitialisedAt: null,
|
|
104
106
|
firstChangeAfterInitAt: null,
|
|
105
|
-
firstContentBodyChangeAfterInitAt: null
|
|
107
|
+
firstContentBodyChangeAfterInitAt: null,
|
|
108
|
+
lastOrganicChangeAt: null
|
|
106
109
|
},
|
|
107
110
|
activeParticipants: undefined,
|
|
108
111
|
sessionId: undefined
|
|
@@ -110,13 +113,15 @@ export var collabEditPlugin = function collabEditPlugin(_ref4) {
|
|
|
110
113
|
}
|
|
111
114
|
var collabPluginState = mainPluginKey.getState(state);
|
|
112
115
|
var metadata = trackNCSInitializationPluginKey.getState(state);
|
|
116
|
+
var lastOrganicChangeState = trackLastOrganicChangePluginKey.getState(state);
|
|
113
117
|
return {
|
|
114
118
|
activeParticipants: collabPluginState === null || collabPluginState === void 0 ? void 0 : collabPluginState.activeParticipants,
|
|
115
119
|
sessionId: collabPluginState === null || collabPluginState === void 0 ? void 0 : collabPluginState.sessionId,
|
|
116
120
|
initialised: {
|
|
117
121
|
collabInitialisedAt: (metadata === null || metadata === void 0 ? void 0 : metadata.collabInitialisedAt) || null,
|
|
118
122
|
firstChangeAfterInitAt: (metadata === null || metadata === void 0 ? void 0 : metadata.firstChangeAfterInitAt) || null,
|
|
119
|
-
firstContentBodyChangeAfterInitAt: (metadata === null || metadata === void 0 ? void 0 : metadata.firstContentBodyChangeAfterInitAt) || null
|
|
123
|
+
firstContentBodyChangeAfterInitAt: (metadata === null || metadata === void 0 ? void 0 : metadata.firstContentBodyChangeAfterInitAt) || null,
|
|
124
|
+
lastOrganicChangeAt: (lastOrganicChangeState === null || lastOrganicChangeState === void 0 ? void 0 : lastOrganicChangeState.lastOrganicChangeAt) || null
|
|
120
125
|
}
|
|
121
126
|
};
|
|
122
127
|
},
|
|
@@ -134,7 +139,7 @@ export var collabEditPlugin = function collabEditPlugin(_ref4) {
|
|
|
134
139
|
useNativePlugin = _ref5$useNativePlugin === void 0 ? false : _ref5$useNativePlugin,
|
|
135
140
|
_ref5$userId = _ref5.userId,
|
|
136
141
|
userId = _ref5$userId === void 0 ? null : _ref5$userId;
|
|
137
|
-
|
|
142
|
+
var plugins = [].concat(_toConsumableArray(useNativePlugin ? [{
|
|
138
143
|
name: 'pmCollab',
|
|
139
144
|
plugin: function plugin() {
|
|
140
145
|
return collab({
|
|
@@ -159,6 +164,13 @@ export var collabEditPlugin = function collabEditPlugin(_ref4) {
|
|
|
159
164
|
name: 'collabTrackNCSInitializationPlugin',
|
|
160
165
|
plugin: createTrackNCSInitializationPlugin
|
|
161
166
|
}]);
|
|
167
|
+
if (fg('platform_editor_last_organic_change')) {
|
|
168
|
+
plugins.push({
|
|
169
|
+
name: 'collabTrackLastOrganicChangePlugin',
|
|
170
|
+
plugin: createLastOrganicChangePlugin
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
return plugins;
|
|
162
174
|
},
|
|
163
175
|
onEditorViewStateUpdated: function onEditorViewStateUpdated(props) {
|
|
164
176
|
var _api$analytics, _api$editorViewMode, _options$useNativePlu;
|
|
@@ -4,13 +4,9 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
4
4
|
import { TELEPOINTER_DIM_CLASS } from '@atlaskit/editor-common/collab';
|
|
5
5
|
import { browser } from '@atlaskit/editor-common/utils';
|
|
6
6
|
import { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
7
|
-
import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
8
7
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
9
8
|
import { Participants } from '../../participants';
|
|
10
|
-
import { createTelepointers, findPointers, getPositionOfTelepointer } from '../../utils';
|
|
11
|
-
var isReplaceStep = function isReplaceStep(step) {
|
|
12
|
-
return step instanceof ReplaceStep;
|
|
13
|
-
};
|
|
9
|
+
import { createTelepointers, findPointers, getPositionOfTelepointer, isReplaceStep } from '../../utils';
|
|
14
10
|
export { TELEPOINTER_DIM_CLASS };
|
|
15
11
|
|
|
16
12
|
/**
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { isDirtyTransaction } from '@atlaskit/editor-common/collab';
|
|
2
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
4
|
+
import { isOrganicChange, originalTransactionHasMeta } from '../utils';
|
|
5
|
+
export var trackLastOrganicChangePluginKey = new PluginKey('collabTrackLastOrganicChangePlugin');
|
|
6
|
+
export var createPlugin = function createPlugin() {
|
|
7
|
+
return new SafePlugin({
|
|
8
|
+
key: trackLastOrganicChangePluginKey,
|
|
9
|
+
state: {
|
|
10
|
+
init: function init() {
|
|
11
|
+
return {
|
|
12
|
+
lastOrganicChangeAt: null
|
|
13
|
+
};
|
|
14
|
+
},
|
|
15
|
+
apply: function apply(transaction, prevPluginState) {
|
|
16
|
+
var isRemote = originalTransactionHasMeta(transaction, 'isRemote');
|
|
17
|
+
var isDocumentReplaceFromRemote = isRemote && originalTransactionHasMeta(transaction, 'replaceDocument');
|
|
18
|
+
if (isDocumentReplaceFromRemote) {
|
|
19
|
+
return prevPluginState;
|
|
20
|
+
}
|
|
21
|
+
if (isRemote || isDirtyTransaction(transaction)) {
|
|
22
|
+
return prevPluginState;
|
|
23
|
+
}
|
|
24
|
+
if (isOrganicChange(transaction)) {
|
|
25
|
+
return {
|
|
26
|
+
lastOrganicChangeAt: Date.now()
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return prevPluginState;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
};
|
|
@@ -1,20 +1,10 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import { isDirtyTransaction } from '@atlaskit/editor-common/collab';
|
|
3
3
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
4
|
-
import { PluginKey
|
|
4
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
5
5
|
import { AddMarkStep } from '@atlaskit/editor-prosemirror/transform';
|
|
6
|
+
import { originalTransactionHasMeta } from '../utils';
|
|
6
7
|
export var trackNCSInitializationPluginKey = new PluginKey('collabTrackNCSInitializationPlugin');
|
|
7
|
-
var originalTransactionHasMeta = function originalTransactionHasMeta(transaction, metaTag) {
|
|
8
|
-
var hasMetaTag = Boolean(transaction.getMeta(metaTag));
|
|
9
|
-
if (hasMetaTag) {
|
|
10
|
-
return true;
|
|
11
|
-
}
|
|
12
|
-
var appendedTransaction = transaction.getMeta('appendedTransaction');
|
|
13
|
-
if (appendedTransaction instanceof Transaction) {
|
|
14
|
-
return originalTransactionHasMeta(appendedTransaction, metaTag);
|
|
15
|
-
}
|
|
16
|
-
return false;
|
|
17
|
-
};
|
|
18
8
|
export var createPlugin = function createPlugin() {
|
|
19
9
|
return new SafePlugin({
|
|
20
10
|
key: trackNCSInitializationPluginKey,
|
package/dist/esm/utils.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import _typeof from "@babel/runtime/helpers/typeof";
|
|
2
|
+
import { AnalyticsStep, SetAttrsStep } from '@atlaskit/adf-schema/steps';
|
|
2
3
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
3
4
|
import { ZERO_WIDTH_JOINER } from '@atlaskit/editor-common/whitespace';
|
|
5
|
+
import { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
4
6
|
import { Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
7
|
+
import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
5
8
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
6
9
|
import { avatarColors } from '@atlaskit/editor-shared-styles/consts';
|
|
7
10
|
export var findPointers = function findPointers(id, decorations) {
|
|
@@ -131,4 +134,61 @@ export var getPositionOfTelepointer = function getPositionOfTelepointer(sessionI
|
|
|
131
134
|
}
|
|
132
135
|
});
|
|
133
136
|
return scrollPosition;
|
|
137
|
+
};
|
|
138
|
+
export var isReplaceStep = function isReplaceStep(step) {
|
|
139
|
+
return step instanceof ReplaceStep;
|
|
140
|
+
};
|
|
141
|
+
export var originalTransactionHasMeta = function originalTransactionHasMeta(transaction, metaTag) {
|
|
142
|
+
var hasMetaTag = Boolean(transaction.getMeta(metaTag));
|
|
143
|
+
if (hasMetaTag) {
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
var appendedTransaction = transaction.getMeta('appendedTransaction');
|
|
147
|
+
if (appendedTransaction instanceof Transaction) {
|
|
148
|
+
return originalTransactionHasMeta(appendedTransaction, metaTag);
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* This list contains step attributes that do not result from a user action.
|
|
155
|
+
* All steps that contain ONLY the blocked attribute are considered automated steps
|
|
156
|
+
* and should not be recognised as organic change.
|
|
157
|
+
*
|
|
158
|
+
* `attr_colwidth` is an exception to above explanation. Resizing the column
|
|
159
|
+
* currently creates too many steps and is therefore also on this list.
|
|
160
|
+
*
|
|
161
|
+
* Steps analycs dashboard: https://atlassian-discover.cloud.databricks.com/dashboardsv3/01ef4d3c8aa916c8b0cb5332a9f37caf/published?o=4482001201517624
|
|
162
|
+
*/
|
|
163
|
+
var blockedAttrsList = ['__contextId', 'localId', '__autoSize', 'attr_colwidth'];
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Takes the transaction and editor state and checks if the transaction is considered organic change
|
|
167
|
+
* @param tr Transaction
|
|
168
|
+
* @returns boolean
|
|
169
|
+
*/
|
|
170
|
+
export var isOrganicChange = function isOrganicChange(tr) {
|
|
171
|
+
// If document has not been marked as `docChanged` by PM, skip the rest of the logic
|
|
172
|
+
if (!tr.docChanged) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
return tr.steps.some(function (step) {
|
|
176
|
+
// If a step is an instance of AnalyticsStep, it is not considered organic
|
|
177
|
+
if (step instanceof AnalyticsStep) {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
// If a step is not an instance of SetAttrsStep, it is considered organic
|
|
181
|
+
if (!(step instanceof SetAttrsStep)) {
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
var allAttributes = Object.keys(step.attrs);
|
|
185
|
+
// If a step is an instance of SetAttrsStep, it checks if the attributes in the step
|
|
186
|
+
// are not in the `blockedAttributes`. If one of the attributes not on the list, it considers the change
|
|
187
|
+
// organic but only if the entire document is not equal to the previous state.
|
|
188
|
+
return allAttributes.some(function (attr) {
|
|
189
|
+
if (!blockedAttrsList.includes(attr)) {
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
}) && !tr.doc.eq(tr.before);
|
|
193
|
+
});
|
|
134
194
|
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
2
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
import type { LastOrganicChangeMetadata } from '../types';
|
|
4
|
+
export declare const trackLastOrganicChangePluginKey: PluginKey<LastOrganicChangeMetadata>;
|
|
5
|
+
export declare const createPlugin: () => SafePlugin<LastOrganicChangeMetadata>;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -22,6 +22,9 @@ export type CollabInitializedMetadata = {
|
|
|
22
22
|
firstChangeAfterInitAt: null | number;
|
|
23
23
|
firstContentBodyChangeAfterInitAt: null | number;
|
|
24
24
|
};
|
|
25
|
+
export type LastOrganicChangeMetadata = {
|
|
26
|
+
lastOrganicChangeAt: null | number;
|
|
27
|
+
};
|
|
25
28
|
export type CollabEditPluginSharedState = {
|
|
26
29
|
initialised: CollabInitializedMetadata;
|
|
27
30
|
activeParticipants: ReadOnlyParticipants | undefined;
|
package/dist/types/utils.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
|
|
2
2
|
import type { CollabEditOptions, CollabParticipant } from '@atlaskit/editor-common/collab';
|
|
3
|
-
import type
|
|
3
|
+
import { type EditorState, type ReadonlyTransaction, Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
4
|
+
import type { Step } from '@atlaskit/editor-prosemirror/transform';
|
|
4
5
|
import type { DecorationSet, EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
5
6
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
6
7
|
export declare const findPointers: (id: string, decorations: DecorationSet) => Decoration[];
|
|
@@ -9,6 +10,14 @@ export declare function getAvatarColor(str: string): {
|
|
|
9
10
|
color: "var(--ds-icon-accent-lime)" | "var(--ds-icon-accent-red)" | "var(--ds-icon-accent-orange)" | "var(--ds-icon-accent-yellow)" | "var(--ds-icon-accent-green)" | "var(--ds-icon-accent-teal)" | "var(--ds-icon-accent-blue)" | "var(--ds-icon-accent-purple)" | "var(--ds-icon-accent-magenta)" | "var(--ds-icon-accent-gray)" | "var(--ds-background-accent-lime-bolder-hovered)" | "var(--ds-background-accent-red-bolder-hovered)" | "var(--ds-background-accent-orange-bolder-hovered)" | "var(--ds-background-accent-yellow-bolder-hovered)" | "var(--ds-background-accent-yellow-bolder-pressed)" | "var(--ds-background-accent-green-bolder-hovered)" | "var(--ds-background-accent-teal-bolder-hovered)" | "var(--ds-background-accent-blue-bolder-hovered)" | "var(--ds-background-accent-purple-bolder-hovered)" | "var(--ds-background-accent-magenta-bolder-hovered)" | "var(--ds-background-accent-gray-bolder-hovered)";
|
|
10
11
|
};
|
|
11
12
|
export declare const createTelepointers: (from: number, to: number, sessionId: string, isSelection: boolean, initial: string) => Decoration[];
|
|
12
|
-
export declare const replaceDocument: (doc: any, state: EditorState, version?: number, options?: CollabEditOptions, reserveCursor?: boolean) =>
|
|
13
|
+
export declare const replaceDocument: (doc: any, state: EditorState, version?: number, options?: CollabEditOptions, reserveCursor?: boolean) => Transaction;
|
|
13
14
|
export declare const scrollToCollabCursor: (editorView: EditorView, participants: CollabParticipant[], sessionId: string | undefined, index: number, editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => void;
|
|
14
15
|
export declare const getPositionOfTelepointer: (sessionId: string, decorationSet: DecorationSet) => undefined | number;
|
|
16
|
+
export declare const isReplaceStep: (step: Step) => boolean;
|
|
17
|
+
export declare const originalTransactionHasMeta: (transaction: Transaction | ReadonlyTransaction, metaTag: string) => boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Takes the transaction and editor state and checks if the transaction is considered organic change
|
|
20
|
+
* @param tr Transaction
|
|
21
|
+
* @returns boolean
|
|
22
|
+
*/
|
|
23
|
+
export declare const isOrganicChange: (tr: ReadonlyTransaction) => boolean;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
2
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
import type { LastOrganicChangeMetadata } from '../types';
|
|
4
|
+
export declare const trackLastOrganicChangePluginKey: PluginKey<LastOrganicChangeMetadata>;
|
|
5
|
+
export declare const createPlugin: () => SafePlugin<LastOrganicChangeMetadata>;
|
|
@@ -22,6 +22,9 @@ export type CollabInitializedMetadata = {
|
|
|
22
22
|
firstChangeAfterInitAt: null | number;
|
|
23
23
|
firstContentBodyChangeAfterInitAt: null | number;
|
|
24
24
|
};
|
|
25
|
+
export type LastOrganicChangeMetadata = {
|
|
26
|
+
lastOrganicChangeAt: null | number;
|
|
27
|
+
};
|
|
25
28
|
export type CollabEditPluginSharedState = {
|
|
26
29
|
initialised: CollabInitializedMetadata;
|
|
27
30
|
activeParticipants: ReadOnlyParticipants | undefined;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
|
|
2
2
|
import type { CollabEditOptions, CollabParticipant } from '@atlaskit/editor-common/collab';
|
|
3
|
-
import type
|
|
3
|
+
import { type EditorState, type ReadonlyTransaction, Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
4
|
+
import type { Step } from '@atlaskit/editor-prosemirror/transform';
|
|
4
5
|
import type { DecorationSet, EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
5
6
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
6
7
|
export declare const findPointers: (id: string, decorations: DecorationSet) => Decoration[];
|
|
@@ -9,6 +10,14 @@ export declare function getAvatarColor(str: string): {
|
|
|
9
10
|
color: "var(--ds-icon-accent-lime)" | "var(--ds-icon-accent-red)" | "var(--ds-icon-accent-orange)" | "var(--ds-icon-accent-yellow)" | "var(--ds-icon-accent-green)" | "var(--ds-icon-accent-teal)" | "var(--ds-icon-accent-blue)" | "var(--ds-icon-accent-purple)" | "var(--ds-icon-accent-magenta)" | "var(--ds-icon-accent-gray)" | "var(--ds-background-accent-lime-bolder-hovered)" | "var(--ds-background-accent-red-bolder-hovered)" | "var(--ds-background-accent-orange-bolder-hovered)" | "var(--ds-background-accent-yellow-bolder-hovered)" | "var(--ds-background-accent-yellow-bolder-pressed)" | "var(--ds-background-accent-green-bolder-hovered)" | "var(--ds-background-accent-teal-bolder-hovered)" | "var(--ds-background-accent-blue-bolder-hovered)" | "var(--ds-background-accent-purple-bolder-hovered)" | "var(--ds-background-accent-magenta-bolder-hovered)" | "var(--ds-background-accent-gray-bolder-hovered)";
|
|
10
11
|
};
|
|
11
12
|
export declare const createTelepointers: (from: number, to: number, sessionId: string, isSelection: boolean, initial: string) => Decoration[];
|
|
12
|
-
export declare const replaceDocument: (doc: any, state: EditorState, version?: number, options?: CollabEditOptions, reserveCursor?: boolean) =>
|
|
13
|
+
export declare const replaceDocument: (doc: any, state: EditorState, version?: number, options?: CollabEditOptions, reserveCursor?: boolean) => Transaction;
|
|
13
14
|
export declare const scrollToCollabCursor: (editorView: EditorView, participants: CollabParticipant[], sessionId: string | undefined, index: number, editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => void;
|
|
14
15
|
export declare const getPositionOfTelepointer: (sessionId: string, decorationSet: DecorationSet) => undefined | number;
|
|
16
|
+
export declare const isReplaceStep: (step: Step) => boolean;
|
|
17
|
+
export declare const originalTransactionHasMeta: (transaction: Transaction | ReadonlyTransaction, metaTag: string) => boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Takes the transaction and editor state and checks if the transaction is considered organic change
|
|
20
|
+
* @param tr Transaction
|
|
21
|
+
* @returns boolean
|
|
22
|
+
*/
|
|
23
|
+
export declare const isOrganicChange: (tr: ReadonlyTransaction) => boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-collab-edit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"description": "Collab Edit plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -32,16 +32,16 @@
|
|
|
32
32
|
".": "./src/index.ts"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@atlaskit/adf-schema": "^40.
|
|
36
|
-
"@atlaskit/custom-steps": "^0.
|
|
37
|
-
"@atlaskit/editor-common": "^87.
|
|
38
|
-
"@atlaskit/editor-plugin-analytics": "1.
|
|
35
|
+
"@atlaskit/adf-schema": "^40.8.1",
|
|
36
|
+
"@atlaskit/custom-steps": "^0.7.0",
|
|
37
|
+
"@atlaskit/editor-common": "^87.6.0",
|
|
38
|
+
"@atlaskit/editor-plugin-analytics": "1.7.0",
|
|
39
39
|
"@atlaskit/editor-plugin-editor-viewmode": "^2.1.0",
|
|
40
40
|
"@atlaskit/editor-plugin-feature-flags": "^1.2.0",
|
|
41
41
|
"@atlaskit/editor-prosemirror": "5.0.1",
|
|
42
42
|
"@atlaskit/editor-shared-styles": "^2.13.0",
|
|
43
43
|
"@atlaskit/platform-feature-flags": "^0.3.0",
|
|
44
|
-
"@atlaskit/prosemirror-collab": "^0.
|
|
44
|
+
"@atlaskit/prosemirror-collab": "^0.9.0",
|
|
45
45
|
"@babel/runtime": "^7.0.0",
|
|
46
46
|
"memoize-one": "^6.0.0"
|
|
47
47
|
},
|
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@af/integration-testing": "*",
|
|
53
53
|
"@af/visual-regression": "*",
|
|
54
|
-
"@atlaskit/editor-plugin-mentions": "^2.
|
|
55
|
-
"@atlaskit/editor-plugin-text-formatting": "^1.
|
|
56
|
-
"@atlaskit/editor-plugin-type-ahead": "^1.
|
|
57
|
-
"@atlaskit/editor-plugin-unsupported-content": "^1.
|
|
58
|
-
"@atlaskit/editor-test-helpers": "^18.
|
|
54
|
+
"@atlaskit/editor-plugin-mentions": "^2.3.0",
|
|
55
|
+
"@atlaskit/editor-plugin-text-formatting": "^1.13.0",
|
|
56
|
+
"@atlaskit/editor-plugin-type-ahead": "^1.7.0",
|
|
57
|
+
"@atlaskit/editor-plugin-unsupported-content": "^1.8.0",
|
|
58
|
+
"@atlaskit/editor-test-helpers": "^18.30.0",
|
|
59
59
|
"@atlaskit/ssr": "*",
|
|
60
60
|
"@atlaskit/synchrony-test-helpers": "^2.5.0",
|
|
61
61
|
"@atlaskit/util-data-test": "^17.9.0",
|
|
@@ -102,6 +102,9 @@
|
|
|
102
102
|
"platform-feature-flags": {
|
|
103
103
|
"platform.editor.no-telecursors-for-viewmode-users_hok8o": {
|
|
104
104
|
"type": "boolean"
|
|
105
|
+
},
|
|
106
|
+
"platform_editor_last_organic_change": {
|
|
107
|
+
"type": "boolean"
|
|
105
108
|
}
|
|
106
109
|
}
|
|
107
110
|
}
|