@atlaskit/editor-core 188.5.0 → 188.5.2

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 (130) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/cjs/labs/next/presets/default.js +2 -2
  3. package/dist/cjs/labs/next/presets/universal.js +1 -6
  4. package/dist/cjs/plugins/expand/index.js +0 -2
  5. package/dist/cjs/plugins/expand/nodeviews/index.js +37 -13
  6. package/dist/cjs/plugins/index.js +0 -7
  7. package/dist/cjs/ui/Addon/click-area-helper.js +9 -11
  8. package/dist/cjs/ui/ContentStyles/index.js +13 -13
  9. package/dist/cjs/utils/selection.js +12 -14
  10. package/dist/cjs/version-wrapper.js +1 -1
  11. package/dist/es2019/labs/next/presets/default.js +1 -1
  12. package/dist/es2019/labs/next/presets/universal.js +1 -6
  13. package/dist/es2019/plugins/expand/index.js +0 -2
  14. package/dist/es2019/plugins/expand/nodeviews/index.js +37 -13
  15. package/dist/es2019/plugins/index.js +0 -1
  16. package/dist/es2019/ui/Addon/click-area-helper.js +4 -6
  17. package/dist/es2019/ui/ContentStyles/index.js +1 -1
  18. package/dist/es2019/utils/selection.js +2 -17
  19. package/dist/es2019/version-wrapper.js +1 -1
  20. package/dist/esm/labs/next/presets/default.js +1 -1
  21. package/dist/esm/labs/next/presets/universal.js +1 -6
  22. package/dist/esm/plugins/expand/index.js +0 -2
  23. package/dist/esm/plugins/expand/nodeviews/index.js +37 -13
  24. package/dist/esm/plugins/index.js +0 -1
  25. package/dist/esm/ui/Addon/click-area-helper.js +4 -6
  26. package/dist/esm/ui/ContentStyles/index.js +1 -1
  27. package/dist/esm/utils/selection.js +2 -13
  28. package/dist/esm/version-wrapper.js +1 -1
  29. package/dist/types/labs/next/presets/default.d.ts +22 -8
  30. package/dist/types/plugins/expand/index.d.ts +1 -1
  31. package/dist/types/plugins/expand/nodeviews/index.d.ts +3 -2
  32. package/dist/types/plugins/index.d.ts +0 -1
  33. package/dist/types/utils/selection.d.ts +1 -4
  34. package/package.json +4 -3
  35. package/dist/cjs/plugins/selection/actions.js +0 -11
  36. package/dist/cjs/plugins/selection/commands.js +0 -257
  37. package/dist/cjs/plugins/selection/gap-cursor/actions.js +0 -272
  38. package/dist/cjs/plugins/selection/gap-cursor/direction.js +0 -23
  39. package/dist/cjs/plugins/selection/gap-cursor/selection.js +0 -30
  40. package/dist/cjs/plugins/selection/gap-cursor/styles.js +0 -17
  41. package/dist/cjs/plugins/selection/gap-cursor/utils/is-ignored.js +0 -12
  42. package/dist/cjs/plugins/selection/gap-cursor/utils/is-valid-target-node.js +0 -12
  43. package/dist/cjs/plugins/selection/gap-cursor/utils/place-gap-cursor.js +0 -103
  44. package/dist/cjs/plugins/selection/gap-cursor/utils.js +0 -137
  45. package/dist/cjs/plugins/selection/gap-cursor-selection.js +0 -37
  46. package/dist/cjs/plugins/selection/index.js +0 -65
  47. package/dist/cjs/plugins/selection/plugin-factory.js +0 -49
  48. package/dist/cjs/plugins/selection/pm-plugins/events/create-selection-between.js +0 -92
  49. package/dist/cjs/plugins/selection/pm-plugins/events/keydown.js +0 -115
  50. package/dist/cjs/plugins/selection/pm-plugins/gap-cursor-keymap.js +0 -46
  51. package/dist/cjs/plugins/selection/pm-plugins/gap-cursor-main.js +0 -160
  52. package/dist/cjs/plugins/selection/pm-plugins/gap-cursor-plugin-key.js +0 -8
  53. package/dist/cjs/plugins/selection/pm-plugins/keymap.js +0 -16
  54. package/dist/cjs/plugins/selection/pm-plugins/selection-main.js +0 -104
  55. package/dist/cjs/plugins/selection/reducer.js +0 -26
  56. package/dist/cjs/plugins/selection/types.js +0 -20
  57. package/dist/cjs/plugins/selection/utils.js +0 -280
  58. package/dist/cjs/selection-api/api.js +0 -27
  59. package/dist/es2019/plugins/selection/actions.js +0 -5
  60. package/dist/es2019/plugins/selection/commands.js +0 -250
  61. package/dist/es2019/plugins/selection/gap-cursor/actions.js +0 -270
  62. package/dist/es2019/plugins/selection/gap-cursor/direction.js +0 -15
  63. package/dist/es2019/plugins/selection/gap-cursor/selection.js +0 -1
  64. package/dist/es2019/plugins/selection/gap-cursor/styles.js +0 -145
  65. package/dist/es2019/plugins/selection/gap-cursor/utils/is-ignored.js +0 -1
  66. package/dist/es2019/plugins/selection/gap-cursor/utils/is-valid-target-node.js +0 -1
  67. package/dist/es2019/plugins/selection/gap-cursor/utils/place-gap-cursor.js +0 -94
  68. package/dist/es2019/plugins/selection/gap-cursor/utils.js +0 -124
  69. package/dist/es2019/plugins/selection/gap-cursor-selection.js +0 -2
  70. package/dist/es2019/plugins/selection/index.js +0 -51
  71. package/dist/es2019/plugins/selection/plugin-factory.js +0 -43
  72. package/dist/es2019/plugins/selection/pm-plugins/events/create-selection-between.js +0 -89
  73. package/dist/es2019/plugins/selection/pm-plugins/events/keydown.js +0 -112
  74. package/dist/es2019/plugins/selection/pm-plugins/gap-cursor-keymap.js +0 -40
  75. package/dist/es2019/plugins/selection/pm-plugins/gap-cursor-main.js +0 -158
  76. package/dist/es2019/plugins/selection/pm-plugins/gap-cursor-plugin-key.js +0 -2
  77. package/dist/es2019/plugins/selection/pm-plugins/keymap.js +0 -10
  78. package/dist/es2019/plugins/selection/pm-plugins/selection-main.js +0 -97
  79. package/dist/es2019/plugins/selection/reducer.js +0 -18
  80. package/dist/es2019/plugins/selection/types.js +0 -9
  81. package/dist/es2019/plugins/selection/utils.js +0 -233
  82. package/dist/es2019/selection-api/api.js +0 -20
  83. package/dist/esm/plugins/selection/actions.js +0 -5
  84. package/dist/esm/plugins/selection/commands.js +0 -251
  85. package/dist/esm/plugins/selection/gap-cursor/actions.js +0 -266
  86. package/dist/esm/plugins/selection/gap-cursor/direction.js +0 -15
  87. package/dist/esm/plugins/selection/gap-cursor/selection.js +0 -1
  88. package/dist/esm/plugins/selection/gap-cursor/styles.js +0 -10
  89. package/dist/esm/plugins/selection/gap-cursor/utils/is-ignored.js +0 -1
  90. package/dist/esm/plugins/selection/gap-cursor/utils/is-valid-target-node.js +0 -1
  91. package/dist/esm/plugins/selection/gap-cursor/utils/place-gap-cursor.js +0 -97
  92. package/dist/esm/plugins/selection/gap-cursor/utils.js +0 -128
  93. package/dist/esm/plugins/selection/gap-cursor-selection.js +0 -2
  94. package/dist/esm/plugins/selection/index.js +0 -58
  95. package/dist/esm/plugins/selection/plugin-factory.js +0 -43
  96. package/dist/esm/plugins/selection/pm-plugins/events/create-selection-between.js +0 -86
  97. package/dist/esm/plugins/selection/pm-plugins/events/keydown.js +0 -110
  98. package/dist/esm/plugins/selection/pm-plugins/gap-cursor-keymap.js +0 -40
  99. package/dist/esm/plugins/selection/pm-plugins/gap-cursor-main.js +0 -154
  100. package/dist/esm/plugins/selection/pm-plugins/gap-cursor-plugin-key.js +0 -2
  101. package/dist/esm/plugins/selection/pm-plugins/keymap.js +0 -10
  102. package/dist/esm/plugins/selection/pm-plugins/selection-main.js +0 -98
  103. package/dist/esm/plugins/selection/reducer.js +0 -19
  104. package/dist/esm/plugins/selection/types.js +0 -9
  105. package/dist/esm/plugins/selection/utils.js +0 -241
  106. package/dist/esm/selection-api/api.js +0 -21
  107. package/dist/types/plugins/selection/actions.d.ts +0 -17
  108. package/dist/types/plugins/selection/commands.d.ts +0 -10
  109. package/dist/types/plugins/selection/gap-cursor/actions.d.ts +0 -25
  110. package/dist/types/plugins/selection/gap-cursor/direction.d.ts +0 -10
  111. package/dist/types/plugins/selection/gap-cursor/selection.d.ts +0 -1
  112. package/dist/types/plugins/selection/gap-cursor/styles.d.ts +0 -2
  113. package/dist/types/plugins/selection/gap-cursor/utils/is-ignored.d.ts +0 -1
  114. package/dist/types/plugins/selection/gap-cursor/utils/is-valid-target-node.d.ts +0 -1
  115. package/dist/types/plugins/selection/gap-cursor/utils/place-gap-cursor.d.ts +0 -2
  116. package/dist/types/plugins/selection/gap-cursor/utils.d.ts +0 -8
  117. package/dist/types/plugins/selection/gap-cursor-selection.d.ts +0 -2
  118. package/dist/types/plugins/selection/index.d.ts +0 -13
  119. package/dist/types/plugins/selection/plugin-factory.d.ts +0 -2
  120. package/dist/types/plugins/selection/pm-plugins/events/create-selection-between.d.ts +0 -4
  121. package/dist/types/plugins/selection/pm-plugins/events/keydown.d.ts +0 -2
  122. package/dist/types/plugins/selection/pm-plugins/gap-cursor-keymap.d.ts +0 -2
  123. package/dist/types/plugins/selection/pm-plugins/gap-cursor-main.d.ts +0 -6
  124. package/dist/types/plugins/selection/pm-plugins/gap-cursor-plugin-key.d.ts +0 -2
  125. package/dist/types/plugins/selection/pm-plugins/keymap.d.ts +0 -3
  126. package/dist/types/plugins/selection/pm-plugins/selection-main.d.ts +0 -7
  127. package/dist/types/plugins/selection/reducer.d.ts +0 -3
  128. package/dist/types/plugins/selection/types.d.ts +0 -12
  129. package/dist/types/plugins/selection/utils.d.ts +0 -58
  130. package/dist/types/selection-api/api.d.ts +0 -11
