@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.
- package/CHANGELOG.md +1 -0
- package/LICENSE.md +13 -0
- package/README.md +30 -0
- package/dist/cjs/actions.js +110 -0
- package/dist/cjs/analytics.js +47 -0
- package/dist/cjs/events/handlers.js +88 -0
- package/dist/cjs/events/initialize.js +58 -0
- package/dist/cjs/events/send-transaction.js +48 -0
- package/dist/cjs/index.js +128 -0
- package/dist/cjs/native-collab-provider-plugin.js +37 -0
- package/dist/cjs/participants.js +95 -0
- package/dist/cjs/plugin-key.js +8 -0
- package/dist/cjs/plugin-state.js +241 -0
- package/dist/cjs/plugin.js +102 -0
- package/dist/cjs/types.js +5 -0
- package/dist/cjs/utils.js +150 -0
- package/dist/es2019/actions.js +119 -0
- package/dist/es2019/analytics.js +41 -0
- package/dist/es2019/events/handlers.js +72 -0
- package/dist/es2019/events/initialize.js +44 -0
- package/dist/es2019/events/send-transaction.js +42 -0
- package/dist/es2019/index.js +86 -0
- package/dist/es2019/native-collab-provider-plugin.js +32 -0
- package/dist/es2019/participants.js +57 -0
- package/dist/es2019/plugin-key.js +2 -0
- package/dist/es2019/plugin-state.js +219 -0
- package/dist/es2019/plugin.js +83 -0
- package/dist/es2019/types.js +1 -0
- package/dist/es2019/utils.js +133 -0
- package/dist/esm/actions.js +103 -0
- package/dist/esm/analytics.js +41 -0
- package/dist/esm/events/handlers.js +82 -0
- package/dist/esm/events/initialize.js +51 -0
- package/dist/esm/events/send-transaction.js +42 -0
- package/dist/esm/index.js +116 -0
- package/dist/esm/native-collab-provider-plugin.js +31 -0
- package/dist/esm/participants.js +88 -0
- package/dist/esm/plugin-key.js +2 -0
- package/dist/esm/plugin-state.js +229 -0
- package/dist/esm/plugin.js +85 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/utils.js +136 -0
- package/dist/types/actions.d.ts +11 -0
- package/dist/types/analytics.d.ts +6 -0
- package/dist/types/events/handlers.d.ts +24 -0
- package/dist/types/events/initialize.d.ts +16 -0
- package/dist/types/events/send-transaction.d.ts +11 -0
- package/dist/types/index.d.ts +29 -0
- package/dist/types/native-collab-provider-plugin.d.ts +7 -0
- package/dist/types/participants.d.ts +18 -0
- package/dist/types/plugin-key.d.ts +3 -0
- package/dist/types/plugin-state.d.ts +25 -0
- package/dist/types/plugin.d.ts +11 -0
- package/dist/types/types.d.ts +8 -0
- package/dist/types/utils.d.ts +16 -0
- package/dist/types-ts4.5/actions.d.ts +11 -0
- package/dist/types-ts4.5/analytics.d.ts +6 -0
- package/dist/types-ts4.5/events/handlers.d.ts +24 -0
- package/dist/types-ts4.5/events/initialize.d.ts +16 -0
- package/dist/types-ts4.5/events/send-transaction.d.ts +11 -0
- package/dist/types-ts4.5/index.d.ts +29 -0
- package/dist/types-ts4.5/native-collab-provider-plugin.d.ts +7 -0
- package/dist/types-ts4.5/participants.d.ts +18 -0
- package/dist/types-ts4.5/plugin-key.d.ts +3 -0
- package/dist/types-ts4.5/plugin-state.d.ts +25 -0
- package/dist/types-ts4.5/plugin.d.ts +11 -0
- package/dist/types-ts4.5/types.d.ts +8 -0
- package/dist/types-ts4.5/utils.d.ts +16 -0
- package/package.json +104 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# @atlaskit/editor-plugin-collab-edit
|
package/LICENSE.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2023 Atlassian Pty Ltd
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Editor plugin collab-edit
|
|
2
|
+
|
|
3
|
+
Collab Edit plugin for @atlaskit/editor-core
|
|
4
|
+
|
|
5
|
+
**Note:** This component is designed for internal Atlassian development.
|
|
6
|
+
External contributors will be able to use this component but will not be able to submit issues.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
---
|
|
10
|
+
- **Install** - *yarn add @atlaskit/editor-plugin-collab-edit*
|
|
11
|
+
- **npm** - [@atlaskit/editor-plugin-collab-edit](https://www.npmjs.com/package/@atlaskit/editor-plugin-collab-edit)
|
|
12
|
+
- **Source** - [Bitbucket](https://bitbucket.org/atlassian/atlassian-frontend/src/master/packages/editor/editor-plugin-collab-edit)
|
|
13
|
+
- **Bundle** - [unpkg.com](https://unpkg.com/@atlaskit/editor-plugin-collab-edit/dist/)
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
---
|
|
17
|
+
**Internal use only**
|
|
18
|
+
|
|
19
|
+
@atlaskit/editor-plugin-collab-edit is intended for internal use by the @atlaskit/editor-core and as a plugin dependency of the Editor within your product.
|
|
20
|
+
|
|
21
|
+
Direct use of this component is not supported.
|
|
22
|
+
|
|
23
|
+
Please see [Atlaskit - Editor plugin collab edit](https://atlaskit.atlassian.com/packages/editor/editor-plugin-collab-edit) for documentation and examples for this package.
|
|
24
|
+
|
|
25
|
+
## Support
|
|
26
|
+
---
|
|
27
|
+
For internal Atlassian, visit the slack channel [#help-editor](https://atlassian.slack.com/archives/CFG3PSQ9E) for support or visit [go/editor-help](https://go/editor-help) to submit a bug.
|
|
28
|
+
## License
|
|
29
|
+
---
|
|
30
|
+
Please see [Atlassian Frontend - License](https://developer.atlassian.com/cloud/framework/atlassian-frontend/#license) for more licensing information.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.handleTelePointer = exports.handlePresence = exports.handleInit = exports.handleConnection = exports.getSendableSelection = exports.applyRemoteSteps = exports.applyRemoteData = void 0;
|
|
8
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
|
+
var _prosemirrorCollab = require("prosemirror-collab");
|
|
10
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
11
|
+
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
12
|
+
var _utils = require("./utils");
|
|
13
|
+
var handleInit = exports.handleInit = function handleInit(initData, view, options) {
|
|
14
|
+
var doc = initData.doc,
|
|
15
|
+
json = initData.json,
|
|
16
|
+
version = initData.version,
|
|
17
|
+
reserveCursor = initData.reserveCursor;
|
|
18
|
+
if (doc) {
|
|
19
|
+
var state = view.state;
|
|
20
|
+
var tr = (0, _utils.replaceDocument)(doc, state, version, options, reserveCursor);
|
|
21
|
+
tr.setMeta('isRemote', true);
|
|
22
|
+
view.dispatch(tr);
|
|
23
|
+
} else if (json) {
|
|
24
|
+
applyRemoteSteps(json, view);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
var handleConnection = exports.handleConnection = function handleConnection(connectionData, view) {
|
|
28
|
+
var tr = view.state.tr;
|
|
29
|
+
view.dispatch(tr.setMeta('sessionId', connectionData));
|
|
30
|
+
};
|
|
31
|
+
var handlePresence = exports.handlePresence = function handlePresence(presenceData, view) {
|
|
32
|
+
var tr = view.state.tr;
|
|
33
|
+
view.dispatch(tr.setMeta('presence', presenceData));
|
|
34
|
+
};
|
|
35
|
+
var applyRemoteData = exports.applyRemoteData = function applyRemoteData(remoteData, view, options) {
|
|
36
|
+
var json = remoteData.json,
|
|
37
|
+
_remoteData$userIds = remoteData.userIds,
|
|
38
|
+
userIds = _remoteData$userIds === void 0 ? [] : _remoteData$userIds;
|
|
39
|
+
if (json) {
|
|
40
|
+
applyRemoteSteps(json, view, userIds, options);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
var applyRemoteSteps = exports.applyRemoteSteps = function applyRemoteSteps(json, view, userIds, options) {
|
|
44
|
+
if (!json || !json.length) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
var state = view.state,
|
|
48
|
+
schema = view.state.schema;
|
|
49
|
+
var steps = json.map(function (step) {
|
|
50
|
+
return _transform.Step.fromJSON(schema, step);
|
|
51
|
+
});
|
|
52
|
+
var tr;
|
|
53
|
+
if (options && options.useNativePlugin && userIds) {
|
|
54
|
+
tr = (0, _prosemirrorCollab.receiveTransaction)(state, steps, userIds);
|
|
55
|
+
} else {
|
|
56
|
+
tr = state.tr;
|
|
57
|
+
steps.forEach(function (step) {
|
|
58
|
+
return tr.step(step);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (tr) {
|
|
62
|
+
tr.setMeta('addToHistory', false);
|
|
63
|
+
tr.setMeta('isRemote', true);
|
|
64
|
+
var _state$selection = state.selection,
|
|
65
|
+
from = _state$selection.from,
|
|
66
|
+
to = _state$selection.to;
|
|
67
|
+
var _json = (0, _slicedToArray2.default)(json, 1),
|
|
68
|
+
firstStep = _json[0];
|
|
69
|
+
|
|
70
|
+
/*
|
|
71
|
+
* Persist marks across transactions. Fixes an issue where
|
|
72
|
+
* marks are lost if remote transactions are dispatched
|
|
73
|
+
* between a user creating the mark and typing.
|
|
74
|
+
*/
|
|
75
|
+
if (state.tr.storedMarks) {
|
|
76
|
+
tr.setStoredMarks(state.tr.storedMarks);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* If the cursor is a the same position as the first step in
|
|
81
|
+
* the remote data, we need to manually set it back again
|
|
82
|
+
* in order to prevent the cursor from moving.
|
|
83
|
+
*/
|
|
84
|
+
if (from === firstStep.from && to === firstStep.to) {
|
|
85
|
+
tr.setSelection(state.selection.map(tr.doc, tr.mapping));
|
|
86
|
+
}
|
|
87
|
+
view.dispatch(tr);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var handleTelePointer = exports.handleTelePointer = function handleTelePointer(telepointerData, view) {
|
|
91
|
+
var tr = view.state.tr;
|
|
92
|
+
view.dispatch(tr.setMeta('telepointer', telepointerData));
|
|
93
|
+
};
|
|
94
|
+
function isAllSelection(selection) {
|
|
95
|
+
return selection instanceof _state.AllSelection;
|
|
96
|
+
}
|
|
97
|
+
function isNodeSelection(selection) {
|
|
98
|
+
return selection instanceof _state.NodeSelection;
|
|
99
|
+
}
|
|
100
|
+
var getSendableSelection = exports.getSendableSelection = function getSendableSelection(selection) {
|
|
101
|
+
/**
|
|
102
|
+
* <kbd>CMD + A</kbd> triggers a AllSelection
|
|
103
|
+
* <kbd>escape</kbd> triggers a NodeSelection
|
|
104
|
+
*/
|
|
105
|
+
return {
|
|
106
|
+
type: 'textSelection',
|
|
107
|
+
anchor: selection.anchor,
|
|
108
|
+
head: isAllSelection(selection) || isNodeSelection(selection) ? selection.head - 1 : selection.head
|
|
109
|
+
};
|
|
110
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.addSynchronyErrorAnalytics = exports.addSynchronyEntityAnalytics = void 0;
|
|
7
|
+
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
8
|
+
var _coreUtils = require("@atlaskit/editor-common/core-utils");
|
|
9
|
+
var _utils = require("@atlaskit/editor-common/utils");
|
|
10
|
+
var addSynchronyErrorAnalytics = exports.addSynchronyErrorAnalytics = function addSynchronyErrorAnalytics(state, tr, featureFlags, editorAnalyticsApi) {
|
|
11
|
+
return function (error) {
|
|
12
|
+
var browserExtensions = (0, _utils.sniffUserBrowserExtensions)({
|
|
13
|
+
extensions: ['grammarly']
|
|
14
|
+
});
|
|
15
|
+
var payload = {
|
|
16
|
+
action: _analytics.ACTION.SYNCHRONY_ERROR,
|
|
17
|
+
actionSubject: _analytics.ACTION_SUBJECT.EDITOR,
|
|
18
|
+
eventType: _analytics.EVENT_TYPE.OPERATIONAL,
|
|
19
|
+
attributes: {
|
|
20
|
+
error: error,
|
|
21
|
+
browserExtensions: browserExtensions
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
if (featureFlags.synchronyErrorDocStructure) {
|
|
25
|
+
payload.attributes.docStructure = (0, _coreUtils.getDocStructure)(state.doc, {
|
|
26
|
+
compact: true
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
editorAnalyticsApi === null || editorAnalyticsApi === void 0 || editorAnalyticsApi.attachAnalyticsEvent(payload)(tr);
|
|
30
|
+
return tr;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
var addSynchronyEntityAnalytics = exports.addSynchronyEntityAnalytics = function addSynchronyEntityAnalytics(state, tr) {
|
|
34
|
+
return function (type, editorAnalyticsApi) {
|
|
35
|
+
editorAnalyticsApi === null || editorAnalyticsApi === void 0 || editorAnalyticsApi.attachAnalyticsEvent({
|
|
36
|
+
action: type === 'error' ? _analytics.ACTION.SYNCHRONY_ENTITY_ERROR : _analytics.ACTION.SYNCHRONY_DISCONNECTED,
|
|
37
|
+
actionSubject: _analytics.ACTION_SUBJECT.EDITOR,
|
|
38
|
+
eventType: _analytics.EVENT_TYPE.OPERATIONAL,
|
|
39
|
+
attributes: {
|
|
40
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine
|
|
41
|
+
onLine: navigator.onLine,
|
|
42
|
+
visibilityState: document.visibilityState
|
|
43
|
+
}
|
|
44
|
+
})(tr);
|
|
45
|
+
return tr;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.subscribe = void 0;
|
|
7
|
+
var _actions = require("../actions");
|
|
8
|
+
var _analytics = require("../analytics");
|
|
9
|
+
var effect = function effect(fn, eq) {
|
|
10
|
+
var previousDeps;
|
|
11
|
+
var cleanup;
|
|
12
|
+
return function () {
|
|
13
|
+
for (var _len = arguments.length, currentDeps = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
14
|
+
currentDeps[_key] = arguments[_key];
|
|
15
|
+
}
|
|
16
|
+
if (cleanup && eq(previousDeps, currentDeps)) {
|
|
17
|
+
return cleanup;
|
|
18
|
+
}
|
|
19
|
+
cleanup = fn.apply(void 0, currentDeps);
|
|
20
|
+
previousDeps = currentDeps;
|
|
21
|
+
return cleanup;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
var subscribe = exports.subscribe = effect(function (view, provider, options, featureFlags, _providerFactory, editorAnalyticsApi) {
|
|
25
|
+
var entityRef;
|
|
26
|
+
var entityHandlers = {
|
|
27
|
+
disconnectedHandler: function disconnectedHandler() {
|
|
28
|
+
(0, _analytics.addSynchronyEntityAnalytics)(view.state, view.state.tr)('disconnected', editorAnalyticsApi);
|
|
29
|
+
},
|
|
30
|
+
errorHandler: function errorHandler() {
|
|
31
|
+
(0, _analytics.addSynchronyEntityAnalytics)(view.state, view.state.tr)('error', editorAnalyticsApi);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
var unsubscribeSynchronyEntity = function unsubscribeSynchronyEntity() {
|
|
35
|
+
if (entityRef) {
|
|
36
|
+
entityRef.off('disconnected', entityHandlers.disconnectedHandler);
|
|
37
|
+
entityRef.off('error', entityHandlers.errorHandler);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var handlers = {
|
|
41
|
+
initHandler: function initHandler(data) {
|
|
42
|
+
view.dispatch(view.state.tr.setMeta('collabInitialised', true));
|
|
43
|
+
(0, _actions.handleInit)(data, view, options);
|
|
44
|
+
},
|
|
45
|
+
connectedHandler: function connectedHandler(data) {
|
|
46
|
+
return (0, _actions.handleConnection)(data, view);
|
|
47
|
+
},
|
|
48
|
+
dataHandler: function dataHandler(data) {
|
|
49
|
+
return (0, _actions.applyRemoteData)(data, view, options);
|
|
50
|
+
},
|
|
51
|
+
presenceHandler: function presenceHandler(data) {
|
|
52
|
+
return (0, _actions.handlePresence)(data, view);
|
|
53
|
+
},
|
|
54
|
+
telepointerHandler: function telepointerHandler(data) {
|
|
55
|
+
return (0, _actions.handleTelePointer)(data, view);
|
|
56
|
+
},
|
|
57
|
+
localStepsHandler: function localStepsHandler(data) {
|
|
58
|
+
var steps = data.steps;
|
|
59
|
+
var state = view.state;
|
|
60
|
+
var tr = state.tr;
|
|
61
|
+
steps.forEach(function (step) {
|
|
62
|
+
return tr.step(step);
|
|
63
|
+
});
|
|
64
|
+
view.dispatch(tr);
|
|
65
|
+
},
|
|
66
|
+
errorHandler: function errorHandler(error) {
|
|
67
|
+
(0, _analytics.addSynchronyErrorAnalytics)(view.state, view.state.tr, featureFlags, editorAnalyticsApi)(error);
|
|
68
|
+
},
|
|
69
|
+
entityHandler: function entityHandler(_ref) {
|
|
70
|
+
var entity = _ref.entity;
|
|
71
|
+
unsubscribeSynchronyEntity();
|
|
72
|
+
if (options.EXPERIMENTAL_allowInternalErrorAnalytics) {
|
|
73
|
+
entity.on('disconnected', entityHandlers.disconnectedHandler);
|
|
74
|
+
entity.on('error', entityHandlers.errorHandler);
|
|
75
|
+
entityRef = entity;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
provider.on('init', handlers.initHandler).on('connected', handlers.connectedHandler).on('data', handlers.dataHandler).on('presence', handlers.presenceHandler).on('telepointer', handlers.telepointerHandler).on('local-steps', handlers.localStepsHandler).on('error', handlers.errorHandler).on('entity', handlers.entityHandler);
|
|
80
|
+
return function () {
|
|
81
|
+
unsubscribeSynchronyEntity();
|
|
82
|
+
provider.off('init', handlers.initHandler).off('connected', handlers.connectedHandler).off('data', handlers.dataHandler).off('presence', handlers.presenceHandler).off('telepointer', handlers.telepointerHandler).off('local-steps', handlers.localStepsHandler).off('error', handlers.errorHandler).off('entity', handlers.entityHandler);
|
|
83
|
+
};
|
|
84
|
+
}, function (previousDeps, currentDeps) {
|
|
85
|
+
return currentDeps && currentDeps.every(function (dep, i) {
|
|
86
|
+
return dep === previousDeps[i];
|
|
87
|
+
});
|
|
88
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.initialize = void 0;
|
|
8
|
+
var _memoizeOne = _interopRequireDefault(require("memoize-one"));
|
|
9
|
+
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
10
|
+
var _pluginKey = require("../plugin-key");
|
|
11
|
+
var _handlers = require("./handlers");
|
|
12
|
+
var initCollab = function initCollab(collabEditProvider, view) {
|
|
13
|
+
if (collabEditProvider.initialize) {
|
|
14
|
+
collabEditProvider.initialize(function () {
|
|
15
|
+
return view.state;
|
|
16
|
+
}, function (json) {
|
|
17
|
+
return _transform.Step.fromJSON(view.state.schema, json);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
var initNewCollab = function initNewCollab(collabEditProvider, view, onSyncUpError) {
|
|
22
|
+
collabEditProvider.setup({
|
|
23
|
+
getState: function getState() {
|
|
24
|
+
return view.state;
|
|
25
|
+
},
|
|
26
|
+
onSyncUpError: onSyncUpError
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
var initCollabMemo = (0, _memoizeOne.default)(initCollab);
|
|
30
|
+
var initialize = exports.initialize = function initialize(_ref) {
|
|
31
|
+
var options = _ref.options,
|
|
32
|
+
providerFactory = _ref.providerFactory,
|
|
33
|
+
view = _ref.view,
|
|
34
|
+
featureFlags = _ref.featureFlags,
|
|
35
|
+
editorAnalyticsApi = _ref.editorAnalyticsApi;
|
|
36
|
+
return function (provider) {
|
|
37
|
+
var cleanup;
|
|
38
|
+
var pluginState = _pluginKey.pluginKey.getState(view.state);
|
|
39
|
+
if (pluginState !== null && pluginState !== void 0 && pluginState.isReady && cleanup) {
|
|
40
|
+
cleanup();
|
|
41
|
+
}
|
|
42
|
+
cleanup = (0, _handlers.subscribe)(view, provider, options, featureFlags, providerFactory, editorAnalyticsApi);
|
|
43
|
+
|
|
44
|
+
// Initialize provider
|
|
45
|
+
if (options.useNativePlugin) {
|
|
46
|
+
// ED-13912 For NCS we don't want to use memoizeOne because it causes
|
|
47
|
+
// infinite text while changing page-width
|
|
48
|
+
initNewCollab(provider, view, options.onSyncUpError);
|
|
49
|
+
} else {
|
|
50
|
+
/**
|
|
51
|
+
* We only want to initialise once, if we reload/reconfigure this plugin
|
|
52
|
+
* We dont want to re-init collab, it would break existing sessions
|
|
53
|
+
*/
|
|
54
|
+
initCollabMemo(provider, view);
|
|
55
|
+
}
|
|
56
|
+
return cleanup;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.sendTransaction = void 0;
|
|
7
|
+
var _actions = require("../actions");
|
|
8
|
+
var _pluginKey = require("../plugin-key");
|
|
9
|
+
var sendTransaction = exports.sendTransaction = function sendTransaction(_ref) {
|
|
10
|
+
var originalTransaction = _ref.originalTransaction,
|
|
11
|
+
transactions = _ref.transactions,
|
|
12
|
+
oldEditorState = _ref.oldEditorState,
|
|
13
|
+
newEditorState = _ref.newEditorState,
|
|
14
|
+
useNativePlugin = _ref.useNativePlugin;
|
|
15
|
+
return function (provider) {
|
|
16
|
+
var docChangedTransaction = transactions.find(function (tr) {
|
|
17
|
+
return tr.docChanged;
|
|
18
|
+
});
|
|
19
|
+
var currentPluginState = _pluginKey.pluginKey.getState(newEditorState);
|
|
20
|
+
if (!(currentPluginState !== null && currentPluginState !== void 0 && currentPluginState.isReady)) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
var shouldSendStepForSynchronyCollabProvider = !originalTransaction.getMeta('isRemote') &&
|
|
24
|
+
// TODO: ED-8995
|
|
25
|
+
// We need to do this check to reduce the number of race conditions when working with tables.
|
|
26
|
+
// This metadata is coming from the scaleTable command in table-resizing plugin
|
|
27
|
+
!originalTransaction.getMeta('scaleTable') && docChangedTransaction;
|
|
28
|
+
if (useNativePlugin || shouldSendStepForSynchronyCollabProvider) {
|
|
29
|
+
provider.send(docChangedTransaction, oldEditorState, newEditorState);
|
|
30
|
+
}
|
|
31
|
+
var prevPluginState = _pluginKey.pluginKey.getState(oldEditorState);
|
|
32
|
+
var _ref2 = prevPluginState || {},
|
|
33
|
+
prevActiveParticipants = _ref2.activeParticipants;
|
|
34
|
+
var activeParticipants = currentPluginState.activeParticipants,
|
|
35
|
+
sessionId = currentPluginState.sessionId;
|
|
36
|
+
var selectionChanged = !oldEditorState.selection.eq(newEditorState.selection);
|
|
37
|
+
var participantsChanged = prevActiveParticipants && !prevActiveParticipants.eq(activeParticipants);
|
|
38
|
+
if (sessionId && selectionChanged && !docChangedTransaction || sessionId && participantsChanged) {
|
|
39
|
+
var selection = (0, _actions.getSendableSelection)(newEditorState.selection);
|
|
40
|
+
var message = {
|
|
41
|
+
type: 'telepointer',
|
|
42
|
+
selection: selection,
|
|
43
|
+
sessionId: sessionId
|
|
44
|
+
};
|
|
45
|
+
provider.sendMessage(message);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.collabEditPlugin = void 0;
|
|
8
|
+
Object.defineProperty(exports, "pluginKey", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function get() {
|
|
11
|
+
return _plugin.pluginKey;
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
15
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
16
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
17
|
+
var _prosemirrorCollab = require("prosemirror-collab");
|
|
18
|
+
var _analytics = require("./analytics");
|
|
19
|
+
var _sendTransaction = require("./events/send-transaction");
|
|
20
|
+
var _nativeCollabProviderPlugin = require("./native-collab-provider-plugin");
|
|
21
|
+
var _plugin = require("./plugin");
|
|
22
|
+
var _utils = require("./utils");
|
|
23
|
+
var providerBuilder = function providerBuilder(collabEditProviderPromise) {
|
|
24
|
+
return /*#__PURE__*/function () {
|
|
25
|
+
var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(codeToExecute, onError) {
|
|
26
|
+
var provider;
|
|
27
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
28
|
+
while (1) switch (_context.prev = _context.next) {
|
|
29
|
+
case 0:
|
|
30
|
+
_context.prev = 0;
|
|
31
|
+
_context.next = 3;
|
|
32
|
+
return collabEditProviderPromise;
|
|
33
|
+
case 3:
|
|
34
|
+
provider = _context.sent;
|
|
35
|
+
if (!provider) {
|
|
36
|
+
_context.next = 6;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
return _context.abrupt("return", codeToExecute(provider));
|
|
40
|
+
case 6:
|
|
41
|
+
_context.next = 11;
|
|
42
|
+
break;
|
|
43
|
+
case 8:
|
|
44
|
+
_context.prev = 8;
|
|
45
|
+
_context.t0 = _context["catch"](0);
|
|
46
|
+
if (onError) {
|
|
47
|
+
onError(_context.t0);
|
|
48
|
+
} else {
|
|
49
|
+
// eslint-disable-next-line no-console
|
|
50
|
+
console.error(_context.t0);
|
|
51
|
+
}
|
|
52
|
+
case 11:
|
|
53
|
+
case "end":
|
|
54
|
+
return _context.stop();
|
|
55
|
+
}
|
|
56
|
+
}, _callee, null, [[0, 8]]);
|
|
57
|
+
}));
|
|
58
|
+
return function (_x, _x2) {
|
|
59
|
+
return _ref.apply(this, arguments);
|
|
60
|
+
};
|
|
61
|
+
}();
|
|
62
|
+
};
|
|
63
|
+
var collabEditPlugin = exports.collabEditPlugin = function collabEditPlugin(_ref2) {
|
|
64
|
+
var _api$featureFlags;
|
|
65
|
+
var options = _ref2.config,
|
|
66
|
+
api = _ref2.api;
|
|
67
|
+
var featureFlags = (api === null || api === void 0 || (_api$featureFlags = api.featureFlags) === null || _api$featureFlags === void 0 ? void 0 : _api$featureFlags.sharedState.currentState()) || {};
|
|
68
|
+
var providerResolver = function providerResolver() {};
|
|
69
|
+
var collabEditProviderPromise = new Promise(function (_providerResolver) {
|
|
70
|
+
providerResolver = _providerResolver;
|
|
71
|
+
});
|
|
72
|
+
var executeProviderCode = providerBuilder(collabEditProviderPromise);
|
|
73
|
+
return {
|
|
74
|
+
name: 'collabEdit',
|
|
75
|
+
getSharedState: function getSharedState(state) {
|
|
76
|
+
if (!state) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
var collabPluginState = _plugin.pluginKey.getState(state);
|
|
80
|
+
return {
|
|
81
|
+
activeParticipants: collabPluginState === null || collabPluginState === void 0 ? void 0 : collabPluginState.activeParticipants,
|
|
82
|
+
sessionId: collabPluginState === null || collabPluginState === void 0 ? void 0 : collabPluginState.sessionId
|
|
83
|
+
};
|
|
84
|
+
},
|
|
85
|
+
actions: {
|
|
86
|
+
getAvatarColor: _utils.getAvatarColor
|
|
87
|
+
},
|
|
88
|
+
pmPlugins: function pmPlugins() {
|
|
89
|
+
var _ref3 = options || {},
|
|
90
|
+
_ref3$useNativePlugin = _ref3.useNativePlugin,
|
|
91
|
+
useNativePlugin = _ref3$useNativePlugin === void 0 ? false : _ref3$useNativePlugin,
|
|
92
|
+
userId = _ref3.userId;
|
|
93
|
+
return [].concat((0, _toConsumableArray2.default)(useNativePlugin ? [{
|
|
94
|
+
name: 'pmCollab',
|
|
95
|
+
plugin: function plugin() {
|
|
96
|
+
return (0, _prosemirrorCollab.collab)({
|
|
97
|
+
clientID: userId
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}, {
|
|
101
|
+
name: 'nativeCollabProviderPlugin',
|
|
102
|
+
plugin: function plugin() {
|
|
103
|
+
return (0, _nativeCollabProviderPlugin.nativeCollabProviderPlugin)({
|
|
104
|
+
providerPromise: collabEditProviderPromise
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}] : []), [{
|
|
108
|
+
name: 'collab',
|
|
109
|
+
plugin: function plugin(_ref4) {
|
|
110
|
+
var dispatch = _ref4.dispatch,
|
|
111
|
+
providerFactory = _ref4.providerFactory;
|
|
112
|
+
return (0, _plugin.createPlugin)(dispatch, providerFactory, providerResolver, executeProviderCode, options, featureFlags, api);
|
|
113
|
+
}
|
|
114
|
+
}]);
|
|
115
|
+
},
|
|
116
|
+
onEditorViewStateUpdated: function onEditorViewStateUpdated(props) {
|
|
117
|
+
var _api$analytics, _options$useNativePlu;
|
|
118
|
+
var addErrorAnalytics = (0, _analytics.addSynchronyErrorAnalytics)(props.newEditorState, props.newEditorState.tr, featureFlags, api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions);
|
|
119
|
+
executeProviderCode((0, _sendTransaction.sendTransaction)({
|
|
120
|
+
originalTransaction: props.originalTransaction,
|
|
121
|
+
transactions: props.transactions,
|
|
122
|
+
oldEditorState: props.oldEditorState,
|
|
123
|
+
newEditorState: props.newEditorState,
|
|
124
|
+
useNativePlugin: (_options$useNativePlu = options === null || options === void 0 ? void 0 : options.useNativePlugin) !== null && _options$useNativePlu !== void 0 ? _options$useNativePlu : false
|
|
125
|
+
}), addErrorAnalytics);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.nativeCollabProviderPlugin = exports.getCollabProvider = void 0;
|
|
7
|
+
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
8
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
9
|
+
var nativeCollabProviderPluginKey = new _state.PluginKey('nativeCollabProviderPlugin');
|
|
10
|
+
var nativeCollabProviderPlugin = exports.nativeCollabProviderPlugin = function nativeCollabProviderPlugin(_ref) {
|
|
11
|
+
var providerPromise = _ref.providerPromise;
|
|
12
|
+
return new _safePlugin.SafePlugin({
|
|
13
|
+
key: nativeCollabProviderPluginKey,
|
|
14
|
+
state: {
|
|
15
|
+
init: function init() {
|
|
16
|
+
return null;
|
|
17
|
+
},
|
|
18
|
+
apply: function apply(tr, currentPluginState) {
|
|
19
|
+
var provider = tr.getMeta(nativeCollabProviderPluginKey);
|
|
20
|
+
return provider ? provider : currentPluginState;
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
view: function view(editorView) {
|
|
24
|
+
providerPromise.then(function (provider) {
|
|
25
|
+
var dispatch = editorView.dispatch,
|
|
26
|
+
state = editorView.state;
|
|
27
|
+
var tr = state.tr;
|
|
28
|
+
tr.setMeta(nativeCollabProviderPluginKey, provider);
|
|
29
|
+
dispatch(tr);
|
|
30
|
+
});
|
|
31
|
+
return {};
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
var getCollabProvider = exports.getCollabProvider = function getCollabProvider(editorState) {
|
|
36
|
+
return nativeCollabProviderPluginKey.getState(editorState);
|
|
37
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.Participants = void 0;
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
10
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
11
|
+
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; }
|
|
12
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
13
|
+
var Participants = exports.Participants = /*#__PURE__*/function () {
|
|
14
|
+
function Participants() {
|
|
15
|
+
var participants = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Map();
|
|
16
|
+
(0, _classCallCheck2.default)(this, Participants);
|
|
17
|
+
this.participants = participants;
|
|
18
|
+
}
|
|
19
|
+
(0, _createClass2.default)(Participants, [{
|
|
20
|
+
key: "add",
|
|
21
|
+
value: function add(data) {
|
|
22
|
+
var newSet = new Map(this.participants);
|
|
23
|
+
data.forEach(function (participant) {
|
|
24
|
+
newSet.set(participant.sessionId, participant);
|
|
25
|
+
});
|
|
26
|
+
return new Participants(newSet);
|
|
27
|
+
}
|
|
28
|
+
}, {
|
|
29
|
+
key: "remove",
|
|
30
|
+
value: function remove(sessionIds) {
|
|
31
|
+
var newSet = new Map(this.participants);
|
|
32
|
+
sessionIds.forEach(function (sessionId) {
|
|
33
|
+
newSet.delete(sessionId);
|
|
34
|
+
});
|
|
35
|
+
return new Participants(newSet);
|
|
36
|
+
}
|
|
37
|
+
}, {
|
|
38
|
+
key: "update",
|
|
39
|
+
value: function update(sessionId, lastActive) {
|
|
40
|
+
var newSet = new Map(this.participants);
|
|
41
|
+
var data = newSet.get(sessionId);
|
|
42
|
+
if (!data) {
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
newSet.set(sessionId, _objectSpread(_objectSpread({}, data), {}, {
|
|
46
|
+
lastActive: lastActive
|
|
47
|
+
}));
|
|
48
|
+
return new Participants(newSet);
|
|
49
|
+
}
|
|
50
|
+
}, {
|
|
51
|
+
key: "updateCursorPos",
|
|
52
|
+
value: function updateCursorPos(sessionId, cursorPos) {
|
|
53
|
+
var newSet = new Map(this.participants);
|
|
54
|
+
var data = newSet.get(sessionId);
|
|
55
|
+
if (!data) {
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
newSet.set(sessionId, _objectSpread(_objectSpread({}, data), {}, {
|
|
59
|
+
cursorPos: cursorPos
|
|
60
|
+
}));
|
|
61
|
+
return new Participants(newSet);
|
|
62
|
+
}
|
|
63
|
+
}, {
|
|
64
|
+
key: "toArray",
|
|
65
|
+
value: function toArray() {
|
|
66
|
+
return Array.from(this.participants.values());
|
|
67
|
+
}
|
|
68
|
+
}, {
|
|
69
|
+
key: "get",
|
|
70
|
+
value: function get(sessionId) {
|
|
71
|
+
return this.participants.get(sessionId);
|
|
72
|
+
}
|
|
73
|
+
}, {
|
|
74
|
+
key: "size",
|
|
75
|
+
value: function size() {
|
|
76
|
+
return this.participants.size;
|
|
77
|
+
}
|
|
78
|
+
}, {
|
|
79
|
+
key: "eq",
|
|
80
|
+
value: function eq(other) {
|
|
81
|
+
var left = this.toArray().map(function (p) {
|
|
82
|
+
return p.sessionId;
|
|
83
|
+
}).sort(function (a, b) {
|
|
84
|
+
return a > b ? -1 : 1;
|
|
85
|
+
}).join('');
|
|
86
|
+
var right = other.toArray().map(function (p) {
|
|
87
|
+
return p.sessionId;
|
|
88
|
+
}).sort(function (a, b) {
|
|
89
|
+
return a > b ? -1 : 1;
|
|
90
|
+
}).join('');
|
|
91
|
+
return left === right;
|
|
92
|
+
}
|
|
93
|
+
}]);
|
|
94
|
+
return Participants;
|
|
95
|
+
}();
|