@atlaskit/editor-plugin-selection 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/LICENSE.md +13 -0
  3. package/README.md +30 -0
  4. package/dist/cjs/actions.js +11 -0
  5. package/dist/cjs/commands.js +257 -0
  6. package/dist/cjs/gap-cursor/actions.js +255 -0
  7. package/dist/cjs/gap-cursor/direction.js +23 -0
  8. package/dist/cjs/gap-cursor/selection.js +30 -0
  9. package/dist/cjs/gap-cursor/utils/is-ignored.js +12 -0
  10. package/dist/cjs/gap-cursor/utils/is-valid-target-node.js +12 -0
  11. package/dist/cjs/gap-cursor/utils/place-gap-cursor.js +103 -0
  12. package/dist/cjs/gap-cursor/utils.js +137 -0
  13. package/dist/cjs/gap-cursor-selection.js +37 -0
  14. package/dist/cjs/index.js +12 -0
  15. package/dist/cjs/plugin-factory.js +49 -0
  16. package/dist/cjs/plugin.js +75 -0
  17. package/dist/cjs/pm-plugins/events/create-selection-between.js +92 -0
  18. package/dist/cjs/pm-plugins/events/keydown.js +115 -0
  19. package/dist/cjs/pm-plugins/gap-cursor-keymap.js +46 -0
  20. package/dist/cjs/pm-plugins/gap-cursor-main.js +159 -0
  21. package/dist/cjs/pm-plugins/gap-cursor-plugin-key.js +8 -0
  22. package/dist/cjs/pm-plugins/keymap.js +16 -0
  23. package/dist/cjs/pm-plugins/selection-main.js +104 -0
  24. package/dist/cjs/reducer.js +26 -0
  25. package/dist/cjs/types.js +20 -0
  26. package/dist/cjs/utils.js +280 -0
  27. package/dist/es2019/actions.js +5 -0
  28. package/dist/es2019/commands.js +250 -0
  29. package/dist/es2019/gap-cursor/actions.js +256 -0
  30. package/dist/es2019/gap-cursor/direction.js +15 -0
  31. package/dist/es2019/gap-cursor/selection.js +1 -0
  32. package/dist/es2019/gap-cursor/utils/is-ignored.js +1 -0
  33. package/dist/es2019/gap-cursor/utils/is-valid-target-node.js +1 -0
  34. package/dist/es2019/gap-cursor/utils/place-gap-cursor.js +94 -0
  35. package/dist/es2019/gap-cursor/utils.js +124 -0
  36. package/dist/es2019/gap-cursor-selection.js +2 -0
  37. package/dist/es2019/index.js +1 -0
  38. package/dist/es2019/plugin-factory.js +43 -0
  39. package/dist/es2019/plugin.js +60 -0
  40. package/dist/es2019/pm-plugins/events/create-selection-between.js +89 -0
  41. package/dist/es2019/pm-plugins/events/keydown.js +111 -0
  42. package/dist/es2019/pm-plugins/gap-cursor-keymap.js +40 -0
  43. package/dist/es2019/pm-plugins/gap-cursor-main.js +157 -0
  44. package/dist/es2019/pm-plugins/gap-cursor-plugin-key.js +2 -0
  45. package/dist/es2019/pm-plugins/keymap.js +10 -0
  46. package/dist/es2019/pm-plugins/selection-main.js +97 -0
  47. package/dist/es2019/reducer.js +18 -0
  48. package/dist/es2019/types.js +9 -0
  49. package/dist/es2019/utils.js +233 -0
  50. package/dist/esm/actions.js +5 -0
  51. package/dist/esm/commands.js +251 -0
  52. package/dist/esm/gap-cursor/actions.js +249 -0
  53. package/dist/esm/gap-cursor/direction.js +15 -0
  54. package/dist/esm/gap-cursor/selection.js +1 -0
  55. package/dist/esm/gap-cursor/utils/is-ignored.js +1 -0
  56. package/dist/esm/gap-cursor/utils/is-valid-target-node.js +1 -0
  57. package/dist/esm/gap-cursor/utils/place-gap-cursor.js +97 -0
  58. package/dist/esm/gap-cursor/utils.js +128 -0
  59. package/dist/esm/gap-cursor-selection.js +2 -0
  60. package/dist/esm/index.js +1 -0
  61. package/dist/esm/plugin-factory.js +43 -0
  62. package/dist/esm/plugin.js +68 -0
  63. package/dist/esm/pm-plugins/events/create-selection-between.js +86 -0
  64. package/dist/esm/pm-plugins/events/keydown.js +109 -0
  65. package/dist/esm/pm-plugins/gap-cursor-keymap.js +40 -0
  66. package/dist/esm/pm-plugins/gap-cursor-main.js +153 -0
  67. package/dist/esm/pm-plugins/gap-cursor-plugin-key.js +2 -0
  68. package/dist/esm/pm-plugins/keymap.js +10 -0
  69. package/dist/esm/pm-plugins/selection-main.js +98 -0
  70. package/dist/esm/reducer.js +19 -0
  71. package/dist/esm/types.js +9 -0
  72. package/dist/esm/utils.js +241 -0
  73. package/dist/types/actions.d.ts +17 -0
  74. package/dist/types/commands.d.ts +9 -0
  75. package/dist/types/gap-cursor/actions.d.ts +23 -0
  76. package/dist/types/gap-cursor/direction.d.ts +10 -0
  77. package/dist/types/gap-cursor/selection.d.ts +1 -0
  78. package/dist/types/gap-cursor/utils/is-ignored.d.ts +1 -0
  79. package/dist/types/gap-cursor/utils/is-valid-target-node.d.ts +1 -0
  80. package/dist/types/gap-cursor/utils/place-gap-cursor.d.ts +2 -0
  81. package/dist/types/gap-cursor/utils.d.ts +8 -0
  82. package/dist/types/gap-cursor-selection.d.ts +2 -0
  83. package/dist/types/index.d.ts +3 -0
  84. package/dist/types/plugin-factory.d.ts +2 -0
  85. package/dist/types/plugin.d.ts +13 -0
  86. package/dist/types/pm-plugins/events/create-selection-between.d.ts +4 -0
  87. package/dist/types/pm-plugins/events/keydown.d.ts +2 -0
  88. package/dist/types/pm-plugins/gap-cursor-keymap.d.ts +2 -0
  89. package/dist/types/pm-plugins/gap-cursor-main.d.ts +6 -0
  90. package/dist/types/pm-plugins/gap-cursor-plugin-key.d.ts +2 -0
  91. package/dist/types/pm-plugins/keymap.d.ts +3 -0
  92. package/dist/types/pm-plugins/selection-main.d.ts +7 -0
  93. package/dist/types/reducer.d.ts +3 -0
  94. package/dist/types/types.d.ts +20 -0
  95. package/dist/types/utils.d.ts +58 -0
  96. package/package.json +93 -0
  97. package/types/package.json +15 -0
