@atlaskit/editor-plugin-collab-edit 0.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/LICENSE.md +13 -0
  3. package/README.md +30 -0
  4. package/dist/cjs/actions.js +110 -0
  5. package/dist/cjs/analytics.js +47 -0
  6. package/dist/cjs/events/handlers.js +88 -0
  7. package/dist/cjs/events/initialize.js +58 -0
  8. package/dist/cjs/events/send-transaction.js +48 -0
  9. package/dist/cjs/index.js +128 -0
  10. package/dist/cjs/native-collab-provider-plugin.js +37 -0
  11. package/dist/cjs/participants.js +95 -0
  12. package/dist/cjs/plugin-key.js +8 -0
  13. package/dist/cjs/plugin-state.js +241 -0
  14. package/dist/cjs/plugin.js +102 -0
  15. package/dist/cjs/types.js +5 -0
  16. package/dist/cjs/utils.js +150 -0
  17. package/dist/es2019/actions.js +119 -0
  18. package/dist/es2019/analytics.js +41 -0
  19. package/dist/es2019/events/handlers.js +72 -0
  20. package/dist/es2019/events/initialize.js +44 -0
  21. package/dist/es2019/events/send-transaction.js +42 -0
  22. package/dist/es2019/index.js +86 -0
  23. package/dist/es2019/native-collab-provider-plugin.js +32 -0
  24. package/dist/es2019/participants.js +57 -0
  25. package/dist/es2019/plugin-key.js +2 -0
  26. package/dist/es2019/plugin-state.js +219 -0
  27. package/dist/es2019/plugin.js +83 -0
  28. package/dist/es2019/types.js +1 -0
  29. package/dist/es2019/utils.js +133 -0
  30. package/dist/esm/actions.js +103 -0
  31. package/dist/esm/analytics.js +41 -0
  32. package/dist/esm/events/handlers.js +82 -0
  33. package/dist/esm/events/initialize.js +51 -0
  34. package/dist/esm/events/send-transaction.js +42 -0
  35. package/dist/esm/index.js +116 -0
  36. package/dist/esm/native-collab-provider-plugin.js +31 -0
  37. package/dist/esm/participants.js +88 -0
  38. package/dist/esm/plugin-key.js +2 -0
  39. package/dist/esm/plugin-state.js +229 -0
  40. package/dist/esm/plugin.js +85 -0
  41. package/dist/esm/types.js +1 -0
  42. package/dist/esm/utils.js +136 -0
  43. package/dist/types/actions.d.ts +11 -0
  44. package/dist/types/analytics.d.ts +6 -0
  45. package/dist/types/events/handlers.d.ts +24 -0
  46. package/dist/types/events/initialize.d.ts +16 -0
  47. package/dist/types/events/send-transaction.d.ts +11 -0
  48. package/dist/types/index.d.ts +29 -0
  49. package/dist/types/native-collab-provider-plugin.d.ts +7 -0
  50. package/dist/types/participants.d.ts +18 -0
  51. package/dist/types/plugin-key.d.ts +3 -0
  52. package/dist/types/plugin-state.d.ts +25 -0
  53. package/dist/types/plugin.d.ts +11 -0
  54. package/dist/types/types.d.ts +8 -0
  55. package/dist/types/utils.d.ts +16 -0
  56. package/dist/types-ts4.5/actions.d.ts +11 -0
  57. package/dist/types-ts4.5/analytics.d.ts +6 -0
  58. package/dist/types-ts4.5/events/handlers.d.ts +24 -0
  59. package/dist/types-ts4.5/events/initialize.d.ts +16 -0
  60. package/dist/types-ts4.5/events/send-transaction.d.ts +11 -0
  61. package/dist/types-ts4.5/index.d.ts +29 -0
  62. package/dist/types-ts4.5/native-collab-provider-plugin.d.ts +7 -0
  63. package/dist/types-ts4.5/participants.d.ts +18 -0
  64. package/dist/types-ts4.5/plugin-key.d.ts +3 -0
  65. package/dist/types-ts4.5/plugin-state.d.ts +25 -0
  66. package/dist/types-ts4.5/plugin.d.ts +11 -0
  67. package/dist/types-ts4.5/types.d.ts +8 -0
  68. package/dist/types-ts4.5/utils.d.ts +16 -0
  69. package/package.json +104 -0
