@atlaskit/editor-core 188.5.0 → 188.6.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 (150) hide show
  1. package/CHANGELOG.md +13 -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/plugins/insert-block/ui/ToolbarInsertBlock/index.js +30 -29
  8. package/dist/cjs/plugins/status/actions.js +14 -11
  9. package/dist/cjs/plugins/status/index.js +17 -8
  10. package/dist/cjs/plugins/status/keymap.js +1 -1
  11. package/dist/cjs/plugins/status/ui/statusPicker.js +2 -2
  12. package/dist/cjs/ui/Addon/click-area-helper.js +9 -11
  13. package/dist/cjs/ui/ContentStyles/index.js +13 -13
  14. package/dist/cjs/utils/selection.js +12 -14
  15. package/dist/cjs/version-wrapper.js +1 -1
  16. package/dist/es2019/labs/next/presets/default.js +1 -1
  17. package/dist/es2019/labs/next/presets/universal.js +1 -6
  18. package/dist/es2019/plugins/expand/index.js +0 -2
  19. package/dist/es2019/plugins/expand/nodeviews/index.js +37 -13
  20. package/dist/es2019/plugins/index.js +0 -1
  21. package/dist/es2019/plugins/insert-block/ui/ToolbarInsertBlock/index.js +3 -3
  22. package/dist/es2019/plugins/status/actions.js +3 -2
  23. package/dist/es2019/plugins/status/index.js +91 -80
  24. package/dist/es2019/plugins/status/keymap.js +1 -1
  25. package/dist/es2019/plugins/status/ui/statusPicker.js +1 -1
  26. package/dist/es2019/ui/Addon/click-area-helper.js +4 -6
  27. package/dist/es2019/ui/ContentStyles/index.js +1 -1
  28. package/dist/es2019/utils/selection.js +2 -17
  29. package/dist/es2019/version-wrapper.js +1 -1
  30. package/dist/esm/labs/next/presets/default.js +1 -1
  31. package/dist/esm/labs/next/presets/universal.js +1 -6
  32. package/dist/esm/plugins/expand/index.js +0 -2
  33. package/dist/esm/plugins/expand/nodeviews/index.js +37 -13
  34. package/dist/esm/plugins/index.js +0 -1
  35. package/dist/esm/plugins/insert-block/ui/ToolbarInsertBlock/index.js +30 -29
  36. package/dist/esm/plugins/status/actions.js +14 -11
  37. package/dist/esm/plugins/status/index.js +17 -8
  38. package/dist/esm/plugins/status/keymap.js +1 -1
  39. package/dist/esm/plugins/status/ui/statusPicker.js +1 -1
  40. package/dist/esm/ui/Addon/click-area-helper.js +4 -6
  41. package/dist/esm/ui/ContentStyles/index.js +1 -1
  42. package/dist/esm/utils/selection.js +2 -13
  43. package/dist/esm/version-wrapper.js +1 -1
  44. package/dist/types/labs/next/presets/default.d.ts +22 -8
  45. package/dist/types/plugins/expand/index.d.ts +1 -1
  46. package/dist/types/plugins/expand/nodeviews/index.d.ts +3 -2
  47. package/dist/types/plugins/index.d.ts +0 -1
  48. package/dist/types/plugins/insert-block/types.d.ts +3 -1
  49. package/dist/types/plugins/status/actions.d.ts +4 -2
  50. package/dist/types/plugins/status/index.d.ts +12 -3
  51. package/dist/types/plugins/status/nodeviews/status.d.ts +1 -1
  52. package/dist/types/plugins/status/plugin.d.ts +1 -1
  53. package/dist/types/utils/selection.d.ts +1 -4
  54. package/package.json +4 -3
  55. package/dist/cjs/plugins/selection/actions.js +0 -11
  56. package/dist/cjs/plugins/selection/commands.js +0 -257
  57. package/dist/cjs/plugins/selection/gap-cursor/actions.js +0 -272
  58. package/dist/cjs/plugins/selection/gap-cursor/direction.js +0 -23
  59. package/dist/cjs/plugins/selection/gap-cursor/selection.js +0 -30
  60. package/dist/cjs/plugins/selection/gap-cursor/styles.js +0 -17
  61. package/dist/cjs/plugins/selection/gap-cursor/utils/is-ignored.js +0 -12
  62. package/dist/cjs/plugins/selection/gap-cursor/utils/is-valid-target-node.js +0 -12
  63. package/dist/cjs/plugins/selection/gap-cursor/utils/place-gap-cursor.js +0 -103
  64. package/dist/cjs/plugins/selection/gap-cursor/utils.js +0 -137
  65. package/dist/cjs/plugins/selection/gap-cursor-selection.js +0 -37
  66. package/dist/cjs/plugins/selection/index.js +0 -65
  67. package/dist/cjs/plugins/selection/plugin-factory.js +0 -49
  68. package/dist/cjs/plugins/selection/pm-plugins/events/create-selection-between.js +0 -92
  69. package/dist/cjs/plugins/selection/pm-plugins/events/keydown.js +0 -115
  70. package/dist/cjs/plugins/selection/pm-plugins/gap-cursor-keymap.js +0 -46
  71. package/dist/cjs/plugins/selection/pm-plugins/gap-cursor-main.js +0 -160
  72. package/dist/cjs/plugins/selection/pm-plugins/gap-cursor-plugin-key.js +0 -8
  73. package/dist/cjs/plugins/selection/pm-plugins/keymap.js +0 -16
  74. package/dist/cjs/plugins/selection/pm-plugins/selection-main.js +0 -104
  75. package/dist/cjs/plugins/selection/reducer.js +0 -26
  76. package/dist/cjs/plugins/selection/types.js +0 -20
  77. package/dist/cjs/plugins/selection/utils.js +0 -280
  78. package/dist/cjs/selection-api/api.js +0 -27
  79. package/dist/es2019/plugins/selection/actions.js +0 -5
  80. package/dist/es2019/plugins/selection/commands.js +0 -250
  81. package/dist/es2019/plugins/selection/gap-cursor/actions.js +0 -270
  82. package/dist/es2019/plugins/selection/gap-cursor/direction.js +0 -15
  83. package/dist/es2019/plugins/selection/gap-cursor/selection.js +0 -1
  84. package/dist/es2019/plugins/selection/gap-cursor/styles.js +0 -145
  85. package/dist/es2019/plugins/selection/gap-cursor/utils/is-ignored.js +0 -1
  86. package/dist/es2019/plugins/selection/gap-cursor/utils/is-valid-target-node.js +0 -1
  87. package/dist/es2019/plugins/selection/gap-cursor/utils/place-gap-cursor.js +0 -94
  88. package/dist/es2019/plugins/selection/gap-cursor/utils.js +0 -124
  89. package/dist/es2019/plugins/selection/gap-cursor-selection.js +0 -2
  90. package/dist/es2019/plugins/selection/index.js +0 -51
  91. package/dist/es2019/plugins/selection/plugin-factory.js +0 -43
  92. package/dist/es2019/plugins/selection/pm-plugins/events/create-selection-between.js +0 -89
  93. package/dist/es2019/plugins/selection/pm-plugins/events/keydown.js +0 -112
  94. package/dist/es2019/plugins/selection/pm-plugins/gap-cursor-keymap.js +0 -40
  95. package/dist/es2019/plugins/selection/pm-plugins/gap-cursor-main.js +0 -158
  96. package/dist/es2019/plugins/selection/pm-plugins/gap-cursor-plugin-key.js +0 -2
  97. package/dist/es2019/plugins/selection/pm-plugins/keymap.js +0 -10
  98. package/dist/es2019/plugins/selection/pm-plugins/selection-main.js +0 -97
  99. package/dist/es2019/plugins/selection/reducer.js +0 -18
  100. package/dist/es2019/plugins/selection/types.js +0 -9
  101. package/dist/es2019/plugins/selection/utils.js +0 -233
  102. package/dist/es2019/selection-api/api.js +0 -20
  103. package/dist/esm/plugins/selection/actions.js +0 -5
  104. package/dist/esm/plugins/selection/commands.js +0 -251
  105. package/dist/esm/plugins/selection/gap-cursor/actions.js +0 -266
  106. package/dist/esm/plugins/selection/gap-cursor/direction.js +0 -15
  107. package/dist/esm/plugins/selection/gap-cursor/selection.js +0 -1
  108. package/dist/esm/plugins/selection/gap-cursor/styles.js +0 -10
  109. package/dist/esm/plugins/selection/gap-cursor/utils/is-ignored.js +0 -1
  110. package/dist/esm/plugins/selection/gap-cursor/utils/is-valid-target-node.js +0 -1
  111. package/dist/esm/plugins/selection/gap-cursor/utils/place-gap-cursor.js +0 -97
  112. package/dist/esm/plugins/selection/gap-cursor/utils.js +0 -128
  113. package/dist/esm/plugins/selection/gap-cursor-selection.js +0 -2
  114. package/dist/esm/plugins/selection/index.js +0 -58
  115. package/dist/esm/plugins/selection/plugin-factory.js +0 -43
  116. package/dist/esm/plugins/selection/pm-plugins/events/create-selection-between.js +0 -86
  117. package/dist/esm/plugins/selection/pm-plugins/events/keydown.js +0 -110
  118. package/dist/esm/plugins/selection/pm-plugins/gap-cursor-keymap.js +0 -40
  119. package/dist/esm/plugins/selection/pm-plugins/gap-cursor-main.js +0 -154
  120. package/dist/esm/plugins/selection/pm-plugins/gap-cursor-plugin-key.js +0 -2
  121. package/dist/esm/plugins/selection/pm-plugins/keymap.js +0 -10
  122. package/dist/esm/plugins/selection/pm-plugins/selection-main.js +0 -98
  123. package/dist/esm/plugins/selection/reducer.js +0 -19
  124. package/dist/esm/plugins/selection/types.js +0 -9
  125. package/dist/esm/plugins/selection/utils.js +0 -241
  126. package/dist/esm/selection-api/api.js +0 -21
  127. package/dist/types/plugins/selection/actions.d.ts +0 -17
  128. package/dist/types/plugins/selection/commands.d.ts +0 -10
  129. package/dist/types/plugins/selection/gap-cursor/actions.d.ts +0 -25
  130. package/dist/types/plugins/selection/gap-cursor/direction.d.ts +0 -10
  131. package/dist/types/plugins/selection/gap-cursor/selection.d.ts +0 -1
  132. package/dist/types/plugins/selection/gap-cursor/styles.d.ts +0 -2
  133. package/dist/types/plugins/selection/gap-cursor/utils/is-ignored.d.ts +0 -1
  134. package/dist/types/plugins/selection/gap-cursor/utils/is-valid-target-node.d.ts +0 -1
  135. package/dist/types/plugins/selection/gap-cursor/utils/place-gap-cursor.d.ts +0 -2
  136. package/dist/types/plugins/selection/gap-cursor/utils.d.ts +0 -8
  137. package/dist/types/plugins/selection/gap-cursor-selection.d.ts +0 -2
  138. package/dist/types/plugins/selection/index.d.ts +0 -13
  139. package/dist/types/plugins/selection/plugin-factory.d.ts +0 -2
  140. package/dist/types/plugins/selection/pm-plugins/events/create-selection-between.d.ts +0 -4
  141. package/dist/types/plugins/selection/pm-plugins/events/keydown.d.ts +0 -2
  142. package/dist/types/plugins/selection/pm-plugins/gap-cursor-keymap.d.ts +0 -2
  143. package/dist/types/plugins/selection/pm-plugins/gap-cursor-main.d.ts +0 -6
  144. package/dist/types/plugins/selection/pm-plugins/gap-cursor-plugin-key.d.ts +0 -2
  145. package/dist/types/plugins/selection/pm-plugins/keymap.d.ts +0 -3
  146. package/dist/types/plugins/selection/pm-plugins/selection-main.d.ts +0 -7
  147. package/dist/types/plugins/selection/reducer.d.ts +0 -3
  148. package/dist/types/plugins/selection/types.d.ts +0 -12
  149. package/dist/types/plugins/selection/utils.d.ts +0 -58
  150. package/dist/types/selection-api/api.d.ts +0 -11
