@atlaskit/editor-plugin-analytics 0.0.1
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 +7 -0
- package/dist/cjs/analytics-api/attach-payload-into-transaction.js +51 -0
- package/dist/cjs/analytics-api/editor-state-context.js +78 -0
- package/dist/cjs/analytics-api/map-attributes.js +23 -0
- package/dist/cjs/consts.js +12 -0
- package/dist/cjs/index.js +12 -0
- package/dist/cjs/plugin-key.js +9 -0
- package/dist/cjs/plugin.js +187 -0
- package/dist/cjs/undo-redo-input-source.js +27 -0
- package/dist/cjs/version.json +5 -0
- package/dist/es2019/analytics-api/attach-payload-into-transaction.js +43 -0
- package/dist/es2019/analytics-api/editor-state-context.js +72 -0
- package/dist/es2019/analytics-api/map-attributes.js +14 -0
- package/dist/es2019/consts.js +4 -0
- package/dist/es2019/index.js +1 -0
- package/dist/es2019/plugin-key.js +2 -0
- package/dist/es2019/plugin.js +162 -0
- package/dist/es2019/undo-redo-input-source.js +18 -0
- package/dist/es2019/version.json +5 -0
- package/dist/esm/analytics-api/attach-payload-into-transaction.js +43 -0
- package/dist/esm/analytics-api/editor-state-context.js +70 -0
- package/dist/esm/analytics-api/map-attributes.js +16 -0
- package/dist/esm/consts.js +4 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/plugin-key.js +2 -0
- package/dist/esm/plugin.js +179 -0
- package/dist/esm/undo-redo-input-source.js +19 -0
- package/dist/esm/version.json +5 -0
- package/dist/types/analytics-api/attach-payload-into-transaction.d.ts +16 -0
- package/dist/types/analytics-api/editor-state-context.d.ts +8 -0
- package/dist/types/analytics-api/map-attributes.d.ts +2 -0
- package/dist/types/consts.d.ts +3 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/plugin-key.d.ts +2 -0
- package/dist/types/plugin.d.ts +24 -0
- package/dist/types/undo-redo-input-source.d.ts +3 -0
- package/dist/types-ts4.5/analytics-api/attach-payload-into-transaction.d.ts +16 -0
- package/dist/types-ts4.5/analytics-api/editor-state-context.d.ts +8 -0
- package/dist/types-ts4.5/analytics-api/map-attributes.d.ts +2 -0
- package/dist/types-ts4.5/consts.d.ts +3 -0
- package/dist/types-ts4.5/index.d.ts +3 -0
- package/dist/types-ts4.5/plugin-key.d.ts +2 -0
- package/dist/types-ts4.5/plugin.d.ts +26 -0
- package/dist/types-ts4.5/undo-redo-input-source.d.ts +3 -0
- package/package.json +92 -0
- package/report.api.md +70 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# @atlaskit/editor-plugin-analytics
|
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,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createAttachPayloadIntoTransaction = exports.attachPayloadIntoTransaction = void 0;
|
|
7
|
+
var _steps = require("@atlaskit/adf-schema/steps");
|
|
8
|
+
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
9
|
+
var _editorStateContext = require("./editor-state-context");
|
|
10
|
+
var _mapAttributes = require("./map-attributes");
|
|
11
|
+
var actionsToIgnore = [_analytics.ACTION.INVOKED, _analytics.ACTION.OPENED];
|
|
12
|
+
var createAttachPayloadIntoTransaction = function createAttachPayloadIntoTransaction(selection) {
|
|
13
|
+
return function (_ref) {
|
|
14
|
+
var payload = _ref.payload,
|
|
15
|
+
tr = _ref.tr,
|
|
16
|
+
channel = _ref.channel;
|
|
17
|
+
return attachPayloadIntoTransaction({
|
|
18
|
+
payload: payload,
|
|
19
|
+
selection: selection,
|
|
20
|
+
tr: tr,
|
|
21
|
+
channel: channel
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// This utils was taken as reference in packages/editor/editor-plugin-ai/src/analytics/utils.ts
|
|
27
|
+
// to create new util attachPayloadIntoTransaction in above file.
|
|
28
|
+
// If you make a change here, please review attachPayloadIntoTransaction in above
|
|
29
|
+
// file and update it as well if needed.
|
|
30
|
+
exports.createAttachPayloadIntoTransaction = createAttachPayloadIntoTransaction;
|
|
31
|
+
var attachPayloadIntoTransaction = function attachPayloadIntoTransaction(_ref2) {
|
|
32
|
+
var payload = _ref2.payload,
|
|
33
|
+
selection = _ref2.selection,
|
|
34
|
+
tr = _ref2.tr,
|
|
35
|
+
channel = _ref2.channel;
|
|
36
|
+
payload = (0, _editorStateContext.getStateContext)(selection, payload);
|
|
37
|
+
payload = (0, _mapAttributes.mapActionSubjectIdToAttributes)(payload);
|
|
38
|
+
var storedMarks = tr.storedMarks;
|
|
39
|
+
var pos = tr.mapping.map(selection.$from.pos, -1);
|
|
40
|
+
tr.step(new _steps.AnalyticsStep([{
|
|
41
|
+
payload: payload,
|
|
42
|
+
channel: channel
|
|
43
|
+
}], actionsToIgnore, pos) // We need to create the step based on a position, this prevent split history for relative changes.
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
// When you add a new step all the storedMarks are removed it
|
|
47
|
+
if (storedMarks) {
|
|
48
|
+
tr.setStoredMarks(storedMarks);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
exports.attachPayloadIntoTransaction = attachPayloadIntoTransaction;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.findInsertLocation = findInsertLocation;
|
|
7
|
+
exports.getSelectionType = getSelectionType;
|
|
8
|
+
exports.getStateContext = getStateContext;
|
|
9
|
+
var _prosemirrorState = require("prosemirror-state");
|
|
10
|
+
var _prosemirrorUtils = require("prosemirror-utils");
|
|
11
|
+
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
12
|
+
var _cellSelection = require("@atlaskit/editor-tables/cell-selection");
|
|
13
|
+
function getSelectionType(selection) {
|
|
14
|
+
var _selection$constructo;
|
|
15
|
+
var type;
|
|
16
|
+
var position;
|
|
17
|
+
if ((selection === null || selection === void 0 ? void 0 : (_selection$constructo = selection.constructor) === null || _selection$constructo === void 0 ? void 0 : _selection$constructo.name) === 'GapCursorSelection') {
|
|
18
|
+
type = _analytics.SELECTION_TYPE.GAP_CURSOR;
|
|
19
|
+
position = selection.side;
|
|
20
|
+
} else if (selection instanceof _cellSelection.CellSelection) {
|
|
21
|
+
type = _analytics.SELECTION_TYPE.CELL;
|
|
22
|
+
} else if (selection instanceof _prosemirrorState.NodeSelection) {
|
|
23
|
+
type = _analytics.SELECTION_TYPE.NODE;
|
|
24
|
+
} else if (selection.from !== selection.to) {
|
|
25
|
+
type = _analytics.SELECTION_TYPE.RANGED;
|
|
26
|
+
} else {
|
|
27
|
+
type = _analytics.SELECTION_TYPE.CURSOR;
|
|
28
|
+
var from = selection.from,
|
|
29
|
+
$from = selection.$from;
|
|
30
|
+
if (from === $from.start()) {
|
|
31
|
+
position = _analytics.SELECTION_POSITION.START;
|
|
32
|
+
} else if (from === $from.end()) {
|
|
33
|
+
position = _analytics.SELECTION_POSITION.END;
|
|
34
|
+
} else {
|
|
35
|
+
position = _analytics.SELECTION_POSITION.MIDDLE;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
type: type,
|
|
40
|
+
position: position
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function findInsertLocation(selection) {
|
|
44
|
+
var _selection$$from$doc$ = selection.$from.doc.type,
|
|
45
|
+
schema = _selection$$from$doc$.schema,
|
|
46
|
+
name = _selection$$from$doc$.name;
|
|
47
|
+
if (selection instanceof _prosemirrorState.NodeSelection) {
|
|
48
|
+
return selection.node.type.name;
|
|
49
|
+
}
|
|
50
|
+
if (selection instanceof _cellSelection.CellSelection) {
|
|
51
|
+
return schema.nodes.table.name;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Text selection
|
|
55
|
+
var parentNodeInfo = (0, _prosemirrorUtils.findParentNode)(function (node) {
|
|
56
|
+
return node.type !== schema.nodes.paragraph;
|
|
57
|
+
})(selection);
|
|
58
|
+
return parentNodeInfo ? parentNodeInfo.node.type.name : name;
|
|
59
|
+
}
|
|
60
|
+
function getStateContext(selection, payload) {
|
|
61
|
+
if (!payload.attributes) {
|
|
62
|
+
return payload;
|
|
63
|
+
}
|
|
64
|
+
var _getSelectionType = getSelectionType(selection),
|
|
65
|
+
type = _getSelectionType.type,
|
|
66
|
+
position = _getSelectionType.position;
|
|
67
|
+
payload.attributes.selectionType = type;
|
|
68
|
+
if (position) {
|
|
69
|
+
payload.attributes.selectionPosition = position;
|
|
70
|
+
}
|
|
71
|
+
var insertLocation = findInsertLocation(selection);
|
|
72
|
+
if (payload.action === _analytics.ACTION.INSERTED && payload.actionSubject === _analytics.ACTION_SUBJECT.DOCUMENT && payload.attributes) {
|
|
73
|
+
payload.attributes.insertLocation = insertLocation;
|
|
74
|
+
} else {
|
|
75
|
+
payload.attributes.nodeLocation = insertLocation;
|
|
76
|
+
}
|
|
77
|
+
return payload;
|
|
78
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.mapActionSubjectIdToAttributes = mapActionSubjectIdToAttributes;
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
10
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
11
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
12
|
+
function mapActionSubjectIdToAttributes(payload) {
|
|
13
|
+
var documentInserted = payload.action === _analytics.ACTION.INSERTED && payload.actionSubject === _analytics.ACTION_SUBJECT.DOCUMENT;
|
|
14
|
+
var textFormatted = payload.action === _analytics.ACTION.FORMATTED && payload.actionSubject === _analytics.ACTION_SUBJECT.TEXT;
|
|
15
|
+
var hasActionSubjectId = !!payload.actionSubjectId;
|
|
16
|
+
if (hasActionSubjectId && (documentInserted || textFormatted)) {
|
|
17
|
+
payload.attributes = _objectSpread(_objectSpread({}, payload.attributes), {}, {
|
|
18
|
+
// @ts-expect-error
|
|
19
|
+
actionSubjectId: payload.actionSubjectId
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return payload;
|
|
23
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.editorAnalyticsChannel = exports.analyticsEventKey = void 0;
|
|
7
|
+
var _analyticsListeners = require("@atlaskit/analytics-listeners");
|
|
8
|
+
var _utils = require("@atlaskit/editor-common/utils");
|
|
9
|
+
var analyticsEventKey = _utils.analyticsEventKey;
|
|
10
|
+
exports.analyticsEventKey = analyticsEventKey;
|
|
11
|
+
var editorAnalyticsChannel = _analyticsListeners.FabricChannel.editor;
|
|
12
|
+
exports.editorAnalyticsChannel = editorAnalyticsChannel;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "analyticsPlugin", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function get() {
|
|
9
|
+
return _plugin.analyticsPlugin;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
var _plugin = require("./plugin");
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.analyticsPluginKey = void 0;
|
|
7
|
+
var _prosemirrorState = require("prosemirror-state");
|
|
8
|
+
var analyticsPluginKey = new _prosemirrorState.PluginKey('analyticsPlugin');
|
|
9
|
+
exports.analyticsPluginKey = analyticsPluginKey;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.analyticsPlugin = void 0;
|
|
8
|
+
exports.extendPayload = extendPayload;
|
|
9
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
10
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
|
+
var _steps = require("@atlaskit/adf-schema/steps");
|
|
12
|
+
var _analyticsListeners = require("@atlaskit/analytics-listeners");
|
|
13
|
+
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
14
|
+
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
15
|
+
var _utils = require("@atlaskit/editor-common/utils");
|
|
16
|
+
var _attachPayloadIntoTransaction = require("./analytics-api/attach-payload-into-transaction");
|
|
17
|
+
var _pluginKey = require("./plugin-key");
|
|
18
|
+
var _undoRedoInputSource = require("./undo-redo-input-source");
|
|
19
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
20
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
21
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
22
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
23
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
24
|
+
function createPlugin(options, featureFlags) {
|
|
25
|
+
if (!options || !options.createAnalyticsEvent) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
var hasRequiredPerformanceAPIs = (0, _utils.isPerformanceAPIAvailable)();
|
|
29
|
+
return new _safePlugin.SafePlugin({
|
|
30
|
+
key: _pluginKey.analyticsPluginKey,
|
|
31
|
+
state: {
|
|
32
|
+
init: function init() {
|
|
33
|
+
return _objectSpread(_objectSpread({}, options), {}, {
|
|
34
|
+
fireAnalytics: (0, _analytics.fireAnalyticsEvent)(options.createAnalyticsEvent)
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
apply: function apply(tr, pluginState, _, state) {
|
|
38
|
+
if (pluginState.createAnalyticsEvent !== options.createAnalyticsEvent) {
|
|
39
|
+
// When the plugin state is reconfigured, the init function isn't called again
|
|
40
|
+
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
41
|
+
createAnalyticsEvent: options.createAnalyticsEvent
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (featureFlags.catchAllTracking) {
|
|
45
|
+
var analyticsEventWithChannel = (0, _analytics.getAnalyticsEventsFromTransaction)(tr);
|
|
46
|
+
if (analyticsEventWithChannel.length > 0) {
|
|
47
|
+
var _iterator = _createForOfIteratorHelper(analyticsEventWithChannel),
|
|
48
|
+
_step;
|
|
49
|
+
try {
|
|
50
|
+
var _loop = function _loop() {
|
|
51
|
+
var _step$value = _step.value,
|
|
52
|
+
payload = _step$value.payload,
|
|
53
|
+
channel = _step$value.channel;
|
|
54
|
+
// Measures how much time it takes to update the DOM after each ProseMirror document update
|
|
55
|
+
// that has an analytics event.
|
|
56
|
+
if (hasRequiredPerformanceAPIs && tr.docChanged && payload.action !== _analytics.ACTION.INSERTED && payload.action !== _analytics.ACTION.DELETED) {
|
|
57
|
+
var measureName = "".concat(payload.actionSubject, ":").concat(payload.action, ":").concat(payload.actionSubjectId);
|
|
58
|
+
(0, _utils.measureRender)(
|
|
59
|
+
// NOTE this name could be resulting in misleading data -- where if multiple payloads are
|
|
60
|
+
// received before a render completes -- the measurement value will be inaccurate (this is
|
|
61
|
+
// due to measureRender requiring unique measureNames)
|
|
62
|
+
measureName, function (_ref) {
|
|
63
|
+
var duration = _ref.duration,
|
|
64
|
+
distortedDuration = _ref.distortedDuration;
|
|
65
|
+
(0, _analytics.fireAnalyticsEvent)(pluginState.createAnalyticsEvent)({
|
|
66
|
+
payload: extendPayload({
|
|
67
|
+
payload: payload,
|
|
68
|
+
duration: duration,
|
|
69
|
+
distortedDuration: distortedDuration
|
|
70
|
+
}),
|
|
71
|
+
channel: channel
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
77
|
+
_loop();
|
|
78
|
+
}
|
|
79
|
+
} catch (err) {
|
|
80
|
+
_iterator.e(err);
|
|
81
|
+
} finally {
|
|
82
|
+
_iterator.f();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return pluginState;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
var analyticsPlugin = function analyticsPlugin(options, api) {
|
|
92
|
+
var _api$dependencies$fea;
|
|
93
|
+
var featureFlags = (api === null || api === void 0 ? void 0 : (_api$dependencies$fea = api.dependencies.featureFlags) === null || _api$dependencies$fea === void 0 ? void 0 : _api$dependencies$fea.sharedState.currentState()) || {};
|
|
94
|
+
return {
|
|
95
|
+
name: 'analytics',
|
|
96
|
+
getSharedState: function getSharedState(editorState) {
|
|
97
|
+
var _analyticsPluginKey$g;
|
|
98
|
+
if (!editorState) {
|
|
99
|
+
return {
|
|
100
|
+
createAnalyticsEvent: null,
|
|
101
|
+
attachAnalyticsEvent: null
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
var _ref2 = (_analyticsPluginKey$g = _pluginKey.analyticsPluginKey.getState(editorState)) !== null && _analyticsPluginKey$g !== void 0 ? _analyticsPluginKey$g : {},
|
|
105
|
+
createAnalyticsEvent = _ref2.createAnalyticsEvent;
|
|
106
|
+
return {
|
|
107
|
+
createAnalyticsEvent: createAnalyticsEvent,
|
|
108
|
+
attachAnalyticsEvent: (0, _attachPayloadIntoTransaction.createAttachPayloadIntoTransaction)(editorState.selection)
|
|
109
|
+
};
|
|
110
|
+
},
|
|
111
|
+
actions: {
|
|
112
|
+
attachAnalyticsEvent: function attachAnalyticsEvent(payload) {
|
|
113
|
+
var channel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _analyticsListeners.FabricChannel.editor;
|
|
114
|
+
return function (tr) {
|
|
115
|
+
var _api$dependencies$ana, _api$dependencies$ana2;
|
|
116
|
+
var _ref3 = (_api$dependencies$ana = api === null || api === void 0 ? void 0 : (_api$dependencies$ana2 = api.dependencies.analytics) === null || _api$dependencies$ana2 === void 0 ? void 0 : _api$dependencies$ana2.sharedState.currentState()) !== null && _api$dependencies$ana !== void 0 ? _api$dependencies$ana : {},
|
|
117
|
+
createAnalyticsEvent = _ref3.createAnalyticsEvent,
|
|
118
|
+
attachAnalyticsEvent = _ref3.attachAnalyticsEvent;
|
|
119
|
+
if (!tr || !createAnalyticsEvent || !attachAnalyticsEvent) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
attachAnalyticsEvent({
|
|
123
|
+
tr: tr,
|
|
124
|
+
payload: payload,
|
|
125
|
+
channel: channel
|
|
126
|
+
});
|
|
127
|
+
return true;
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
pmPlugins: function pmPlugins() {
|
|
132
|
+
return [{
|
|
133
|
+
name: 'analyticsPlugin',
|
|
134
|
+
plugin: function plugin() {
|
|
135
|
+
return createPlugin(options, featureFlags);
|
|
136
|
+
}
|
|
137
|
+
}];
|
|
138
|
+
},
|
|
139
|
+
onEditorViewStateUpdated: function onEditorViewStateUpdated(_ref4) {
|
|
140
|
+
var originalTransaction = _ref4.originalTransaction,
|
|
141
|
+
transactions = _ref4.transactions,
|
|
142
|
+
newEditorState = _ref4.newEditorState;
|
|
143
|
+
var pluginState = _pluginKey.analyticsPluginKey.getState(newEditorState);
|
|
144
|
+
if (!pluginState || !pluginState.createAnalyticsEvent) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
var steps = transactions.reduce(function (acc, tr) {
|
|
148
|
+
var payloads = tr.steps.filter(function (step) {
|
|
149
|
+
return step instanceof _steps.AnalyticsStep;
|
|
150
|
+
}).map(function (x) {
|
|
151
|
+
return x.analyticsEvents;
|
|
152
|
+
}).reduce(function (acc, val) {
|
|
153
|
+
return acc.concat(val);
|
|
154
|
+
}, []);
|
|
155
|
+
acc.push.apply(acc, (0, _toConsumableArray2.default)(payloads));
|
|
156
|
+
return acc;
|
|
157
|
+
}, []);
|
|
158
|
+
if (steps.length === 0) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
var createAnalyticsEvent = pluginState.createAnalyticsEvent;
|
|
162
|
+
var undoAnaltyicsEventTransformer = (0, _undoRedoInputSource.generateUndoRedoInputSoucePayload)(originalTransaction);
|
|
163
|
+
steps.forEach(function (_ref5) {
|
|
164
|
+
var payload = _ref5.payload,
|
|
165
|
+
channel = _ref5.channel;
|
|
166
|
+
var nextPayload = undoAnaltyicsEventTransformer(payload);
|
|
167
|
+
(0, _analytics.fireAnalyticsEvent)(createAnalyticsEvent)({
|
|
168
|
+
payload: nextPayload,
|
|
169
|
+
channel: channel
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
exports.analyticsPlugin = analyticsPlugin;
|
|
176
|
+
function extendPayload(_ref6) {
|
|
177
|
+
var payload = _ref6.payload,
|
|
178
|
+
duration = _ref6.duration,
|
|
179
|
+
distortedDuration = _ref6.distortedDuration;
|
|
180
|
+
return _objectSpread(_objectSpread({}, payload), {}, {
|
|
181
|
+
attributes: _objectSpread(_objectSpread({}, payload.attributes), {}, {
|
|
182
|
+
duration: duration,
|
|
183
|
+
distortedDuration: distortedDuration
|
|
184
|
+
}),
|
|
185
|
+
eventType: _analytics.EVENT_TYPE.OPERATIONAL
|
|
186
|
+
});
|
|
187
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.generateUndoRedoInputSoucePayload = void 0;
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
10
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
11
|
+
var getUndoRedoInputSource = function getUndoRedoInputSource(tr) {
|
|
12
|
+
var _tr$getMeta;
|
|
13
|
+
// TODO: Please, do not copy or use this kind of code below
|
|
14
|
+
return (_tr$getMeta = tr.getMeta('undoRedoPlugin$')) !== null && _tr$getMeta !== void 0 ? _tr$getMeta : null;
|
|
15
|
+
};
|
|
16
|
+
var generateUndoRedoInputSoucePayload = function generateUndoRedoInputSoucePayload(tr) {
|
|
17
|
+
var undoRedoPluginInputSource = getUndoRedoInputSource(tr);
|
|
18
|
+
return function (payload) {
|
|
19
|
+
var shouldAddHistoryTriggerMethodAttribute = undoRedoPluginInputSource && ['undid', 'redid'].includes(payload.action);
|
|
20
|
+
return !shouldAddHistoryTriggerMethodAttribute ? payload : _objectSpread(_objectSpread({}, payload), {}, {
|
|
21
|
+
attributes: _objectSpread(_objectSpread({}, payload.attributes), {}, {
|
|
22
|
+
historyTriggerMethod: undoRedoPluginInputSource
|
|
23
|
+
})
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
exports.generateUndoRedoInputSoucePayload = generateUndoRedoInputSoucePayload;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { AnalyticsStep } from '@atlaskit/adf-schema/steps';
|
|
2
|
+
import { ACTION } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import { getStateContext } from './editor-state-context';
|
|
4
|
+
import { mapActionSubjectIdToAttributes } from './map-attributes';
|
|
5
|
+
const actionsToIgnore = [ACTION.INVOKED, ACTION.OPENED];
|
|
6
|
+
export const createAttachPayloadIntoTransaction = selection => ({
|
|
7
|
+
payload,
|
|
8
|
+
tr,
|
|
9
|
+
channel
|
|
10
|
+
}) => attachPayloadIntoTransaction({
|
|
11
|
+
payload,
|
|
12
|
+
selection,
|
|
13
|
+
tr,
|
|
14
|
+
channel
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// This utils was taken as reference in packages/editor/editor-plugin-ai/src/analytics/utils.ts
|
|
18
|
+
// to create new util attachPayloadIntoTransaction in above file.
|
|
19
|
+
// If you make a change here, please review attachPayloadIntoTransaction in above
|
|
20
|
+
// file and update it as well if needed.
|
|
21
|
+
export const attachPayloadIntoTransaction = ({
|
|
22
|
+
payload,
|
|
23
|
+
selection,
|
|
24
|
+
tr,
|
|
25
|
+
channel
|
|
26
|
+
}) => {
|
|
27
|
+
payload = getStateContext(selection, payload);
|
|
28
|
+
payload = mapActionSubjectIdToAttributes(payload);
|
|
29
|
+
const {
|
|
30
|
+
storedMarks
|
|
31
|
+
} = tr;
|
|
32
|
+
const pos = tr.mapping.map(selection.$from.pos, -1);
|
|
33
|
+
tr.step(new AnalyticsStep([{
|
|
34
|
+
payload,
|
|
35
|
+
channel
|
|
36
|
+
}], actionsToIgnore, pos) // We need to create the step based on a position, this prevent split history for relative changes.
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
// When you add a new step all the storedMarks are removed it
|
|
40
|
+
if (storedMarks) {
|
|
41
|
+
tr.setStoredMarks(storedMarks);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { NodeSelection } from 'prosemirror-state';
|
|
2
|
+
import { findParentNode } from 'prosemirror-utils';
|
|
3
|
+
import { ACTION, ACTION_SUBJECT, SELECTION_POSITION, SELECTION_TYPE } from '@atlaskit/editor-common/analytics';
|
|
4
|
+
import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
|
|
5
|
+
export function getSelectionType(selection) {
|
|
6
|
+
var _selection$constructo;
|
|
7
|
+
let type;
|
|
8
|
+
let position;
|
|
9
|
+
if ((selection === null || selection === void 0 ? void 0 : (_selection$constructo = selection.constructor) === null || _selection$constructo === void 0 ? void 0 : _selection$constructo.name) === 'GapCursorSelection') {
|
|
10
|
+
type = SELECTION_TYPE.GAP_CURSOR;
|
|
11
|
+
position = selection.side;
|
|
12
|
+
} else if (selection instanceof CellSelection) {
|
|
13
|
+
type = SELECTION_TYPE.CELL;
|
|
14
|
+
} else if (selection instanceof NodeSelection) {
|
|
15
|
+
type = SELECTION_TYPE.NODE;
|
|
16
|
+
} else if (selection.from !== selection.to) {
|
|
17
|
+
type = SELECTION_TYPE.RANGED;
|
|
18
|
+
} else {
|
|
19
|
+
type = SELECTION_TYPE.CURSOR;
|
|
20
|
+
const {
|
|
21
|
+
from,
|
|
22
|
+
$from
|
|
23
|
+
} = selection;
|
|
24
|
+
if (from === $from.start()) {
|
|
25
|
+
position = SELECTION_POSITION.START;
|
|
26
|
+
} else if (from === $from.end()) {
|
|
27
|
+
position = SELECTION_POSITION.END;
|
|
28
|
+
} else {
|
|
29
|
+
position = SELECTION_POSITION.MIDDLE;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
type,
|
|
34
|
+
position
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function findInsertLocation(selection) {
|
|
38
|
+
const {
|
|
39
|
+
schema,
|
|
40
|
+
name
|
|
41
|
+
} = selection.$from.doc.type;
|
|
42
|
+
if (selection instanceof NodeSelection) {
|
|
43
|
+
return selection.node.type.name;
|
|
44
|
+
}
|
|
45
|
+
if (selection instanceof CellSelection) {
|
|
46
|
+
return schema.nodes.table.name;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Text selection
|
|
50
|
+
const parentNodeInfo = findParentNode(node => node.type !== schema.nodes.paragraph)(selection);
|
|
51
|
+
return parentNodeInfo ? parentNodeInfo.node.type.name : name;
|
|
52
|
+
}
|
|
53
|
+
export function getStateContext(selection, payload) {
|
|
54
|
+
if (!payload.attributes) {
|
|
55
|
+
return payload;
|
|
56
|
+
}
|
|
57
|
+
const {
|
|
58
|
+
type,
|
|
59
|
+
position
|
|
60
|
+
} = getSelectionType(selection);
|
|
61
|
+
payload.attributes.selectionType = type;
|
|
62
|
+
if (position) {
|
|
63
|
+
payload.attributes.selectionPosition = position;
|
|
64
|
+
}
|
|
65
|
+
const insertLocation = findInsertLocation(selection);
|
|
66
|
+
if (payload.action === ACTION.INSERTED && payload.actionSubject === ACTION_SUBJECT.DOCUMENT && payload.attributes) {
|
|
67
|
+
payload.attributes.insertLocation = insertLocation;
|
|
68
|
+
} else {
|
|
69
|
+
payload.attributes.nodeLocation = insertLocation;
|
|
70
|
+
}
|
|
71
|
+
return payload;
|
|
72
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ACTION, ACTION_SUBJECT } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
export function mapActionSubjectIdToAttributes(payload) {
|
|
3
|
+
const documentInserted = payload.action === ACTION.INSERTED && payload.actionSubject === ACTION_SUBJECT.DOCUMENT;
|
|
4
|
+
const textFormatted = payload.action === ACTION.FORMATTED && payload.actionSubject === ACTION_SUBJECT.TEXT;
|
|
5
|
+
const hasActionSubjectId = !!payload.actionSubjectId;
|
|
6
|
+
if (hasActionSubjectId && (documentInserted || textFormatted)) {
|
|
7
|
+
payload.attributes = {
|
|
8
|
+
...payload.attributes,
|
|
9
|
+
// @ts-expect-error
|
|
10
|
+
actionSubjectId: payload.actionSubjectId
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
return payload;
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { analyticsPlugin } from './plugin';
|