@@ -0,0 +1,88 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
+ import _createClass from "@babel/runtime/helpers/createClass";
4
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
5
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
6
+ export var Participants = /*#__PURE__*/function () {
7
+ function Participants() {
8
+ var participants = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Map();
9
+ _classCallCheck(this, Participants);
10
+ this.participants = participants;
11
+ }
12
+ _createClass(Participants, [{
13
+ key: "add",
14
+ value: function add(data) {
15
+ var newSet = new Map(this.participants);
16
+ data.forEach(function (participant) {
17
+ newSet.set(participant.sessionId, participant);
18
+ });
19
+ return new Participants(newSet);
20
+ }
21
+ }, {
22
+ key: "remove",
23
+ value: function remove(sessionIds) {
24
+ var newSet = new Map(this.participants);
25
+ sessionIds.forEach(function (sessionId) {
26
+ newSet.delete(sessionId);
27
+ });
28
+ return new Participants(newSet);
29
+ }
30
+ }, {
31
+ key: "update",
32
+ value: function update(sessionId, lastActive) {
33
+ var newSet = new Map(this.participants);
34
+ var data = newSet.get(sessionId);
35
+ if (!data) {
36
+ return this;
37
+ }
38
+ newSet.set(sessionId, _objectSpread(_objectSpread({}, data), {}, {
39
+ lastActive: lastActive
40
+ }));
41
+ return new Participants(newSet);
42
+ }
43
+ }, {
44
+ key: "updateCursorPos",
45
+ value: function updateCursorPos(sessionId, cursorPos) {
46
+ var newSet = new Map(this.participants);
47
+ var data = newSet.get(sessionId);
48
+ if (!data) {
49
+ return this;
50
+ }
51
+ newSet.set(sessionId, _objectSpread(_objectSpread({}, data), {}, {
52
+ cursorPos: cursorPos
53
+ }));
54
+ return new Participants(newSet);
55
+ }
56
+ }, {
57
+ key: "toArray",
58
+ value: function toArray() {
59
+ return Array.from(this.participants.values());
60
+ }
61
+ }, {
62
+ key: "get",
63
+ value: function get(sessionId) {
64
+ return this.participants.get(sessionId);
65
+ }
66
+ }, {
67
+ key: "size",
68
+ value: function size() {
69
+ return this.participants.size;
70
+ }
71
+ }, {
72
+ key: "eq",
73
+ value: function eq(other) {
74
+ var left = this.toArray().map(function (p) {
75
+ return p.sessionId;
76
+ }).sort(function (a, b) {
77
+ return a > b ? -1 : 1;
78
+ }).join('');
79
+ var right = other.toArray().map(function (p) {
80
+ return p.sessionId;
81
+ }).sort(function (a, b) {
82
+ return a > b ? -1 : 1;
83
+ }).join('');
84
+ return left === right;
85
+ }
86
+ }]);
87
+ return Participants;
88
+ }();
@@ -0,0 +1,2 @@
1
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
2
+ export var pluginKey = new PluginKey('collabEditPlugin');
@@ -0,0 +1,229 @@
1
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
+ import _createClass from "@babel/runtime/helpers/createClass";
3
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
+ import { TELEPOINTER_DIM_CLASS } from '@atlaskit/editor-common/collab';
5
+ import { browser } from '@atlaskit/editor-common/utils';
6
+ import { Selection } from '@atlaskit/editor-prosemirror/state';
7
+ import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
8
+ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
9
+ import { Participants } from './participants';
10
+ import { createTelepointers, findPointers, getPositionOfTelepointer } from './utils';
11
+ var isReplaceStep = function isReplaceStep(step) {
12
+ return step instanceof ReplaceStep;
13
+ };
14
+ export { TELEPOINTER_DIM_CLASS };
15
+
16
+ /**
17
+ * Returns position where it's possible to place a decoration.
18
+ */
19
+ export var getValidPos = function getValidPos(tr, pos) {
20
+ var endOfDocPos = tr.doc.nodeSize - 2;
21
+ if (pos <= endOfDocPos) {
22
+ var resolvedPos = tr.doc.resolve(pos);
23
+ var backwardSelection = Selection.findFrom(resolvedPos, -1, true);
24
+ // if there's no correct cursor position before the `pos`, we try to find it after the `pos`
25
+ var forwardSelection = Selection.findFrom(resolvedPos, 1, true);
26
+ return backwardSelection ? backwardSelection.from : forwardSelection ? forwardSelection.from : pos;
27
+ }
28
+ return endOfDocPos;
29
+ };
30
+ export var PluginState = /*#__PURE__*/function () {
31
+ function PluginState(decorations, participants, sessionId) {
32
+ var collabInitalised = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
33
+ var onError = arguments.length > 4 ? arguments[4] : undefined;
34
+ _classCallCheck(this, PluginState);
35
+ // eslint-disable-next-line no-console
36
+ _defineProperty(this, "onError", function (error) {
37
+ return console.error(error);
38
+ });
39
+ this.decorationSet = decorations;
40
+ this.participants = participants;
41
+ this.sid = sessionId;
42
+ this.isReady = collabInitalised;
43
+ this.onError = onError || this.onError;
44
+ }
45
+ _createClass(PluginState, [{
46
+ key: "decorations",
47
+ get: function get() {
48
+ return this.decorationSet;
49
+ }
50
+ }, {
51
+ key: "activeParticipants",
52
+ get: function get() {
53
+ return this.participants;
54
+ }
55
+ }, {
56
+ key: "sessionId",
57
+ get: function get() {
58
+ return this.sid;
59
+ }
60
+ }, {
61
+ key: "getInitial",
62
+ value: function getInitial(sessionId) {
63
+ var participant = this.participants.get(sessionId);
64
+ return participant ? participant.name.substring(0, 1).toUpperCase() : 'X';
65
+ }
66
+ }, {
67
+ key: "apply",
68
+ value: function apply(tr) {
69
+ var _this = this;
70
+ var participants = this.participants,
71
+ sid = this.sid,
72
+ isReady = this.isReady;
73
+ var presenceData = tr.getMeta('presence');
74
+ var telepointerData = tr.getMeta('telepointer');
75
+ var sessionIdData = tr.getMeta('sessionId');
76
+ var collabInitialised = tr.getMeta('collabInitialised');
77
+ if (typeof collabInitialised !== 'boolean') {
78
+ collabInitialised = isReady;
79
+ }
80
+ if (sessionIdData) {
81
+ sid = sessionIdData.sid;
82
+ }
83
+ var add = [];
84
+ var remove = [];
85
+ if (presenceData) {
86
+ var _presenceData$joined = presenceData.joined,
87
+ joined = _presenceData$joined === void 0 ? [] : _presenceData$joined,
88
+ _presenceData$left = presenceData.left,
89
+ left = _presenceData$left === void 0 ? [] : _presenceData$left;
90
+ participants = participants.remove(left.map(function (i) {
91
+ return i.sessionId;
92
+ }));
93
+ participants = participants.add(joined);
94
+
95
+ // Remove telepointers for users that left
96
+ left.forEach(function (i) {
97
+ var pointers = findPointers(i.sessionId, _this.decorationSet);
98
+ if (pointers) {
99
+ remove = remove.concat(pointers);
100
+ }
101
+ });
102
+ }
103
+ if (telepointerData) {
104
+ var sessionId = telepointerData.sessionId;
105
+ if (participants.get(sessionId) && sessionId !== sid) {
106
+ var oldPointers = findPointers(telepointerData.sessionId, this.decorationSet);
107
+ if (oldPointers) {
108
+ remove = remove.concat(oldPointers);
109
+ }
110
+ var endOfDocPos = tr.doc.nodeSize - 2;
111
+ var anchor = telepointerData.selection.anchor;
112
+ var head = telepointerData.selection.head;
113
+ var rawFrom = anchor < head ? anchor : head;
114
+ var rawTo = anchor >= head ? anchor : head;
115
+ if (rawFrom > endOfDocPos) {
116
+ rawFrom = endOfDocPos;
117
+ }
118
+ if (rawTo > endOfDocPos) {
119
+ rawTo = endOfDocPos;
120
+ }
121
+ var isSelection = rawTo - rawFrom > 0;
122
+ var from = 1;
123
+ var to = 1;
124
+ try {
125
+ from = getValidPos(tr, isSelection ? Math.max(rawFrom - 1, 0) : rawFrom);
126
+ to = isSelection ? getValidPos(tr, rawTo) : from;
127
+ } catch (err) {
128
+ this.onError(err);
129
+ }
130
+ add = add.concat(createTelepointers(from, to, sessionId, isSelection, this.getInitial(sessionId)));
131
+ }
132
+ }
133
+ if (tr.docChanged) {
134
+ // Adjust decoration positions to changes made by the transaction
135
+ try {
136
+ this.decorationSet = this.decorationSet.map(tr.mapping, tr.doc, {
137
+ // Reapplies decorators those got removed by the state change
138
+ onRemove: function onRemove(spec) {
139
+ if (spec.pointer && spec.pointer.sessionId && spec.key === "telepointer-".concat(spec.pointer.sessionId)) {
140
+ var step = tr.steps.filter(isReplaceStep)[0];
141
+ if (step) {
142
+ var _sessionId = spec.pointer.sessionId;
143
+ var _ref = step,
144
+ size = _ref.slice.content.size,
145
+ _from = _ref.from;
146
+ var pos = getValidPos(tr, size ? Math.min(_from + size, tr.doc.nodeSize - 3) : Math.max(_from, 1));
147
+ add = add.concat(createTelepointers(pos, pos, _sessionId, false, _this.getInitial(_sessionId)));
148
+ }
149
+ }
150
+ }
151
+ });
152
+ } catch (err) {
153
+ this.onError(err);
154
+ }
155
+
156
+ // Remove any selection decoration within the change range,
157
+ // takes care of the issue when after pasting we end up with a dead selection
158
+ tr.steps.filter(isReplaceStep).forEach(function (s) {
159
+ var _ref2 = s,
160
+ from = _ref2.from,
161
+ to = _ref2.to;
162
+ _this.decorationSet.find(from, to).forEach(function (deco) {
163
+ // `type` is private, `from` and `to` are public in latest version
164
+ // `from` != `to` means it's a selection
165
+ if (deco.from !== deco.to) {
166
+ remove.push(deco);
167
+ }
168
+ });
169
+ });
170
+ }
171
+ var selection = tr.selection;
172
+ this.decorationSet.find().forEach(function (deco) {
173
+ if (deco.type.toDOM) {
174
+ var hasTelepointerDimClass = deco.type.toDOM.classList.contains(TELEPOINTER_DIM_CLASS);
175
+ if (deco.from === selection.from && deco.to === selection.to) {
176
+ if (!hasTelepointerDimClass) {
177
+ deco.type.toDOM.classList.add(TELEPOINTER_DIM_CLASS);
178
+ }
179
+
180
+ // Browser condition here to fix ED-14722 where telepointer
181
+ // decorations with side -1 in Firefox causes backspace issues.
182
+ // This is likely caused by contenteditable quirks in Firefox
183
+ if (!browser.gecko) {
184
+ deco.type.side = -1;
185
+ }
186
+ } else {
187
+ if (hasTelepointerDimClass) {
188
+ deco.type.toDOM.classList.remove(TELEPOINTER_DIM_CLASS);
189
+ }
190
+ deco.type.side = 0;
191
+ }
192
+ }
193
+ });
194
+ if (remove.length) {
195
+ this.decorationSet = this.decorationSet.remove(remove);
196
+ }
197
+ if (add.length) {
198
+ this.decorationSet = this.decorationSet.add(tr.doc, add);
199
+ }
200
+
201
+ // This piece needs to be after the decorationSet adjustments,
202
+ // otherwise it's always one step behind where the cursor is
203
+ if (telepointerData) {
204
+ var _sessionId2 = telepointerData.sessionId;
205
+ if (participants.get(_sessionId2)) {
206
+ var positionForScroll = getPositionOfTelepointer(_sessionId2, this.decorationSet);
207
+ if (positionForScroll) {
208
+ participants = participants.updateCursorPos(_sessionId2, positionForScroll);
209
+ }
210
+ }
211
+ }
212
+ var nextState = new PluginState(this.decorationSet, participants, sid, collabInitialised);
213
+ return PluginState.eq(nextState, this) ? this : nextState;
214
+ }
215
+ }], [{
216
+ key: "eq",
217
+ value: function eq(a, b) {
218
+ return a.participants === b.participants && a.sessionId === b.sessionId && a.isReady === b.isReady;
219
+ }
220
+ }, {
221
+ key: "init",
222
+ value: function init(config) {
223
+ var doc = config.doc,
224
+ onError = config.onError;
225
+ return new PluginState(DecorationSet.create(doc, []), new Participants(), undefined, undefined, onError);
226
+ }
227
+ }]);
228
+ return PluginState;
229
+ }();
@@ -0,0 +1,85 @@
1
+ import { ACTION, ACTION_SUBJECT, EVENT_TYPE, fireAnalyticsEvent } from '@atlaskit/editor-common/analytics';
2
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
3
+ import { addSynchronyErrorAnalytics } from './analytics';
4
+ import { initialize } from './events/initialize';
5
+ import { pluginKey } from './plugin-key';
6
+ import { PluginState } from './plugin-state';
7
+ export { PluginState, pluginKey };
8
+ export var createPlugin = function createPlugin(dispatch, providerFactory, providerResolver, collabProviderCallback, options, featureFlags, pluginInjectionApi) {
9
+ return new SafePlugin({
10
+ key: pluginKey,
11
+ state: {
12
+ init: function init(config) {
13
+ return PluginState.init(config);
14
+ },
15
+ apply: function apply(transaction, prevPluginState, _oldEditorState, _newEditorState) {
16
+ var pluginState = prevPluginState.apply(transaction);
17
+ dispatch(pluginKey, pluginState);
18
+ return pluginState;
19
+ }
20
+ },
21
+ props: {
22
+ decorations: function decorations(state) {
23
+ var _pluginKey$getState;
24
+ return (_pluginKey$getState = pluginKey.getState(state)) === null || _pluginKey$getState === void 0 ? void 0 : _pluginKey$getState.decorations;
25
+ }
26
+ },
27
+ filterTransaction: function filterTransaction(tr, state) {
28
+ var pluginState = pluginKey.getState(state);
29
+ var collabInitialiseTr = tr.getMeta('collabInitialised');
30
+
31
+ // Don't allow transactions that modifies the document before
32
+ // collab-plugin is ready.
33
+ if (collabInitialiseTr) {
34
+ return true;
35
+ }
36
+ if (!(pluginState !== null && pluginState !== void 0 && pluginState.isReady) && tr.docChanged) {
37
+ return false;
38
+ }
39
+ return true;
40
+ },
41
+ view: function view(_view) {
42
+ var _pluginInjectionApi$a, _pluginInjectionApi$a4;
43
+ var addErrorAnalytics = addSynchronyErrorAnalytics(_view.state, _view.state.tr, featureFlags, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions);
44
+ var onSyncUpError = function onSyncUpError(attributes) {
45
+ var _pluginInjectionApi$a2, _pluginInjectionApi$a3;
46
+ var fireAnalyticsCallback = fireAnalyticsEvent((_pluginInjectionApi$a2 = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a3 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a3 === void 0 || (_pluginInjectionApi$a3 = _pluginInjectionApi$a3.sharedState.currentState()) === null || _pluginInjectionApi$a3 === void 0 ? void 0 : _pluginInjectionApi$a3.createAnalyticsEvent) !== null && _pluginInjectionApi$a2 !== void 0 ? _pluginInjectionApi$a2 : undefined);
47
+ fireAnalyticsCallback({
48
+ payload: {
49
+ action: ACTION.NEW_COLLAB_SYNC_UP_ERROR_NO_STEPS,
50
+ actionSubject: ACTION_SUBJECT.EDITOR,
51
+ eventType: EVENT_TYPE.OPERATIONAL,
52
+ attributes: attributes
53
+ }
54
+ });
55
+ };
56
+ options.onSyncUpError = onSyncUpError;
57
+ var cleanup = collabProviderCallback(initialize({
58
+ view: _view,
59
+ options: options,
60
+ providerFactory: providerFactory,
61
+ featureFlags: featureFlags,
62
+ editorAnalyticsApi: pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a4 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a4 === void 0 ? void 0 : _pluginInjectionApi$a4.actions
63
+ }), addErrorAnalytics);
64
+ providerFactory && providerFactory.subscribe('collabEditProvider', function (_name, providerPromise) {
65
+ if (providerPromise) {
66
+ providerPromise.then(function (provider) {
67
+ return providerResolver(provider);
68
+ });
69
+ }
70
+ });
71
+ return {
72
+ destroy: function destroy() {
73
+ providerFactory.unsubscribeAll('collabEditProvider');
74
+ if (cleanup) {
75
+ cleanup.then(function (unsubscribe) {
76
+ if (unsubscribe) {
77
+ unsubscribe();
78
+ }
79
+ });
80
+ }
81
+ }
82
+ };
83
+ }
84
+ });
85
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,136 @@
1
+ import _typeof from "@babel/runtime/helpers/typeof";
2
+ import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
3
+ import { colors } from '@atlaskit/editor-common/collab';
4
+ import { ZERO_WIDTH_JOINER } from '@atlaskit/editor-common/utils';
5
+ import { Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
6
+ import { Decoration } from '@atlaskit/editor-prosemirror/view';
7
+ export { colors };
8
+ export var findPointers = function findPointers(id, decorations) {
9
+ return decorations.find().reduce(function (arr, deco) {
10
+ return deco.spec.pointer.sessionId === id ? arr.concat(deco) : arr;
11
+ }, []);
12
+ };
13
+ function style(options) {
14
+ var color = options && options.color || 'black';
15
+ return "border-left: 1px solid ".concat(color, "; border-right: 1px solid ").concat(color, "; margin-right: -2px;");
16
+ }
17
+ export function getAvatarColor(str) {
18
+ var hash = 0;
19
+ for (var i = 0; i < str.length; i++) {
20
+ /* eslint-disable no-bitwise */
21
+ hash = (hash << 5) - hash + str.charCodeAt(i);
22
+ hash = hash & hash;
23
+ /* eslint-enable no-bitwise */
24
+ }
25
+
26
+ var index = Math.abs(hash) % colors.length;
27
+ return {
28
+ index: index,
29
+ color: colors[index]
30
+ };
31
+ }
32
+ export var createTelepointers = function createTelepointers(from, to, sessionId, isSelection, initial) {
33
+ var decorations = [];
34
+ var avatarColor = getAvatarColor(sessionId);
35
+ var color = avatarColor.index.toString();
36
+ if (isSelection) {
37
+ var className = "telepointer color-".concat(color, " telepointer-selection");
38
+ decorations.push(Decoration.inline(from, to, {
39
+ class: className,
40
+ 'data-initial': initial
41
+ }, {
42
+ pointer: {
43
+ sessionId: sessionId
44
+ }
45
+ }));
46
+ }
47
+ var spaceJoinerBefore = document.createElement('span');
48
+ spaceJoinerBefore.textContent = ZERO_WIDTH_JOINER;
49
+ var spaceJoinerAfter = document.createElement('span');
50
+ spaceJoinerAfter.textContent = ZERO_WIDTH_JOINER;
51
+ var cursor = document.createElement('span');
52
+ cursor.textContent = ZERO_WIDTH_JOINER;
53
+ cursor.className = "telepointer color-".concat(color, " telepointer-selection-badge");
54
+ cursor.style.cssText = "".concat(style({
55
+ color: avatarColor.color.solid
56
+ }), ";");
57
+ cursor.setAttribute('data-initial', initial);
58
+ return decorations.concat(Decoration.widget(to, spaceJoinerAfter, {
59
+ pointer: {
60
+ sessionId: sessionId
61
+ },
62
+ key: "telepointer-".concat(sessionId, "-zero")
63
+ })).concat(Decoration.widget(to, cursor, {
64
+ pointer: {
65
+ sessionId: sessionId
66
+ },
67
+ key: "telepointer-".concat(sessionId)
68
+ })).concat(Decoration.widget(to, spaceJoinerBefore, {
69
+ pointer: {
70
+ sessionId: sessionId
71
+ },
72
+ key: "telepointer-".concat(sessionId, "-zero")
73
+ }));
74
+ };
75
+ export var replaceDocument = function replaceDocument(doc, state, version, options, reserveCursor) {
76
+ var schema = state.schema,
77
+ tr = state.tr;
78
+ var content = (doc.content || []).map(function (child) {
79
+ return schema.nodeFromJSON(child);
80
+ });
81
+ var hasContent = !!content.length;
82
+ if (hasContent) {
83
+ tr.setMeta('addToHistory', false);
84
+ tr.replaceWith(0, state.doc.nodeSize - 2, content);
85
+ var selection = state.selection;
86
+ if (reserveCursor) {
87
+ // If the cursor is still in the range of the new document,
88
+ // keep where it was.
89
+ if (selection.to < tr.doc.content.size - 2) {
90
+ var $from = tr.doc.resolve(selection.from);
91
+ var $to = tr.doc.resolve(selection.to);
92
+ var newselection = new TextSelection($from, $to);
93
+ tr.setSelection(newselection);
94
+ }
95
+ } else {
96
+ tr.setSelection(Selection.atStart(tr.doc));
97
+ }
98
+ tr.setMeta('replaceDocument', true);
99
+ if (_typeof(version) !== undefined && options && options.useNativePlugin) {
100
+ var collabState = {
101
+ version: version,
102
+ unconfirmed: []
103
+ };
104
+ tr.setMeta('collab$', collabState);
105
+ }
106
+ }
107
+ return tr;
108
+ };
109
+ export var scrollToCollabCursor = function scrollToCollabCursor(editorView, participants, sessionId, index, editorAnalyticsAPI) {
110
+ var selectedUser = participants[index];
111
+ if (selectedUser && selectedUser.cursorPos !== undefined && selectedUser.sessionId !== sessionId) {
112
+ var state = editorView.state;
113
+ var tr = state.tr;
114
+ var analyticsPayload = {
115
+ action: ACTION.MATCHED,
116
+ actionSubject: ACTION_SUBJECT.SELECTION,
117
+ eventType: EVENT_TYPE.TRACK
118
+ };
119
+ tr.setSelection(Selection.near(tr.doc.resolve(selectedUser.cursorPos)));
120
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent(analyticsPayload)(tr);
121
+ tr.scrollIntoView();
122
+ editorView.dispatch(tr);
123
+ if (!editorView.hasFocus()) {
124
+ editorView.focus();
125
+ }
126
+ }
127
+ };
128
+ export var getPositionOfTelepointer = function getPositionOfTelepointer(sessionId, decorationSet) {
129
+ var scrollPosition;
130
+ decorationSet.find().forEach(function (deco) {
131
+ if (deco.type.spec.pointer.sessionId === sessionId) {
132
+ scrollPosition = deco.from;
133
+ }
134
+ });
135
+ return scrollPosition;
136
+ };
@@ -0,0 +1,11 @@
1
+ import type { CollabEventConnectionData, CollabEventInitData, CollabEventPresenceData, CollabEventRemoteData, CollabSendableSelection, CollabTelepointerPayload } from '@atlaskit/editor-common/collab';
2
+ import type { Selection } from '@atlaskit/editor-prosemirror/state';
3
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
4
+ import type { PrivateCollabEditOptions } from './types';
5
+ export declare const handleInit: (initData: CollabEventInitData, view: EditorView, options?: PrivateCollabEditOptions) => void;
6
+ export declare const handleConnection: (connectionData: CollabEventConnectionData, view: EditorView) => void;
7
+ export declare const handlePresence: (presenceData: CollabEventPresenceData, view: EditorView) => void;
8
+ export declare const applyRemoteData: (remoteData: CollabEventRemoteData, view: EditorView, options: PrivateCollabEditOptions) => void;
9
+ export declare const applyRemoteSteps: (json: any[], view: EditorView, userIds?: (number | string)[], options?: PrivateCollabEditOptions) => void;
10
+ export declare const handleTelePointer: (telepointerData: CollabTelepointerPayload, view: EditorView) => void;
11
+ export declare const getSendableSelection: (selection: Selection) => CollabSendableSelection;
@@ -0,0 +1,6 @@
1
+ import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
2
+ import type { FeatureFlags } from '@atlaskit/editor-common/types';
3
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
4
+ export declare const addSynchronyErrorAnalytics: (state: EditorState, tr: Transaction, featureFlags: FeatureFlags, editorAnalyticsApi: EditorAnalyticsAPI | undefined) => (error: Error) => Transaction;
5
+ export type EntityEventType = 'error' | 'disconnected';
6
+ export declare const addSynchronyEntityAnalytics: (state: EditorState, tr: Transaction) => (type: EntityEventType, editorAnalyticsApi: EditorAnalyticsAPI | undefined) => Transaction;
@@ -0,0 +1,24 @@
1
+ import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
2
+ import type { CollabEditProvider, CollabEventConnectionData, CollabEventInitData, CollabEventLocalStepData, CollabEventPresenceData, CollabEventRemoteData, CollabTelepointerPayload } from '@atlaskit/editor-common/collab';
3
+ import type { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
4
+ import type { FeatureFlags } from '@atlaskit/editor-common/types';
5
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
6
+ import type { PrivateCollabEditOptions } from '../types';
7
+ export type SynchronyEntity = {
8
+ on: (evt: 'disconnected' | 'error', handler: (...args: any) => void) => void;
9
+ off: (evt: 'disconnected' | 'error', handler: (...args: any) => void) => void;
10
+ };
11
+ export interface CollabHandlers {
12
+ initHandler: (data: CollabEventInitData) => void;
13
+ connectedHandler: (data: CollabEventConnectionData) => void;
14
+ dataHandler: (data: CollabEventRemoteData) => void;
15
+ presenceHandler: (data: CollabEventPresenceData) => void;
16
+ telepointerHandler: (data: CollabTelepointerPayload) => void;
17
+ localStepsHandler: (data: CollabEventLocalStepData) => void;
18
+ errorHandler: (error: any) => void;
19
+ entityHandler: ({ entity }: {
20
+ entity: SynchronyEntity;
21
+ }) => void;
22
+ }
23
+ export type Cleanup = () => void;
24
+ export declare const subscribe: (currentDeps_0: EditorView, currentDeps_1: CollabEditProvider<import("@atlaskit/editor-common/collab").CollabEvents>, currentDeps_2: PrivateCollabEditOptions, currentDeps_3: FeatureFlags, currentDeps_4?: ProviderFactory | undefined, currentDeps_5?: EditorAnalyticsAPI | undefined) => Cleanup;
@@ -0,0 +1,16 @@
1
+ import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
2
+ import type { CollabEditProvider } from '@atlaskit/editor-common/collab';
3
+ import type { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
4
+ import type { FeatureFlags } from '@atlaskit/editor-common/types';
5
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
6
+ import type { PrivateCollabEditOptions } from '../types';
7
+ import type { Cleanup } from './handlers';
8
+ type Props = {
9
+ view: EditorView;
10
+ options: PrivateCollabEditOptions;
11
+ providerFactory: ProviderFactory;
12
+ featureFlags: FeatureFlags;
13
+ editorAnalyticsApi: EditorAnalyticsAPI | undefined;
14
+ };
15
+ export declare const initialize: ({ options, providerFactory, view, featureFlags, editorAnalyticsApi, }: Props) => (provider: CollabEditProvider) => Cleanup;
16
+ export {};
@@ -0,0 +1,11 @@
1
+ import type { CollabEditProvider } from '@atlaskit/editor-common/collab';
2
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ type Props = {
4
+ originalTransaction: Readonly<Transaction>;
5
+ transactions: readonly Transaction[];
6
+ oldEditorState: EditorState;
7
+ newEditorState: EditorState;
8
+ useNativePlugin: boolean;
9
+ };
10
+ export declare const sendTransaction: ({ originalTransaction, transactions, oldEditorState, newEditorState, useNativePlugin, }: Props) => (provider: CollabEditProvider) => void;
11
+ export {};
@@ -0,0 +1,29 @@
1
+ import type { NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
2
+ import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
3
+ import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
4
+ import type { ReadOnlyParticipants } from './participants';
5
+ import { pluginKey } from './plugin';
6
+ import type { PrivateCollabEditOptions } from './types';
7
+ export { pluginKey };
8
+ import type { Color } from './utils';
9
+ export type { PluginState } from './plugin-state';
10
+ export type { CollabInviteToEditProps, InviteToEditComponentProps, PrivateCollabEditOptions, } from './types';
11
+ export type { ReadOnlyParticipants } from './participants';
12
+ export type CollabEditPlugin = NextEditorPlugin<'collabEdit', {
13
+ pluginConfiguration: PrivateCollabEditOptions;
14
+ dependencies: [
15
+ OptionalPlugin<FeatureFlagsPlugin>,
16
+ OptionalPlugin<AnalyticsPlugin>
17
+ ];
18
+ sharedState: {
19
+ activeParticipants: ReadOnlyParticipants | undefined;
20
+ sessionId: string | undefined;
21
+ } | undefined;
22
+ actions: {
23
+ getAvatarColor: (str: string) => {
24
+ index: number;
25
+ color: Color;
26
+ };
27
+ };
28
+ }>;
29
+ export declare const collabEditPlugin: CollabEditPlugin;
@@ -0,0 +1,7 @@
1
+ import type { CollabEditProvider, CollabEvents } from '@atlaskit/editor-common/collab';
2
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
3
+ import type { EditorState } from '@atlaskit/editor-prosemirror/state';
4
+ export declare const nativeCollabProviderPlugin: ({ providerPromise, }: {
5
+ providerPromise: Promise<CollabEditProvider>;
6
+ }) => SafePlugin<CollabEditProvider<CollabEvents> | null>;
7
+ export declare const getCollabProvider: (editorState: EditorState) => CollabEditProvider | null;