@@ -1,51 +0,0 @@
1
- import { createPlugin } from './pm-plugins/selection-main';
2
- import { selectionPluginKey } from './types';
3
- import selectionKeymapPlugin from './pm-plugins/keymap';
4
- import gapCursorPlugin from './pm-plugins/gap-cursor-main';
5
- import { gapCursorPluginKey } from './pm-plugins/gap-cursor-plugin-key';
6
- import gapCursorKeymapPlugin from './pm-plugins/gap-cursor-keymap';
7
- import { selectNearNode } from './commands';
8
- const displayGapCursor = toggle => ({
9
- tr
10
- }) => {
11
- return tr.setMeta(gapCursorPluginKey, {
12
- displayGapCursor: toggle
13
- });
14
- };
15
- export const selectionPlugin = ({
16
- config: options
17
- }) => ({
18
- name: 'selection',
19
- commands: {
20
- displayGapCursor,
21
- selectNearNode
22
- },
23
- getSharedState(editorState) {
24
- if (!editorState) {
25
- return undefined;
26
- }
27
- const pluginState = selectionPluginKey.getState(editorState);
28
- return {
29
- selectionRelativeToNode: pluginState === null || pluginState === void 0 ? void 0 : pluginState.selectionRelativeToNode
30
- };
31
- },
32
- pmPlugins() {
33
- return [{
34
- name: 'selection',
35
- plugin: ({
36
- dispatch,
37
- dispatchAnalyticsEvent
38
- }) => createPlugin(dispatch, dispatchAnalyticsEvent, options)
39
- }, {
40
- name: 'selectionKeymap',
41
- plugin: selectionKeymapPlugin
42
- }, {
43
- name: 'gapCursorKeymap',
44
- plugin: () => gapCursorKeymapPlugin()
45
- }, {
46
- name: 'gapCursor',
47
- plugin: () => gapCursorPlugin
48
- }];
49
- }
50
- });
51
- export default selectionPlugin;
@@ -1,43 +0,0 @@
1
- import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
2
- import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
3
- import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
4
- import { pluginFactory } from '@atlaskit/editor-common/utils';
5
- import { reducer } from './reducer';
6
- import { selectionPluginKey } from './types';
7
- import { getDecorations, isSelectableContainerNode } from './utils';
8
- const handleDocChanged = (tr, pluginState) => {
9
- // in some collab edge cases mapping decorations could throw an error
10
- try {
11
- if (pluginState.decorationSet.find().length === 0 && (!tr.selectionSet || getDecorations(tr).find().length === 0)) {
12
- return pluginState;
13
- }
14
- const decorationSet = pluginState.decorationSet.map(tr.mapping, tr.doc);
15
- return {
16
- ...pluginState,
17
- decorationSet
18
- };
19
- } catch (error) {
20
- return {
21
- ...pluginState,
22
- decorationSet: DecorationSet.empty
23
- };
24
- }
25
- };
26
- const handleSelectionChanged = (tr, pluginState) => {
27
- // Reset relative selection pos when user clicks to select a node
28
- if ((tr.selection instanceof NodeSelection && isSelectableContainerNode(tr.selection.node) || tr.selection instanceof CellSelection) && !tr.getMeta(selectionPluginKey)) {
29
- return {
30
- ...pluginState,
31
- selectionRelativeToNode: undefined
32
- };
33
- }
34
- return pluginState;
35
- };
36
- export const {
37
- createCommand,
38
- getPluginState,
39
- createPluginState
40
- } = pluginFactory(selectionPluginKey, reducer, {
41
- onDocChanged: handleDocChanged,
42
- onSelectionChanged: handleSelectionChanged
43
- });
@@ -1,89 +0,0 @@
1
- import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
2
- function isNodeContentEmpty(maybeNode) {
3
- return (maybeNode === null || maybeNode === void 0 ? void 0 : maybeNode.content.size) === 0 || (maybeNode === null || maybeNode === void 0 ? void 0 : maybeNode.textContent) === '';
4
- }
5
- function findEmptySelectableParentNodePosition($pos, isValidPosition) {
6
- const {
7
- doc
8
- } = $pos;
9
- if ($pos.pos + 1 > doc.content.size) {
10
- return null;
11
- }
12
- if ($pos.nodeBefore !== null) {
13
- if (isValidPosition($pos)) {
14
- return $pos;
15
- }
16
-
17
- // We can not use `$pos.before()` because ProseMirror throws an error when depth is zero.
18
- const currentPosIndex = $pos.index();
19
- if (currentPosIndex === 0) {
20
- return null;
21
- }
22
- const previousIndex = currentPosIndex - 1;
23
- const $previousPos = $pos.doc.resolve($pos.posAtIndex(previousIndex));
24
- if (isValidPosition($previousPos)) {
25
- return $previousPos;
26
- }
27
- return null;
28
- }
29
- if (isValidPosition($pos)) {
30
- return $pos;
31
- }
32
- const positionLevelUp = $pos.before();
33
- const resolvedPositionLevelUp = doc.resolve(positionLevelUp);
34
- return findEmptySelectableParentNodePosition(resolvedPositionLevelUp, isValidPosition);
35
- }
36
- const checkPositionNode = $pos => {
37
- const maybeNode = $pos.nodeAfter;
38
- if (!maybeNode || !maybeNode.isBlock) {
39
- return false;
40
- }
41
- if (maybeNode.isAtom) {
42
- return true;
43
- }
44
- return isNodeContentEmpty(maybeNode) && NodeSelection.isSelectable(maybeNode);
45
- };
46
- function findNextSelectionPosition({
47
- $targetHead,
48
- $anchor,
49
- doc
50
- }) {
51
- const direction = $anchor.pos < $targetHead.pos ? 'down' : 'up';
52
- const maybeNextPosition = findEmptySelectableParentNodePosition($targetHead, checkPositionNode);
53
- if (maybeNextPosition && maybeNextPosition.nodeAfter) {
54
- const nodeAfter = maybeNextPosition.nodeAfter;
55
- const pos = maybeNextPosition.pos;
56
- const nextPositionToSelect = direction === 'down' ? Math.min(nodeAfter.nodeSize + pos, doc.content.size) : Math.max(pos, 0);
57
- return doc.resolve(nextPositionToSelect);
58
- }
59
- return null;
60
- }
61
- export const onCreateSelectionBetween = (view, $anchor, $head) => {
62
- var _$head$parent, _$head$parent2;
63
- if ($anchor.pos === $head.pos) {
64
- return null;
65
- }
66
- if ($anchor.depth === $head.depth && $anchor.sameParent($head)) {
67
- return null;
68
- }
69
-
70
- // If the head is targeting a paragraph on root, then let ProseMirror handle the text selection
71
- if ($head.depth === 1 && ((_$head$parent = $head.parent) === null || _$head$parent === void 0 ? void 0 : _$head$parent.type.name) === 'paragraph') {
72
- return null;
73
- }
74
-
75
- // If head is at the beginning of a non-empty textblock, let ProseMirror handle the text selection
76
- if ((_$head$parent2 = $head.parent) !== null && _$head$parent2 !== void 0 && _$head$parent2.isTextblock && !isNodeContentEmpty($head.parent) && $head.parentOffset === 0) {
77
- return null;
78
- }
79
- const $nextHeadPosition = findNextSelectionPosition({
80
- $targetHead: $head,
81
- $anchor,
82
- doc: view.state.doc
83
- });
84
- if (!$nextHeadPosition) {
85
- return null;
86
- }
87
- const forcedTextSelection = TextSelection.create(view.state.doc, $anchor.pos, $nextHeadPosition.pos);
88
- return forcedTextSelection;
89
- };
@@ -1,112 +0,0 @@
1
- import { TextSelection } from '@atlaskit/editor-prosemirror/state';
2
-
3
- /*
4
- * The way expand was built, no browser reconize selection on it.
5
- * For instance, when a selection going to a "collapsed" expand
6
- * the browser will try to send the cursor to inside the expand content (wrong),
7
- * this behavior is caused because the expand content is never true hidden
8
- * we just set the height to 1px.
9
- *
10
- * So, we need to capture a possible selection event
11
- * when a collapsed exxpand is the next node in the common depth.
12
- * If that is true, we create a new TextSelection and stop the event bubble
13
- */
14
- const isCollpasedExpand = node => {
15
- return Boolean(node && ['expand', 'nestedExpand'].includes(node.type.name) && !node.attrs.__expanded);
16
- };
17
-
18
- /**
19
- * ED-18072 - Cannot shift + arrow past bodied extension if it is not empty
20
- */
21
- const isBodiedExtension = node => {
22
- return Boolean(node && ['bodiedExtension'].includes(node.type.name));
23
- };
24
-
25
- /**
26
- * ED-19861 - [Regression] keyboard selections within action items are unpredicatable
27
- * Table was added to the list of problematic nodes because the desired behaviour when Shift+Up from outside the
28
- * table is to select the table node itself, rather than the table cell content. Previously this behaviour was handled
29
- * in `packages/editor/editor-core/src/plugins/selection/pm-plugins/events/create-selection-between.ts` but there was
30
- * a bug in `create-selection-between` which after fixing the bug that code was no longer handling table selection
31
- * correctly, so to fix that table was added here.
32
- */
33
- const isTable = node => {
34
- return Boolean(node && ['table'].includes(node.type.name));
35
- };
36
- const isProblematicNode = node => {
37
- return isCollpasedExpand(node) || isBodiedExtension(node) || isTable(node);
38
- };
39
- const findFixedProblematicNodePosition = (doc, $head, direction) => {
40
- if ($head.pos === 0 || $head.depth === 0) {
41
- return null;
42
- }
43
- if (direction === 'up') {
44
- const pos = $head.before();
45
- const $posResolved = $head.doc.resolve(pos);
46
- const maybeProblematicNode = $posResolved.nodeBefore;
47
- if (maybeProblematicNode && isProblematicNode(maybeProblematicNode)) {
48
- const nodeSize = maybeProblematicNode.nodeSize;
49
- const nodeStartPosition = pos - nodeSize;
50
-
51
- // ($head.pos - 1) will correspond to (nodeStartPosition + nodeSize) when we are at the start of the text node
52
- const isAtEndOfProblematicNode = $head.pos - 1 === nodeStartPosition + nodeSize;
53
- if (isAtEndOfProblematicNode) {
54
- const startPosNode = Math.max(nodeStartPosition, 0);
55
- const $startPosNode = $head.doc.resolve(Math.min(startPosNode, $head.doc.content.size));
56
- return $startPosNode;
57
- }
58
- }
59
- }
60
- if (direction === 'down') {
61
- const pos = $head.after();
62
- const maybeProblematicNode = doc.nodeAt(pos);
63
- if (maybeProblematicNode && isProblematicNode(maybeProblematicNode) && $head.pos + 1 === pos) {
64
- const nodeSize = maybeProblematicNode.nodeSize;
65
- const nodePosition = pos + nodeSize;
66
- const startPosNode = Math.max(nodePosition, 0);
67
- const $startPosNode = $head.doc.resolve(Math.min(startPosNode, $head.doc.content.size));
68
- return $startPosNode;
69
- }
70
- }
71
- return null;
72
- };
73
- export const onKeydown = (view, event) => {
74
- /*
75
- * This workaround is needed for some specific situations.
76
- * - expand collapse
77
- * - bodied extension
78
- */
79
- if (!(event instanceof KeyboardEvent)) {
80
- return false;
81
- }
82
- if (!event.shiftKey || event.ctrlKey || event.metaKey) {
83
- return false;
84
- }
85
- if (!['ArrowUp', 'ArrowDown', 'ArrowRight', 'ArrowLeft', 'Home', 'End'].includes(event.key)) {
86
- return false;
87
- }
88
- const {
89
- doc,
90
- selection: {
91
- $head,
92
- $anchor
93
- }
94
- } = view.state;
95
- if (event.key === 'ArrowRight' && $head.nodeAfter || event.key === 'ArrowLeft' && $head.nodeBefore) {
96
- return false;
97
- }
98
- const direction = ['ArrowLeft', 'ArrowUp', 'Home'].includes(event.key) ? 'up' : 'down';
99
- const $fixedProblematicNodePosition = findFixedProblematicNodePosition(doc, $head, direction);
100
- if ($fixedProblematicNodePosition) {
101
- // an offset is used here so that left arrow selects the first character before the node (consistent with arrow right)
102
- const headOffset = event.key === 'ArrowLeft' ? -1 : 0;
103
- const head = $fixedProblematicNodePosition.pos + headOffset;
104
- const forcedTextSelection = TextSelection.create(view.state.doc, $anchor.pos, head);
105
- const tr = view.state.tr;
106
- tr.setSelection(forcedTextSelection);
107
- view.dispatch(tr);
108
- event.preventDefault();
109
- return true;
110
- }
111
- return false;
112
- };
@@ -1,40 +0,0 @@
1
- import { keymap } from '@atlaskit/editor-prosemirror/keymap';
2
- import { bindKeymapWithCommand, insertNewLine, moveLeft, moveRight, moveUp, moveDown, backspace, deleteKey } from '@atlaskit/editor-common/keymaps';
3
- import { arrow, deleteNode } from '../gap-cursor/actions';
4
- import { Direction } from '../gap-cursor/direction';
5
- import { GapCursorSelection } from '../gap-cursor/selection';
6
- import { createParagraphNear } from '@atlaskit/editor-prosemirror/commands';
7
- export default function keymapPlugin() {
8
- const map = {};
9
- bindKeymapWithCommand(insertNewLine.common, (state, dispatch, view) => {
10
- const isInGapCursor = state.selection instanceof GapCursorSelection;
11
- // Only operate in gap cursor
12
- if (!isInGapCursor) {
13
- return false;
14
- }
15
- return createParagraphNear(state, dispatch);
16
- }, map);
17
- bindKeymapWithCommand(moveLeft.common, (state, dispatch, view) => {
18
- const endOfTextblock = view ? view.endOfTextblock.bind(view) : undefined;
19
- return arrow(Direction.LEFT, endOfTextblock)(state, dispatch, view);
20
- }, map);
21
- bindKeymapWithCommand(moveRight.common, (state, dispatch, view) => {
22
- const endOfTextblock = view ? view.endOfTextblock.bind(view) : undefined;
23
- return arrow(Direction.RIGHT, endOfTextblock)(state, dispatch);
24
- }, map);
25
- bindKeymapWithCommand(moveUp.common, (state, dispatch, view) => {
26
- const endOfTextblock = view ? view.endOfTextblock.bind(view) : undefined;
27
- return arrow(Direction.UP, endOfTextblock)(state, dispatch);
28
- }, map);
29
- bindKeymapWithCommand(moveDown.common, (state, dispatch, view) => {
30
- const endOfTextblock = view ? view.endOfTextblock.bind(view) : undefined;
31
- return arrow(Direction.DOWN, endOfTextblock)(state, dispatch);
32
- }, map);
33
-
34
- // default PM's Backspace doesn't handle removing block nodes when cursor is after it
35
- bindKeymapWithCommand(backspace.common, deleteNode(Direction.BACKWARD), map);
36
-
37
- // handle Delete key (remove node after the cursor)
38
- bindKeymapWithCommand(deleteKey.common, deleteNode(Direction.FORWARD), map);
39
- return keymap(map);
40
- }
@@ -1,158 +0,0 @@
1
- import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
- import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
3
- import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
- import { findPositionOfNodeBefore } from '@atlaskit/editor-prosemirror/utils';
5
- import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
6
- import { hideCaretModifier } from '../gap-cursor/styles';
7
- import { GapCursorSelection, JSON_ID, Side as GapCursorSide, Side } from '../gap-cursor/selection';
8
- import { getLayoutModeFromTargetNode, isIgnoredClick } from '../gap-cursor/utils';
9
- import { toDOM } from '../gap-cursor/utils/place-gap-cursor';
10
- import { deleteNode, setGapCursorAtPos } from '../gap-cursor/actions';
11
- import { Direction } from '../gap-cursor/direction';
12
- import { gapCursorPluginKey } from './gap-cursor-plugin-key';
13
- const plugin = new SafePlugin({
14
- key: gapCursorPluginKey,
15
- state: {
16
- init: () => ({
17
- selectionIsGapCursor: false,
18
- displayGapCursor: true
19
- }),
20
- apply: (tr, pluginState, _oldState, newState) => {
21
- var _meta$displayGapCurso;
22
- const meta = tr.getMeta(gapCursorPluginKey);
23
- const selectionIsGapCursor = newState.selection instanceof GapCursorSelection;
24
- return {
25
- selectionIsGapCursor,
26
- // only attempt to hide gap cursor if selection is gap cursor
27
- displayGapCursor: selectionIsGapCursor ? (_meta$displayGapCurso = meta === null || meta === void 0 ? void 0 : meta.displayGapCursor) !== null && _meta$displayGapCurso !== void 0 ? _meta$displayGapCurso : pluginState.displayGapCursor : true
28
- };
29
- }
30
- },
31
- view: view => {
32
- /**
33
- * If the selection is at the beginning of a document and is a NodeSelection,
34
- * convert to a GapCursor selection. This is to stop users accidentally replacing
35
- * the first node of a document by accident.
36
- */
37
- if (view.state.selection.anchor === 0 && view.state.selection instanceof NodeSelection) {
38
- // This is required otherwise the dispatch doesn't trigger in the correct place
39
- window.requestAnimationFrame(() => {
40
- view.dispatch(view.state.tr.setSelection(new GapCursorSelection(view.state.doc.resolve(0), GapCursorSide.LEFT)));
41
- });
42
- }
43
- return {
44
- update(view) {
45
- const {
46
- selectionIsGapCursor
47
- } = gapCursorPluginKey.getState(view.state);
48
- /**
49
- * Starting with prosemirror-view 1.19.4, cursor wrapper that previously was hiding cursor doesn't exist:
50
- * https://github.com/ProseMirror/prosemirror-view/commit/4a56bc7b7e61e96ef879d1dae1014ede0fc09e43
51
- *
52
- * Because it was causing issues with RTL: https://github.com/ProseMirror/prosemirror/issues/948
53
- *
54
- * This is the work around which uses `caret-color: transparent` in order to hide regular caret,
55
- * when gap cursor is visible.
56
- *
57
- * Browser support is pretty good: https://caniuse.com/#feat=css-caret-color
58
- */
59
- view.dom.classList.toggle(hideCaretModifier, selectionIsGapCursor);
60
- }
61
- };
62
- },
63
- props: {
64
- decorations: editorState => {
65
- const {
66
- doc,
67
- selection
68
- } = editorState;
69
- const {
70
- displayGapCursor
71
- } = gapCursorPluginKey.getState(editorState);
72
- if (selection instanceof GapCursorSelection && displayGapCursor) {
73
- const {
74
- $from,
75
- side
76
- } = selection;
77
-
78
- // render decoration DOM node always to the left of the target node even if selection points to the right
79
- // otherwise positioning of the right gap cursor is a nightmare when the target node has a nodeView with vertical margins
80
- let position = selection.head;
81
- const isRightCursor = side === Side.RIGHT;
82
- if (isRightCursor && $from.nodeBefore) {
83
- const nodeBeforeStart = findPositionOfNodeBefore(selection);
84
- if (typeof nodeBeforeStart === 'number') {
85
- position = nodeBeforeStart;
86
- }
87
- }
88
- const node = isRightCursor ? $from.nodeBefore : $from.nodeAfter;
89
- const layoutMode = node && getLayoutModeFromTargetNode(node);
90
- return DecorationSet.create(doc, [Decoration.widget(position, toDOM, {
91
- key: `${JSON_ID}-${side}-${layoutMode}`,
92
- side: layoutMode ? -1 : 0
93
- })]);
94
- }
95
- return null;
96
- },
97
- // render gap cursor only when its valid
98
- createSelectionBetween(view, $anchor, $head) {
99
- if (view && view.state && view.state.selection instanceof CellSelection) {
100
- // Do not show GapCursor when there is a CellSection happening
101
- return null;
102
- }
103
- if ($anchor.pos === $head.pos && GapCursorSelection.valid($head)) {
104
- return new GapCursorSelection($head);
105
- }
106
- return null;
107
- },
108
- handleClick(view, nodePos, event) {
109
- var _$pos$parent;
110
- const posAtCoords = view.posAtCoords({
111
- left: event.clientX,
112
- top: event.clientY
113
- });
114
- if (!posAtCoords || isIgnoredClick(event.target)) {
115
- return false;
116
- }
117
- const isInsideTheTarget = posAtCoords.pos === posAtCoords.inside;
118
- if (isInsideTheTarget) {
119
- return false;
120
- }
121
- const leftSideOffsetX = 20;
122
- const side = event.offsetX > leftSideOffsetX ? Side.RIGHT : Side.LEFT;
123
- const $pos = view.state.doc.resolve(nodePos);
124
- // In the new prosemirror-view posAtCoords is not returning a precise value for our media nodes
125
- if (((_$pos$parent = $pos.parent) === null || _$pos$parent === void 0 ? void 0 : _$pos$parent.type.name) === 'mediaSingle') {
126
- const $insidePos = view.state.doc.resolve(Math.max(posAtCoords.inside, 0));
127
- // We don't have GapCursors problems when the node target is inside the root level
128
- if ($insidePos.depth <= 1) {
129
- return false;
130
- }
131
- const mediaGapCursor = !$pos.nodeBefore ? $pos.before() : $pos.after();
132
- return setGapCursorAtPos(mediaGapCursor, side)(view.state, view.dispatch);
133
- }
134
- const docSize = view.state.doc.content.size;
135
- const nodeInside = posAtCoords.inside < 0 || posAtCoords.inside > docSize ? null : view.state.doc.nodeAt(posAtCoords.inside);
136
- if (nodeInside !== null && nodeInside !== void 0 && nodeInside.isAtom) {
137
- return false;
138
- }
139
- return setGapCursorAtPos(nodePos, side)(view.state, view.dispatch);
140
- },
141
- handleDOMEvents: {
142
- /**
143
- * Android composition events aren't handled well by Prosemirror
144
- * We've added a couple of beforeinput hooks to help PM out when trying to delete
145
- * certain nodes. We can remove these when PM has better composition support.
146
- * @see https://github.com/ProseMirror/prosemirror/issues/543
147
- */
148
- beforeinput: (view, event) => {
149
- if (event.inputType === 'deleteContentBackward' && view.state.selection instanceof GapCursorSelection) {
150
- event.preventDefault();
151
- return deleteNode(Direction.BACKWARD)(view.state, view.dispatch);
152
- }
153
- return false;
154
- }
155
- }
156
- }
157
- });
158
- export default plugin;
@@ -1,2 +0,0 @@
1
- import { PluginKey } from '@atlaskit/editor-prosemirror/state';
2
- export const gapCursorPluginKey = new PluginKey('gapCursorPlugin');
@@ -1,10 +0,0 @@
1
- import { keymap } from '@atlaskit/editor-prosemirror/keymap';
2
- import { bindKeymapWithCommand, moveRight, moveLeft } from '@atlaskit/editor-common/keymaps';
3
- import { arrowRight, arrowLeft } from '../commands';
4
- function keymapPlugin() {
5
- const list = {};
6
- bindKeymapWithCommand(moveRight.common, arrowRight, list);
7
- bindKeymapWithCommand(moveLeft.common, arrowLeft, list);
8
- return keymap(list);
9
- }
10
- export default keymapPlugin;
@@ -1,97 +0,0 @@
1
- import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
- import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
3
- import { SelectionActionTypes } from '../actions';
4
- import { createPluginState, getPluginState } from '../plugin-factory';
5
- import { selectionPluginKey } from '../types';
6
- import { getAllSelectionAnalyticsPayload, getCellSelectionAnalyticsPayload, getDecorations, getNodeSelectionAnalyticsPayload, getRangeSelectionAnalyticsPayload, shouldRecalcDecorations } from '../utils';
7
- import { onKeydown } from './events/keydown';
8
- import { onCreateSelectionBetween } from './events/create-selection-between';
9
- export const getInitialState = state => ({
10
- decorationSet: getDecorations(state.tr),
11
- selection: state.selection
12
- });
13
- export const createPlugin = (dispatch, dispatchAnalyticsEvent, options = {}) => {
14
- return new SafePlugin({
15
- key: selectionPluginKey,
16
- state: createPluginState(dispatch, getInitialState),
17
- view: () => ({
18
- update: (editorView, oldEditorState) => {
19
- const {
20
- state
21
- } = editorView;
22
- if (!shouldRecalcDecorations({
23
- oldEditorState,
24
- newEditorState: state
25
- })) {
26
- return;
27
- }
28
- const analyticsPayload = getNodeSelectionAnalyticsPayload(state.selection) || getAllSelectionAnalyticsPayload(state.selection) ||
29
- // We handle all range/cell selections except click and drag here, which is
30
- // handled in mouseup handler below
31
- !editorView.mouseDown && (getRangeSelectionAnalyticsPayload(state.selection, state.doc) || getCellSelectionAnalyticsPayload(state));
32
-
33
- // We have to use dispatchAnalyticsEvent over any of the analytics plugin helpers
34
- // as there were several issues caused by the fact that adding analytics through
35
- // the plugin adds a new step to the transaction
36
- // This causes prosemirror to run through some different code paths, eg. attempting
37
- // to map selection
38
- if (analyticsPayload) {
39
- dispatchAnalyticsEvent(analyticsPayload);
40
- }
41
- }
42
- }),
43
- appendTransaction(_transactions, oldEditorState, newEditorState) {
44
- if (!shouldRecalcDecorations({
45
- oldEditorState,
46
- newEditorState
47
- })) {
48
- return;
49
- }
50
- const {
51
- tr
52
- } = newEditorState;
53
- tr.setMeta(selectionPluginKey, {
54
- type: SelectionActionTypes.SET_DECORATIONS,
55
- selection: tr.selection,
56
- decorationSet: getDecorations(tr)
57
- });
58
- return tr;
59
- },
60
- filterTransaction(tr, state) {
61
- // Prevent single click selecting atom nodes on mobile (we want to select with long press gesture instead)
62
- if (options.useLongPressSelection && tr.selectionSet && tr.selection instanceof NodeSelection && !tr.getMeta(selectionPluginKey)) {
63
- return false;
64
- }
65
-
66
- // Prevent prosemirror's mutation observer overriding a node selection with a text selection
67
- // for exact same range - this was cause of being unable to change dates in collab:
68
- // https://product-fabric.atlassian.net/browse/ED-10645
69
- if (state.selection instanceof NodeSelection && tr.selection instanceof TextSelection && state.selection.from === tr.selection.from && state.selection.to === tr.selection.to) {
70
- return false;
71
- }
72
- return true;
73
- },
74
- props: {
75
- createSelectionBetween: onCreateSelectionBetween,
76
- decorations(state) {
77
- return getPluginState(state).decorationSet;
78
- },
79
- handleDOMEvents: {
80
- keydown: onKeydown,
81
- // We only want to fire analytics for a click and drag range/cell selection when
82
- // the user has finished, otherwise we will get an event almost every time they move
83
- // their mouse which is too much
84
- mouseup: (editorView, event) => {
85
- const mouseEvent = event;
86
- if (!mouseEvent.shiftKey) {
87
- const analyticsPayload = getRangeSelectionAnalyticsPayload(editorView.state.selection, editorView.state.doc) || getCellSelectionAnalyticsPayload(editorView.state);
88
- if (analyticsPayload) {
89
- dispatchAnalyticsEvent(analyticsPayload);
90
- }
91
- }
92
- return false;
93
- }
94
- }
95
- }
96
- });
97
- };
@@ -1,18 +0,0 @@
1
- import { SelectionActionTypes } from './actions';
2
- export function reducer(pluginState, action) {
3
- switch (action.type) {
4
- case SelectionActionTypes.SET_DECORATIONS:
5
- return {
6
- ...pluginState,
7
- decorationSet: action.decorationSet,
8
- selection: action.selection
9
- };
10
- case SelectionActionTypes.SET_RELATIVE_SELECTION:
11
- return {
12
- ...pluginState,
13
- selectionRelativeToNode: action.selectionRelativeToNode
14
- };
15
- default:
16
- return pluginState;
17
- }
18
- }
@@ -1,9 +0,0 @@
1
- import { PluginKey } from '@atlaskit/editor-prosemirror/state';
2
- import { RelativeSelectionPos } from '@atlaskit/editor-common/selection';
3
- export const selectionPluginKey = new PluginKey('selection');
4
- export { RelativeSelectionPos };
5
- export let SelectionDirection = /*#__PURE__*/function (SelectionDirection) {
6
- SelectionDirection[SelectionDirection["Before"] = -1] = "Before";
7
- SelectionDirection[SelectionDirection["After"] = 1] = "After";
8
- return SelectionDirection;
9
- }({});