@atlaskit/editor-plugin-selection 2.0.7 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/dist/cjs/pm-plugins/commands.js +55 -22
- package/dist/cjs/pm-plugins/gap-cursor/utils/place-gap-cursor.js +0 -2
- package/dist/cjs/pm-plugins/keymap.js +6 -0
- package/dist/cjs/pm-plugins/selection-analytics.js +74 -0
- package/dist/cjs/selectionPlugin.js +9 -1
- package/dist/es2019/pm-plugins/commands.js +35 -0
- package/dist/es2019/pm-plugins/gap-cursor/utils/place-gap-cursor.js +0 -2
- package/dist/es2019/pm-plugins/keymap.js +8 -2
- package/dist/es2019/pm-plugins/selection-analytics.js +64 -0
- package/dist/es2019/selectionPlugin.js +8 -1
- package/dist/esm/pm-plugins/commands.js +33 -0
- package/dist/esm/pm-plugins/gap-cursor/utils/place-gap-cursor.js +0 -2
- package/dist/esm/pm-plugins/keymap.js +8 -2
- package/dist/esm/pm-plugins/selection-analytics.js +67 -0
- package/dist/esm/selectionPlugin.js +9 -1
- package/dist/types/pm-plugins/commands.d.ts +1 -0
- package/dist/types/pm-plugins/selection-analytics.d.ts +10 -0
- package/dist/types-ts4.5/pm-plugins/commands.d.ts +1 -0
- package/dist/types-ts4.5/pm-plugins/selection-analytics.d.ts +10 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-selection
|
|
2
2
|
|
|
3
|
+
## 2.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#124688](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/124688)
|
|
8
|
+
[`9b1137bda6f87`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/9b1137bda6f87) -
|
|
9
|
+
[ux] ED-25486 Updates cmd+a behaviour to progressively select nodes behind
|
|
10
|
+
platform_editor_cmd_a_progressively_select_nodes experiment.
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies
|
|
15
|
+
|
|
3
16
|
## 2.0.7
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.setSelectionRelativeToNode = exports.setSelectionInsideAtNodeEnd = exports.selectNearNode = exports.arrowRight = exports.arrowLeft = void 0;
|
|
6
|
+
exports.setSelectionRelativeToNode = exports.setSelectionInsideAtNodeEnd = exports.selectNodeWithModA = exports.selectNearNode = exports.arrowRight = exports.arrowLeft = void 0;
|
|
7
7
|
var _selection = require("@atlaskit/editor-common/selection");
|
|
8
8
|
var _utils = require("@atlaskit/editor-common/utils");
|
|
9
9
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
10
|
+
var _utils2 = require("@atlaskit/editor-tables/utils");
|
|
10
11
|
var _types = require("../types");
|
|
11
12
|
var _actions = require("./actions");
|
|
12
13
|
var _pluginFactory = require("./plugin-factory");
|
|
13
|
-
var
|
|
14
|
+
var _utils3 = require("./utils");
|
|
14
15
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
15
16
|
|
|
16
17
|
var selectNearNode = exports.selectNearNode = function selectNearNode(selectionRelativeToNode, selection) {
|
|
@@ -64,12 +65,12 @@ var arrowRightFromGapCursor = function arrowRightFromGapCursor(selection) {
|
|
|
64
65
|
$to = selection.$to,
|
|
65
66
|
side = selection.side;
|
|
66
67
|
if (side === _selection.Side.LEFT) {
|
|
67
|
-
var selectableNode = (0,
|
|
68
|
+
var selectableNode = (0, _utils3.findSelectableContainerAfter)($to, state.doc);
|
|
68
69
|
if (selectableNode) {
|
|
69
70
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.Start, _state.NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
|
|
70
71
|
}
|
|
71
|
-
} else if (side === _selection.Side.RIGHT && (0,
|
|
72
|
-
var _selectableNode = (0,
|
|
72
|
+
} else if (side === _selection.Side.RIGHT && (0, _utils3.isSelectionAtEndOfParentNode)($from, selection)) {
|
|
73
|
+
var _selectableNode = (0, _utils3.findSelectableContainerParent)(selection);
|
|
73
74
|
if (_selectableNode) {
|
|
74
75
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.End, _state.NodeSelection.create(state.doc, _selectableNode.pos))(state, dispatch);
|
|
75
76
|
}
|
|
@@ -84,15 +85,15 @@ var arrowLeftFromGapCursor = function arrowLeftFromGapCursor(selection) {
|
|
|
84
85
|
var _getPluginState = (0, _pluginFactory.getPluginState)(state),
|
|
85
86
|
selectionRelativeToNode = _getPluginState.selectionRelativeToNode;
|
|
86
87
|
if (side === _selection.Side.RIGHT) {
|
|
87
|
-
var selectableNode = (0,
|
|
88
|
+
var selectableNode = (0, _utils3.findSelectableContainerBefore)($from, state.doc);
|
|
88
89
|
if (selectableNode) {
|
|
89
90
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.End, _state.NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
|
|
90
91
|
}
|
|
91
|
-
} else if (side === _selection.Side.LEFT && (0,
|
|
92
|
+
} else if (side === _selection.Side.LEFT && (0, _utils3.isSelectionAtStartOfParentNode)($from, selection)) {
|
|
92
93
|
if (selectionRelativeToNode === _selection.RelativeSelectionPos.Before) {
|
|
93
94
|
var $parent = state.doc.resolve(selection.$from.before(selection.$from.depth));
|
|
94
95
|
if ($parent) {
|
|
95
|
-
var _selectableNode2 = (0,
|
|
96
|
+
var _selectableNode2 = (0, _utils3.findSelectableContainerBefore)($parent, state.doc);
|
|
96
97
|
if (_selectableNode2 && (0, _selection.isIgnored)(_selectableNode2.node)) {
|
|
97
98
|
// selection is inside node without gap cursor preceeded by another node without gap cursor - set node selection for previous node
|
|
98
99
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.End, _state.NodeSelection.create(state.doc, _selectableNode2.pos))(state, dispatch);
|
|
@@ -102,7 +103,7 @@ var arrowLeftFromGapCursor = function arrowLeftFromGapCursor(selection) {
|
|
|
102
103
|
// from responding to arrow left key
|
|
103
104
|
setSelectionRelativeToNode()(state, dispatch);
|
|
104
105
|
} else {
|
|
105
|
-
var _selectableNode3 = (0,
|
|
106
|
+
var _selectableNode3 = (0, _utils3.findSelectableContainerParent)(selection);
|
|
106
107
|
if (_selectableNode3) {
|
|
107
108
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.Start, _state.NodeSelection.create(state.doc, _selectableNode3.pos))(state, dispatch);
|
|
108
109
|
}
|
|
@@ -119,7 +120,7 @@ var arrowRightFromNode = function arrowRightFromNode(selection) {
|
|
|
119
120
|
var _getPluginState2 = (0, _pluginFactory.getPluginState)(state),
|
|
120
121
|
selectionRelativeToNode = _getPluginState2.selectionRelativeToNode;
|
|
121
122
|
if (node.isAtom) {
|
|
122
|
-
if ((0,
|
|
123
|
+
if ((0, _utils3.isSelectionAtEndOfParentNode)($to, selection) && (node.isInline || (0, _selection.isIgnored)(node))) {
|
|
123
124
|
// selection is for inline node or atom node which is ignored by gap-cursor and that is the last child of its parent node - set text selection after it
|
|
124
125
|
return findAndSetTextSelection(_selection.RelativeSelectionPos.End, state.doc.resolve(from + 1), _types.SelectionDirection.After)(state, dispatch);
|
|
125
126
|
}
|
|
@@ -128,7 +129,7 @@ var arrowRightFromNode = function arrowRightFromNode(selection) {
|
|
|
128
129
|
// selection is for container node - set selection inside it at the start
|
|
129
130
|
return setSelectionInsideAtNodeStart(_selection.RelativeSelectionPos.Inside, node, from)(state, dispatch);
|
|
130
131
|
} else if ((0, _selection.isIgnored)(node) && (!selectionRelativeToNode || selectionRelativeToNode === _selection.RelativeSelectionPos.End)) {
|
|
131
|
-
var selectableNode = (0,
|
|
132
|
+
var selectableNode = (0, _utils3.findSelectableContainerAfter)($to, state.doc);
|
|
132
133
|
if (selectableNode && (0, _selection.isIgnored)(selectableNode.node)) {
|
|
133
134
|
// selection is for node without gap cursor followed by another node without gap cursor - set node selection for next node
|
|
134
135
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.Start, _state.NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
|
|
@@ -146,7 +147,7 @@ var arrowLeftFromNode = function arrowLeftFromNode(selection) {
|
|
|
146
147
|
var _getPluginState3 = (0, _pluginFactory.getPluginState)(state),
|
|
147
148
|
selectionRelativeToNode = _getPluginState3.selectionRelativeToNode;
|
|
148
149
|
if (node.isAtom) {
|
|
149
|
-
if ((0,
|
|
150
|
+
if ((0, _utils3.isSelectionAtStartOfParentNode)($from, selection) && (node.isInline || (0, _selection.isIgnored)(node))) {
|
|
150
151
|
// selection is for inline node or atom node which is ignored by gap-cursor and that is the first child of its parent node - set text selection before it
|
|
151
152
|
return findAndSetTextSelection(_selection.RelativeSelectionPos.Start, state.doc.resolve(from), _types.SelectionDirection.Before)(state, dispatch);
|
|
152
153
|
}
|
|
@@ -160,7 +161,7 @@ var arrowLeftFromNode = function arrowLeftFromNode(selection) {
|
|
|
160
161
|
return setSelectionInsideAtNodeStart(_selection.RelativeSelectionPos.Before, node, from)(state, dispatch);
|
|
161
162
|
} else if ((0, _selection.isIgnored)(node) && selectionRelativeToNode === _selection.RelativeSelectionPos.Start) {
|
|
162
163
|
// selection is for node without gap cursor preceeded by another node without gap cursor - set node selection for previous node
|
|
163
|
-
var selectableNode = (0,
|
|
164
|
+
var selectableNode = (0, _utils3.findSelectableContainerBefore)($from, state.doc);
|
|
164
165
|
if (selectableNode && (0, _selection.isIgnored)(selectableNode.node)) {
|
|
165
166
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.End, _state.NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
|
|
166
167
|
}
|
|
@@ -170,8 +171,8 @@ var arrowLeftFromNode = function arrowLeftFromNode(selection) {
|
|
|
170
171
|
};
|
|
171
172
|
var arrowRightFromText = function arrowRightFromText(selection) {
|
|
172
173
|
return function (state, dispatch) {
|
|
173
|
-
if ((0,
|
|
174
|
-
var selectableNode = (0,
|
|
174
|
+
if ((0, _utils3.isSelectionAtEndOfParentNode)(selection.$to, selection)) {
|
|
175
|
+
var selectableNode = (0, _utils3.findSelectableContainerParent)(selection);
|
|
175
176
|
if (selectableNode) {
|
|
176
177
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.End, _state.NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
|
|
177
178
|
}
|
|
@@ -184,7 +185,7 @@ var arrowLeftFromText = function arrowLeftFromText(selection) {
|
|
|
184
185
|
var _getPluginState4 = (0, _pluginFactory.getPluginState)(state),
|
|
185
186
|
selectionRelativeToNode = _getPluginState4.selectionRelativeToNode;
|
|
186
187
|
if (selectionRelativeToNode === _selection.RelativeSelectionPos.Before) {
|
|
187
|
-
var selectableNode = (0,
|
|
188
|
+
var selectableNode = (0, _utils3.findSelectableContainerBefore)(selection.$from, state.doc);
|
|
188
189
|
if (selectableNode && (0, _selection.isIgnored)(selectableNode.node)) {
|
|
189
190
|
// selection is inside node without gap cursor preceeded by another node without gap cursor - set node selection for previous node
|
|
190
191
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.End, _state.NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
|
|
@@ -192,8 +193,8 @@ var arrowLeftFromText = function arrowLeftFromText(selection) {
|
|
|
192
193
|
// we don't return this as we want to reset the relative pos, but not block other plugins
|
|
193
194
|
// from responding to arrow left key
|
|
194
195
|
setSelectionRelativeToNode(undefined)(state, dispatch);
|
|
195
|
-
} else if ((0,
|
|
196
|
-
var _selectableNode4 = (0,
|
|
196
|
+
} else if ((0, _utils3.isSelectionAtStartOfParentNode)(selection.$from, selection)) {
|
|
197
|
+
var _selectableNode4 = (0, _utils3.findSelectableContainerParent)(selection);
|
|
197
198
|
if (_selectableNode4) {
|
|
198
199
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.Start, _state.NodeSelection.create(state.doc, _selectableNode4.pos))(state, dispatch);
|
|
199
200
|
}
|
|
@@ -215,7 +216,7 @@ var setSelectionInsideAtNodeStart = function setSelectionInsideAtNodeStart(selec
|
|
|
215
216
|
if ((0, _utils.isNodeEmpty)(node)) {
|
|
216
217
|
return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(pos), _types.SelectionDirection.After)(state, dispatch);
|
|
217
218
|
}
|
|
218
|
-
var selectableNode = (0,
|
|
219
|
+
var selectableNode = (0, _utils3.findFirstChildNodeToSelect)(node);
|
|
219
220
|
if (selectableNode) {
|
|
220
221
|
var childNode = selectableNode.node,
|
|
221
222
|
childPos = selectableNode.pos;
|
|
@@ -227,7 +228,7 @@ var setSelectionInsideAtNodeStart = function setSelectionInsideAtNodeStart(selec
|
|
|
227
228
|
return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos + 1), _types.SelectionDirection.Before)(state, dispatch);
|
|
228
229
|
} else if (!(0, _selection.isIgnored)(node)) {
|
|
229
230
|
return setSelectionRelativeToNode(selectionRelativeToNode, new _selection.GapCursorSelection(state.doc.resolve(selectionPos), _selection.Side.LEFT))(state, dispatch);
|
|
230
|
-
} else if ((0,
|
|
231
|
+
} else if ((0, _utils3.isSelectableContainerNode)(node)) {
|
|
231
232
|
return setSelectionRelativeToNode(selectionRelativeToNode, _state.NodeSelection.create(state.doc, selectionPos))(state, dispatch);
|
|
232
233
|
}
|
|
233
234
|
}
|
|
@@ -239,7 +240,7 @@ var setSelectionInsideAtNodeEnd = exports.setSelectionInsideAtNodeEnd = function
|
|
|
239
240
|
if ((0, _utils.isNodeEmpty)(node)) {
|
|
240
241
|
return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(to), _types.SelectionDirection.Before)(state, dispatch);
|
|
241
242
|
}
|
|
242
|
-
var selectableNode = (0,
|
|
243
|
+
var selectableNode = (0, _utils3.findLastChildNodeToSelect)(node);
|
|
243
244
|
if (selectableNode) {
|
|
244
245
|
var childNode = selectableNode.node,
|
|
245
246
|
childPos = selectableNode.pos;
|
|
@@ -251,10 +252,42 @@ var setSelectionInsideAtNodeEnd = exports.setSelectionInsideAtNodeEnd = function
|
|
|
251
252
|
return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos), _types.SelectionDirection.After)(state, dispatch);
|
|
252
253
|
} else if (!(0, _selection.isIgnored)(node)) {
|
|
253
254
|
return setSelectionRelativeToNode(selectionRelativeToNode, new _selection.GapCursorSelection(state.doc.resolve(selectionPos + 1), _selection.Side.RIGHT))(state, dispatch);
|
|
254
|
-
} else if ((0,
|
|
255
|
+
} else if ((0, _utils3.isSelectableContainerNode)(node)) {
|
|
255
256
|
return setSelectionRelativeToNode(selectionRelativeToNode, _state.NodeSelection.create(state.doc, selectionPos))(state, dispatch);
|
|
256
257
|
}
|
|
257
258
|
}
|
|
258
259
|
return false;
|
|
259
260
|
};
|
|
261
|
+
};
|
|
262
|
+
var selectNodeWithModA = exports.selectNodeWithModA = function selectNodeWithModA() {
|
|
263
|
+
return function (state, dispatch) {
|
|
264
|
+
var selection = state.selection;
|
|
265
|
+
var $from = selection.$from,
|
|
266
|
+
$to = selection.$to;
|
|
267
|
+
// Check if the selection is at the top level (e.g., in a paragraph)
|
|
268
|
+
var isTopLevelSelection = $from.depth === 1 || $to.depth === 1;
|
|
269
|
+
|
|
270
|
+
// Determine if the selection is within a code block
|
|
271
|
+
var isInCodeBlock = $from.sameParent($to) && $from.parent.type === state.schema.nodes.codeBlock;
|
|
272
|
+
|
|
273
|
+
// If the selection is at the top level and not in a code block, or if a table is selected, do nothing
|
|
274
|
+
if (isTopLevelSelection && !isInCodeBlock || (0, _utils2.isTableSelected)(selection)) {
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Get the depth of the first common ancestor node
|
|
279
|
+
var commonAncestorDepth = $from.sharedDepth($to.pos);
|
|
280
|
+
for (var depth = commonAncestorDepth; depth > 0; depth--) {
|
|
281
|
+
var node = $from.node(depth);
|
|
282
|
+
var isParentBlockQuote = node.type.name === 'blockquote';
|
|
283
|
+
var isSelectable = _state.NodeSelection.isSelectable(node) && !isParentBlockQuote;
|
|
284
|
+
if (isSelectable) {
|
|
285
|
+
if (dispatch) {
|
|
286
|
+
dispatch(state.tr.setSelection(_state.NodeSelection.create(state.doc, $from.before(depth))));
|
|
287
|
+
}
|
|
288
|
+
return true;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return false;
|
|
292
|
+
};
|
|
260
293
|
};
|
|
@@ -87,8 +87,6 @@ var toDOM = exports.toDOM = function toDOM(view, getPos) {
|
|
|
87
87
|
var gapCursor = element.firstChild;
|
|
88
88
|
gapCursor.style.height = "".concat(measureHeight(style), "px");
|
|
89
89
|
var layoutMode = node && (0, _utils.getLayoutModeFromTargetNode)(node);
|
|
90
|
-
|
|
91
|
-
// TODO remove this table specific piece. need to figure out margin collapsing logic
|
|
92
90
|
if (nodeStart !== 0 || layoutMode || (node === null || node === void 0 ? void 0 : node.type.name) === 'table') {
|
|
93
91
|
gapCursor.style.marginTop = style.getPropertyValue('margin-top');
|
|
94
92
|
}
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _keymaps = require("@atlaskit/editor-common/keymaps");
|
|
8
8
|
var _keymap = require("@atlaskit/editor-prosemirror/keymap");
|
|
9
|
+
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
9
10
|
var _commands = require("./commands");
|
|
10
11
|
function keymapPlugin() {
|
|
11
12
|
var list = {};
|
|
@@ -17,6 +18,11 @@ function keymapPlugin() {
|
|
|
17
18
|
// Ignored via go/ees005
|
|
18
19
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
19
20
|
(0, _keymaps.bindKeymapWithCommand)(_keymaps.moveLeft.common, _commands.arrowLeft, list);
|
|
21
|
+
if ((0, _experiments.editorExperiment)('platform_editor_cmd_a_progressively_select_nodes', true)) {
|
|
22
|
+
// Ignored via go/ees005
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
24
|
+
(0, _keymaps.bindKeymapWithCommand)(_keymaps.selectNode.common, (0, _commands.selectNodeWithModA)(), list);
|
|
25
|
+
}
|
|
20
26
|
return (0, _keymap.keymap)(list);
|
|
21
27
|
}
|
|
22
28
|
var _default = exports.default = keymapPlugin;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.selectionAnalyticsPluginKey = exports.createSelectionAnalyticsPlugin = void 0;
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
10
|
+
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
11
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
12
|
+
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; }
|
|
13
|
+
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; }
|
|
14
|
+
var selectionAnalyticsPluginKey = exports.selectionAnalyticsPluginKey = new _state.PluginKey('selectionAnalyticsPluginKey');
|
|
15
|
+
var createSelectionAnalyticsPlugin = exports.createSelectionAnalyticsPlugin = function createSelectionAnalyticsPlugin(dispatchAnalyticsEvent) {
|
|
16
|
+
var keyActions = new Map([['c', 'copy'], ['x', 'cut'], ['z', 'undo'], ['Escape', 'escape'], ['Backspace', 'delete']]);
|
|
17
|
+
var isFollowUpKey = function isFollowUpKey(event) {
|
|
18
|
+
return ['c', 'x', 'z'].includes(event.key) && (event.metaKey || event.ctrlKey) || ['Escape', 'Backspace'].includes(event.key);
|
|
19
|
+
};
|
|
20
|
+
var dispatchEvent = function dispatchEvent(fromDepth, followedBy) {
|
|
21
|
+
dispatchAnalyticsEvent({
|
|
22
|
+
action: _analytics.ACTION.SELECT_ALL,
|
|
23
|
+
actionSubject: _analytics.ACTION_SUBJECT.DOCUMENT,
|
|
24
|
+
actionSubjectId: _analytics.ACTION_SUBJECT_ID.ALL,
|
|
25
|
+
eventType: _analytics.EVENT_TYPE.TRACK,
|
|
26
|
+
attributes: {
|
|
27
|
+
followedBy: followedBy,
|
|
28
|
+
fromDepth: fromDepth
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
return new _safePlugin.SafePlugin({
|
|
33
|
+
key: selectionAnalyticsPluginKey,
|
|
34
|
+
state: {
|
|
35
|
+
init: function init() {
|
|
36
|
+
return {
|
|
37
|
+
lastCmdAPress: 0,
|
|
38
|
+
trackingCmdA: false
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
apply: function apply(tr, state) {
|
|
42
|
+
var meta = tr.getMeta(selectionAnalyticsPluginKey);
|
|
43
|
+
return meta ? _objectSpread(_objectSpread({}, state), meta) : state;
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
props: {
|
|
47
|
+
handleDOMEvents: {
|
|
48
|
+
keydown: function keydown(view, event) {
|
|
49
|
+
var _selectionAnalyticsPl = selectionAnalyticsPluginKey.getState(view.state),
|
|
50
|
+
lastCmdAPress = _selectionAnalyticsPl.lastCmdAPress,
|
|
51
|
+
trackingCmdA = _selectionAnalyticsPl.trackingCmdA;
|
|
52
|
+
var tr = view.state.tr;
|
|
53
|
+
var depth = view.state.selection.$from.depth;
|
|
54
|
+
var metaKey = event.metaKey || event.ctrlKey;
|
|
55
|
+
if (event.key === 'a' && metaKey) {
|
|
56
|
+
tr.setMeta(selectionAnalyticsPluginKey, {
|
|
57
|
+
lastCmdAPress: Date.now(),
|
|
58
|
+
trackingCmdA: true
|
|
59
|
+
});
|
|
60
|
+
dispatchEvent(depth);
|
|
61
|
+
view.dispatch(tr);
|
|
62
|
+
} else if (trackingCmdA && Date.now() - lastCmdAPress < 5000 && isFollowUpKey(event)) {
|
|
63
|
+
tr.setMeta(selectionAnalyticsPluginKey, {
|
|
64
|
+
trackingCmdA: false
|
|
65
|
+
});
|
|
66
|
+
dispatchEvent(depth, keyActions.get(event.key));
|
|
67
|
+
view.dispatch(tr);
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
};
|
|
@@ -15,6 +15,7 @@ var _gapCursorMain = _interopRequireDefault(require("./pm-plugins/gap-cursor-mai
|
|
|
15
15
|
var _gapCursorPluginKey = require("./pm-plugins/gap-cursor-plugin-key");
|
|
16
16
|
var _keymap = _interopRequireDefault(require("./pm-plugins/keymap"));
|
|
17
17
|
var _markBoundaryCursorMain = require("./pm-plugins/mark-boundary-cursor-main");
|
|
18
|
+
var _selectionAnalytics = require("./pm-plugins/selection-analytics");
|
|
18
19
|
var _selectionMain = require("./pm-plugins/selection-main");
|
|
19
20
|
var _types = require("./types");
|
|
20
21
|
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; }
|
|
@@ -109,7 +110,14 @@ var selectionPlugin = exports.selectionPlugin = function selectionPlugin(_ref4)
|
|
|
109
110
|
plugin: function plugin() {
|
|
110
111
|
return (0, _autoExpandSelectionRangeOnInlineNodeMain.createAutoExpandSelectionRangeOnInlineNodePlugin)();
|
|
111
112
|
}
|
|
112
|
-
}] : [])
|
|
113
|
+
}] : []), [{
|
|
114
|
+
name: 'selectionAnalytics',
|
|
115
|
+
plugin: function plugin(_ref7) {
|
|
116
|
+
var dispatch = _ref7.dispatch,
|
|
117
|
+
dispatchAnalyticsEvent = _ref7.dispatchAnalyticsEvent;
|
|
118
|
+
return (0, _selectionAnalytics.createSelectionAnalyticsPlugin)(dispatchAnalyticsEvent);
|
|
119
|
+
}
|
|
120
|
+
}]);
|
|
113
121
|
}
|
|
114
122
|
};
|
|
115
123
|
};
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { isIgnored as isIgnoredByGapCursor, RelativeSelectionPos, GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
|
|
3
3
|
import { isEmptyParagraph, isNodeEmpty } from '@atlaskit/editor-common/utils';
|
|
4
4
|
import { NodeSelection, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
5
|
+
import { isTableSelected } from '@atlaskit/editor-tables/utils';
|
|
5
6
|
import { SelectionDirection, selectionPluginKey } from '../types';
|
|
6
7
|
import { SelectionActionTypes } from './actions';
|
|
7
8
|
import { createCommand, getPluginState } from './plugin-factory';
|
|
@@ -249,4 +250,38 @@ export const setSelectionInsideAtNodeEnd = (selectionRelativeToNode, node, from,
|
|
|
249
250
|
}
|
|
250
251
|
}
|
|
251
252
|
return false;
|
|
253
|
+
};
|
|
254
|
+
export const selectNodeWithModA = () => (state, dispatch) => {
|
|
255
|
+
const {
|
|
256
|
+
selection
|
|
257
|
+
} = state;
|
|
258
|
+
const {
|
|
259
|
+
$from,
|
|
260
|
+
$to
|
|
261
|
+
} = selection;
|
|
262
|
+
// Check if the selection is at the top level (e.g., in a paragraph)
|
|
263
|
+
const isTopLevelSelection = $from.depth === 1 || $to.depth === 1;
|
|
264
|
+
|
|
265
|
+
// Determine if the selection is within a code block
|
|
266
|
+
const isInCodeBlock = $from.sameParent($to) && $from.parent.type === state.schema.nodes.codeBlock;
|
|
267
|
+
|
|
268
|
+
// If the selection is at the top level and not in a code block, or if a table is selected, do nothing
|
|
269
|
+
if (isTopLevelSelection && !isInCodeBlock || isTableSelected(selection)) {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Get the depth of the first common ancestor node
|
|
274
|
+
const commonAncestorDepth = $from.sharedDepth($to.pos);
|
|
275
|
+
for (let depth = commonAncestorDepth; depth > 0; depth--) {
|
|
276
|
+
const node = $from.node(depth);
|
|
277
|
+
const isParentBlockQuote = node.type.name === 'blockquote';
|
|
278
|
+
const isSelectable = NodeSelection.isSelectable(node) && !isParentBlockQuote;
|
|
279
|
+
if (isSelectable) {
|
|
280
|
+
if (dispatch) {
|
|
281
|
+
dispatch(state.tr.setSelection(NodeSelection.create(state.doc, $from.before(depth))));
|
|
282
|
+
}
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return false;
|
|
252
287
|
};
|
|
@@ -78,8 +78,6 @@ export const toDOM = (view, getPos) => {
|
|
|
78
78
|
const gapCursor = element.firstChild;
|
|
79
79
|
gapCursor.style.height = `${measureHeight(style)}px`;
|
|
80
80
|
const layoutMode = node && getLayoutModeFromTargetNode(node);
|
|
81
|
-
|
|
82
|
-
// TODO remove this table specific piece. need to figure out margin collapsing logic
|
|
83
81
|
if (nodeStart !== 0 || layoutMode || (node === null || node === void 0 ? void 0 : node.type.name) === 'table') {
|
|
84
82
|
gapCursor.style.marginTop = style.getPropertyValue('margin-top');
|
|
85
83
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { bindKeymapWithCommand, moveLeft, moveRight } from '@atlaskit/editor-common/keymaps';
|
|
1
|
+
import { bindKeymapWithCommand, moveLeft, moveRight, selectNode } from '@atlaskit/editor-common/keymaps';
|
|
2
2
|
import { keymap } from '@atlaskit/editor-prosemirror/keymap';
|
|
3
|
-
import {
|
|
3
|
+
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
4
|
+
import { arrowLeft, arrowRight, selectNodeWithModA } from './commands';
|
|
4
5
|
function keymapPlugin() {
|
|
5
6
|
const list = {};
|
|
6
7
|
|
|
@@ -11,6 +12,11 @@ function keymapPlugin() {
|
|
|
11
12
|
// Ignored via go/ees005
|
|
12
13
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
13
14
|
bindKeymapWithCommand(moveLeft.common, arrowLeft, list);
|
|
15
|
+
if (editorExperiment('platform_editor_cmd_a_progressively_select_nodes', true)) {
|
|
16
|
+
// Ignored via go/ees005
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
18
|
+
bindKeymapWithCommand(selectNode.common, selectNodeWithModA(), list);
|
|
19
|
+
}
|
|
14
20
|
return keymap(list);
|
|
15
21
|
}
|
|
16
22
|
export default keymapPlugin;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
4
|
+
export const selectionAnalyticsPluginKey = new PluginKey('selectionAnalyticsPluginKey');
|
|
5
|
+
export const createSelectionAnalyticsPlugin = dispatchAnalyticsEvent => {
|
|
6
|
+
const keyActions = new Map([['c', 'copy'], ['x', 'cut'], ['z', 'undo'], ['Escape', 'escape'], ['Backspace', 'delete']]);
|
|
7
|
+
const isFollowUpKey = event => ['c', 'x', 'z'].includes(event.key) && (event.metaKey || event.ctrlKey) || ['Escape', 'Backspace'].includes(event.key);
|
|
8
|
+
const dispatchEvent = (fromDepth, followedBy) => {
|
|
9
|
+
dispatchAnalyticsEvent({
|
|
10
|
+
action: ACTION.SELECT_ALL,
|
|
11
|
+
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
12
|
+
actionSubjectId: ACTION_SUBJECT_ID.ALL,
|
|
13
|
+
eventType: EVENT_TYPE.TRACK,
|
|
14
|
+
attributes: {
|
|
15
|
+
followedBy,
|
|
16
|
+
fromDepth
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
return new SafePlugin({
|
|
21
|
+
key: selectionAnalyticsPluginKey,
|
|
22
|
+
state: {
|
|
23
|
+
init: () => ({
|
|
24
|
+
lastCmdAPress: 0,
|
|
25
|
+
trackingCmdA: false
|
|
26
|
+
}),
|
|
27
|
+
apply(tr, state) {
|
|
28
|
+
const meta = tr.getMeta(selectionAnalyticsPluginKey);
|
|
29
|
+
return meta ? {
|
|
30
|
+
...state,
|
|
31
|
+
...meta
|
|
32
|
+
} : state;
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
props: {
|
|
36
|
+
handleDOMEvents: {
|
|
37
|
+
keydown(view, event) {
|
|
38
|
+
const {
|
|
39
|
+
lastCmdAPress,
|
|
40
|
+
trackingCmdA
|
|
41
|
+
} = selectionAnalyticsPluginKey.getState(view.state);
|
|
42
|
+
const tr = view.state.tr;
|
|
43
|
+
const depth = view.state.selection.$from.depth;
|
|
44
|
+
const metaKey = event.metaKey || event.ctrlKey;
|
|
45
|
+
if (event.key === 'a' && metaKey) {
|
|
46
|
+
tr.setMeta(selectionAnalyticsPluginKey, {
|
|
47
|
+
lastCmdAPress: Date.now(),
|
|
48
|
+
trackingCmdA: true
|
|
49
|
+
});
|
|
50
|
+
dispatchEvent(depth);
|
|
51
|
+
view.dispatch(tr);
|
|
52
|
+
} else if (trackingCmdA && Date.now() - lastCmdAPress < 5000 && isFollowUpKey(event)) {
|
|
53
|
+
tr.setMeta(selectionAnalyticsPluginKey, {
|
|
54
|
+
trackingCmdA: false
|
|
55
|
+
});
|
|
56
|
+
dispatchEvent(depth, keyActions.get(event.key));
|
|
57
|
+
view.dispatch(tr);
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
};
|
|
@@ -6,6 +6,7 @@ import gapCursorPlugin from './pm-plugins/gap-cursor-main';
|
|
|
6
6
|
import { gapCursorPluginKey } from './pm-plugins/gap-cursor-plugin-key';
|
|
7
7
|
import selectionKeymapPlugin from './pm-plugins/keymap';
|
|
8
8
|
import { createMarkBoundaryCursorPlugin } from './pm-plugins/mark-boundary-cursor-main';
|
|
9
|
+
import { createSelectionAnalyticsPlugin } from './pm-plugins/selection-analytics';
|
|
9
10
|
import { createPlugin } from './pm-plugins/selection-main';
|
|
10
11
|
import { selectionPluginKey } from './types';
|
|
11
12
|
const displayGapCursor = toggle => ({
|
|
@@ -87,7 +88,13 @@ export const selectionPlugin = ({
|
|
|
87
88
|
}, ...(fg('editor_auto_expand_selection_on_inline_node') ? [{
|
|
88
89
|
name: 'autoExpandSelectionRangeOnInlineNode',
|
|
89
90
|
plugin: () => createAutoExpandSelectionRangeOnInlineNodePlugin()
|
|
90
|
-
}] : [])
|
|
91
|
+
}] : []), {
|
|
92
|
+
name: 'selectionAnalytics',
|
|
93
|
+
plugin: ({
|
|
94
|
+
dispatch,
|
|
95
|
+
dispatchAnalyticsEvent
|
|
96
|
+
}) => createSelectionAnalyticsPlugin(dispatchAnalyticsEvent)
|
|
97
|
+
}];
|
|
91
98
|
}
|
|
92
99
|
});
|
|
93
100
|
export default selectionPlugin;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { isIgnored as isIgnoredByGapCursor, RelativeSelectionPos, GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
|
|
3
3
|
import { isEmptyParagraph, isNodeEmpty } from '@atlaskit/editor-common/utils';
|
|
4
4
|
import { NodeSelection, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
5
|
+
import { isTableSelected } from '@atlaskit/editor-tables/utils';
|
|
5
6
|
import { SelectionDirection, selectionPluginKey } from '../types';
|
|
6
7
|
import { SelectionActionTypes } from './actions';
|
|
7
8
|
import { createCommand, getPluginState } from './plugin-factory';
|
|
@@ -250,4 +251,36 @@ export var setSelectionInsideAtNodeEnd = function setSelectionInsideAtNodeEnd(se
|
|
|
250
251
|
}
|
|
251
252
|
return false;
|
|
252
253
|
};
|
|
254
|
+
};
|
|
255
|
+
export var selectNodeWithModA = function selectNodeWithModA() {
|
|
256
|
+
return function (state, dispatch) {
|
|
257
|
+
var selection = state.selection;
|
|
258
|
+
var $from = selection.$from,
|
|
259
|
+
$to = selection.$to;
|
|
260
|
+
// Check if the selection is at the top level (e.g., in a paragraph)
|
|
261
|
+
var isTopLevelSelection = $from.depth === 1 || $to.depth === 1;
|
|
262
|
+
|
|
263
|
+
// Determine if the selection is within a code block
|
|
264
|
+
var isInCodeBlock = $from.sameParent($to) && $from.parent.type === state.schema.nodes.codeBlock;
|
|
265
|
+
|
|
266
|
+
// If the selection is at the top level and not in a code block, or if a table is selected, do nothing
|
|
267
|
+
if (isTopLevelSelection && !isInCodeBlock || isTableSelected(selection)) {
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Get the depth of the first common ancestor node
|
|
272
|
+
var commonAncestorDepth = $from.sharedDepth($to.pos);
|
|
273
|
+
for (var depth = commonAncestorDepth; depth > 0; depth--) {
|
|
274
|
+
var node = $from.node(depth);
|
|
275
|
+
var isParentBlockQuote = node.type.name === 'blockquote';
|
|
276
|
+
var isSelectable = NodeSelection.isSelectable(node) && !isParentBlockQuote;
|
|
277
|
+
if (isSelectable) {
|
|
278
|
+
if (dispatch) {
|
|
279
|
+
dispatch(state.tr.setSelection(NodeSelection.create(state.doc, $from.before(depth))));
|
|
280
|
+
}
|
|
281
|
+
return true;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return false;
|
|
285
|
+
};
|
|
253
286
|
};
|
|
@@ -81,8 +81,6 @@ export var toDOM = function toDOM(view, getPos) {
|
|
|
81
81
|
var gapCursor = element.firstChild;
|
|
82
82
|
gapCursor.style.height = "".concat(measureHeight(style), "px");
|
|
83
83
|
var layoutMode = node && getLayoutModeFromTargetNode(node);
|
|
84
|
-
|
|
85
|
-
// TODO remove this table specific piece. need to figure out margin collapsing logic
|
|
86
84
|
if (nodeStart !== 0 || layoutMode || (node === null || node === void 0 ? void 0 : node.type.name) === 'table') {
|
|
87
85
|
gapCursor.style.marginTop = style.getPropertyValue('margin-top');
|
|
88
86
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { bindKeymapWithCommand, moveLeft, moveRight } from '@atlaskit/editor-common/keymaps';
|
|
1
|
+
import { bindKeymapWithCommand, moveLeft, moveRight, selectNode } from '@atlaskit/editor-common/keymaps';
|
|
2
2
|
import { keymap } from '@atlaskit/editor-prosemirror/keymap';
|
|
3
|
-
import {
|
|
3
|
+
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
4
|
+
import { arrowLeft, arrowRight, selectNodeWithModA } from './commands';
|
|
4
5
|
function keymapPlugin() {
|
|
5
6
|
var list = {};
|
|
6
7
|
|
|
@@ -11,6 +12,11 @@ function keymapPlugin() {
|
|
|
11
12
|
// Ignored via go/ees005
|
|
12
13
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
13
14
|
bindKeymapWithCommand(moveLeft.common, arrowLeft, list);
|
|
15
|
+
if (editorExperiment('platform_editor_cmd_a_progressively_select_nodes', true)) {
|
|
16
|
+
// Ignored via go/ees005
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
18
|
+
bindKeymapWithCommand(selectNode.common, selectNodeWithModA(), list);
|
|
19
|
+
}
|
|
14
20
|
return keymap(list);
|
|
15
21
|
}
|
|
16
22
|
export default keymapPlugin;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
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; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
5
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
6
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
7
|
+
export var selectionAnalyticsPluginKey = new PluginKey('selectionAnalyticsPluginKey');
|
|
8
|
+
export var createSelectionAnalyticsPlugin = function createSelectionAnalyticsPlugin(dispatchAnalyticsEvent) {
|
|
9
|
+
var keyActions = new Map([['c', 'copy'], ['x', 'cut'], ['z', 'undo'], ['Escape', 'escape'], ['Backspace', 'delete']]);
|
|
10
|
+
var isFollowUpKey = function isFollowUpKey(event) {
|
|
11
|
+
return ['c', 'x', 'z'].includes(event.key) && (event.metaKey || event.ctrlKey) || ['Escape', 'Backspace'].includes(event.key);
|
|
12
|
+
};
|
|
13
|
+
var dispatchEvent = function dispatchEvent(fromDepth, followedBy) {
|
|
14
|
+
dispatchAnalyticsEvent({
|
|
15
|
+
action: ACTION.SELECT_ALL,
|
|
16
|
+
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
17
|
+
actionSubjectId: ACTION_SUBJECT_ID.ALL,
|
|
18
|
+
eventType: EVENT_TYPE.TRACK,
|
|
19
|
+
attributes: {
|
|
20
|
+
followedBy: followedBy,
|
|
21
|
+
fromDepth: fromDepth
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
return new SafePlugin({
|
|
26
|
+
key: selectionAnalyticsPluginKey,
|
|
27
|
+
state: {
|
|
28
|
+
init: function init() {
|
|
29
|
+
return {
|
|
30
|
+
lastCmdAPress: 0,
|
|
31
|
+
trackingCmdA: false
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
apply: function apply(tr, state) {
|
|
35
|
+
var meta = tr.getMeta(selectionAnalyticsPluginKey);
|
|
36
|
+
return meta ? _objectSpread(_objectSpread({}, state), meta) : state;
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
props: {
|
|
40
|
+
handleDOMEvents: {
|
|
41
|
+
keydown: function keydown(view, event) {
|
|
42
|
+
var _selectionAnalyticsPl = selectionAnalyticsPluginKey.getState(view.state),
|
|
43
|
+
lastCmdAPress = _selectionAnalyticsPl.lastCmdAPress,
|
|
44
|
+
trackingCmdA = _selectionAnalyticsPl.trackingCmdA;
|
|
45
|
+
var tr = view.state.tr;
|
|
46
|
+
var depth = view.state.selection.$from.depth;
|
|
47
|
+
var metaKey = event.metaKey || event.ctrlKey;
|
|
48
|
+
if (event.key === 'a' && metaKey) {
|
|
49
|
+
tr.setMeta(selectionAnalyticsPluginKey, {
|
|
50
|
+
lastCmdAPress: Date.now(),
|
|
51
|
+
trackingCmdA: true
|
|
52
|
+
});
|
|
53
|
+
dispatchEvent(depth);
|
|
54
|
+
view.dispatch(tr);
|
|
55
|
+
} else if (trackingCmdA && Date.now() - lastCmdAPress < 5000 && isFollowUpKey(event)) {
|
|
56
|
+
tr.setMeta(selectionAnalyticsPluginKey, {
|
|
57
|
+
trackingCmdA: false
|
|
58
|
+
});
|
|
59
|
+
dispatchEvent(depth, keyActions.get(event.key));
|
|
60
|
+
view.dispatch(tr);
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
};
|
|
@@ -10,6 +10,7 @@ import gapCursorPlugin from './pm-plugins/gap-cursor-main';
|
|
|
10
10
|
import { gapCursorPluginKey } from './pm-plugins/gap-cursor-plugin-key';
|
|
11
11
|
import selectionKeymapPlugin from './pm-plugins/keymap';
|
|
12
12
|
import { createMarkBoundaryCursorPlugin } from './pm-plugins/mark-boundary-cursor-main';
|
|
13
|
+
import { createSelectionAnalyticsPlugin } from './pm-plugins/selection-analytics';
|
|
13
14
|
import { createPlugin } from './pm-plugins/selection-main';
|
|
14
15
|
import { selectionPluginKey } from './types';
|
|
15
16
|
var displayGapCursor = function displayGapCursor(toggle) {
|
|
@@ -102,7 +103,14 @@ export var selectionPlugin = function selectionPlugin(_ref4) {
|
|
|
102
103
|
plugin: function plugin() {
|
|
103
104
|
return createAutoExpandSelectionRangeOnInlineNodePlugin();
|
|
104
105
|
}
|
|
105
|
-
}] : [])
|
|
106
|
+
}] : []), [{
|
|
107
|
+
name: 'selectionAnalytics',
|
|
108
|
+
plugin: function plugin(_ref7) {
|
|
109
|
+
var dispatch = _ref7.dispatch,
|
|
110
|
+
dispatchAnalyticsEvent = _ref7.dispatchAnalyticsEvent;
|
|
111
|
+
return createSelectionAnalyticsPlugin(dispatchAnalyticsEvent);
|
|
112
|
+
}
|
|
113
|
+
}]);
|
|
106
114
|
}
|
|
107
115
|
};
|
|
108
116
|
};
|
|
@@ -7,3 +7,4 @@ export declare const setSelectionRelativeToNode: (selectionRelativeToNode?: Rela
|
|
|
7
7
|
export declare const arrowRight: Command;
|
|
8
8
|
export declare const arrowLeft: Command;
|
|
9
9
|
export declare const setSelectionInsideAtNodeEnd: (selectionRelativeToNode: RelativeSelectionPos, node: PmNode, from: number, to: number) => Command;
|
|
10
|
+
export declare const selectNodeWithModA: () => Command;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
4
|
+
export declare const selectionAnalyticsPluginKey: PluginKey<any>;
|
|
5
|
+
interface SelectionAnalyticsState {
|
|
6
|
+
lastCmdAPress: number;
|
|
7
|
+
trackingCmdA: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const createSelectionAnalyticsPlugin: (dispatchAnalyticsEvent: DispatchAnalyticsEvent) => SafePlugin<SelectionAnalyticsState>;
|
|
10
|
+
export {};
|
|
@@ -7,3 +7,4 @@ export declare const setSelectionRelativeToNode: (selectionRelativeToNode?: Rela
|
|
|
7
7
|
export declare const arrowRight: Command;
|
|
8
8
|
export declare const arrowLeft: Command;
|
|
9
9
|
export declare const setSelectionInsideAtNodeEnd: (selectionRelativeToNode: RelativeSelectionPos, node: PmNode, from: number, to: number) => Command;
|
|
10
|
+
export declare const selectNodeWithModA: () => Command;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
4
|
+
export declare const selectionAnalyticsPluginKey: PluginKey<any>;
|
|
5
|
+
interface SelectionAnalyticsState {
|
|
6
|
+
lastCmdAPress: number;
|
|
7
|
+
trackingCmdA: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const createSelectionAnalyticsPlugin: (dispatchAnalyticsEvent: DispatchAnalyticsEvent) => SafePlugin<SelectionAnalyticsState>;
|
|
10
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-selection",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Selection plugin for @atlaskit/editor-core",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
"runReact18": true
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@atlaskit/editor-common": "^102.
|
|
23
|
+
"@atlaskit/editor-common": "^102.3.0",
|
|
24
24
|
"@atlaskit/editor-prosemirror": "7.0.0",
|
|
25
25
|
"@atlaskit/editor-shared-styles": "^3.4.0",
|
|
26
26
|
"@atlaskit/editor-tables": "^2.9.0",
|
|
27
27
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
28
|
-
"@atlaskit/tmp-editor-statsig": "^3.
|
|
28
|
+
"@atlaskit/tmp-editor-statsig": "^3.5.0",
|
|
29
29
|
"@atlaskit/tokens": "^4.3.0",
|
|
30
30
|
"@babel/runtime": "^7.0.0"
|
|
31
31
|
},
|