@@ -0,0 +1,241 @@
1
+ import { createSelectionClickHandler, getAllSelectionAnalyticsPayload, getCellSelectionAnalyticsPayload, getNodeSelectionAnalyticsPayload, getRangeSelectionAnalyticsPayload, isIgnored as isIgnoredByGapCursor, isSelectionAtEndOfNode, isSelectionAtStartOfNode } from '@atlaskit/editor-common/selection';
2
+ import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
3
+ import { AllSelection, NodeSelection, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
4
+ import { findParentNode, flatten } from '@atlaskit/editor-prosemirror/utils';
5
+ import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
6
+ import { akEditorSelectedNodeClassName } from '@atlaskit/editor-shared-styles';
7
+ import { selectionPluginKey } from './types';
8
+ export var getDecorations = function getDecorations(tr) {
9
+ if (tr.selection instanceof NodeSelection) {
10
+ return DecorationSet.create(tr.doc, [Decoration.node(tr.selection.from, tr.selection.to, {
11
+ class: akEditorSelectedNodeClassName
12
+ })]);
13
+ }
14
+ if (tr.selection instanceof TextSelection || tr.selection instanceof AllSelection) {
15
+ var decorations = getNodesToDecorateFromSelection(tr.selection, tr.doc).map(function (_ref) {
16
+ var node = _ref.node,
17
+ pos = _ref.pos;
18
+ return Decoration.node(pos, pos + node.nodeSize, {
19
+ class: akEditorSelectedNodeClassName
20
+ });
21
+ });
22
+ return DecorationSet.create(tr.doc, decorations);
23
+ }
24
+ return DecorationSet.empty;
25
+ };
26
+ var topLevelBlockNodesThatHaveSelectionStyles = ['table', 'panel', 'expand', 'layoutSection', 'decisionList', 'decisionItem', 'codeBlock'];
27
+
28
+ /**
29
+ * Use `getNodesToDecorateFromSelection` to collect and return
30
+ * a list of nodes within the Selection that should have Selection
31
+ * decorations applied. This allows selection styles to be added to
32
+ * nested nodes. It will ignore text nodes as decorations are
33
+ * applied natively and also ignore nodes that don't completely
34
+ * sit within the given `Selection`.
35
+ */
36
+ export var getNodesToDecorateFromSelection = function getNodesToDecorateFromSelection(selection, doc) {
37
+ var nodes = [];
38
+ if (selection.from !== selection.to) {
39
+ var from = selection.from,
40
+ to = selection.to;
41
+ doc.nodesBetween(from, to, function (node, pos) {
42
+ var withinSelection = from <= pos && pos + node.nodeSize <= to;
43
+ // The reason we need to check for these nodes is to stop
44
+ // traversing their children if they are within a selection -
45
+ // this is to prevent selection styles from being added to
46
+ // the children as well as the parent node.
47
+ // Example scenario is if an entire table has been selected
48
+ // we should not traverse its children so we can apply the
49
+ // selection styles to the table. But if an entire tableRow
50
+ // has been selected (but the parent table has not) we should
51
+ // traverse it as it could contain other nodes that need
52
+ // selection styles. I couldn’t see a clear way to differentiate
53
+ // without explicitly stating which nodes should be traversed
54
+ // and which shouldn’t.
55
+ var isTopLevelNodeThatHasSelectionStyles = topLevelBlockNodesThatHaveSelectionStyles.includes(node.type.name);
56
+ // If the node is a top-level block node and completely sits within
57
+ // the selection, we do not recurse it's children to prevent selection
58
+ // styles being added to its child nodes. The expected behaviour
59
+ // is that selection styles are only added to the parent.
60
+ if (node && withinSelection && isTopLevelNodeThatHasSelectionStyles) {
61
+ nodes.push({
62
+ node: node,
63
+ pos: pos
64
+ });
65
+ return false;
66
+ // Otherwise we recurse the children and return them so we can apply
67
+ // selection styles. Text is handled by the browser.
68
+ } else if (node && withinSelection && !node.isText) {
69
+ nodes.push({
70
+ node: node,
71
+ pos: pos
72
+ });
73
+ }
74
+ return true;
75
+ });
76
+ }
77
+ return nodes;
78
+ };
79
+ export function shouldRecalcDecorations(_ref2) {
80
+ var oldEditorState = _ref2.oldEditorState,
81
+ newEditorState = _ref2.newEditorState;
82
+ var oldSelection = oldEditorState.selection;
83
+ var newSelection = newEditorState.selection;
84
+ var oldPluginState = selectionPluginKey.getState(oldEditorState);
85
+ var newPluginState = selectionPluginKey.getState(newEditorState);
86
+ if (!oldPluginState || !newPluginState) {
87
+ return false;
88
+ }
89
+
90
+ // If selection is unchanged, no need to recalculate
91
+ if (oldSelection.eq(newSelection)) {
92
+ // We need this special case for NodeSelection, as Prosemirror still thinks the
93
+ // selections are equal when the node has changed
94
+ if (oldSelection instanceof NodeSelection && newSelection instanceof NodeSelection) {
95
+ var oldDecorations = oldPluginState.decorationSet.find();
96
+ var newDecorations = newPluginState.decorationSet.find();
97
+ // There might not be old or new decorations if the node selection is for a text node
98
+ // This wouldn't have happened intentionally, but we need to handle this case regardless
99
+ if (oldDecorations.length > 0 && newDecorations.length > 0) {
100
+ return !oldDecorations[0].eq(newDecorations[0]);
101
+ }
102
+ return !(oldDecorations.length === 0 && newDecorations.length === 0);
103
+ }
104
+ return false;
105
+ }
106
+
107
+ // There's no point updating decorations if going from one standard TextSelection to another
108
+ if (oldSelection instanceof TextSelection && newSelection instanceof TextSelection && oldSelection.from === oldSelection.to && newSelection.from === newSelection.to) {
109
+ return false;
110
+ }
111
+ return true;
112
+ }
113
+ export var isSelectableContainerNode = function isSelectableContainerNode(node) {
114
+ return !!(node && !node.isAtom && NodeSelection.isSelectable(node));
115
+ };
116
+ export var isSelectableChildNode = function isSelectableChildNode(node) {
117
+ return !!(node && (node.isText || isEmptyParagraph(node) || NodeSelection.isSelectable(node)));
118
+ };
119
+
120
+ /**
121
+ * Finds closest parent node that is a selectable block container node
122
+ * If it finds a parent that is not selectable but supports gap cursor, will
123
+ * return undefined
124
+ */
125
+ export var findSelectableContainerParent = function findSelectableContainerParent(selection) {
126
+ var foundNodeThatSupportsGapCursor = false;
127
+ var selectableNode = findParentNode(function (node) {
128
+ var isSelectable = isSelectableContainerNode(node);
129
+ if (!isSelectable && !isIgnoredByGapCursor(node)) {
130
+ foundNodeThatSupportsGapCursor = true;
131
+ }
132
+ return isSelectable;
133
+ })(selection);
134
+ if (!foundNodeThatSupportsGapCursor) {
135
+ return selectableNode;
136
+ }
137
+ };
138
+
139
+ /**
140
+ * Finds node before that is a selectable block container node, starting
141
+ * from $pos.depth + 1 and working in
142
+ * If it finds a node that is not selectable but supports gap cursor, will
143
+ * return undefined
144
+ */
145
+ export var findSelectableContainerBefore = function findSelectableContainerBefore($pos, doc) {
146
+ // prosemirror just returns the same pos from Selection.findFrom when
147
+ // parent.inlineContent is true, so we move position back one here
148
+ // to counteract that
149
+ if ($pos.parent.inlineContent && isSelectableContainerNode($pos.parent)) {
150
+ $pos = doc.resolve($pos.start() - 1);
151
+ }
152
+ var selectionBefore = Selection.findFrom($pos, -1);
153
+ if (selectionBefore) {
154
+ var $selectionBefore = doc.resolve(selectionBefore.from);
155
+ for (var i = $pos.depth + 1; i <= $selectionBefore.depth; i++) {
156
+ var node = $selectionBefore.node(i);
157
+ if (isSelectableContainerNode(node)) {
158
+ return {
159
+ node: node,
160
+ pos: $selectionBefore.start(i) - 1
161
+ };
162
+ }
163
+ if (i > $pos.depth + 1 && !isIgnoredByGapCursor(node)) {
164
+ return;
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Stick to the default left selection behaviour,
170
+ * useful for mediaSingleWithCaption
171
+ */
172
+ if (selectionBefore instanceof NodeSelection && NodeSelection.isSelectable(selectionBefore.node)) {
173
+ return {
174
+ node: selectionBefore.node,
175
+ pos: selectionBefore.from
176
+ };
177
+ }
178
+ }
179
+ };
180
+
181
+ /**
182
+ * Finds node after that is a selectable block container node, starting
183
+ * from $pos.depth + 1 and working in
184
+ * If it finds a node that is not selectable but supports gap cursor, will
185
+ * return undefined
186
+ */
187
+ export var findSelectableContainerAfter = function findSelectableContainerAfter($pos, doc) {
188
+ var selectionAfter = Selection.findFrom($pos, 1);
189
+ if (selectionAfter) {
190
+ var $selectionAfter = doc.resolve(selectionAfter.from);
191
+ for (var i = $pos.depth + 1; i <= $selectionAfter.depth; i++) {
192
+ var node = $selectionAfter.node(i);
193
+ if (isSelectableContainerNode(node)) {
194
+ return {
195
+ node: node,
196
+ pos: $selectionAfter.start(i) - 1
197
+ };
198
+ }
199
+ if (i > $pos.depth + 1 && !isIgnoredByGapCursor(node)) {
200
+ return;
201
+ }
202
+ }
203
+ }
204
+ };
205
+
206
+ /**
207
+ * Finds first child node that is a selectable block container node OR that
208
+ * supports gap cursor
209
+ */
210
+ export var findFirstChildNodeToSelect = function findFirstChildNodeToSelect(parent) {
211
+ return flatten(parent).find(function (child) {
212
+ return isSelectableChildNode(child.node) || !isIgnoredByGapCursor(child.node);
213
+ });
214
+ };
215
+
216
+ /**
217
+ * Finds last child node that is a selectable block container node OR that
218
+ * supports gap cursor
219
+ */
220
+ export var findLastChildNodeToSelect = function findLastChildNodeToSelect(parent) {
221
+ var child;
222
+ parent.descendants(function (node, pos) {
223
+ if (isSelectableChildNode(node) || !isIgnoredByGapCursor(node)) {
224
+ child = {
225
+ node: node,
226
+ pos: pos
227
+ };
228
+ return false;
229
+ }
230
+ });
231
+ if (child) {
232
+ return child;
233
+ }
234
+ };
235
+ export var isSelectionAtStartOfParentNode = function isSelectionAtStartOfParentNode($pos, selection) {
236
+ return isSelectionAtStartOfNode($pos, findSelectableContainerParent(selection));
237
+ };
238
+ export var isSelectionAtEndOfParentNode = function isSelectionAtEndOfParentNode($pos, selection) {
239
+ return isSelectionAtEndOfNode($pos, findSelectableContainerParent(selection));
240
+ };
241
+ export { getNodeSelectionAnalyticsPayload, getAllSelectionAnalyticsPayload, getRangeSelectionAnalyticsPayload, getCellSelectionAnalyticsPayload, createSelectionClickHandler };
@@ -0,0 +1,17 @@
1
+ import type { Selection } from '@atlaskit/editor-prosemirror/state';
2
+ import type { DecorationSet } from '@atlaskit/editor-prosemirror/view';
3
+ import type { RelativeSelectionPos } from './types';
4
+ export declare enum SelectionActionTypes {
5
+ SET_DECORATIONS = "SET_DECORATIONS",
6
+ SET_RELATIVE_SELECTION = "SET_RELATIVE_SELECTION"
7
+ }
8
+ export interface SetDecorations {
9
+ type: SelectionActionTypes.SET_DECORATIONS;
10
+ decorationSet: DecorationSet;
11
+ selection: Selection;
12
+ }
13
+ export interface SetRelativeSelection {
14
+ type: SelectionActionTypes.SET_RELATIVE_SELECTION;
15
+ selectionRelativeToNode?: RelativeSelectionPos;
16
+ }
17
+ export type SelectionAction = SetDecorations | SetRelativeSelection;
@@ -0,0 +1,9 @@
1
+ import type { Command, EditorCommandWithMetadata } from '@atlaskit/editor-common/types';
2
+ import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
3
+ import { Selection } from '@atlaskit/editor-prosemirror/state';
4
+ import { RelativeSelectionPos } from './types';
5
+ export declare const selectNearNode: EditorCommandWithMetadata;
6
+ export declare const setSelectionRelativeToNode: (selectionRelativeToNode?: RelativeSelectionPos, selection?: Selection | null) => Command;
7
+ export declare const arrowRight: Command;
8
+ export declare const arrowLeft: Command;
9
+ export declare const setSelectionInsideAtNodeEnd: (selectionRelativeToNode: RelativeSelectionPos, node: PmNode, from: number, to: number) => Command;
@@ -0,0 +1,23 @@
1
+ import type { Command } from '@atlaskit/editor-common/types';
2
+ import type { ResolvedPos } from '@atlaskit/editor-prosemirror/model';
3
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
4
+ import { Direction } from './direction';
5
+ export type DirectionString = 'up' | 'down' | 'left' | 'right' | 'forward' | 'backward';
6
+ export declare const shouldSkipGapCursor: (direction: Direction, state: EditorState, $pos: ResolvedPos) => boolean;
7
+ export declare const arrow: (dir: Direction, endOfTextblock?: ((dir: DirectionString, state?: EditorState) => boolean) | undefined) => Command;
8
+ export declare const deleteNode: (dir: Direction) => Command;
9
+ export declare const setSelectionTopLevelBlocks: (tr: Transaction, event: React.MouseEvent<any>, editorRef: HTMLElement, posAtCoords: (coords: {
10
+ left: number;
11
+ top: number;
12
+ }) => {
13
+ pos: number;
14
+ inside: number;
15
+ } | null | void, editorFocused: boolean) => void;
16
+ export declare const setCursorForTopLevelBlocks: (event: React.MouseEvent<any>, editorRef: HTMLElement, posAtCoords: (coords: {
17
+ left: number;
18
+ top: number;
19
+ }) => {
20
+ pos: number;
21
+ inside: number;
22
+ } | null | void, editorFocused: boolean) => Command;
23
+ export declare const hasGapCursorPlugin: (state: EditorState) => boolean;
@@ -0,0 +1,10 @@
1
+ export declare enum Direction {
2
+ UP = "up",
3
+ RIGHT = "right",
4
+ DOWN = "down",
5
+ LEFT = "left",
6
+ BACKWARD = "backward",
7
+ FORWARD = "forward"
8
+ }
9
+ export declare function isBackward(dir: Direction): boolean;
10
+ export declare function isForward(dir: Direction): boolean;
@@ -0,0 +1 @@
1
+ export { GapCursorSelection, JSON_ID, Side, GapBookmark, } from '@atlaskit/editor-common/selection';
@@ -0,0 +1 @@
1
+ export { isIgnored } from '@atlaskit/editor-common/selection';
@@ -0,0 +1 @@
1
+ export { isValidTargetNode } from '@atlaskit/editor-common/selection';
@@ -0,0 +1,2 @@
1
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
2
+ export declare const toDOM: (view: EditorView, getPos: () => number | undefined) => HTMLSpanElement;
@@ -0,0 +1,8 @@
1
+ import type { Node as PMNode, ResolvedPos, Schema } from '@atlaskit/editor-prosemirror/model';
2
+ import { Side } from './selection';
3
+ export declare const isLeftCursor: (side: Side) => side is Side.LEFT;
4
+ export declare function getMediaNearPos(doc: PMNode, $pos: ResolvedPos, schema: Schema, dir?: number): PMNode | null;
5
+ export declare const isTextBlockNearPos: (doc: PMNode, schema: Schema, $pos: ResolvedPos, dir: number) => boolean;
6
+ export declare function getLayoutModeFromTargetNode(node: PMNode): string;
7
+ export declare const isIgnoredClick: (elem: HTMLElement) => boolean;
8
+ export declare const getComputedStyleForLayoutMode: (dom: HTMLElement, node: PMNode | undefined | null, style: CSSStyleDeclaration) => CSSStyleDeclaration;
@@ -0,0 +1,2 @@
1
+ export { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
2
+ export { setCursorForTopLevelBlocks, setSelectionTopLevelBlocks, hasGapCursorPlugin, } from './gap-cursor/actions';
@@ -0,0 +1,3 @@
1
+ export { selectionPlugin } from './plugin';
2
+ export type { SelectionPlugin } from './plugin';
3
+ export type { EditorSelectionAPI, SetSelectionRelativeToNode } from './types';
@@ -0,0 +1,2 @@
1
+ import type { SelectionPluginState } from './types';
2
+ export declare const createCommand: <A = import("./actions").SelectionAction>(action: A | ((state: Readonly<import("prosemirror-state").EditorState>) => false | A), transform?: ((tr: import("prosemirror-state").Transaction, state: import("prosemirror-state").EditorState) => import("prosemirror-state").Transaction) | undefined) => import("@atlaskit/editor-common/types").Command, getPluginState: (state: import("prosemirror-state").EditorState) => SelectionPluginState, createPluginState: (dispatch: import("@atlaskit/editor-common/event-dispatcher").Dispatch<any>, initialState: SelectionPluginState | ((state: import("prosemirror-state").EditorState) => SelectionPluginState)) => import("prosemirror-state").SafeStateField<SelectionPluginState>;
@@ -0,0 +1,13 @@
1
+ import type { SelectionSharedState } from '@atlaskit/editor-common/selection';
2
+ import type { EditorCommand, NextEditorPlugin } from '@atlaskit/editor-common/types';
3
+ import type { EditorSelectionAPI, SelectionPluginOptions } from './types';
4
+ export type SelectionPlugin = NextEditorPlugin<'selection', {
5
+ pluginConfiguration: SelectionPluginOptions | undefined;
6
+ actions: EditorSelectionAPI;
7
+ commands: {
8
+ displayGapCursor: (toggle: boolean) => EditorCommand;
9
+ };
10
+ sharedState: SelectionSharedState;
11
+ }>;
12
+ export declare const selectionPlugin: SelectionPlugin;
13
+ export default selectionPlugin;
@@ -0,0 +1,4 @@
1
+ import type { ResolvedPos } from '@atlaskit/editor-prosemirror/model';
2
+ import { TextSelection } from '@atlaskit/editor-prosemirror/state';
3
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
4
+ export declare const onCreateSelectionBetween: (view: EditorView, $anchor: ResolvedPos, $head: ResolvedPos) => TextSelection | null;
@@ -0,0 +1,2 @@
1
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
2
+ export declare const onKeydown: (view: EditorView, event: Event) => boolean;
@@ -0,0 +1,2 @@
1
+ import type { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
+ export default function keymapPlugin(): SafePlugin;
@@ -0,0 +1,6 @@
1
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
+ declare const plugin: SafePlugin<{
3
+ selectionIsGapCursor: boolean;
4
+ displayGapCursor: boolean;
5
+ }>;
6
+ export default plugin;
@@ -0,0 +1,2 @@
1
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
2
+ export declare const gapCursorPluginKey: PluginKey<any>;
@@ -0,0 +1,3 @@
1
+ import type { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
+ declare function keymapPlugin(): SafePlugin<any>;
3
+ export default keymapPlugin;
@@ -0,0 +1,7 @@
1
+ import type { DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
2
+ import type { Dispatch } from '@atlaskit/editor-common/event-dispatcher';
3
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
4
+ import type { EditorState } from '@atlaskit/editor-prosemirror/state';
5
+ import type { SelectionPluginOptions, SelectionPluginState } from '../types';
6
+ export declare const getInitialState: (state: EditorState) => SelectionPluginState;
7
+ export declare const createPlugin: (dispatch: Dispatch, dispatchAnalyticsEvent: DispatchAnalyticsEvent, options?: SelectionPluginOptions) => SafePlugin<SelectionPluginState>;
@@ -0,0 +1,3 @@
1
+ import type { SelectionAction } from './actions';
2
+ import type { SelectionPluginState } from './types';
3
+ export declare function reducer(pluginState: SelectionPluginState, action: SelectionAction): SelectionPluginState;
@@ -0,0 +1,20 @@
1
+ import { RelativeSelectionPos } from '@atlaskit/editor-common/selection';
2
+ export type { SelectionPluginState } from '@atlaskit/editor-common/selection';
3
+ import type { LongPressSelectionPluginOptions } from '@atlaskit/editor-common/types';
4
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
5
+ import type { EditorState, Selection, Transaction } from '@atlaskit/editor-prosemirror/state';
6
+ export declare const selectionPluginKey: PluginKey<any>;
7
+ export { RelativeSelectionPos };
8
+ export declare enum SelectionDirection {
9
+ Before = -1,
10
+ After = 1
11
+ }
12
+ export type SetSelectionRelativeToNode = (props: {
13
+ selectionRelativeToNode?: RelativeSelectionPos;
14
+ selection?: Selection | null;
15
+ }) => (state: EditorState) => Transaction;
16
+ export type EditorSelectionAPI = {
17
+ selectNearNode: SetSelectionRelativeToNode;
18
+ };
19
+ export interface SelectionPluginOptions extends LongPressSelectionPluginOptions {
20
+ }
@@ -0,0 +1,58 @@
1
+ import { createSelectionClickHandler, getAllSelectionAnalyticsPayload, getCellSelectionAnalyticsPayload, getNodeSelectionAnalyticsPayload, getRangeSelectionAnalyticsPayload } from '@atlaskit/editor-common/selection';
2
+ import type { Node as PmNode, ResolvedPos } from '@atlaskit/editor-prosemirror/model';
3
+ import type { EditorState, ReadonlyTransaction, Transaction } from '@atlaskit/editor-prosemirror/state';
4
+ import { Selection } from '@atlaskit/editor-prosemirror/state';
5
+ import type { ContentNodeWithPos, NodeWithPos } from '@atlaskit/editor-prosemirror/utils';
6
+ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
7
+ export declare const getDecorations: (tr: Transaction | ReadonlyTransaction) => DecorationSet;
8
+ /**
9
+ * Use `getNodesToDecorateFromSelection` to collect and return
10
+ * a list of nodes within the Selection that should have Selection
11
+ * decorations applied. This allows selection styles to be added to
12
+ * nested nodes. It will ignore text nodes as decorations are
13
+ * applied natively and also ignore nodes that don't completely
14
+ * sit within the given `Selection`.
15
+ */
16
+ export declare const getNodesToDecorateFromSelection: (selection: Selection, doc: PmNode) => {
17
+ node: PmNode;
18
+ pos: number;
19
+ }[];
20
+ export declare function shouldRecalcDecorations({ oldEditorState, newEditorState, }: {
21
+ oldEditorState: EditorState;
22
+ newEditorState: EditorState;
23
+ }): boolean;
24
+ export declare const isSelectableContainerNode: (node?: PmNode | null) => boolean;
25
+ export declare const isSelectableChildNode: (node?: PmNode | null) => boolean;
26
+ /**
27
+ * Finds closest parent node that is a selectable block container node
28
+ * If it finds a parent that is not selectable but supports gap cursor, will
29
+ * return undefined
30
+ */
31
+ export declare const findSelectableContainerParent: (selection: Selection) => ContentNodeWithPos | undefined;
32
+ /**
33
+ * Finds node before that is a selectable block container node, starting
34
+ * from $pos.depth + 1 and working in
35
+ * If it finds a node that is not selectable but supports gap cursor, will
36
+ * return undefined
37
+ */
38
+ export declare const findSelectableContainerBefore: ($pos: ResolvedPos, doc: PmNode) => NodeWithPos | undefined;
39
+ /**
40
+ * Finds node after that is a selectable block container node, starting
41
+ * from $pos.depth + 1 and working in
42
+ * If it finds a node that is not selectable but supports gap cursor, will
43
+ * return undefined
44
+ */
45
+ export declare const findSelectableContainerAfter: ($pos: ResolvedPos, doc: PmNode) => NodeWithPos | undefined;
46
+ /**
47
+ * Finds first child node that is a selectable block container node OR that
48
+ * supports gap cursor
49
+ */
50
+ export declare const findFirstChildNodeToSelect: (parent: PmNode) => NodeWithPos | undefined;
51
+ /**
52
+ * Finds last child node that is a selectable block container node OR that
53
+ * supports gap cursor
54
+ */
55
+ export declare const findLastChildNodeToSelect: (parent: PmNode) => NodeWithPos | undefined;
56
+ export declare const isSelectionAtStartOfParentNode: ($pos: ResolvedPos, selection: Selection) => boolean;
57
+ export declare const isSelectionAtEndOfParentNode: ($pos: ResolvedPos, selection: Selection) => boolean;
58
+ export { getNodeSelectionAnalyticsPayload, getAllSelectionAnalyticsPayload, getRangeSelectionAnalyticsPayload, getCellSelectionAnalyticsPayload, createSelectionClickHandler, };
package/package.json ADDED
@@ -0,0 +1,93 @@
1
+ {
2
+ "name": "@atlaskit/editor-plugin-selection",
3
+ "version": "0.1.0",
4
+ "description": "Selection plugin for @atlaskit/editor-core",
5
+ "publishConfig": {
6
+ "registry": "https://registry.npmjs.org/"
7
+ },
8
+ "repository": "https://bitbucket.org/atlassian/atlassian-frontend",
9
+ "author": "Atlassian Pty Ltd",
10
+ "license": "Apache-2.0",
11
+ "main": "dist/cjs/index.js",
12
+ "module": "dist/esm/index.js",
13
+ "module:es2019": "dist/es2019/index.js",
14
+ "types": "dist/types/index.d.ts",
15
+ "sideEffects": false,
16
+ "atlaskit:src": "src/index.ts",
17
+ "atlassian": {
18
+ "team": "Editor: Lego",
19
+ "releaseModel": "continuous",
20
+ "singleton": true
21
+ },
22
+ "dependencies": {
23
+ "@atlaskit/editor-common": "^76.8.0",
24
+ "@atlaskit/editor-prosemirror": "1.1.0",
25
+ "@atlaskit/editor-shared-styles": "^2.7.0",
26
+ "@atlaskit/editor-tables": "^2.3.10",
27
+ "@babel/runtime": "^7.0.0"
28
+ },
29
+ "peerDependencies": {
30
+ "react": "^16.8.0"
31
+ },
32
+ "devDependencies": {
33
+ "@af/editor-libra": "*",
34
+ "@af/visual-regression": "*",
35
+ "@atlaskit/editor-plugin-analytics": "^0.2.4",
36
+ "@atlaskit/editor-plugin-feature-flags": "^1.0.0",
37
+ "@atlaskit/editor-plugin-focus": "^0.2.1",
38
+ "@atlaskit/editor-plugin-grid": "^0.3.0",
39
+ "@atlaskit/editor-plugin-guideline": "^0.5.1",
40
+ "@atlaskit/editor-plugin-rule": "^0.1.2",
41
+ "@atlaskit/editor-plugin-width": "^0.2.2",
42
+ "@atlaskit/media-integration-test-helpers": "^3.0.0",
43
+ "@atlaskit/media-test-helpers": "^33.0.0",
44
+ "@atlaskit/ssr": "*",
45
+ "@atlaskit/visual-regression": "*",
46
+ "@atlaskit/webdriver-runner": "*",
47
+ "@atlassian/atlassian-frontend-prettier-config-1.0.0": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.0",
48
+ "@testing-library/react": "^12.1.5",
49
+ "react-dom": "^16.8.0",
50
+ "typescript": "~4.9.5",
51
+ "wait-for-expect": "^1.2.0"
52
+ },
53
+ "techstack": {
54
+ "@atlassian/frontend": {
55
+ "import-structure": [
56
+ "atlassian-conventions"
57
+ ],
58
+ "circular-dependencies": [
59
+ "file-and-folder-level"
60
+ ]
61
+ },
62
+ "@repo/internal": {
63
+ "dom-events": "use-bind-event-listener",
64
+ "analytics": [
65
+ "analytics-next"
66
+ ],
67
+ "design-tokens": [
68
+ "color"
69
+ ],
70
+ "theming": [
71
+ "react-context"
72
+ ],
73
+ "ui-components": [
74
+ "lite-mode"
75
+ ],
76
+ "deprecation": [
77
+ "no-deprecated-imports"
78
+ ],
79
+ "styling": [
80
+ "static",
81
+ "emotion"
82
+ ],
83
+ "imports": [
84
+ "import-no-extraneous-disable-for-examples-and-docs"
85
+ ]
86
+ }
87
+ },
88
+ "af:exports": {
89
+ ".": "./src/index.ts",
90
+ "./types": "./src/types.ts"
91
+ },
92
+ "prettier": "@atlassian/atlassian-frontend-prettier-config-1.0.0"
93
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "@atlaskit/editor-plugin-selection/types",
3
+ "main": "../dist/cjs/types.js",
4
+ "module": "../dist/esm/types.js",
5
+ "module:es2019": "../dist/es2019/types.js",
6
+ "sideEffects": false,
7
+ "types": "../dist/types/types.d.ts",
8
+ "typesVersions": {
9
+ ">=4.5 <4.9": {
10
+ "*": [
11
+ "../dist/types-ts4.5/types.d.ts"
12
+ ]
13
+ }
14
+ }
15
+ }