@atlaskit/editor-plugin-metrics 3.2.1 → 3.2.3
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 +15 -0
- package/dist/cjs/pm-plugins/main.js +25 -8
- package/dist/cjs/pm-plugins/utils/analytics.js +2 -2
- package/dist/cjs/pm-plugins/utils/check-tr-action-type.js +160 -7
- package/dist/cjs/pm-plugins/utils/is-tr-with-doc-changes.js +14 -0
- package/dist/es2019/pm-plugins/main.js +27 -6
- package/dist/es2019/pm-plugins/utils/analytics.js +2 -2
- package/dist/es2019/pm-plugins/utils/check-tr-action-type.js +128 -9
- package/dist/es2019/pm-plugins/utils/is-tr-with-doc-changes.js +6 -0
- package/dist/esm/pm-plugins/main.js +25 -8
- package/dist/esm/pm-plugins/utils/analytics.js +2 -2
- package/dist/esm/pm-plugins/utils/check-tr-action-type.js +162 -9
- package/dist/esm/pm-plugins/utils/is-tr-with-doc-changes.js +8 -0
- package/dist/types/pm-plugins/main.d.ts +1 -0
- package/dist/types/pm-plugins/utils/check-tr-action-type.d.ts +25 -5
- package/dist/types/pm-plugins/utils/is-tr-with-doc-changes.d.ts +2 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +1 -0
- package/dist/types-ts4.5/pm-plugins/utils/check-tr-action-type.d.ts +25 -5
- package/dist/types-ts4.5/pm-plugins/utils/is-tr-with-doc-changes.d.ts +2 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-metrics
|
|
2
2
|
|
|
3
|
+
## 3.2.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#118316](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/118316)
|
|
8
|
+
[`642dc2d7b337a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/642dc2d7b337a) -
|
|
9
|
+
ED-26237 Update ease of use metrics to check nodeAttribute changes
|
|
10
|
+
- Updated dependencies
|
|
11
|
+
|
|
12
|
+
## 3.2.2
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
|
|
3
18
|
## 3.2.1
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
|
@@ -9,11 +9,11 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
|
|
|
9
9
|
var _bindEventListener = require("bind-event-listener");
|
|
10
10
|
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
11
11
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
12
|
-
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
13
12
|
var _activeSessionTimer = require("./utils/active-session-timer");
|
|
14
13
|
var _analytics = require("./utils/analytics");
|
|
15
14
|
var _checkTrActionType = require("./utils/check-tr-action-type");
|
|
16
15
|
var _isNonTextUndo = require("./utils/is-non-text-undo");
|
|
16
|
+
var _isTrWithDocChanges = require("./utils/is-tr-with-doc-changes");
|
|
17
17
|
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; }
|
|
18
18
|
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; }
|
|
19
19
|
var metricsKey = exports.metricsKey = new _state.PluginKey('metricsPlugin');
|
|
@@ -32,7 +32,8 @@ var initialPluginState = exports.initialPluginState = {
|
|
|
32
32
|
contentMovedCount: 0,
|
|
33
33
|
nodeDeletionCount: 0,
|
|
34
34
|
undoCount: 0
|
|
35
|
-
}
|
|
35
|
+
},
|
|
36
|
+
repeatedActionCount: 0
|
|
36
37
|
};
|
|
37
38
|
var createPlugin = exports.createPlugin = function createPlugin(api) {
|
|
38
39
|
var timer = new _activeSessionTimer.ActiveSessionTimer(api);
|
|
@@ -46,7 +47,7 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
|
|
|
46
47
|
},
|
|
47
48
|
// eslint-disable-next-line @typescript-eslint/max-params
|
|
48
49
|
apply: function apply(tr, pluginState, oldState, newState) {
|
|
49
|
-
var _meta$shouldPersistAc
|
|
50
|
+
var _meta$shouldPersistAc;
|
|
50
51
|
if (tr.getMeta('isRemote') || tr.getMeta('replaceDocument')) {
|
|
51
52
|
return pluginState;
|
|
52
53
|
}
|
|
@@ -59,9 +60,7 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
|
|
|
59
60
|
});
|
|
60
61
|
}
|
|
61
62
|
var shouldPersistActiveSession = (_meta$shouldPersistAc = meta === null || meta === void 0 ? void 0 : meta.shouldPersistActiveSession) !== null && _meta$shouldPersistAc !== void 0 ? _meta$shouldPersistAc : pluginState.shouldPersistActiveSession;
|
|
62
|
-
var hasDocChanges =
|
|
63
|
-
return step instanceof _transform.ReplaceStep || step instanceof _transform.ReplaceAroundStep || step instanceof _transform.AddMarkStep;
|
|
64
|
-
}));
|
|
63
|
+
var hasDocChanges = (0, _isTrWithDocChanges.isTrWithDocChanges)(tr);
|
|
65
64
|
var intentToStartEditTime = (meta === null || meta === void 0 ? void 0 : meta.intentToStartEditTime) || pluginState.intentToStartEditTime;
|
|
66
65
|
var now = performance.now();
|
|
67
66
|
if (!intentToStartEditTime && !hasDocChanges && !tr.storedMarksSet) {
|
|
@@ -121,17 +120,35 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
|
|
|
121
120
|
if (timeOfLastTextInput && isTextInput && previousTrType && [_checkTrActionType.ActionType.TEXT_INPUT, _checkTrActionType.ActionType.EMPTY_LINE_ADDED_OR_DELETED, _checkTrActionType.ActionType.UPDATING_NEW_LIST_TYPE_ITEM, _checkTrActionType.ActionType.INSERTING_NEW_LIST_TYPE_NODE].includes(previousTrType.type)) {
|
|
122
121
|
newTextInputCount = actionTypeCount.textInputCount;
|
|
123
122
|
}
|
|
123
|
+
var newNodeAttrCount = actionTypeCount.nodeAttributeChangeCount;
|
|
124
|
+
var newRepeatedActionCount = pluginState.repeatedActionCount;
|
|
125
|
+
if ((trType === null || trType === void 0 ? void 0 : trType.type) === _checkTrActionType.ActionType.CHANGING_ATTRS) {
|
|
126
|
+
newNodeAttrCount = newNodeAttrCount + 1;
|
|
127
|
+
if ((previousTrType === null || previousTrType === void 0 ? void 0 : previousTrType.type) === _checkTrActionType.ActionType.CHANGING_ATTRS) {
|
|
128
|
+
var _trType$extraData2 = trType.extraData,
|
|
129
|
+
newAttr = _trType$extraData2.attr,
|
|
130
|
+
newFrom = _trType$extraData2.from,
|
|
131
|
+
newTo = _trType$extraData2.to;
|
|
132
|
+
var _previousTrType$extra2 = previousTrType.extraData,
|
|
133
|
+
prevAttr = _previousTrType$extra2.attr,
|
|
134
|
+
prevFrom = _previousTrType$extra2.from,
|
|
135
|
+
prevTo = _previousTrType$extra2.to;
|
|
136
|
+
newRepeatedActionCount = newAttr === prevAttr && newFrom === prevFrom && newTo === prevTo ? newRepeatedActionCount + 1 : newRepeatedActionCount;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
124
139
|
var newPluginState = _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
125
140
|
activeSessionTime: now - intentToStartEditTime,
|
|
126
141
|
totalActionCount: newTotalActionCount,
|
|
127
142
|
timeOfLastTextInput: shouldSetTimeOfLastTextInput ? now : undefined,
|
|
128
143
|
contentSizeChanged: pluginState.contentSizeChanged + (newState.doc.content.size - oldState.doc.content.size),
|
|
129
144
|
actionTypeCount: _objectSpread(_objectSpread({}, newActionTypeCount), {}, {
|
|
130
|
-
textInputCount: newTextInputCount
|
|
145
|
+
textInputCount: newTextInputCount,
|
|
146
|
+
nodeAttributeChangeCount: newNodeAttrCount
|
|
131
147
|
}),
|
|
132
148
|
intentToStartEditTime: intentToStartEditTime,
|
|
133
149
|
shouldPersistActiveSession: shouldPersistActiveSession,
|
|
134
|
-
previousTrType: trType
|
|
150
|
+
previousTrType: trType,
|
|
151
|
+
repeatedActionCount: newRepeatedActionCount
|
|
135
152
|
});
|
|
136
153
|
return newPluginState;
|
|
137
154
|
}
|
|
@@ -22,7 +22,7 @@ var getPayloadAttributes = exports.getPayloadAttributes = function getPayloadAtt
|
|
|
22
22
|
},
|
|
23
23
|
effectiveness: {
|
|
24
24
|
undoCount: pluginState.actionTypeCount.undoCount,
|
|
25
|
-
repeatedActionCount:
|
|
25
|
+
repeatedActionCount: pluginState.repeatedActionCount,
|
|
26
26
|
safeInsertCount: 0
|
|
27
27
|
},
|
|
28
28
|
contentSizeChanged: contentSizeChanged
|
|
@@ -63,7 +63,7 @@ var getAnalyticsPayload = exports.getAnalyticsPayload = function getAnalyticsPay
|
|
|
63
63
|
},
|
|
64
64
|
effectiveness: {
|
|
65
65
|
undoCount: pluginState.actionTypeCount.undoCount,
|
|
66
|
-
repeatedActionCount:
|
|
66
|
+
repeatedActionCount: pluginState.repeatedActionCount,
|
|
67
67
|
safeInsertCount: 0
|
|
68
68
|
},
|
|
69
69
|
contentSizeChanged: pluginState.contentSizeChanged
|
|
@@ -6,8 +6,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
});
|
|
7
7
|
exports.shouldSkipTr = exports.checkTrActionType = exports.ActionType = void 0;
|
|
8
8
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
10
|
var _steps = require("@atlaskit/adf-schema/steps");
|
|
10
11
|
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
12
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, 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 o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
13
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
14
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
11
15
|
var ActionType = exports.ActionType = /*#__PURE__*/function (ActionType) {
|
|
12
16
|
ActionType["TEXT_INPUT"] = "textInput";
|
|
13
17
|
ActionType["EMPTY_LINE_ADDED_OR_DELETED"] = "emptyLineAddedOrDeleted";
|
|
@@ -16,6 +20,8 @@ var ActionType = exports.ActionType = /*#__PURE__*/function (ActionType) {
|
|
|
16
20
|
ActionType["UPDATING_NEW_LIST_TYPE_ITEM"] = "updatingNewListItem";
|
|
17
21
|
ActionType["ADDING_LINK"] = "addingLink";
|
|
18
22
|
ActionType["UPDATING_STATUS"] = "updatingStatus";
|
|
23
|
+
ActionType["CHANGING_MARK"] = "changingMark";
|
|
24
|
+
ActionType["CHANGING_ATTRS"] = "changingAttrs";
|
|
19
25
|
return ActionType;
|
|
20
26
|
}({});
|
|
21
27
|
var isTextInput = function isTextInput(step) {
|
|
@@ -43,20 +49,104 @@ var isEmptyLineAddedOrDeleted = function isEmptyLineAddedOrDeleted(step) {
|
|
|
43
49
|
});
|
|
44
50
|
return isEmptyLineAdded;
|
|
45
51
|
};
|
|
52
|
+
var compareAttributes = function compareAttributes(prevAttr, newAttr) {
|
|
53
|
+
var allKeys = new Set([].concat((0, _toConsumableArray2.default)(Object.keys(prevAttr)), (0, _toConsumableArray2.default)(Object.keys(newAttr))));
|
|
54
|
+
var _iterator = _createForOfIteratorHelper(allKeys),
|
|
55
|
+
_step;
|
|
56
|
+
try {
|
|
57
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
58
|
+
var key = _step.value;
|
|
59
|
+
var prevValue = prevAttr[key];
|
|
60
|
+
var newValue = newAttr[key];
|
|
61
|
+
if (prevValue !== newValue) {
|
|
62
|
+
return key;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
} catch (err) {
|
|
66
|
+
_iterator.e(err);
|
|
67
|
+
} finally {
|
|
68
|
+
_iterator.f();
|
|
69
|
+
}
|
|
70
|
+
return undefined;
|
|
71
|
+
};
|
|
72
|
+
var compareMarks = function compareMarks(prevMarks, newMarks) {
|
|
73
|
+
if (!prevMarks && !newMarks) {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
var previousMarksArr = new Map(prevMarks.map(function (mark) {
|
|
77
|
+
return [mark.type.name, mark.attrs];
|
|
78
|
+
}));
|
|
79
|
+
var newMarksArr = new Map(newMarks.map(function (mark) {
|
|
80
|
+
return [mark.type.name, mark.attrs];
|
|
81
|
+
}));
|
|
82
|
+
var allMarks = new Set([].concat((0, _toConsumableArray2.default)(previousMarksArr.keys()), (0, _toConsumableArray2.default)(newMarksArr.keys())));
|
|
83
|
+
var _iterator2 = _createForOfIteratorHelper(allMarks),
|
|
84
|
+
_step2;
|
|
85
|
+
try {
|
|
86
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
87
|
+
var key = _step2.value;
|
|
88
|
+
var previousValue = previousMarksArr.get(key);
|
|
89
|
+
var newValue = newMarksArr.get(key);
|
|
90
|
+
if (JSON.stringify(previousValue) !== JSON.stringify(newValue)) {
|
|
91
|
+
return key;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
} catch (err) {
|
|
95
|
+
_iterator2.e(err);
|
|
96
|
+
} finally {
|
|
97
|
+
_iterator2.f();
|
|
98
|
+
}
|
|
99
|
+
return undefined;
|
|
100
|
+
};
|
|
101
|
+
var detectNodeAttributeChange = function detectNodeAttributeChange(tr, step) {
|
|
102
|
+
var from = step.from,
|
|
103
|
+
slice = step.slice,
|
|
104
|
+
to = step.to;
|
|
105
|
+
var oldNode = tr.docs[0].nodeAt(from);
|
|
106
|
+
var newNode = slice.content.firstChild;
|
|
107
|
+
if (!oldNode || !newNode) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
var changedAttr = compareAttributes(oldNode.attrs, newNode.attrs);
|
|
111
|
+
if (changedAttr) {
|
|
112
|
+
return {
|
|
113
|
+
attr: changedAttr,
|
|
114
|
+
from: from,
|
|
115
|
+
to: to
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
var changedMarks = compareMarks(oldNode.marks, newNode.marks);
|
|
119
|
+
if (changedMarks) {
|
|
120
|
+
return {
|
|
121
|
+
attr: changedMarks,
|
|
122
|
+
from: from,
|
|
123
|
+
to: to
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
return undefined;
|
|
127
|
+
};
|
|
46
128
|
var isUpdatingListTypeNode = function isUpdatingListTypeNode(step) {
|
|
47
129
|
var slice = step.slice;
|
|
48
130
|
var childCount = slice.content.childCount;
|
|
49
131
|
if (childCount < 1) {
|
|
50
132
|
return false;
|
|
51
133
|
}
|
|
52
|
-
var
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
134
|
+
var _iterator3 = _createForOfIteratorHelper(slice.content.content),
|
|
135
|
+
_step3;
|
|
136
|
+
try {
|
|
137
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
138
|
+
var node = _step3.value;
|
|
139
|
+
var isListTypeNode = ['decisionList', 'decisionItem', 'bulletList', 'listItem', 'orderedList', 'taskList', 'taskItem'].includes(node.type.name);
|
|
140
|
+
if (isListTypeNode) {
|
|
141
|
+
return childCount === 1 ? ActionType.INSERTING_NEW_LIST_TYPE_NODE : ActionType.UPDATING_NEW_LIST_TYPE_ITEM;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
} catch (err) {
|
|
145
|
+
_iterator3.e(err);
|
|
146
|
+
} finally {
|
|
147
|
+
_iterator3.f();
|
|
58
148
|
}
|
|
59
|
-
return
|
|
149
|
+
return false;
|
|
60
150
|
};
|
|
61
151
|
var isUpdatingStatus = function isUpdatingStatus(step) {
|
|
62
152
|
var slice = step.slice;
|
|
@@ -106,6 +196,45 @@ var shouldSkipTr = exports.shouldSkipTr = function shouldSkipTr(tr) {
|
|
|
106
196
|
return tr.getMeta('appendedTransaction');
|
|
107
197
|
}
|
|
108
198
|
};
|
|
199
|
+
var isResizingColumns = function isResizingColumns(tr) {
|
|
200
|
+
var COL_WIDTH_ATTR = 'colwidth';
|
|
201
|
+
var steps = tr.steps;
|
|
202
|
+
var resizingColumnStep = steps.find(function (step) {
|
|
203
|
+
return step instanceof _transform.AttrStep || step instanceof _steps.BatchAttrsStep;
|
|
204
|
+
});
|
|
205
|
+
if (!resizingColumnStep) {
|
|
206
|
+
return undefined;
|
|
207
|
+
}
|
|
208
|
+
var pos;
|
|
209
|
+
|
|
210
|
+
// BatchAttrsStep is used for resizing columns in tables
|
|
211
|
+
if (resizingColumnStep instanceof _steps.BatchAttrsStep) {
|
|
212
|
+
var _resizingColumnStep$d = resizingColumnStep.data[0],
|
|
213
|
+
attrs = _resizingColumnStep$d.attrs,
|
|
214
|
+
nodeType = _resizingColumnStep$d.nodeType,
|
|
215
|
+
position = _resizingColumnStep$d.position;
|
|
216
|
+
if (['tableHeader', 'tableCell'].includes(nodeType) && attrs !== null && attrs !== void 0 && attrs[COL_WIDTH_ATTR]) {
|
|
217
|
+
pos = position;
|
|
218
|
+
}
|
|
219
|
+
} else if (resizingColumnStep instanceof _transform.AttrStep && resizingColumnStep.attr === COL_WIDTH_ATTR) {
|
|
220
|
+
pos = resizingColumnStep.pos;
|
|
221
|
+
}
|
|
222
|
+
if (!pos) {
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
var $pos = tr.doc.resolve(pos);
|
|
226
|
+
var blockRange = $pos.blockRange();
|
|
227
|
+
if (!blockRange) {
|
|
228
|
+
return undefined;
|
|
229
|
+
}
|
|
230
|
+
var from = blockRange.start;
|
|
231
|
+
var to = from + blockRange.parent.content.size;
|
|
232
|
+
return {
|
|
233
|
+
attr: COL_WIDTH_ATTR,
|
|
234
|
+
from: from,
|
|
235
|
+
to: to
|
|
236
|
+
};
|
|
237
|
+
};
|
|
109
238
|
var checkTrActionType = exports.checkTrActionType = function checkTrActionType(tr) {
|
|
110
239
|
if (tr.getMeta('input_rule_plugin_transaction')) {
|
|
111
240
|
return {
|
|
@@ -121,10 +250,27 @@ var checkTrActionType = exports.checkTrActionType = function checkTrActionType(t
|
|
|
121
250
|
type: ActionType.ADDING_LINK
|
|
122
251
|
};
|
|
123
252
|
}
|
|
253
|
+
var isResizingCol = isResizingColumns(tr);
|
|
254
|
+
if (isResizingCol) {
|
|
255
|
+
return {
|
|
256
|
+
type: ActionType.CHANGING_ATTRS,
|
|
257
|
+
extraData: isResizingCol
|
|
258
|
+
};
|
|
259
|
+
}
|
|
124
260
|
var _tr$steps = (0, _slicedToArray2.default)(tr.steps, 1),
|
|
125
261
|
firstStep = _tr$steps[0];
|
|
126
262
|
var isReplaceStep = firstStep instanceof _transform.ReplaceStep;
|
|
127
263
|
var isReplaceAroundStep = firstStep instanceof _transform.ReplaceAroundStep;
|
|
264
|
+
if (firstStep instanceof _transform.AddMarkStep || firstStep instanceof _transform.RemoveMarkStep) {
|
|
265
|
+
return {
|
|
266
|
+
type: ActionType.CHANGING_MARK,
|
|
267
|
+
extraData: {
|
|
268
|
+
markType: firstStep.mark.type.name,
|
|
269
|
+
from: firstStep.from,
|
|
270
|
+
to: firstStep.to
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
}
|
|
128
274
|
if (!isReplaceStep && !isReplaceAroundStep) {
|
|
129
275
|
return undefined;
|
|
130
276
|
}
|
|
@@ -155,5 +301,12 @@ var checkTrActionType = exports.checkTrActionType = function checkTrActionType(t
|
|
|
155
301
|
type: updatingListTypeNode
|
|
156
302
|
};
|
|
157
303
|
}
|
|
304
|
+
var nodeAttributeChange = detectNodeAttributeChange(tr, firstStep);
|
|
305
|
+
if (nodeAttributeChange) {
|
|
306
|
+
return {
|
|
307
|
+
type: ActionType.CHANGING_ATTRS,
|
|
308
|
+
extraData: nodeAttributeChange
|
|
309
|
+
};
|
|
310
|
+
}
|
|
158
311
|
return undefined;
|
|
159
312
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isTrWithDocChanges = void 0;
|
|
7
|
+
var _steps = require("@atlaskit/adf-schema/steps");
|
|
8
|
+
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
9
|
+
var isTrWithDocChanges = exports.isTrWithDocChanges = function isTrWithDocChanges(tr) {
|
|
10
|
+
var _tr$steps;
|
|
11
|
+
return tr.steps.length > 0 && ((_tr$steps = tr.steps) === null || _tr$steps === void 0 ? void 0 : _tr$steps.some(function (step) {
|
|
12
|
+
return step instanceof _transform.ReplaceStep || step instanceof _transform.ReplaceAroundStep || step instanceof _transform.AddMarkStep || step instanceof _transform.AttrStep || step instanceof _transform.RemoveMarkStep || step instanceof _steps.BatchAttrsStep;
|
|
13
|
+
}));
|
|
14
|
+
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { bind } from 'bind-event-listener';
|
|
2
2
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
3
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
4
|
-
import { AddMarkStep, ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
5
4
|
import { ActiveSessionTimer } from './utils/active-session-timer';
|
|
6
5
|
import { getAnalyticsPayload } from './utils/analytics';
|
|
7
6
|
import { ActionType, checkTrActionType, shouldSkipTr } from './utils/check-tr-action-type';
|
|
8
7
|
import { isNonTextUndo } from './utils/is-non-text-undo';
|
|
8
|
+
import { isTrWithDocChanges } from './utils/is-tr-with-doc-changes';
|
|
9
9
|
export const metricsKey = new PluginKey('metricsPlugin');
|
|
10
10
|
export const initialPluginState = {
|
|
11
11
|
intentToStartEditTime: undefined,
|
|
@@ -22,7 +22,8 @@ export const initialPluginState = {
|
|
|
22
22
|
contentMovedCount: 0,
|
|
23
23
|
nodeDeletionCount: 0,
|
|
24
24
|
undoCount: 0
|
|
25
|
-
}
|
|
25
|
+
},
|
|
26
|
+
repeatedActionCount: 0
|
|
26
27
|
};
|
|
27
28
|
export const createPlugin = api => {
|
|
28
29
|
const timer = new ActiveSessionTimer(api);
|
|
@@ -37,7 +38,7 @@ export const createPlugin = api => {
|
|
|
37
38
|
},
|
|
38
39
|
// eslint-disable-next-line @typescript-eslint/max-params
|
|
39
40
|
apply(tr, pluginState, oldState, newState) {
|
|
40
|
-
var _meta$shouldPersistAc
|
|
41
|
+
var _meta$shouldPersistAc;
|
|
41
42
|
if (tr.getMeta('isRemote') || tr.getMeta('replaceDocument')) {
|
|
42
43
|
return pluginState;
|
|
43
44
|
}
|
|
@@ -51,7 +52,7 @@ export const createPlugin = api => {
|
|
|
51
52
|
};
|
|
52
53
|
}
|
|
53
54
|
const shouldPersistActiveSession = (_meta$shouldPersistAc = meta === null || meta === void 0 ? void 0 : meta.shouldPersistActiveSession) !== null && _meta$shouldPersistAc !== void 0 ? _meta$shouldPersistAc : pluginState.shouldPersistActiveSession;
|
|
54
|
-
const hasDocChanges =
|
|
55
|
+
const hasDocChanges = isTrWithDocChanges(tr);
|
|
55
56
|
let intentToStartEditTime = (meta === null || meta === void 0 ? void 0 : meta.intentToStartEditTime) || pluginState.intentToStartEditTime;
|
|
56
57
|
const now = performance.now();
|
|
57
58
|
if (!intentToStartEditTime && !hasDocChanges && !tr.storedMarksSet) {
|
|
@@ -115,6 +116,24 @@ export const createPlugin = api => {
|
|
|
115
116
|
if (timeOfLastTextInput && isTextInput && previousTrType && [ActionType.TEXT_INPUT, ActionType.EMPTY_LINE_ADDED_OR_DELETED, ActionType.UPDATING_NEW_LIST_TYPE_ITEM, ActionType.INSERTING_NEW_LIST_TYPE_NODE].includes(previousTrType.type)) {
|
|
116
117
|
newTextInputCount = actionTypeCount.textInputCount;
|
|
117
118
|
}
|
|
119
|
+
let newNodeAttrCount = actionTypeCount.nodeAttributeChangeCount;
|
|
120
|
+
let newRepeatedActionCount = pluginState.repeatedActionCount;
|
|
121
|
+
if ((trType === null || trType === void 0 ? void 0 : trType.type) === ActionType.CHANGING_ATTRS) {
|
|
122
|
+
newNodeAttrCount = newNodeAttrCount + 1;
|
|
123
|
+
if ((previousTrType === null || previousTrType === void 0 ? void 0 : previousTrType.type) === ActionType.CHANGING_ATTRS) {
|
|
124
|
+
const {
|
|
125
|
+
attr: newAttr,
|
|
126
|
+
from: newFrom,
|
|
127
|
+
to: newTo
|
|
128
|
+
} = trType.extraData;
|
|
129
|
+
const {
|
|
130
|
+
attr: prevAttr,
|
|
131
|
+
from: prevFrom,
|
|
132
|
+
to: prevTo
|
|
133
|
+
} = previousTrType.extraData;
|
|
134
|
+
newRepeatedActionCount = newAttr === prevAttr && newFrom === prevFrom && newTo === prevTo ? newRepeatedActionCount + 1 : newRepeatedActionCount;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
118
137
|
const newPluginState = {
|
|
119
138
|
...pluginState,
|
|
120
139
|
activeSessionTime: now - intentToStartEditTime,
|
|
@@ -123,11 +142,13 @@ export const createPlugin = api => {
|
|
|
123
142
|
contentSizeChanged: pluginState.contentSizeChanged + (newState.doc.content.size - oldState.doc.content.size),
|
|
124
143
|
actionTypeCount: {
|
|
125
144
|
...newActionTypeCount,
|
|
126
|
-
textInputCount: newTextInputCount
|
|
145
|
+
textInputCount: newTextInputCount,
|
|
146
|
+
nodeAttributeChangeCount: newNodeAttrCount
|
|
127
147
|
},
|
|
128
148
|
intentToStartEditTime,
|
|
129
149
|
shouldPersistActiveSession,
|
|
130
|
-
previousTrType: trType
|
|
150
|
+
previousTrType: trType,
|
|
151
|
+
repeatedActionCount: newRepeatedActionCount
|
|
131
152
|
};
|
|
132
153
|
return newPluginState;
|
|
133
154
|
}
|
|
@@ -11,7 +11,7 @@ export const getPayloadAttributes = ({
|
|
|
11
11
|
},
|
|
12
12
|
effectiveness: {
|
|
13
13
|
undoCount: pluginState.actionTypeCount.undoCount,
|
|
14
|
-
repeatedActionCount:
|
|
14
|
+
repeatedActionCount: pluginState.repeatedActionCount,
|
|
15
15
|
safeInsertCount: 0
|
|
16
16
|
},
|
|
17
17
|
contentSizeChanged
|
|
@@ -50,7 +50,7 @@ export const getAnalyticsPayload = ({
|
|
|
50
50
|
},
|
|
51
51
|
effectiveness: {
|
|
52
52
|
undoCount: pluginState.actionTypeCount.undoCount,
|
|
53
|
-
repeatedActionCount:
|
|
53
|
+
repeatedActionCount: pluginState.repeatedActionCount,
|
|
54
54
|
safeInsertCount: 0
|
|
55
55
|
},
|
|
56
56
|
contentSizeChanged: pluginState.contentSizeChanged
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { InsertTypeAheadStep, LinkMetaStep } from '@atlaskit/adf-schema/steps';
|
|
2
|
-
import { ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
1
|
+
import { BatchAttrsStep, InsertTypeAheadStep, LinkMetaStep } from '@atlaskit/adf-schema/steps';
|
|
2
|
+
import { AddMarkStep, AttrStep, RemoveMarkStep, ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
3
3
|
export let ActionType = /*#__PURE__*/function (ActionType) {
|
|
4
4
|
ActionType["TEXT_INPUT"] = "textInput";
|
|
5
5
|
ActionType["EMPTY_LINE_ADDED_OR_DELETED"] = "emptyLineAddedOrDeleted";
|
|
@@ -8,6 +8,8 @@ export let ActionType = /*#__PURE__*/function (ActionType) {
|
|
|
8
8
|
ActionType["UPDATING_NEW_LIST_TYPE_ITEM"] = "updatingNewListItem";
|
|
9
9
|
ActionType["ADDING_LINK"] = "addingLink";
|
|
10
10
|
ActionType["UPDATING_STATUS"] = "updatingStatus";
|
|
11
|
+
ActionType["CHANGING_MARK"] = "changingMark";
|
|
12
|
+
ActionType["CHANGING_ATTRS"] = "changingAttrs";
|
|
11
13
|
return ActionType;
|
|
12
14
|
}({});
|
|
13
15
|
const isTextInput = step => {
|
|
@@ -41,6 +43,62 @@ const isEmptyLineAddedOrDeleted = step => {
|
|
|
41
43
|
});
|
|
42
44
|
return isEmptyLineAdded;
|
|
43
45
|
};
|
|
46
|
+
const compareAttributes = (prevAttr, newAttr) => {
|
|
47
|
+
const allKeys = new Set([...Object.keys(prevAttr), ...Object.keys(newAttr)]);
|
|
48
|
+
for (const key of allKeys) {
|
|
49
|
+
const prevValue = prevAttr[key];
|
|
50
|
+
const newValue = newAttr[key];
|
|
51
|
+
if (prevValue !== newValue) {
|
|
52
|
+
return key;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
};
|
|
57
|
+
const compareMarks = (prevMarks, newMarks) => {
|
|
58
|
+
if (!prevMarks && !newMarks) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
const previousMarksArr = new Map(prevMarks.map(mark => [mark.type.name, mark.attrs]));
|
|
62
|
+
const newMarksArr = new Map(newMarks.map(mark => [mark.type.name, mark.attrs]));
|
|
63
|
+
const allMarks = new Set([...previousMarksArr.keys(), ...newMarksArr.keys()]);
|
|
64
|
+
for (const key of allMarks) {
|
|
65
|
+
const previousValue = previousMarksArr.get(key);
|
|
66
|
+
const newValue = newMarksArr.get(key);
|
|
67
|
+
if (JSON.stringify(previousValue) !== JSON.stringify(newValue)) {
|
|
68
|
+
return key;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
};
|
|
73
|
+
const detectNodeAttributeChange = (tr, step) => {
|
|
74
|
+
const {
|
|
75
|
+
from,
|
|
76
|
+
slice,
|
|
77
|
+
to
|
|
78
|
+
} = step;
|
|
79
|
+
const oldNode = tr.docs[0].nodeAt(from);
|
|
80
|
+
const newNode = slice.content.firstChild;
|
|
81
|
+
if (!oldNode || !newNode) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const changedAttr = compareAttributes(oldNode.attrs, newNode.attrs);
|
|
85
|
+
if (changedAttr) {
|
|
86
|
+
return {
|
|
87
|
+
attr: changedAttr,
|
|
88
|
+
from,
|
|
89
|
+
to
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
const changedMarks = compareMarks(oldNode.marks, newNode.marks);
|
|
93
|
+
if (changedMarks) {
|
|
94
|
+
return {
|
|
95
|
+
attr: changedMarks,
|
|
96
|
+
from,
|
|
97
|
+
to
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return undefined;
|
|
101
|
+
};
|
|
44
102
|
const isUpdatingListTypeNode = step => {
|
|
45
103
|
const {
|
|
46
104
|
slice
|
|
@@ -49,14 +107,13 @@ const isUpdatingListTypeNode = step => {
|
|
|
49
107
|
if (childCount < 1) {
|
|
50
108
|
return false;
|
|
51
109
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return false;
|
|
110
|
+
for (const node of slice.content.content) {
|
|
111
|
+
const isListTypeNode = ['decisionList', 'decisionItem', 'bulletList', 'listItem', 'orderedList', 'taskList', 'taskItem'].includes(node.type.name);
|
|
112
|
+
if (isListTypeNode) {
|
|
113
|
+
return childCount === 1 ? ActionType.INSERTING_NEW_LIST_TYPE_NODE : ActionType.UPDATING_NEW_LIST_TYPE_ITEM;
|
|
114
|
+
}
|
|
58
115
|
}
|
|
59
|
-
return
|
|
116
|
+
return false;
|
|
60
117
|
};
|
|
61
118
|
const isUpdatingStatus = step => {
|
|
62
119
|
const {
|
|
@@ -100,6 +157,44 @@ export const shouldSkipTr = tr => {
|
|
|
100
157
|
return tr.getMeta('appendedTransaction');
|
|
101
158
|
}
|
|
102
159
|
};
|
|
160
|
+
const isResizingColumns = tr => {
|
|
161
|
+
const COL_WIDTH_ATTR = 'colwidth';
|
|
162
|
+
const steps = tr.steps;
|
|
163
|
+
const resizingColumnStep = steps.find(step => step instanceof AttrStep || step instanceof BatchAttrsStep);
|
|
164
|
+
if (!resizingColumnStep) {
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
let pos;
|
|
168
|
+
|
|
169
|
+
// BatchAttrsStep is used for resizing columns in tables
|
|
170
|
+
if (resizingColumnStep instanceof BatchAttrsStep) {
|
|
171
|
+
const {
|
|
172
|
+
attrs,
|
|
173
|
+
nodeType,
|
|
174
|
+
position
|
|
175
|
+
} = resizingColumnStep.data[0];
|
|
176
|
+
if (['tableHeader', 'tableCell'].includes(nodeType) && attrs !== null && attrs !== void 0 && attrs[COL_WIDTH_ATTR]) {
|
|
177
|
+
pos = position;
|
|
178
|
+
}
|
|
179
|
+
} else if (resizingColumnStep instanceof AttrStep && resizingColumnStep.attr === COL_WIDTH_ATTR) {
|
|
180
|
+
pos = resizingColumnStep.pos;
|
|
181
|
+
}
|
|
182
|
+
if (!pos) {
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
const $pos = tr.doc.resolve(pos);
|
|
186
|
+
const blockRange = $pos.blockRange();
|
|
187
|
+
if (!blockRange) {
|
|
188
|
+
return undefined;
|
|
189
|
+
}
|
|
190
|
+
const from = blockRange.start;
|
|
191
|
+
const to = from + blockRange.parent.content.size;
|
|
192
|
+
return {
|
|
193
|
+
attr: COL_WIDTH_ATTR,
|
|
194
|
+
from,
|
|
195
|
+
to
|
|
196
|
+
};
|
|
197
|
+
};
|
|
103
198
|
export const checkTrActionType = tr => {
|
|
104
199
|
if (tr.getMeta('input_rule_plugin_transaction')) {
|
|
105
200
|
return {
|
|
@@ -115,9 +210,26 @@ export const checkTrActionType = tr => {
|
|
|
115
210
|
type: ActionType.ADDING_LINK
|
|
116
211
|
};
|
|
117
212
|
}
|
|
213
|
+
const isResizingCol = isResizingColumns(tr);
|
|
214
|
+
if (isResizingCol) {
|
|
215
|
+
return {
|
|
216
|
+
type: ActionType.CHANGING_ATTRS,
|
|
217
|
+
extraData: isResizingCol
|
|
218
|
+
};
|
|
219
|
+
}
|
|
118
220
|
const [firstStep] = tr.steps;
|
|
119
221
|
const isReplaceStep = firstStep instanceof ReplaceStep;
|
|
120
222
|
const isReplaceAroundStep = firstStep instanceof ReplaceAroundStep;
|
|
223
|
+
if (firstStep instanceof AddMarkStep || firstStep instanceof RemoveMarkStep) {
|
|
224
|
+
return {
|
|
225
|
+
type: ActionType.CHANGING_MARK,
|
|
226
|
+
extraData: {
|
|
227
|
+
markType: firstStep.mark.type.name,
|
|
228
|
+
from: firstStep.from,
|
|
229
|
+
to: firstStep.to
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
}
|
|
121
233
|
if (!isReplaceStep && !isReplaceAroundStep) {
|
|
122
234
|
return undefined;
|
|
123
235
|
}
|
|
@@ -148,5 +260,12 @@ export const checkTrActionType = tr => {
|
|
|
148
260
|
type: updatingListTypeNode
|
|
149
261
|
};
|
|
150
262
|
}
|
|
263
|
+
const nodeAttributeChange = detectNodeAttributeChange(tr, firstStep);
|
|
264
|
+
if (nodeAttributeChange) {
|
|
265
|
+
return {
|
|
266
|
+
type: ActionType.CHANGING_ATTRS,
|
|
267
|
+
extraData: nodeAttributeChange
|
|
268
|
+
};
|
|
269
|
+
}
|
|
151
270
|
return undefined;
|
|
152
271
|
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { BatchAttrsStep } from '@atlaskit/adf-schema/steps';
|
|
2
|
+
import { AddMarkStep, AttrStep, RemoveMarkStep, ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
3
|
+
export const isTrWithDocChanges = tr => {
|
|
4
|
+
var _tr$steps;
|
|
5
|
+
return tr.steps.length > 0 && ((_tr$steps = tr.steps) === null || _tr$steps === void 0 ? void 0 : _tr$steps.some(step => step instanceof ReplaceStep || step instanceof ReplaceAroundStep || step instanceof AddMarkStep || step instanceof AttrStep || step instanceof RemoveMarkStep || step instanceof BatchAttrsStep));
|
|
6
|
+
};
|
|
@@ -4,11 +4,11 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
4
4
|
import { bind } from 'bind-event-listener';
|
|
5
5
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
6
6
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
7
|
-
import { AddMarkStep, ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
8
7
|
import { ActiveSessionTimer } from './utils/active-session-timer';
|
|
9
8
|
import { getAnalyticsPayload } from './utils/analytics';
|
|
10
9
|
import { ActionType, checkTrActionType, shouldSkipTr } from './utils/check-tr-action-type';
|
|
11
10
|
import { isNonTextUndo } from './utils/is-non-text-undo';
|
|
11
|
+
import { isTrWithDocChanges } from './utils/is-tr-with-doc-changes';
|
|
12
12
|
export var metricsKey = new PluginKey('metricsPlugin');
|
|
13
13
|
export var initialPluginState = {
|
|
14
14
|
intentToStartEditTime: undefined,
|
|
@@ -25,7 +25,8 @@ export var initialPluginState = {
|
|
|
25
25
|
contentMovedCount: 0,
|
|
26
26
|
nodeDeletionCount: 0,
|
|
27
27
|
undoCount: 0
|
|
28
|
-
}
|
|
28
|
+
},
|
|
29
|
+
repeatedActionCount: 0
|
|
29
30
|
};
|
|
30
31
|
export var createPlugin = function createPlugin(api) {
|
|
31
32
|
var timer = new ActiveSessionTimer(api);
|
|
@@ -39,7 +40,7 @@ export var createPlugin = function createPlugin(api) {
|
|
|
39
40
|
},
|
|
40
41
|
// eslint-disable-next-line @typescript-eslint/max-params
|
|
41
42
|
apply: function apply(tr, pluginState, oldState, newState) {
|
|
42
|
-
var _meta$shouldPersistAc
|
|
43
|
+
var _meta$shouldPersistAc;
|
|
43
44
|
if (tr.getMeta('isRemote') || tr.getMeta('replaceDocument')) {
|
|
44
45
|
return pluginState;
|
|
45
46
|
}
|
|
@@ -52,9 +53,7 @@ export var createPlugin = function createPlugin(api) {
|
|
|
52
53
|
});
|
|
53
54
|
}
|
|
54
55
|
var shouldPersistActiveSession = (_meta$shouldPersistAc = meta === null || meta === void 0 ? void 0 : meta.shouldPersistActiveSession) !== null && _meta$shouldPersistAc !== void 0 ? _meta$shouldPersistAc : pluginState.shouldPersistActiveSession;
|
|
55
|
-
var hasDocChanges =
|
|
56
|
-
return step instanceof ReplaceStep || step instanceof ReplaceAroundStep || step instanceof AddMarkStep;
|
|
57
|
-
}));
|
|
56
|
+
var hasDocChanges = isTrWithDocChanges(tr);
|
|
58
57
|
var intentToStartEditTime = (meta === null || meta === void 0 ? void 0 : meta.intentToStartEditTime) || pluginState.intentToStartEditTime;
|
|
59
58
|
var now = performance.now();
|
|
60
59
|
if (!intentToStartEditTime && !hasDocChanges && !tr.storedMarksSet) {
|
|
@@ -114,17 +113,35 @@ export var createPlugin = function createPlugin(api) {
|
|
|
114
113
|
if (timeOfLastTextInput && isTextInput && previousTrType && [ActionType.TEXT_INPUT, ActionType.EMPTY_LINE_ADDED_OR_DELETED, ActionType.UPDATING_NEW_LIST_TYPE_ITEM, ActionType.INSERTING_NEW_LIST_TYPE_NODE].includes(previousTrType.type)) {
|
|
115
114
|
newTextInputCount = actionTypeCount.textInputCount;
|
|
116
115
|
}
|
|
116
|
+
var newNodeAttrCount = actionTypeCount.nodeAttributeChangeCount;
|
|
117
|
+
var newRepeatedActionCount = pluginState.repeatedActionCount;
|
|
118
|
+
if ((trType === null || trType === void 0 ? void 0 : trType.type) === ActionType.CHANGING_ATTRS) {
|
|
119
|
+
newNodeAttrCount = newNodeAttrCount + 1;
|
|
120
|
+
if ((previousTrType === null || previousTrType === void 0 ? void 0 : previousTrType.type) === ActionType.CHANGING_ATTRS) {
|
|
121
|
+
var _trType$extraData2 = trType.extraData,
|
|
122
|
+
newAttr = _trType$extraData2.attr,
|
|
123
|
+
newFrom = _trType$extraData2.from,
|
|
124
|
+
newTo = _trType$extraData2.to;
|
|
125
|
+
var _previousTrType$extra2 = previousTrType.extraData,
|
|
126
|
+
prevAttr = _previousTrType$extra2.attr,
|
|
127
|
+
prevFrom = _previousTrType$extra2.from,
|
|
128
|
+
prevTo = _previousTrType$extra2.to;
|
|
129
|
+
newRepeatedActionCount = newAttr === prevAttr && newFrom === prevFrom && newTo === prevTo ? newRepeatedActionCount + 1 : newRepeatedActionCount;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
117
132
|
var newPluginState = _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
118
133
|
activeSessionTime: now - intentToStartEditTime,
|
|
119
134
|
totalActionCount: newTotalActionCount,
|
|
120
135
|
timeOfLastTextInput: shouldSetTimeOfLastTextInput ? now : undefined,
|
|
121
136
|
contentSizeChanged: pluginState.contentSizeChanged + (newState.doc.content.size - oldState.doc.content.size),
|
|
122
137
|
actionTypeCount: _objectSpread(_objectSpread({}, newActionTypeCount), {}, {
|
|
123
|
-
textInputCount: newTextInputCount
|
|
138
|
+
textInputCount: newTextInputCount,
|
|
139
|
+
nodeAttributeChangeCount: newNodeAttrCount
|
|
124
140
|
}),
|
|
125
141
|
intentToStartEditTime: intentToStartEditTime,
|
|
126
142
|
shouldPersistActiveSession: shouldPersistActiveSession,
|
|
127
|
-
previousTrType: trType
|
|
143
|
+
previousTrType: trType,
|
|
144
|
+
repeatedActionCount: newRepeatedActionCount
|
|
128
145
|
});
|
|
129
146
|
return newPluginState;
|
|
130
147
|
}
|
|
@@ -15,7 +15,7 @@ export var getPayloadAttributes = function getPayloadAttributes(_ref) {
|
|
|
15
15
|
},
|
|
16
16
|
effectiveness: {
|
|
17
17
|
undoCount: pluginState.actionTypeCount.undoCount,
|
|
18
|
-
repeatedActionCount:
|
|
18
|
+
repeatedActionCount: pluginState.repeatedActionCount,
|
|
19
19
|
safeInsertCount: 0
|
|
20
20
|
},
|
|
21
21
|
contentSizeChanged: contentSizeChanged
|
|
@@ -56,7 +56,7 @@ export var getAnalyticsPayload = function getAnalyticsPayload(_ref2) {
|
|
|
56
56
|
},
|
|
57
57
|
effectiveness: {
|
|
58
58
|
undoCount: pluginState.actionTypeCount.undoCount,
|
|
59
|
-
repeatedActionCount:
|
|
59
|
+
repeatedActionCount: pluginState.repeatedActionCount,
|
|
60
60
|
safeInsertCount: 0
|
|
61
61
|
},
|
|
62
62
|
contentSizeChanged: pluginState.contentSizeChanged
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
-
import
|
|
3
|
-
|
|
2
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
3
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, 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 o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
4
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
5
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
6
|
+
import { BatchAttrsStep, InsertTypeAheadStep, LinkMetaStep } from '@atlaskit/adf-schema/steps';
|
|
7
|
+
import { AddMarkStep, AttrStep, RemoveMarkStep, ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
4
8
|
export var ActionType = /*#__PURE__*/function (ActionType) {
|
|
5
9
|
ActionType["TEXT_INPUT"] = "textInput";
|
|
6
10
|
ActionType["EMPTY_LINE_ADDED_OR_DELETED"] = "emptyLineAddedOrDeleted";
|
|
@@ -9,6 +13,8 @@ export var ActionType = /*#__PURE__*/function (ActionType) {
|
|
|
9
13
|
ActionType["UPDATING_NEW_LIST_TYPE_ITEM"] = "updatingNewListItem";
|
|
10
14
|
ActionType["ADDING_LINK"] = "addingLink";
|
|
11
15
|
ActionType["UPDATING_STATUS"] = "updatingStatus";
|
|
16
|
+
ActionType["CHANGING_MARK"] = "changingMark";
|
|
17
|
+
ActionType["CHANGING_ATTRS"] = "changingAttrs";
|
|
12
18
|
return ActionType;
|
|
13
19
|
}({});
|
|
14
20
|
var isTextInput = function isTextInput(step) {
|
|
@@ -36,20 +42,104 @@ var isEmptyLineAddedOrDeleted = function isEmptyLineAddedOrDeleted(step) {
|
|
|
36
42
|
});
|
|
37
43
|
return isEmptyLineAdded;
|
|
38
44
|
};
|
|
45
|
+
var compareAttributes = function compareAttributes(prevAttr, newAttr) {
|
|
46
|
+
var allKeys = new Set([].concat(_toConsumableArray(Object.keys(prevAttr)), _toConsumableArray(Object.keys(newAttr))));
|
|
47
|
+
var _iterator = _createForOfIteratorHelper(allKeys),
|
|
48
|
+
_step;
|
|
49
|
+
try {
|
|
50
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
51
|
+
var key = _step.value;
|
|
52
|
+
var prevValue = prevAttr[key];
|
|
53
|
+
var newValue = newAttr[key];
|
|
54
|
+
if (prevValue !== newValue) {
|
|
55
|
+
return key;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
} catch (err) {
|
|
59
|
+
_iterator.e(err);
|
|
60
|
+
} finally {
|
|
61
|
+
_iterator.f();
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
};
|
|
65
|
+
var compareMarks = function compareMarks(prevMarks, newMarks) {
|
|
66
|
+
if (!prevMarks && !newMarks) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
var previousMarksArr = new Map(prevMarks.map(function (mark) {
|
|
70
|
+
return [mark.type.name, mark.attrs];
|
|
71
|
+
}));
|
|
72
|
+
var newMarksArr = new Map(newMarks.map(function (mark) {
|
|
73
|
+
return [mark.type.name, mark.attrs];
|
|
74
|
+
}));
|
|
75
|
+
var allMarks = new Set([].concat(_toConsumableArray(previousMarksArr.keys()), _toConsumableArray(newMarksArr.keys())));
|
|
76
|
+
var _iterator2 = _createForOfIteratorHelper(allMarks),
|
|
77
|
+
_step2;
|
|
78
|
+
try {
|
|
79
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
80
|
+
var key = _step2.value;
|
|
81
|
+
var previousValue = previousMarksArr.get(key);
|
|
82
|
+
var newValue = newMarksArr.get(key);
|
|
83
|
+
if (JSON.stringify(previousValue) !== JSON.stringify(newValue)) {
|
|
84
|
+
return key;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
} catch (err) {
|
|
88
|
+
_iterator2.e(err);
|
|
89
|
+
} finally {
|
|
90
|
+
_iterator2.f();
|
|
91
|
+
}
|
|
92
|
+
return undefined;
|
|
93
|
+
};
|
|
94
|
+
var detectNodeAttributeChange = function detectNodeAttributeChange(tr, step) {
|
|
95
|
+
var from = step.from,
|
|
96
|
+
slice = step.slice,
|
|
97
|
+
to = step.to;
|
|
98
|
+
var oldNode = tr.docs[0].nodeAt(from);
|
|
99
|
+
var newNode = slice.content.firstChild;
|
|
100
|
+
if (!oldNode || !newNode) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
var changedAttr = compareAttributes(oldNode.attrs, newNode.attrs);
|
|
104
|
+
if (changedAttr) {
|
|
105
|
+
return {
|
|
106
|
+
attr: changedAttr,
|
|
107
|
+
from: from,
|
|
108
|
+
to: to
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
var changedMarks = compareMarks(oldNode.marks, newNode.marks);
|
|
112
|
+
if (changedMarks) {
|
|
113
|
+
return {
|
|
114
|
+
attr: changedMarks,
|
|
115
|
+
from: from,
|
|
116
|
+
to: to
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return undefined;
|
|
120
|
+
};
|
|
39
121
|
var isUpdatingListTypeNode = function isUpdatingListTypeNode(step) {
|
|
40
122
|
var slice = step.slice;
|
|
41
123
|
var childCount = slice.content.childCount;
|
|
42
124
|
if (childCount < 1) {
|
|
43
125
|
return false;
|
|
44
126
|
}
|
|
45
|
-
var
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
127
|
+
var _iterator3 = _createForOfIteratorHelper(slice.content.content),
|
|
128
|
+
_step3;
|
|
129
|
+
try {
|
|
130
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
131
|
+
var node = _step3.value;
|
|
132
|
+
var isListTypeNode = ['decisionList', 'decisionItem', 'bulletList', 'listItem', 'orderedList', 'taskList', 'taskItem'].includes(node.type.name);
|
|
133
|
+
if (isListTypeNode) {
|
|
134
|
+
return childCount === 1 ? ActionType.INSERTING_NEW_LIST_TYPE_NODE : ActionType.UPDATING_NEW_LIST_TYPE_ITEM;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
} catch (err) {
|
|
138
|
+
_iterator3.e(err);
|
|
139
|
+
} finally {
|
|
140
|
+
_iterator3.f();
|
|
51
141
|
}
|
|
52
|
-
return
|
|
142
|
+
return false;
|
|
53
143
|
};
|
|
54
144
|
var isUpdatingStatus = function isUpdatingStatus(step) {
|
|
55
145
|
var slice = step.slice;
|
|
@@ -99,6 +189,45 @@ export var shouldSkipTr = function shouldSkipTr(tr) {
|
|
|
99
189
|
return tr.getMeta('appendedTransaction');
|
|
100
190
|
}
|
|
101
191
|
};
|
|
192
|
+
var isResizingColumns = function isResizingColumns(tr) {
|
|
193
|
+
var COL_WIDTH_ATTR = 'colwidth';
|
|
194
|
+
var steps = tr.steps;
|
|
195
|
+
var resizingColumnStep = steps.find(function (step) {
|
|
196
|
+
return step instanceof AttrStep || step instanceof BatchAttrsStep;
|
|
197
|
+
});
|
|
198
|
+
if (!resizingColumnStep) {
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
var pos;
|
|
202
|
+
|
|
203
|
+
// BatchAttrsStep is used for resizing columns in tables
|
|
204
|
+
if (resizingColumnStep instanceof BatchAttrsStep) {
|
|
205
|
+
var _resizingColumnStep$d = resizingColumnStep.data[0],
|
|
206
|
+
attrs = _resizingColumnStep$d.attrs,
|
|
207
|
+
nodeType = _resizingColumnStep$d.nodeType,
|
|
208
|
+
position = _resizingColumnStep$d.position;
|
|
209
|
+
if (['tableHeader', 'tableCell'].includes(nodeType) && attrs !== null && attrs !== void 0 && attrs[COL_WIDTH_ATTR]) {
|
|
210
|
+
pos = position;
|
|
211
|
+
}
|
|
212
|
+
} else if (resizingColumnStep instanceof AttrStep && resizingColumnStep.attr === COL_WIDTH_ATTR) {
|
|
213
|
+
pos = resizingColumnStep.pos;
|
|
214
|
+
}
|
|
215
|
+
if (!pos) {
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
218
|
+
var $pos = tr.doc.resolve(pos);
|
|
219
|
+
var blockRange = $pos.blockRange();
|
|
220
|
+
if (!blockRange) {
|
|
221
|
+
return undefined;
|
|
222
|
+
}
|
|
223
|
+
var from = blockRange.start;
|
|
224
|
+
var to = from + blockRange.parent.content.size;
|
|
225
|
+
return {
|
|
226
|
+
attr: COL_WIDTH_ATTR,
|
|
227
|
+
from: from,
|
|
228
|
+
to: to
|
|
229
|
+
};
|
|
230
|
+
};
|
|
102
231
|
export var checkTrActionType = function checkTrActionType(tr) {
|
|
103
232
|
if (tr.getMeta('input_rule_plugin_transaction')) {
|
|
104
233
|
return {
|
|
@@ -114,10 +243,27 @@ export var checkTrActionType = function checkTrActionType(tr) {
|
|
|
114
243
|
type: ActionType.ADDING_LINK
|
|
115
244
|
};
|
|
116
245
|
}
|
|
246
|
+
var isResizingCol = isResizingColumns(tr);
|
|
247
|
+
if (isResizingCol) {
|
|
248
|
+
return {
|
|
249
|
+
type: ActionType.CHANGING_ATTRS,
|
|
250
|
+
extraData: isResizingCol
|
|
251
|
+
};
|
|
252
|
+
}
|
|
117
253
|
var _tr$steps = _slicedToArray(tr.steps, 1),
|
|
118
254
|
firstStep = _tr$steps[0];
|
|
119
255
|
var isReplaceStep = firstStep instanceof ReplaceStep;
|
|
120
256
|
var isReplaceAroundStep = firstStep instanceof ReplaceAroundStep;
|
|
257
|
+
if (firstStep instanceof AddMarkStep || firstStep instanceof RemoveMarkStep) {
|
|
258
|
+
return {
|
|
259
|
+
type: ActionType.CHANGING_MARK,
|
|
260
|
+
extraData: {
|
|
261
|
+
markType: firstStep.mark.type.name,
|
|
262
|
+
from: firstStep.from,
|
|
263
|
+
to: firstStep.to
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
}
|
|
121
267
|
if (!isReplaceStep && !isReplaceAroundStep) {
|
|
122
268
|
return undefined;
|
|
123
269
|
}
|
|
@@ -148,5 +294,12 @@ export var checkTrActionType = function checkTrActionType(tr) {
|
|
|
148
294
|
type: updatingListTypeNode
|
|
149
295
|
};
|
|
150
296
|
}
|
|
297
|
+
var nodeAttributeChange = detectNodeAttributeChange(tr, firstStep);
|
|
298
|
+
if (nodeAttributeChange) {
|
|
299
|
+
return {
|
|
300
|
+
type: ActionType.CHANGING_ATTRS,
|
|
301
|
+
extraData: nodeAttributeChange
|
|
302
|
+
};
|
|
303
|
+
}
|
|
151
304
|
return undefined;
|
|
152
305
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BatchAttrsStep } from '@atlaskit/adf-schema/steps';
|
|
2
|
+
import { AddMarkStep, AttrStep, RemoveMarkStep, ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
3
|
+
export var isTrWithDocChanges = function isTrWithDocChanges(tr) {
|
|
4
|
+
var _tr$steps;
|
|
5
|
+
return tr.steps.length > 0 && ((_tr$steps = tr.steps) === null || _tr$steps === void 0 ? void 0 : _tr$steps.some(function (step) {
|
|
6
|
+
return step instanceof ReplaceStep || step instanceof ReplaceAroundStep || step instanceof AddMarkStep || step instanceof AttrStep || step instanceof RemoveMarkStep || step instanceof BatchAttrsStep;
|
|
7
|
+
}));
|
|
8
|
+
};
|
|
@@ -6,13 +6,33 @@ export declare enum ActionType {
|
|
|
6
6
|
INSERTING_NEW_LIST_TYPE_NODE = "insertingNewListTypeNode",
|
|
7
7
|
UPDATING_NEW_LIST_TYPE_ITEM = "updatingNewListItem",
|
|
8
8
|
ADDING_LINK = "addingLink",
|
|
9
|
-
UPDATING_STATUS = "updatingStatus"
|
|
9
|
+
UPDATING_STATUS = "updatingStatus",
|
|
10
|
+
CHANGING_MARK = "changingMark",
|
|
11
|
+
CHANGING_ATTRS = "changingAttrs"
|
|
10
12
|
}
|
|
11
|
-
|
|
13
|
+
type AttrChangeActionData = {
|
|
14
|
+
attr: string;
|
|
15
|
+
from: number;
|
|
16
|
+
to: number;
|
|
17
|
+
};
|
|
12
18
|
export type TrActionType = {
|
|
13
|
-
type: ActionType;
|
|
14
|
-
extraData
|
|
15
|
-
statusId
|
|
19
|
+
type: ActionType.UPDATING_STATUS;
|
|
20
|
+
extraData: {
|
|
21
|
+
statusId: string;
|
|
22
|
+
};
|
|
23
|
+
} | {
|
|
24
|
+
type: ActionType.CHANGING_MARK;
|
|
25
|
+
extraData: {
|
|
26
|
+
markType: string;
|
|
27
|
+
from: number;
|
|
28
|
+
to: number;
|
|
16
29
|
};
|
|
30
|
+
} | {
|
|
31
|
+
type: ActionType.CHANGING_ATTRS;
|
|
32
|
+
extraData: AttrChangeActionData;
|
|
33
|
+
} | {
|
|
34
|
+
type: Exclude<ActionType, ActionType.CHANGING_ATTRS | ActionType.CHANGING_MARK | ActionType.UPDATING_STATUS>;
|
|
17
35
|
} | undefined;
|
|
36
|
+
export declare const shouldSkipTr: (tr: ReadonlyTransaction) => boolean;
|
|
18
37
|
export declare const checkTrActionType: (tr: ReadonlyTransaction) => TrActionType;
|
|
38
|
+
export {};
|
|
@@ -6,13 +6,33 @@ export declare enum ActionType {
|
|
|
6
6
|
INSERTING_NEW_LIST_TYPE_NODE = "insertingNewListTypeNode",
|
|
7
7
|
UPDATING_NEW_LIST_TYPE_ITEM = "updatingNewListItem",
|
|
8
8
|
ADDING_LINK = "addingLink",
|
|
9
|
-
UPDATING_STATUS = "updatingStatus"
|
|
9
|
+
UPDATING_STATUS = "updatingStatus",
|
|
10
|
+
CHANGING_MARK = "changingMark",
|
|
11
|
+
CHANGING_ATTRS = "changingAttrs"
|
|
10
12
|
}
|
|
11
|
-
|
|
13
|
+
type AttrChangeActionData = {
|
|
14
|
+
attr: string;
|
|
15
|
+
from: number;
|
|
16
|
+
to: number;
|
|
17
|
+
};
|
|
12
18
|
export type TrActionType = {
|
|
13
|
-
type: ActionType;
|
|
14
|
-
extraData
|
|
15
|
-
statusId
|
|
19
|
+
type: ActionType.UPDATING_STATUS;
|
|
20
|
+
extraData: {
|
|
21
|
+
statusId: string;
|
|
22
|
+
};
|
|
23
|
+
} | {
|
|
24
|
+
type: ActionType.CHANGING_MARK;
|
|
25
|
+
extraData: {
|
|
26
|
+
markType: string;
|
|
27
|
+
from: number;
|
|
28
|
+
to: number;
|
|
16
29
|
};
|
|
30
|
+
} | {
|
|
31
|
+
type: ActionType.CHANGING_ATTRS;
|
|
32
|
+
extraData: AttrChangeActionData;
|
|
33
|
+
} | {
|
|
34
|
+
type: Exclude<ActionType, ActionType.CHANGING_ATTRS | ActionType.CHANGING_MARK | ActionType.UPDATING_STATUS>;
|
|
17
35
|
} | undefined;
|
|
36
|
+
export declare const shouldSkipTr: (tr: ReadonlyTransaction) => boolean;
|
|
18
37
|
export declare const checkTrActionType: (tr: ReadonlyTransaction) => TrActionType;
|
|
38
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-metrics",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.3",
|
|
4
4
|
"description": "Metrics plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@atlaskit/adf-schema": "^47.2.1",
|
|
28
|
-
"@atlaskit/editor-common": "^
|
|
29
|
-
"@atlaskit/editor-plugin-analytics": "^
|
|
30
|
-
"@atlaskit/editor-plugin-block-controls": "^
|
|
28
|
+
"@atlaskit/editor-common": "^100.2.0",
|
|
29
|
+
"@atlaskit/editor-plugin-analytics": "^2.0.0",
|
|
30
|
+
"@atlaskit/editor-plugin-block-controls": "^3.1.0",
|
|
31
31
|
"@atlaskit/editor-prosemirror": "7.0.0",
|
|
32
32
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
33
33
|
"@babel/runtime": "^7.0.0",
|