@atlaskit/editor-plugin-selection 2.0.7 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/cjs/pm-plugins/commands.js +65 -22
- package/dist/cjs/pm-plugins/gap-cursor/utils/place-gap-cursor.js +0 -2
- package/dist/cjs/pm-plugins/keymap.js +8 -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 +45 -0
- package/dist/es2019/pm-plugins/gap-cursor/utils/place-gap-cursor.js +0 -2
- package/dist/es2019/pm-plugins/keymap.js +10 -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 +43 -0
- package/dist/esm/pm-plugins/gap-cursor/utils/place-gap-cursor.js +0 -2
- package/dist/esm/pm-plugins/keymap.js +10 -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 +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-selection
|
|
2
2
|
|
|
3
|
+
## 2.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#124883](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/124883)
|
|
8
|
+
[`cdc857701ad32`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/cdc857701ad32) -
|
|
9
|
+
[ux] EDF-2571 Updated `selectNodeWithModA` function to account for nested tables.
|
|
10
|
+
- Updated dependencies
|
|
11
|
+
|
|
12
|
+
## 2.1.0
|
|
13
|
+
|
|
14
|
+
### Minor Changes
|
|
15
|
+
|
|
16
|
+
- [#124688](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/124688)
|
|
17
|
+
[`9b1137bda6f87`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/9b1137bda6f87) -
|
|
18
|
+
[ux] ED-25486 Updates cmd+a behaviour to progressively select nodes behind
|
|
19
|
+
platform_editor_cmd_a_progressively_select_nodes experiment.
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies
|
|
24
|
+
|
|
3
25
|
## 2.0.7
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
|
@@ -3,14 +3,16 @@
|
|
|
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-prosemirror/utils");
|
|
11
|
+
var _utils3 = require("@atlaskit/editor-tables/utils");
|
|
10
12
|
var _types = require("../types");
|
|
11
13
|
var _actions = require("./actions");
|
|
12
14
|
var _pluginFactory = require("./plugin-factory");
|
|
13
|
-
var
|
|
15
|
+
var _utils4 = require("./utils");
|
|
14
16
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
15
17
|
|
|
16
18
|
var selectNearNode = exports.selectNearNode = function selectNearNode(selectionRelativeToNode, selection) {
|
|
@@ -64,12 +66,12 @@ var arrowRightFromGapCursor = function arrowRightFromGapCursor(selection) {
|
|
|
64
66
|
$to = selection.$to,
|
|
65
67
|
side = selection.side;
|
|
66
68
|
if (side === _selection.Side.LEFT) {
|
|
67
|
-
var selectableNode = (0,
|
|
69
|
+
var selectableNode = (0, _utils4.findSelectableContainerAfter)($to, state.doc);
|
|
68
70
|
if (selectableNode) {
|
|
69
71
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.Start, _state.NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
|
|
70
72
|
}
|
|
71
|
-
} else if (side === _selection.Side.RIGHT && (0,
|
|
72
|
-
var _selectableNode = (0,
|
|
73
|
+
} else if (side === _selection.Side.RIGHT && (0, _utils4.isSelectionAtEndOfParentNode)($from, selection)) {
|
|
74
|
+
var _selectableNode = (0, _utils4.findSelectableContainerParent)(selection);
|
|
73
75
|
if (_selectableNode) {
|
|
74
76
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.End, _state.NodeSelection.create(state.doc, _selectableNode.pos))(state, dispatch);
|
|
75
77
|
}
|
|
@@ -84,15 +86,15 @@ var arrowLeftFromGapCursor = function arrowLeftFromGapCursor(selection) {
|
|
|
84
86
|
var _getPluginState = (0, _pluginFactory.getPluginState)(state),
|
|
85
87
|
selectionRelativeToNode = _getPluginState.selectionRelativeToNode;
|
|
86
88
|
if (side === _selection.Side.RIGHT) {
|
|
87
|
-
var selectableNode = (0,
|
|
89
|
+
var selectableNode = (0, _utils4.findSelectableContainerBefore)($from, state.doc);
|
|
88
90
|
if (selectableNode) {
|
|
89
91
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.End, _state.NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
|
|
90
92
|
}
|
|
91
|
-
} else if (side === _selection.Side.LEFT && (0,
|
|
93
|
+
} else if (side === _selection.Side.LEFT && (0, _utils4.isSelectionAtStartOfParentNode)($from, selection)) {
|
|
92
94
|
if (selectionRelativeToNode === _selection.RelativeSelectionPos.Before) {
|
|
93
95
|
var $parent = state.doc.resolve(selection.$from.before(selection.$from.depth));
|
|
94
96
|
if ($parent) {
|
|
95
|
-
var _selectableNode2 = (0,
|
|
97
|
+
var _selectableNode2 = (0, _utils4.findSelectableContainerBefore)($parent, state.doc);
|
|
96
98
|
if (_selectableNode2 && (0, _selection.isIgnored)(_selectableNode2.node)) {
|
|
97
99
|
// selection is inside node without gap cursor preceeded by another node without gap cursor - set node selection for previous node
|
|
98
100
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.End, _state.NodeSelection.create(state.doc, _selectableNode2.pos))(state, dispatch);
|
|
@@ -102,7 +104,7 @@ var arrowLeftFromGapCursor = function arrowLeftFromGapCursor(selection) {
|
|
|
102
104
|
// from responding to arrow left key
|
|
103
105
|
setSelectionRelativeToNode()(state, dispatch);
|
|
104
106
|
} else {
|
|
105
|
-
var _selectableNode3 = (0,
|
|
107
|
+
var _selectableNode3 = (0, _utils4.findSelectableContainerParent)(selection);
|
|
106
108
|
if (_selectableNode3) {
|
|
107
109
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.Start, _state.NodeSelection.create(state.doc, _selectableNode3.pos))(state, dispatch);
|
|
108
110
|
}
|
|
@@ -119,7 +121,7 @@ var arrowRightFromNode = function arrowRightFromNode(selection) {
|
|
|
119
121
|
var _getPluginState2 = (0, _pluginFactory.getPluginState)(state),
|
|
120
122
|
selectionRelativeToNode = _getPluginState2.selectionRelativeToNode;
|
|
121
123
|
if (node.isAtom) {
|
|
122
|
-
if ((0,
|
|
124
|
+
if ((0, _utils4.isSelectionAtEndOfParentNode)($to, selection) && (node.isInline || (0, _selection.isIgnored)(node))) {
|
|
123
125
|
// 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
126
|
return findAndSetTextSelection(_selection.RelativeSelectionPos.End, state.doc.resolve(from + 1), _types.SelectionDirection.After)(state, dispatch);
|
|
125
127
|
}
|
|
@@ -128,7 +130,7 @@ var arrowRightFromNode = function arrowRightFromNode(selection) {
|
|
|
128
130
|
// selection is for container node - set selection inside it at the start
|
|
129
131
|
return setSelectionInsideAtNodeStart(_selection.RelativeSelectionPos.Inside, node, from)(state, dispatch);
|
|
130
132
|
} else if ((0, _selection.isIgnored)(node) && (!selectionRelativeToNode || selectionRelativeToNode === _selection.RelativeSelectionPos.End)) {
|
|
131
|
-
var selectableNode = (0,
|
|
133
|
+
var selectableNode = (0, _utils4.findSelectableContainerAfter)($to, state.doc);
|
|
132
134
|
if (selectableNode && (0, _selection.isIgnored)(selectableNode.node)) {
|
|
133
135
|
// selection is for node without gap cursor followed by another node without gap cursor - set node selection for next node
|
|
134
136
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.Start, _state.NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
|
|
@@ -146,7 +148,7 @@ var arrowLeftFromNode = function arrowLeftFromNode(selection) {
|
|
|
146
148
|
var _getPluginState3 = (0, _pluginFactory.getPluginState)(state),
|
|
147
149
|
selectionRelativeToNode = _getPluginState3.selectionRelativeToNode;
|
|
148
150
|
if (node.isAtom) {
|
|
149
|
-
if ((0,
|
|
151
|
+
if ((0, _utils4.isSelectionAtStartOfParentNode)($from, selection) && (node.isInline || (0, _selection.isIgnored)(node))) {
|
|
150
152
|
// 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
153
|
return findAndSetTextSelection(_selection.RelativeSelectionPos.Start, state.doc.resolve(from), _types.SelectionDirection.Before)(state, dispatch);
|
|
152
154
|
}
|
|
@@ -160,7 +162,7 @@ var arrowLeftFromNode = function arrowLeftFromNode(selection) {
|
|
|
160
162
|
return setSelectionInsideAtNodeStart(_selection.RelativeSelectionPos.Before, node, from)(state, dispatch);
|
|
161
163
|
} else if ((0, _selection.isIgnored)(node) && selectionRelativeToNode === _selection.RelativeSelectionPos.Start) {
|
|
162
164
|
// selection is for node without gap cursor preceeded by another node without gap cursor - set node selection for previous node
|
|
163
|
-
var selectableNode = (0,
|
|
165
|
+
var selectableNode = (0, _utils4.findSelectableContainerBefore)($from, state.doc);
|
|
164
166
|
if (selectableNode && (0, _selection.isIgnored)(selectableNode.node)) {
|
|
165
167
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.End, _state.NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
|
|
166
168
|
}
|
|
@@ -170,8 +172,8 @@ var arrowLeftFromNode = function arrowLeftFromNode(selection) {
|
|
|
170
172
|
};
|
|
171
173
|
var arrowRightFromText = function arrowRightFromText(selection) {
|
|
172
174
|
return function (state, dispatch) {
|
|
173
|
-
if ((0,
|
|
174
|
-
var selectableNode = (0,
|
|
175
|
+
if ((0, _utils4.isSelectionAtEndOfParentNode)(selection.$to, selection)) {
|
|
176
|
+
var selectableNode = (0, _utils4.findSelectableContainerParent)(selection);
|
|
175
177
|
if (selectableNode) {
|
|
176
178
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.End, _state.NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
|
|
177
179
|
}
|
|
@@ -184,7 +186,7 @@ var arrowLeftFromText = function arrowLeftFromText(selection) {
|
|
|
184
186
|
var _getPluginState4 = (0, _pluginFactory.getPluginState)(state),
|
|
185
187
|
selectionRelativeToNode = _getPluginState4.selectionRelativeToNode;
|
|
186
188
|
if (selectionRelativeToNode === _selection.RelativeSelectionPos.Before) {
|
|
187
|
-
var selectableNode = (0,
|
|
189
|
+
var selectableNode = (0, _utils4.findSelectableContainerBefore)(selection.$from, state.doc);
|
|
188
190
|
if (selectableNode && (0, _selection.isIgnored)(selectableNode.node)) {
|
|
189
191
|
// selection is inside node without gap cursor preceeded by another node without gap cursor - set node selection for previous node
|
|
190
192
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.End, _state.NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
|
|
@@ -192,8 +194,8 @@ var arrowLeftFromText = function arrowLeftFromText(selection) {
|
|
|
192
194
|
// we don't return this as we want to reset the relative pos, but not block other plugins
|
|
193
195
|
// from responding to arrow left key
|
|
194
196
|
setSelectionRelativeToNode(undefined)(state, dispatch);
|
|
195
|
-
} else if ((0,
|
|
196
|
-
var _selectableNode4 = (0,
|
|
197
|
+
} else if ((0, _utils4.isSelectionAtStartOfParentNode)(selection.$from, selection)) {
|
|
198
|
+
var _selectableNode4 = (0, _utils4.findSelectableContainerParent)(selection);
|
|
197
199
|
if (_selectableNode4) {
|
|
198
200
|
return setSelectionRelativeToNode(_selection.RelativeSelectionPos.Start, _state.NodeSelection.create(state.doc, _selectableNode4.pos))(state, dispatch);
|
|
199
201
|
}
|
|
@@ -215,7 +217,7 @@ var setSelectionInsideAtNodeStart = function setSelectionInsideAtNodeStart(selec
|
|
|
215
217
|
if ((0, _utils.isNodeEmpty)(node)) {
|
|
216
218
|
return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(pos), _types.SelectionDirection.After)(state, dispatch);
|
|
217
219
|
}
|
|
218
|
-
var selectableNode = (0,
|
|
220
|
+
var selectableNode = (0, _utils4.findFirstChildNodeToSelect)(node);
|
|
219
221
|
if (selectableNode) {
|
|
220
222
|
var childNode = selectableNode.node,
|
|
221
223
|
childPos = selectableNode.pos;
|
|
@@ -227,7 +229,7 @@ var setSelectionInsideAtNodeStart = function setSelectionInsideAtNodeStart(selec
|
|
|
227
229
|
return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos + 1), _types.SelectionDirection.Before)(state, dispatch);
|
|
228
230
|
} else if (!(0, _selection.isIgnored)(node)) {
|
|
229
231
|
return setSelectionRelativeToNode(selectionRelativeToNode, new _selection.GapCursorSelection(state.doc.resolve(selectionPos), _selection.Side.LEFT))(state, dispatch);
|
|
230
|
-
} else if ((0,
|
|
232
|
+
} else if ((0, _utils4.isSelectableContainerNode)(node)) {
|
|
231
233
|
return setSelectionRelativeToNode(selectionRelativeToNode, _state.NodeSelection.create(state.doc, selectionPos))(state, dispatch);
|
|
232
234
|
}
|
|
233
235
|
}
|
|
@@ -239,7 +241,7 @@ var setSelectionInsideAtNodeEnd = exports.setSelectionInsideAtNodeEnd = function
|
|
|
239
241
|
if ((0, _utils.isNodeEmpty)(node)) {
|
|
240
242
|
return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(to), _types.SelectionDirection.Before)(state, dispatch);
|
|
241
243
|
}
|
|
242
|
-
var selectableNode = (0,
|
|
244
|
+
var selectableNode = (0, _utils4.findLastChildNodeToSelect)(node);
|
|
243
245
|
if (selectableNode) {
|
|
244
246
|
var childNode = selectableNode.node,
|
|
245
247
|
childPos = selectableNode.pos;
|
|
@@ -251,10 +253,51 @@ var setSelectionInsideAtNodeEnd = exports.setSelectionInsideAtNodeEnd = function
|
|
|
251
253
|
return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos), _types.SelectionDirection.After)(state, dispatch);
|
|
252
254
|
} else if (!(0, _selection.isIgnored)(node)) {
|
|
253
255
|
return setSelectionRelativeToNode(selectionRelativeToNode, new _selection.GapCursorSelection(state.doc.resolve(selectionPos + 1), _selection.Side.RIGHT))(state, dispatch);
|
|
254
|
-
} else if ((0,
|
|
256
|
+
} else if ((0, _utils4.isSelectableContainerNode)(node)) {
|
|
255
257
|
return setSelectionRelativeToNode(selectionRelativeToNode, _state.NodeSelection.create(state.doc, selectionPos))(state, dispatch);
|
|
256
258
|
}
|
|
257
259
|
}
|
|
258
260
|
return false;
|
|
259
261
|
};
|
|
262
|
+
};
|
|
263
|
+
var selectNodeWithModA = exports.selectNodeWithModA = function selectNodeWithModA() {
|
|
264
|
+
return function (state, dispatch) {
|
|
265
|
+
var selection = state.selection;
|
|
266
|
+
var $from = selection.$from,
|
|
267
|
+
$to = selection.$to;
|
|
268
|
+
// Check if the selection is at the top level (e.g., in a paragraph)
|
|
269
|
+
var isTopLevelSelection = $from.depth === 1 || $to.depth === 1;
|
|
270
|
+
|
|
271
|
+
// Determine if the selection is within a code block
|
|
272
|
+
var isInCodeBlock = $from.sameParent($to) && $from.parent.type === state.schema.nodes.codeBlock;
|
|
273
|
+
|
|
274
|
+
// If the selection is at the top level and not in a code block, or if a table is selected, do nothing
|
|
275
|
+
if (isTopLevelSelection && !isInCodeBlock) {
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Get the depth of the first common ancestor node
|
|
280
|
+
var commonAncestorDepth = $from.sharedDepth($to.pos);
|
|
281
|
+
|
|
282
|
+
// We need to adjust the common ancestor depth if a table is selected
|
|
283
|
+
// to skip the current table node and select the parent node instead
|
|
284
|
+
if ((0, _utils3.isTableSelected)(state.selection)) {
|
|
285
|
+
var table = (0, _utils2.findParentNodeOfType)(state.schema.nodes.table)(state.selection);
|
|
286
|
+
if (table) {
|
|
287
|
+
commonAncestorDepth = table.depth - 1;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
for (var depth = commonAncestorDepth; depth > 0; depth--) {
|
|
291
|
+
var node = $from.node(depth);
|
|
292
|
+
var isParentBlockQuote = node.type.name === 'blockquote';
|
|
293
|
+
var isSelectable = _state.NodeSelection.isSelectable(node) && !isParentBlockQuote;
|
|
294
|
+
if (isSelectable) {
|
|
295
|
+
if (dispatch) {
|
|
296
|
+
dispatch(state.tr.setSelection(_state.NodeSelection.create(state.doc, $from.before(depth))));
|
|
297
|
+
}
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return false;
|
|
302
|
+
};
|
|
260
303
|
};
|
|
@@ -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,13 @@ 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
|
+
exposure: true
|
|
23
|
+
})) {
|
|
24
|
+
// Ignored via go/ees005
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
26
|
+
(0, _keymaps.bindKeymapWithCommand)(_keymaps.selectNode.common, (0, _commands.selectNodeWithModA)(), list);
|
|
27
|
+
}
|
|
20
28
|
return (0, _keymap.keymap)(list);
|
|
21
29
|
}
|
|
22
30
|
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,8 @@
|
|
|
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 { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
6
|
+
import { isTableSelected } from '@atlaskit/editor-tables/utils';
|
|
5
7
|
import { SelectionDirection, selectionPluginKey } from '../types';
|
|
6
8
|
import { SelectionActionTypes } from './actions';
|
|
7
9
|
import { createCommand, getPluginState } from './plugin-factory';
|
|
@@ -249,4 +251,47 @@ export const setSelectionInsideAtNodeEnd = (selectionRelativeToNode, node, from,
|
|
|
249
251
|
}
|
|
250
252
|
}
|
|
251
253
|
return false;
|
|
254
|
+
};
|
|
255
|
+
export const selectNodeWithModA = () => (state, dispatch) => {
|
|
256
|
+
const {
|
|
257
|
+
selection
|
|
258
|
+
} = state;
|
|
259
|
+
const {
|
|
260
|
+
$from,
|
|
261
|
+
$to
|
|
262
|
+
} = selection;
|
|
263
|
+
// Check if the selection is at the top level (e.g., in a paragraph)
|
|
264
|
+
const isTopLevelSelection = $from.depth === 1 || $to.depth === 1;
|
|
265
|
+
|
|
266
|
+
// Determine if the selection is within a code block
|
|
267
|
+
const isInCodeBlock = $from.sameParent($to) && $from.parent.type === state.schema.nodes.codeBlock;
|
|
268
|
+
|
|
269
|
+
// If the selection is at the top level and not in a code block, or if a table is selected, do nothing
|
|
270
|
+
if (isTopLevelSelection && !isInCodeBlock) {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Get the depth of the first common ancestor node
|
|
275
|
+
let commonAncestorDepth = $from.sharedDepth($to.pos);
|
|
276
|
+
|
|
277
|
+
// We need to adjust the common ancestor depth if a table is selected
|
|
278
|
+
// to skip the current table node and select the parent node instead
|
|
279
|
+
if (isTableSelected(state.selection)) {
|
|
280
|
+
const table = findParentNodeOfType(state.schema.nodes.table)(state.selection);
|
|
281
|
+
if (table) {
|
|
282
|
+
commonAncestorDepth = table.depth - 1;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
for (let depth = commonAncestorDepth; depth > 0; depth--) {
|
|
286
|
+
const node = $from.node(depth);
|
|
287
|
+
const isParentBlockQuote = node.type.name === 'blockquote';
|
|
288
|
+
const isSelectable = NodeSelection.isSelectable(node) && !isParentBlockQuote;
|
|
289
|
+
if (isSelectable) {
|
|
290
|
+
if (dispatch) {
|
|
291
|
+
dispatch(state.tr.setSelection(NodeSelection.create(state.doc, $from.before(depth))));
|
|
292
|
+
}
|
|
293
|
+
return true;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return false;
|
|
252
297
|
};
|
|
@@ -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,13 @@ 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
|
+
exposure: true
|
|
17
|
+
})) {
|
|
18
|
+
// Ignored via go/ees005
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
20
|
+
bindKeymapWithCommand(selectNode.common, selectNodeWithModA(), list);
|
|
21
|
+
}
|
|
14
22
|
return keymap(list);
|
|
15
23
|
}
|
|
16
24
|
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,8 @@
|
|
|
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 { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
6
|
+
import { isTableSelected } from '@atlaskit/editor-tables/utils';
|
|
5
7
|
import { SelectionDirection, selectionPluginKey } from '../types';
|
|
6
8
|
import { SelectionActionTypes } from './actions';
|
|
7
9
|
import { createCommand, getPluginState } from './plugin-factory';
|
|
@@ -250,4 +252,45 @@ export var setSelectionInsideAtNodeEnd = function setSelectionInsideAtNodeEnd(se
|
|
|
250
252
|
}
|
|
251
253
|
return false;
|
|
252
254
|
};
|
|
255
|
+
};
|
|
256
|
+
export var selectNodeWithModA = function selectNodeWithModA() {
|
|
257
|
+
return function (state, dispatch) {
|
|
258
|
+
var selection = state.selection;
|
|
259
|
+
var $from = selection.$from,
|
|
260
|
+
$to = selection.$to;
|
|
261
|
+
// Check if the selection is at the top level (e.g., in a paragraph)
|
|
262
|
+
var isTopLevelSelection = $from.depth === 1 || $to.depth === 1;
|
|
263
|
+
|
|
264
|
+
// Determine if the selection is within a code block
|
|
265
|
+
var isInCodeBlock = $from.sameParent($to) && $from.parent.type === state.schema.nodes.codeBlock;
|
|
266
|
+
|
|
267
|
+
// If the selection is at the top level and not in a code block, or if a table is selected, do nothing
|
|
268
|
+
if (isTopLevelSelection && !isInCodeBlock) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Get the depth of the first common ancestor node
|
|
273
|
+
var commonAncestorDepth = $from.sharedDepth($to.pos);
|
|
274
|
+
|
|
275
|
+
// We need to adjust the common ancestor depth if a table is selected
|
|
276
|
+
// to skip the current table node and select the parent node instead
|
|
277
|
+
if (isTableSelected(state.selection)) {
|
|
278
|
+
var table = findParentNodeOfType(state.schema.nodes.table)(state.selection);
|
|
279
|
+
if (table) {
|
|
280
|
+
commonAncestorDepth = table.depth - 1;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
for (var depth = commonAncestorDepth; depth > 0; depth--) {
|
|
284
|
+
var node = $from.node(depth);
|
|
285
|
+
var isParentBlockQuote = node.type.name === 'blockquote';
|
|
286
|
+
var isSelectable = NodeSelection.isSelectable(node) && !isParentBlockQuote;
|
|
287
|
+
if (isSelectable) {
|
|
288
|
+
if (dispatch) {
|
|
289
|
+
dispatch(state.tr.setSelection(NodeSelection.create(state.doc, $from.before(depth))));
|
|
290
|
+
}
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return false;
|
|
295
|
+
};
|
|
253
296
|
};
|
|
@@ -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,13 @@ 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
|
+
exposure: true
|
|
17
|
+
})) {
|
|
18
|
+
// Ignored via go/ees005
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
20
|
+
bindKeymapWithCommand(selectNode.common, selectNodeWithModA(), list);
|
|
21
|
+
}
|
|
14
22
|
return keymap(list);
|
|
15
23
|
}
|
|
16
24
|
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.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "Selection plugin for @atlaskit/editor-core",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -20,13 +20,13 @@
|
|
|
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.
|
|
29
|
-
"@atlaskit/tokens": "^4.
|
|
28
|
+
"@atlaskit/tmp-editor-statsig": "^3.5.0",
|
|
29
|
+
"@atlaskit/tokens": "^4.4.0",
|
|
30
30
|
"@babel/runtime": "^7.0.0"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|