@atlaskit/editor-plugin-collab-edit 2.0.1 → 2.1.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 +24 -0
- package/dist/cjs/collabEditPlugin.js +21 -2
- package/dist/cjs/pm-plugins/actions.js +14 -2
- package/dist/cjs/pm-plugins/analytics.js +6 -1
- package/dist/cjs/pm-plugins/events/handlers.js +12 -1
- package/dist/cjs/pm-plugins/events/initialize.js +4 -1
- package/dist/cjs/pm-plugins/main/index.js +13 -1
- package/dist/cjs/pm-plugins/main/plugin-state.js +24 -4
- package/dist/cjs/pm-plugins/mergeUnconfirmed.js +85 -0
- package/dist/cjs/pm-plugins/utils.js +53 -25
- package/dist/es2019/collabEditPlugin.js +20 -2
- package/dist/es2019/pm-plugins/actions.js +12 -2
- package/dist/es2019/pm-plugins/analytics.js +6 -1
- package/dist/es2019/pm-plugins/events/handlers.js +13 -1
- package/dist/es2019/pm-plugins/events/initialize.js +4 -1
- package/dist/es2019/pm-plugins/main/index.js +13 -1
- package/dist/es2019/pm-plugins/main/plugin-state.js +24 -4
- package/dist/es2019/pm-plugins/mergeUnconfirmed.js +66 -0
- package/dist/es2019/pm-plugins/utils.js +56 -29
- package/dist/esm/collabEditPlugin.js +21 -2
- package/dist/esm/pm-plugins/actions.js +12 -2
- package/dist/esm/pm-plugins/analytics.js +6 -1
- package/dist/esm/pm-plugins/events/handlers.js +13 -1
- package/dist/esm/pm-plugins/events/initialize.js +4 -1
- package/dist/esm/pm-plugins/main/index.js +13 -1
- package/dist/esm/pm-plugins/main/plugin-state.js +24 -4
- package/dist/esm/pm-plugins/mergeUnconfirmed.js +78 -0
- package/dist/esm/pm-plugins/utils.js +54 -27
- package/dist/types/collabEditPluginType.d.ts +2 -2
- package/dist/types/pm-plugins/main/plugin-state.d.ts +1 -0
- package/dist/types/pm-plugins/mergeUnconfirmed.d.ts +24 -0
- package/dist/types/pm-plugins/utils.d.ts +3 -2
- package/dist/types-ts4.5/collabEditPluginType.d.ts +2 -2
- package/dist/types-ts4.5/pm-plugins/main/plugin-state.d.ts +1 -0
- package/dist/types-ts4.5/pm-plugins/mergeUnconfirmed.d.ts +24 -0
- package/dist/types-ts4.5/pm-plugins/utils.d.ts +3 -2
- package/package.json +6 -3
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
2
2
|
import { getDocStructure } from '@atlaskit/editor-common/core-utils';
|
|
3
3
|
import { sniffUserBrowserExtensions } from '@atlaskit/editor-common/utils';
|
|
4
|
-
export const addSynchronyErrorAnalytics = (state, tr, featureFlags, editorAnalyticsApi
|
|
4
|
+
export const addSynchronyErrorAnalytics = (state, tr, featureFlags, editorAnalyticsApi
|
|
5
|
+
// Ignored via go/ees005
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
7
|
+
) => {
|
|
5
8
|
return error => {
|
|
6
9
|
const browserExtensions = sniffUserBrowserExtensions({
|
|
7
10
|
extensions: ['grammarly']
|
|
@@ -16,6 +19,8 @@ export const addSynchronyErrorAnalytics = (state, tr, featureFlags, editorAnalyt
|
|
|
16
19
|
}
|
|
17
20
|
};
|
|
18
21
|
if (featureFlags.synchronyErrorDocStructure) {
|
|
22
|
+
// Ignored via go/ees005
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
19
24
|
payload.attributes.docStructure = getDocStructure(state.doc, {
|
|
20
25
|
compact: true
|
|
21
26
|
});
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { applyRemoteData, handleActivityAck, handleActivityJoin, handleConnection, handleInit, handlePresence, handleTelePointer } from '../actions';
|
|
2
2
|
import { addSynchronyEntityAnalytics, addSynchronyErrorAnalytics } from '../analytics';
|
|
3
|
+
|
|
4
|
+
// Ignored via go/ees005
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
|
+
|
|
7
|
+
// Ignored via go/ees005
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
|
|
10
|
+
// Ignored via go/ees005
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3
12
|
const effect = (fn, eq) => {
|
|
4
13
|
let previousDeps;
|
|
5
14
|
let cleanup;
|
|
@@ -12,7 +21,10 @@ const effect = (fn, eq) => {
|
|
|
12
21
|
return cleanup;
|
|
13
22
|
};
|
|
14
23
|
};
|
|
15
|
-
export const subscribe = effect(
|
|
24
|
+
export const subscribe = effect(
|
|
25
|
+
// Ignored via go/ees005
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
27
|
+
(view, provider, options, featureFlags, _providerFactory, editorAnalyticsApi) => {
|
|
16
28
|
let entityRef;
|
|
17
29
|
const entityHandlers = {
|
|
18
30
|
disconnectedHandler: () => {
|
|
@@ -7,7 +7,10 @@ const initCollab = (collabEditProvider, view) => {
|
|
|
7
7
|
collabEditProvider.initialize(() => view.state, json => Step.fromJSON(view.state.schema, json));
|
|
8
8
|
}
|
|
9
9
|
};
|
|
10
|
-
const initNewCollab = (collabEditProvider, view, editorApi, onSyncUpError
|
|
10
|
+
const initNewCollab = (collabEditProvider, view, editorApi, onSyncUpError
|
|
11
|
+
// Ignored via go/ees005
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
13
|
+
) => {
|
|
11
14
|
collabEditProvider.setup({
|
|
12
15
|
getState: () => view.state,
|
|
13
16
|
editorApi,
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
// It is important to get all steps in that package
|
|
2
|
+
|
|
3
|
+
// Ignored via go/ees005
|
|
4
|
+
// eslint-disable-next-line import/no-namespace
|
|
2
5
|
import * as adfCustomSteps from '@atlaskit/adf-schema/steps';
|
|
3
6
|
// It is important to get all steps in that package
|
|
7
|
+
// Ignored via go/ees005
|
|
8
|
+
// eslint-disable-next-line import/no-namespace
|
|
4
9
|
import * as atlaskKitCustomSteps from '@atlaskit/custom-steps';
|
|
5
10
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE, fireAnalyticsEvent } from '@atlaskit/editor-common/analytics';
|
|
6
11
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
@@ -37,14 +42,21 @@ const enforceCustomStepRegisters = () => {
|
|
|
37
42
|
// @ts-expect-error
|
|
38
43
|
tryToRegisterStep(adfCustomSteps);
|
|
39
44
|
};
|
|
40
|
-
export const createPlugin = (dispatch, providerFactory, providerResolver, collabProviderCallback, options, featureFlags, pluginInjectionApi
|
|
45
|
+
export const createPlugin = (dispatch, providerFactory, providerResolver, collabProviderCallback, options, featureFlags, pluginInjectionApi
|
|
46
|
+
// Ignored via go/ees005
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
48
|
+
) => {
|
|
41
49
|
enforceCustomStepRegisters();
|
|
42
50
|
return new SafePlugin({
|
|
43
51
|
key: pluginKey,
|
|
44
52
|
state: {
|
|
53
|
+
// Ignored via go/ees005
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
55
|
init(config) {
|
|
46
56
|
return PluginState.init(config);
|
|
47
57
|
},
|
|
58
|
+
// Ignored via go/ees005
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
48
60
|
apply(transaction, prevPluginState, _oldEditorState, _newEditorState) {
|
|
49
61
|
const pluginState = prevPluginState.apply(transaction);
|
|
50
62
|
dispatch(pluginKey, pluginState);
|
|
@@ -30,6 +30,9 @@ export class PluginState {
|
|
|
30
30
|
get sessionId() {
|
|
31
31
|
return this.sid;
|
|
32
32
|
}
|
|
33
|
+
|
|
34
|
+
// Ignored via go/ees005
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
33
36
|
constructor(decorations, participants, sessionId, collabInitalised = false, onError) {
|
|
34
37
|
// eslint-disable-next-line no-console
|
|
35
38
|
_defineProperty(this, "onError", error => console.error(error));
|
|
@@ -43,6 +46,11 @@ export class PluginState {
|
|
|
43
46
|
const participant = this.participants.get(sessionId);
|
|
44
47
|
return participant ? participant.name.substring(0, 1).toUpperCase() : 'X';
|
|
45
48
|
}
|
|
49
|
+
getPresenceId(sessionId) {
|
|
50
|
+
var _participant$presence;
|
|
51
|
+
const participant = this.participants.get(sessionId);
|
|
52
|
+
return (_participant$presence = participant === null || participant === void 0 ? void 0 : participant.presenceId) !== null && _participant$presence !== void 0 ? _participant$presence : sessionId;
|
|
53
|
+
}
|
|
46
54
|
apply(tr) {
|
|
47
55
|
let {
|
|
48
56
|
participants,
|
|
@@ -82,7 +90,7 @@ export class PluginState {
|
|
|
82
90
|
sessionId
|
|
83
91
|
} = telepointerData;
|
|
84
92
|
if (participants.get(sessionId) && sessionId !== sid) {
|
|
85
|
-
const oldPointers = findPointers(
|
|
93
|
+
const oldPointers = findPointers(sessionId, this.decorationSet);
|
|
86
94
|
if (oldPointers) {
|
|
87
95
|
remove = remove.concat(oldPointers);
|
|
88
96
|
}
|
|
@@ -106,7 +114,7 @@ export class PluginState {
|
|
|
106
114
|
} catch (err) {
|
|
107
115
|
this.onError(err);
|
|
108
116
|
}
|
|
109
|
-
add = add.concat(createTelepointers(from, to, sessionId, isSelection, this.getInitial(sessionId)));
|
|
117
|
+
add = add.concat(createTelepointers(from, to, sessionId, isSelection, this.getInitial(sessionId), this.getPresenceId(sessionId)));
|
|
110
118
|
}
|
|
111
119
|
}
|
|
112
120
|
if (tr.docChanged) {
|
|
@@ -119,7 +127,8 @@ export class PluginState {
|
|
|
119
127
|
const step = tr.steps.filter(isReplaceStep)[0];
|
|
120
128
|
if (step) {
|
|
121
129
|
const {
|
|
122
|
-
sessionId
|
|
130
|
+
sessionId,
|
|
131
|
+
presenceId
|
|
123
132
|
} = spec.pointer;
|
|
124
133
|
const {
|
|
125
134
|
slice: {
|
|
@@ -128,9 +137,11 @@ export class PluginState {
|
|
|
128
137
|
}
|
|
129
138
|
},
|
|
130
139
|
from
|
|
140
|
+
// Ignored via go/ees005
|
|
141
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
131
142
|
} = step;
|
|
132
143
|
const pos = getValidPos(tr, size ? Math.min(from + size, tr.doc.nodeSize - 3) : Math.max(from, 1));
|
|
133
|
-
add = add.concat(createTelepointers(pos, pos, sessionId, false, this.getInitial(sessionId)));
|
|
144
|
+
add = add.concat(createTelepointers(pos, pos, sessionId, false, this.getInitial(sessionId), presenceId));
|
|
134
145
|
}
|
|
135
146
|
}
|
|
136
147
|
}
|
|
@@ -142,10 +153,14 @@ export class PluginState {
|
|
|
142
153
|
// Remove any selection decoration within the change range,
|
|
143
154
|
// takes care of the issue when after pasting we end up with a dead selection
|
|
144
155
|
tr.steps.filter(isReplaceStep).forEach(s => {
|
|
156
|
+
// Ignored via go/ees005
|
|
157
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
145
158
|
const {
|
|
146
159
|
from,
|
|
147
160
|
to
|
|
148
161
|
} = s;
|
|
162
|
+
// Ignored via go/ees005
|
|
163
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
149
164
|
this.decorationSet.find(from, to).forEach(deco => {
|
|
150
165
|
// `type` is private, `from` and `to` are public in latest version
|
|
151
166
|
// `from` != `to` means it's a selection
|
|
@@ -158,6 +173,8 @@ export class PluginState {
|
|
|
158
173
|
const {
|
|
159
174
|
selection
|
|
160
175
|
} = tr;
|
|
176
|
+
// Ignored via go/ees005
|
|
177
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
161
178
|
this.decorationSet.find().forEach(deco => {
|
|
162
179
|
if (deco.type.toDOM) {
|
|
163
180
|
const hasTelepointerDimClass = deco.type.toDOM.classList.contains(TELEPOINTER_DIM_CLASS);
|
|
@@ -206,6 +223,9 @@ export class PluginState {
|
|
|
206
223
|
static eq(a, b) {
|
|
207
224
|
return a.participants === b.participants && a.sessionId === b.sessionId && a.isReady === b.isReady;
|
|
208
225
|
}
|
|
226
|
+
|
|
227
|
+
// Ignored via go/ees005
|
|
228
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
209
229
|
static init(config) {
|
|
210
230
|
const {
|
|
211
231
|
doc,
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform';
|
|
2
|
+
function isLockable(step) {
|
|
3
|
+
return (step === null || step === void 0 ? void 0 : step.lockStep) !== undefined;
|
|
4
|
+
}
|
|
5
|
+
const createLockableProseMirrorStep = step => {
|
|
6
|
+
let stepIsLocked = false;
|
|
7
|
+
if (isLockable(step)) {
|
|
8
|
+
return step;
|
|
9
|
+
}
|
|
10
|
+
return new Proxy(step, {
|
|
11
|
+
get(target, prop, receiver) {
|
|
12
|
+
if (prop === 'lockStep') {
|
|
13
|
+
return () => {
|
|
14
|
+
stepIsLocked = true;
|
|
15
|
+
};
|
|
16
|
+
} else if (prop === 'isLocked') {
|
|
17
|
+
return () => {
|
|
18
|
+
return stepIsLocked;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return Reflect.get(target, prop, receiver);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// Based on: `packages/editor/prosemirror-collab/src/index.ts`
|
|
27
|
+
class LockableRebaseable {
|
|
28
|
+
constructor(step, inverted, origin) {
|
|
29
|
+
this.step = step;
|
|
30
|
+
this.inverted = inverted;
|
|
31
|
+
this.origin = origin;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
class LockableProseMirrorStep extends ProseMirrorStep {}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Merge a set of steps together to reduce the total number of steps stored in memory.
|
|
38
|
+
*
|
|
39
|
+
* All steps passing through here should be "lockable" (ie. can be locked by the document service)
|
|
40
|
+
* so that it can be indicated they have already been sent (or are about to be sent) to the backend
|
|
41
|
+
* and cannot be merged.
|
|
42
|
+
*
|
|
43
|
+
* @param steps Rebaseable steps
|
|
44
|
+
* @returns Rebaseable steps
|
|
45
|
+
*/
|
|
46
|
+
export function mergeUnconfirmedSteps(steps) {
|
|
47
|
+
const mergedSteps = steps.reduce((acc, rebaseable) => {
|
|
48
|
+
var _lastStep$step$isLock, _lastStep$step, _rebaseable$step$isLo, _rebaseable$step;
|
|
49
|
+
const lastStep = acc[acc.length - 1];
|
|
50
|
+
if (lastStep && ((_lastStep$step$isLock = (_lastStep$step = lastStep.step).isLocked) === null || _lastStep$step$isLock === void 0 ? void 0 : _lastStep$step$isLock.call(_lastStep$step)) !== true && ((_rebaseable$step$isLo = (_rebaseable$step = rebaseable.step).isLocked) === null || _rebaseable$step$isLo === void 0 ? void 0 : _rebaseable$step$isLo.call(_rebaseable$step)) !== true) {
|
|
51
|
+
const mergedStep = lastStep.step.merge(rebaseable.step);
|
|
52
|
+
const inverted = rebaseable.inverted.merge(lastStep.inverted);
|
|
53
|
+
// Always take the origin of the new step.
|
|
54
|
+
// We use this in packages/editor/collab-provider/src/document/document-service.ts:commitUnconfirmedSteps
|
|
55
|
+
// to confirm that the last transaction has been sent. Since we're taking the latest this still works as expected
|
|
56
|
+
// As we want to wait until all the transactions have been pushed through
|
|
57
|
+
const origin = lastStep.origin;
|
|
58
|
+
if (mergedStep && inverted) {
|
|
59
|
+
acc[acc.length - 1] = new LockableRebaseable(createLockableProseMirrorStep(mergedStep), inverted, origin);
|
|
60
|
+
return acc;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return acc.concat(new LockableRebaseable(createLockableProseMirrorStep(rebaseable.step), rebaseable.inverted, rebaseable.origin));
|
|
64
|
+
}, []);
|
|
65
|
+
return mergedSteps;
|
|
66
|
+
}
|
|
@@ -2,43 +2,46 @@ import { AnalyticsStep, SetAttrsStep } from '@atlaskit/adf-schema/steps';
|
|
|
2
2
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
3
3
|
import { processRawValueWithoutValidation } from '@atlaskit/editor-common/process-raw-value';
|
|
4
4
|
import { ZERO_WIDTH_JOINER } from '@atlaskit/editor-common/whitespace';
|
|
5
|
-
import { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
6
|
-
import { Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
5
|
+
import { Transaction, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
7
6
|
import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
8
7
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
9
|
-
import {
|
|
8
|
+
import { getParticipantColor } from '@atlaskit/editor-shared-styles';
|
|
10
9
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
11
|
-
export const findPointers = (id, decorations) => decorations.find()
|
|
10
|
+
export const findPointers = (id, decorations) => decorations.find()
|
|
11
|
+
// Ignored via go/ees005
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13
|
+
.reduce((arr, deco) => deco.spec.pointer.sessionId === id ? arr.concat(deco) : arr, []);
|
|
12
14
|
function style(options) {
|
|
13
15
|
const color = options && options.color || 'black';
|
|
14
16
|
return `border-right: 2px solid ${color}; margin-right: -2px;`;
|
|
15
17
|
}
|
|
16
18
|
export function getAvatarColor(str) {
|
|
17
|
-
|
|
18
|
-
for (let i = 0; i < str.length; i++) {
|
|
19
|
-
/* eslint-disable no-bitwise */
|
|
20
|
-
hash = (hash << 5) - hash + str.charCodeAt(i);
|
|
21
|
-
hash = hash & hash;
|
|
22
|
-
/* eslint-enable no-bitwise */
|
|
23
|
-
}
|
|
24
|
-
const index = Math.abs(hash) % avatarColors.length;
|
|
19
|
+
const participantColor = getParticipantColor(str);
|
|
25
20
|
return {
|
|
26
|
-
index,
|
|
27
|
-
|
|
21
|
+
index: participantColor.index,
|
|
22
|
+
backgroundColor: participantColor.color.backgroundColor,
|
|
23
|
+
textColor: participantColor.color.textColor
|
|
28
24
|
};
|
|
29
25
|
}
|
|
30
|
-
export const createTelepointers = (from, to, sessionId, isSelection, initial
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
export const createTelepointers = (from, to, sessionId, isSelection, initial, presenceId
|
|
27
|
+
// Ignored via go/ees005
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
29
|
+
) => {
|
|
30
|
+
const decorations = [];
|
|
31
|
+
const avatarColor = getAvatarColor(presenceId);
|
|
33
32
|
const color = avatarColor.index.toString();
|
|
34
33
|
if (isSelection) {
|
|
35
34
|
const className = `telepointer color-${color} telepointer-selection`;
|
|
36
|
-
decorations.push(
|
|
35
|
+
decorations.push(
|
|
36
|
+
// Ignored via go/ees005
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
|
+
Decoration.inline(from, to, {
|
|
37
39
|
class: className,
|
|
38
40
|
'data-initial': initial
|
|
39
41
|
}, {
|
|
40
42
|
pointer: {
|
|
41
|
-
sessionId
|
|
43
|
+
sessionId,
|
|
44
|
+
presenceId
|
|
42
45
|
}
|
|
43
46
|
}));
|
|
44
47
|
}
|
|
@@ -50,27 +53,42 @@ export const createTelepointers = (from, to, sessionId, isSelection, initial) =>
|
|
|
50
53
|
cursor.textContent = ZERO_WIDTH_JOINER;
|
|
51
54
|
cursor.className = `telepointer color-${color} telepointer-selection-badge`;
|
|
52
55
|
cursor.style.cssText = `${style({
|
|
53
|
-
color: avatarColor.
|
|
56
|
+
color: avatarColor.backgroundColor
|
|
54
57
|
})};`;
|
|
55
58
|
cursor.setAttribute('data-initial', initial);
|
|
56
|
-
return decorations.concat(
|
|
59
|
+
return decorations.concat(
|
|
60
|
+
// Ignored via go/ees005
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
62
|
+
Decoration.widget(to, spaceJoinerAfter, {
|
|
57
63
|
pointer: {
|
|
58
|
-
sessionId
|
|
64
|
+
sessionId,
|
|
65
|
+
presenceId
|
|
59
66
|
},
|
|
60
67
|
key: `telepointer-${sessionId}-zero`
|
|
61
|
-
})).concat(
|
|
68
|
+
})).concat(
|
|
69
|
+
// Ignored via go/ees005
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
71
|
+
Decoration.widget(to, cursor, {
|
|
62
72
|
pointer: {
|
|
63
|
-
sessionId
|
|
73
|
+
sessionId,
|
|
74
|
+
presenceId
|
|
64
75
|
},
|
|
65
76
|
key: `telepointer-${sessionId}`
|
|
66
|
-
})).concat(
|
|
77
|
+
})).concat(
|
|
78
|
+
// Ignored via go/ees005
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
80
|
+
Decoration.widget(to, spaceJoinerBefore, {
|
|
67
81
|
pointer: {
|
|
68
|
-
sessionId
|
|
82
|
+
sessionId,
|
|
83
|
+
presenceId
|
|
69
84
|
},
|
|
70
85
|
key: `telepointer-${sessionId}-zero`
|
|
71
86
|
}));
|
|
72
87
|
};
|
|
73
|
-
export const replaceDocument = (doc, state, version, options, reserveCursor, editorAnalyticsAPI
|
|
88
|
+
export const replaceDocument = (doc, state, version, options, reserveCursor, editorAnalyticsAPI
|
|
89
|
+
// Ignored via go/ees005
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
91
|
+
) => {
|
|
74
92
|
const {
|
|
75
93
|
schema,
|
|
76
94
|
tr
|
|
@@ -82,11 +100,15 @@ export const replaceDocument = (doc, state, version, options, reserveCursor, edi
|
|
|
82
100
|
hasContent = !!(parsedDoc !== null && parsedDoc !== void 0 && parsedDoc.childCount);
|
|
83
101
|
content = parsedDoc === null || parsedDoc === void 0 ? void 0 : parsedDoc.content;
|
|
84
102
|
} else {
|
|
103
|
+
// Ignored via go/ees005
|
|
104
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
85
105
|
content = (doc.content || []).map(child => schema.nodeFromJSON(child));
|
|
86
106
|
hasContent = Array.isArray(content) && !!content.length;
|
|
87
107
|
}
|
|
88
108
|
if (hasContent) {
|
|
89
109
|
tr.setMeta('addToHistory', false);
|
|
110
|
+
// Ignored via go/ees005
|
|
111
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
90
112
|
tr.replaceWith(0, state.doc.nodeSize - 2, content);
|
|
91
113
|
const selection = state.selection;
|
|
92
114
|
if (reserveCursor) {
|
|
@@ -112,13 +134,16 @@ export const replaceDocument = (doc, state, version, options, reserveCursor, edi
|
|
|
112
134
|
}
|
|
113
135
|
return tr;
|
|
114
136
|
};
|
|
115
|
-
export const scrollToCollabCursor = (editorView, participants, sessionId, index, editorAnalyticsAPI
|
|
137
|
+
export const scrollToCollabCursor = (editorView, participants, sessionId, index, editorAnalyticsAPI
|
|
138
|
+
// Ignored via go/ees005
|
|
139
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
140
|
+
) => {
|
|
116
141
|
const selectedUser = participants[index];
|
|
117
142
|
if (selectedUser && selectedUser.cursorPos !== undefined && selectedUser.sessionId !== sessionId) {
|
|
118
143
|
const {
|
|
119
144
|
state
|
|
120
145
|
} = editorView;
|
|
121
|
-
|
|
146
|
+
const tr = state.tr;
|
|
122
147
|
const analyticsPayload = {
|
|
123
148
|
action: ACTION.MATCHED,
|
|
124
149
|
actionSubject: ACTION_SUBJECT.SELECTION,
|
|
@@ -135,6 +160,8 @@ export const scrollToCollabCursor = (editorView, participants, sessionId, index,
|
|
|
135
160
|
};
|
|
136
161
|
export const getPositionOfTelepointer = (sessionId, decorationSet) => {
|
|
137
162
|
let scrollPosition;
|
|
163
|
+
// Ignored via go/ees005
|
|
164
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
138
165
|
decorationSet.find().forEach(deco => {
|
|
139
166
|
if (deco.type.spec.pointer.sessionId === sessionId) {
|
|
140
167
|
scrollPosition = deco.from;
|
|
@@ -7,11 +7,13 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
|
7
7
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
8
8
|
import { JSONTransformer } from '@atlaskit/editor-json-transformer';
|
|
9
9
|
import { AddMarkStep, AddNodeMarkStep } from '@atlaskit/editor-prosemirror/transform';
|
|
10
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
10
11
|
import { collab, getCollabState, sendableSteps } from '@atlaskit/prosemirror-collab';
|
|
11
12
|
import { addSynchronyErrorAnalytics } from './pm-plugins/analytics';
|
|
12
13
|
import { sendTransaction } from './pm-plugins/events/send-transaction';
|
|
13
14
|
import { createPlugin } from './pm-plugins/main';
|
|
14
15
|
import { pluginKey as mainPluginKey } from './pm-plugins/main/plugin-key';
|
|
16
|
+
import { mergeUnconfirmedSteps } from './pm-plugins/mergeUnconfirmed';
|
|
15
17
|
import { nativeCollabProviderPlugin } from './pm-plugins/native-collab-provider-plugin';
|
|
16
18
|
import { sanitizeFilteredStep, createPlugin as trackSpammingStepsPlugin } from './pm-plugins/track-and-filter-spamming-steps';
|
|
17
19
|
import { createPlugin as createLastOrganicChangePlugin, trackLastOrganicChangePluginKey } from './pm-plugins/track-last-organic-change';
|
|
@@ -144,16 +146,32 @@ export var collabEditPlugin = function collabEditPlugin(_ref4) {
|
|
|
144
146
|
},
|
|
145
147
|
getCurrentCollabState: function getCurrentCollabState() {
|
|
146
148
|
var _getCollabState;
|
|
149
|
+
// Ignored via go/ees005
|
|
150
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
147
151
|
var adfDocument = new JSONTransformer().encode(editorViewRef.current.state.doc);
|
|
148
152
|
return {
|
|
149
153
|
content: adfDocument,
|
|
154
|
+
// Ignored via go/ees005
|
|
155
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
150
156
|
version: ((_getCollabState = getCollabState(editorViewRef.current.state)) === null || _getCollabState === void 0 ? void 0 : _getCollabState.version) || 0,
|
|
157
|
+
// Ignored via go/ees005
|
|
158
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
151
159
|
sendableSteps: sendableSteps(editorViewRef.current.state)
|
|
152
160
|
};
|
|
153
161
|
},
|
|
162
|
+
// Ignored via go/ees005
|
|
163
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
154
164
|
validatePMJSONDocument: function validatePMJSONDocument(doc) {
|
|
165
|
+
// Ignored via go/ees005
|
|
166
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
155
167
|
var content = (doc.content || []).map(function (child) {
|
|
156
|
-
return
|
|
168
|
+
return (
|
|
169
|
+
// Ignored via go/ees005
|
|
170
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
171
|
+
// Ignored via go/ees005
|
|
172
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
173
|
+
editorViewRef.current.state.schema.nodeFromJSON(child)
|
|
174
|
+
);
|
|
157
175
|
});
|
|
158
176
|
return content.every(function (node) {
|
|
159
177
|
try {
|
|
@@ -175,7 +193,8 @@ export var collabEditPlugin = function collabEditPlugin(_ref4) {
|
|
|
175
193
|
name: 'pmCollab',
|
|
176
194
|
plugin: function plugin() {
|
|
177
195
|
return collab({
|
|
178
|
-
clientID: userId
|
|
196
|
+
clientID: userId,
|
|
197
|
+
transformUnconfirmed: fg('platform_editor_merge_unconfirmed_steps') ? mergeUnconfirmedSteps : undefined
|
|
179
198
|
});
|
|
180
199
|
}
|
|
181
200
|
}, {
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
// Ignored via go/ees005
|
|
2
|
+
// eslint-disable-next-line import/no-namespace
|
|
1
3
|
import * as allAdfSchemaSteps from '@atlaskit/adf-schema/steps';
|
|
4
|
+
// Ignored via go/ees005
|
|
5
|
+
// eslint-disable-next-line import/no-namespace
|
|
2
6
|
import * as allAtlaskitCustomSteps from '@atlaskit/custom-steps';
|
|
3
7
|
import { AllSelection, NodeSelection } from '@atlaskit/editor-prosemirror/state';
|
|
4
8
|
import { Step } from '@atlaskit/editor-prosemirror/transform';
|
|
@@ -12,7 +16,10 @@ export var registerAllCustomSteps = function registerAllCustomSteps() {
|
|
|
12
16
|
Object.entries(allAtlaskitCustomSteps).forEach(function () {});
|
|
13
17
|
Object.entries(allAdfSchemaSteps).forEach(function () {});
|
|
14
18
|
};
|
|
15
|
-
export var handleInit = function handleInit(initData, view, options, editorAnalyticsApi
|
|
19
|
+
export var handleInit = function handleInit(initData, view, options, editorAnalyticsApi
|
|
20
|
+
// Ignored via go/ees005
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
22
|
+
) {
|
|
16
23
|
var doc = initData.doc,
|
|
17
24
|
json = initData.json,
|
|
18
25
|
version = initData.version,
|
|
@@ -67,7 +74,10 @@ export var applyRemoteData = function applyRemoteData(remoteData, view, options)
|
|
|
67
74
|
applyRemoteSteps(json, view, userIds, options);
|
|
68
75
|
}
|
|
69
76
|
};
|
|
70
|
-
export var applyRemoteSteps = function applyRemoteSteps(json, view, userIds, options
|
|
77
|
+
export var applyRemoteSteps = function applyRemoteSteps(json, view, userIds, options
|
|
78
|
+
// Ignored via go/ees005
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
80
|
+
) {
|
|
71
81
|
if (!json || !json.length) {
|
|
72
82
|
return;
|
|
73
83
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
2
2
|
import { getDocStructure } from '@atlaskit/editor-common/core-utils';
|
|
3
3
|
import { sniffUserBrowserExtensions } from '@atlaskit/editor-common/utils';
|
|
4
|
-
export var addSynchronyErrorAnalytics = function addSynchronyErrorAnalytics(state, tr, featureFlags, editorAnalyticsApi
|
|
4
|
+
export var addSynchronyErrorAnalytics = function addSynchronyErrorAnalytics(state, tr, featureFlags, editorAnalyticsApi
|
|
5
|
+
// Ignored via go/ees005
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
7
|
+
) {
|
|
5
8
|
return function (error) {
|
|
6
9
|
var browserExtensions = sniffUserBrowserExtensions({
|
|
7
10
|
extensions: ['grammarly']
|
|
@@ -16,6 +19,8 @@ export var addSynchronyErrorAnalytics = function addSynchronyErrorAnalytics(stat
|
|
|
16
19
|
}
|
|
17
20
|
};
|
|
18
21
|
if (featureFlags.synchronyErrorDocStructure) {
|
|
22
|
+
// Ignored via go/ees005
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
19
24
|
payload.attributes.docStructure = getDocStructure(state.doc, {
|
|
20
25
|
compact: true
|
|
21
26
|
});
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { applyRemoteData, handleActivityAck, handleActivityJoin, handleConnection, handleInit, handlePresence, handleTelePointer } from '../actions';
|
|
2
2
|
import { addSynchronyEntityAnalytics, addSynchronyErrorAnalytics } from '../analytics';
|
|
3
|
+
|
|
4
|
+
// Ignored via go/ees005
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
|
+
|
|
7
|
+
// Ignored via go/ees005
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
|
|
10
|
+
// Ignored via go/ees005
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3
12
|
var effect = function effect(fn, eq) {
|
|
4
13
|
var previousDeps;
|
|
5
14
|
var cleanup;
|
|
@@ -15,7 +24,10 @@ var effect = function effect(fn, eq) {
|
|
|
15
24
|
return cleanup;
|
|
16
25
|
};
|
|
17
26
|
};
|
|
18
|
-
export var subscribe = effect(
|
|
27
|
+
export var subscribe = effect(
|
|
28
|
+
// Ignored via go/ees005
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
30
|
+
function (view, provider, options, featureFlags, _providerFactory, editorAnalyticsApi) {
|
|
19
31
|
var entityRef;
|
|
20
32
|
var entityHandlers = {
|
|
21
33
|
disconnectedHandler: function disconnectedHandler() {
|
|
@@ -11,7 +11,10 @@ var initCollab = function initCollab(collabEditProvider, view) {
|
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
13
|
};
|
|
14
|
-
var initNewCollab = function initNewCollab(collabEditProvider, view, editorApi, onSyncUpError
|
|
14
|
+
var initNewCollab = function initNewCollab(collabEditProvider, view, editorApi, onSyncUpError
|
|
15
|
+
// Ignored via go/ees005
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
17
|
+
) {
|
|
15
18
|
collabEditProvider.setup({
|
|
16
19
|
getState: function getState() {
|
|
17
20
|
return view.state;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
// It is important to get all steps in that package
|
|
2
|
+
|
|
3
|
+
// Ignored via go/ees005
|
|
4
|
+
// eslint-disable-next-line import/no-namespace
|
|
2
5
|
import * as adfCustomSteps from '@atlaskit/adf-schema/steps';
|
|
3
6
|
// It is important to get all steps in that package
|
|
7
|
+
// Ignored via go/ees005
|
|
8
|
+
// eslint-disable-next-line import/no-namespace
|
|
4
9
|
import * as atlaskKitCustomSteps from '@atlaskit/custom-steps';
|
|
5
10
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE, fireAnalyticsEvent } from '@atlaskit/editor-common/analytics';
|
|
6
11
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
@@ -38,14 +43,21 @@ var enforceCustomStepRegisters = function enforceCustomStepRegisters() {
|
|
|
38
43
|
// @ts-expect-error
|
|
39
44
|
tryToRegisterStep(adfCustomSteps);
|
|
40
45
|
};
|
|
41
|
-
export var createPlugin = function createPlugin(dispatch, providerFactory, providerResolver, collabProviderCallback, options, featureFlags, pluginInjectionApi
|
|
46
|
+
export var createPlugin = function createPlugin(dispatch, providerFactory, providerResolver, collabProviderCallback, options, featureFlags, pluginInjectionApi
|
|
47
|
+
// Ignored via go/ees005
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
49
|
+
) {
|
|
42
50
|
enforceCustomStepRegisters();
|
|
43
51
|
return new SafePlugin({
|
|
44
52
|
key: pluginKey,
|
|
45
53
|
state: {
|
|
54
|
+
// Ignored via go/ees005
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
46
56
|
init: function init(config) {
|
|
47
57
|
return PluginState.init(config);
|
|
48
58
|
},
|
|
59
|
+
// Ignored via go/ees005
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
49
61
|
apply: function apply(transaction, prevPluginState, _oldEditorState, _newEditorState) {
|
|
50
62
|
var pluginState = prevPluginState.apply(transaction);
|
|
51
63
|
dispatch(pluginKey, pluginState);
|