@@ -1,94 +0,0 @@
1
- import { getLayoutModeFromTargetNode, isLeftCursor, getComputedStyleForLayoutMode } from '../utils';
2
- import { Side } from '@atlaskit/editor-common/selection';
3
-
4
- /**
5
- * We have a couple of nodes that require us to compute style
6
- * on different elements, ideally all nodes should be able to
7
- * compute the appropriate styles based on their wrapper.
8
- */
9
- const nestedCases = {
10
- 'tableView-content-wrap': 'table',
11
- 'mediaSingleView-content-wrap': '.rich-media-item',
12
- 'bodiedExtensionView-content-wrap': '.extension-container',
13
- 'embedCardView-content-wrap': '.rich-media-item',
14
- 'datasourceView-content-wrap': '.datasourceView-content-inner-wrap'
15
- };
16
- const computeNestedStyle = dom => {
17
- const foundKey = Object.keys(nestedCases).find(className => dom.classList.contains(className));
18
- const nestedSelector = foundKey && nestedCases[foundKey];
19
- if (nestedSelector) {
20
- const nestedElement = dom.querySelector(nestedSelector);
21
- if (nestedElement) {
22
- return window.getComputedStyle(nestedElement);
23
- }
24
- }
25
- };
26
- const measureHeight = style => {
27
- return measureValue(style, ['height', 'padding-top', 'padding-bottom', 'border-top-width', 'border-bottom-width']);
28
- };
29
- const measureWidth = style => {
30
- return measureValue(style, ['width', 'padding-left', 'padding-right', 'border-left-width', 'border-right-width']);
31
- };
32
- const measureValue = (style, measureValues) => {
33
- const [base, ...contentBoxValues] = measureValues;
34
- const measures = [style.getPropertyValue(base)];
35
- const boxSizing = style.getPropertyValue('box-sizing');
36
- if (boxSizing === 'content-box') {
37
- contentBoxValues.forEach(value => {
38
- measures.push(style.getPropertyValue(value));
39
- });
40
- }
41
- let result = 0;
42
- for (let i = 0; i < measures.length; i++) {
43
- result += parseFloat(measures[i]);
44
- }
45
- return result;
46
- };
47
- const mutateElementStyle = (element, style, side) => {
48
- element.style.transform = style.getPropertyValue('transform');
49
- if (isLeftCursor(side)) {
50
- element.style.width = style.getPropertyValue('width');
51
- element.style.marginLeft = style.getPropertyValue('margin-left');
52
- } else {
53
- const marginRight = parseFloat(style.getPropertyValue('margin-right'));
54
- if (marginRight > 0) {
55
- element.style.marginLeft = `-${Math.abs(marginRight)}px`;
56
- } else {
57
- element.style.paddingRight = `${Math.abs(marginRight)}px`;
58
- }
59
- }
60
- };
61
- export const toDOM = (view, getPos) => {
62
- const selection = view.state.selection;
63
- const {
64
- $from,
65
- side
66
- } = selection;
67
- const isRightCursor = side === Side.RIGHT;
68
- const node = isRightCursor ? $from.nodeBefore : $from.nodeAfter;
69
- const nodeStart = getPos();
70
- // @ts-ignore - [unblock prosemirror bump] nodeStart can be undefined
71
- const dom = view.nodeDOM(nodeStart);
72
- const element = document.createElement('span');
73
- element.className = `ProseMirror-gapcursor ${isRightCursor ? '-right' : '-left'}`;
74
- element.appendChild(document.createElement('span'));
75
- if (dom instanceof HTMLElement && element.firstChild) {
76
- const style = computeNestedStyle(dom) || window.getComputedStyle(dom);
77
- const gapCursor = element.firstChild;
78
- gapCursor.style.height = `${measureHeight(style)}px`;
79
- const layoutMode = node && getLayoutModeFromTargetNode(node);
80
-
81
- // TODO remove this table specific piece. need to figure out margin collapsing logic
82
- if (nodeStart !== 0 || layoutMode || (node === null || node === void 0 ? void 0 : node.type.name) === 'table') {
83
- gapCursor.style.marginTop = style.getPropertyValue('margin-top');
84
- }
85
- if (layoutMode) {
86
- gapCursor.setAttribute('layout', layoutMode);
87
- const breakoutModeStyle = getComputedStyleForLayoutMode(dom, node, style);
88
- gapCursor.style.width = `${measureWidth(breakoutModeStyle)}px`;
89
- } else {
90
- mutateElementStyle(gapCursor, style, selection.side);
91
- }
92
- }
93
- return element;
94
- };
@@ -1,124 +0,0 @@
1
- import { TableSharedCssClassName, UnsupportedSharedCssClassName } from '@atlaskit/editor-common/styles';
2
- import { Side } from './selection';
3
- import { CAPTION_PLACEHOLDER_ID } from '@atlaskit/editor-common/media-single';
4
- export const isLeftCursor = side => side === Side.LEFT;
5
- export function getMediaNearPos(doc, $pos, schema, dir = -1) {
6
- let $currentPos = $pos;
7
- let currentNode = null;
8
- const {
9
- mediaSingle,
10
- media,
11
- mediaGroup
12
- } = schema.nodes;
13
- do {
14
- $currentPos = doc.resolve(dir === -1 ? $currentPos.before() : $currentPos.after());
15
- if (!$currentPos) {
16
- return null;
17
- }
18
- currentNode = (dir === -1 ? $currentPos.nodeBefore : $currentPos.nodeAfter) || $currentPos.parent;
19
- if (!currentNode || currentNode.type === schema.nodes.doc) {
20
- return null;
21
- }
22
- if (currentNode.type === mediaSingle || currentNode.type === media || currentNode.type === mediaGroup) {
23
- return currentNode;
24
- }
25
- } while ($currentPos.depth > 0);
26
- return null;
27
- }
28
- export const isTextBlockNearPos = (doc, schema, $pos, dir) => {
29
- let $currentPos = $pos;
30
- let currentNode = dir === -1 ? $currentPos.nodeBefore : $currentPos.nodeAfter;
31
-
32
- // If next node is a text or a text block bail out early.
33
- if (currentNode && (currentNode.isTextblock || currentNode.isText)) {
34
- return true;
35
- }
36
- while ($currentPos.depth > 0) {
37
- $currentPos = doc.resolve(dir === -1 ? $currentPos.before() : $currentPos.after());
38
- if (!$currentPos) {
39
- return false;
40
- }
41
- currentNode = (dir === -1 ? $currentPos.nodeBefore : $currentPos.nodeAfter) || $currentPos.parent;
42
- if (!currentNode || currentNode.type === schema.nodes.doc) {
43
- return false;
44
- }
45
- if (currentNode.isTextblock) {
46
- return true;
47
- }
48
- }
49
- let childNode = currentNode;
50
- while (childNode && childNode.firstChild) {
51
- childNode = childNode.firstChild;
52
- if (childNode && (childNode.isTextblock || childNode.isText)) {
53
- return true;
54
- }
55
- }
56
- return false;
57
- };
58
- export function getLayoutModeFromTargetNode(node) {
59
- let layout;
60
- if (node.attrs.layout) {
61
- layout = node.attrs.layout;
62
- }
63
- if (node.marks && node.marks.length) {
64
- layout = (node.marks.find(mark => mark.type.name === 'breakout') || {
65
- attrs: {
66
- mode: ''
67
- }
68
- }).attrs.mode;
69
- }
70
- if (node.type.name === 'table' && node.attrs.width) {
71
- layout = 'fixed-width';
72
- }
73
- if (['wide', 'full-width', 'fixed-width'].indexOf(layout) === -1) {
74
- return '';
75
- }
76
- return layout;
77
- }
78
- export const isIgnoredClick = elem => {
79
- if (elem.nodeName === 'BUTTON' || elem.closest('button')) {
80
- return true;
81
- }
82
-
83
- // check if we're clicking an image caption placeholder
84
- if (elem.closest(`[data-id="${CAPTION_PLACEHOLDER_ID}"]`)) {
85
- return true;
86
- }
87
-
88
- // check if target node has a parent table node
89
- let tableWrap;
90
- let node = elem;
91
- while (node) {
92
- if (node.className && (node.getAttribute('class') || '').indexOf(TableSharedCssClassName.TABLE_CONTAINER) > -1) {
93
- tableWrap = node;
94
- break;
95
- }
96
- node = node.parentNode;
97
- }
98
- if (tableWrap) {
99
- const rowControls = tableWrap.querySelector(`.${TableSharedCssClassName.TABLE_ROW_CONTROLS_WRAPPER}`);
100
- const isColumnControlsDecoration = elem && elem.classList && elem.classList.contains(TableSharedCssClassName.TABLE_COLUMN_CONTROLS_DECORATIONS);
101
- return rowControls && rowControls.contains(elem) || isColumnControlsDecoration;
102
- }
103
-
104
- // Check if unsupported node selection
105
- // (without this, selection requires double clicking in FF due to posAtCoords differences)
106
- if (elem.closest(`.${UnsupportedSharedCssClassName.BLOCK_CONTAINER}`)) {
107
- return true;
108
- }
109
- return false;
110
- };
111
-
112
- /*
113
- Calculates custom style for breakout mode
114
- Mainly to handle table width to include the numbered column width as well
115
- */
116
- export const getComputedStyleForLayoutMode = (dom, node, style) => {
117
- if (node && node.type.name === 'table') {
118
- const tableContainer = dom.querySelector('.pm-table-container');
119
- if (tableContainer) {
120
- return window.getComputedStyle(tableContainer);
121
- }
122
- }
123
- return style;
124
- };
@@ -1,2 +0,0 @@
1
- export { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
2
- export { setCursorForTopLevelBlocks, setSelectionTopLevelBlocks, hasGapCursorPlugin } from './gap-cursor/actions';
@@ -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
- }