@atlaskit/editor-core 178.0.2 → 178.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/cjs/create-editor/create-plugins-list.js +3 -1
  3. package/dist/cjs/plugins/alignment/ui/ToolbarAlignment/index.js +26 -13
  4. package/dist/cjs/plugins/annotation/index.js +4 -2
  5. package/dist/cjs/plugins/annotation/ui/InlineCommentView.js +6 -2
  6. package/dist/cjs/plugins/base/pm-plugins/react-nodeview.js +8 -1
  7. package/dist/cjs/plugins/block-type/commands/delete-block-content.js +53 -0
  8. package/dist/cjs/plugins/block-type/commands/index.js +9 -1
  9. package/dist/cjs/plugins/block-type/pm-plugins/keymap.js +2 -2
  10. package/dist/cjs/plugins/block-type/ui/ToolbarBlockType/index.js +8 -4
  11. package/dist/cjs/plugins/card/nodeviews/blockCard.js +1 -1
  12. package/dist/cjs/plugins/card/nodeviews/embedCard.js +1 -3
  13. package/dist/cjs/plugins/card/pm-plugins/doc.js +21 -4
  14. package/dist/cjs/plugins/card/toolbar.js +4 -2
  15. package/dist/cjs/plugins/card/ui/EditLinkToolbar.js +4 -1
  16. package/dist/cjs/plugins/card/ui/LinkToolbarAppearance.js +16 -9
  17. package/dist/cjs/plugins/collab-edit/actions.js +1 -1
  18. package/dist/cjs/plugins/collab-edit/index.js +1 -1
  19. package/dist/cjs/plugins/collab-edit/provider/channel.js +1 -1
  20. package/dist/cjs/plugins/expand/pm-plugins/keymap.js +5 -0
  21. package/dist/cjs/plugins/floating-toolbar/ui/Select.js +2 -1
  22. package/dist/cjs/plugins/floating-toolbar/ui/Toolbar.js +18 -9
  23. package/dist/cjs/plugins/hyperlink/HyperlinkToolbarAppearance.js +1 -0
  24. package/dist/cjs/plugins/hyperlink/index.js +2 -1
  25. package/dist/cjs/plugins/hyperlink/ui/EditorLinkPicker/index.js +15 -2
  26. package/dist/cjs/plugins/hyperlink/ui/HyperlinkAddToolbar/HyperlinkAddToolbar.js +27 -22
  27. package/dist/cjs/plugins/hyperlink/ui/HyperlinkAddToolbar/index.js +6 -2
  28. package/dist/cjs/plugins/insert-block/ui/ToolbarInsertBlock/block-insert-element-browser.js +2 -1
  29. package/dist/cjs/plugins/insert-block/ui/ToolbarInsertBlock/block-insert-menu.js +2 -1
  30. package/dist/cjs/plugins/insert-block/ui/ToolbarInsertBlock/index.js +2 -1
  31. package/dist/cjs/plugins/media/commands/helpers.js +24 -2
  32. package/dist/cjs/plugins/media/nodeviews/mediaGroup.js +14 -16
  33. package/dist/cjs/plugins/media/nodeviews/mediaNodeUpdater.js +232 -183
  34. package/dist/cjs/plugins/media/nodeviews/mediaNodeView/index.js +1 -3
  35. package/dist/cjs/plugins/media/nodeviews/mediaSingle.js +1 -1
  36. package/dist/cjs/plugins/media/pm-plugins/keymap.js +46 -0
  37. package/dist/cjs/plugins/rank.js +3 -2
  38. package/dist/cjs/plugins/selection/pm-plugins/events/create-selection-between.js +86 -0
  39. package/dist/cjs/plugins/selection/pm-plugins/events/keydown.js +84 -0
  40. package/dist/cjs/plugins/selection/pm-plugins/selection-main.js +6 -56
  41. package/dist/cjs/plugins/text-color/ui/ToolbarTextColor/index.js +1 -1
  42. package/dist/cjs/plugins/text-formatting/ui/Toolbar/dropdown-menu.js +7 -2
  43. package/dist/cjs/plugins/toolbar-lists-indentation/ui/ToolbarDropdown.js +4 -2
  44. package/dist/cjs/ui/Addon/ClickAreaBlock/index.js +22 -61
  45. package/dist/cjs/ui/Addon/ClickAreaInline/index.js +22 -56
  46. package/dist/cjs/ui/Addon/click-area-helper.js +28 -6
  47. package/dist/cjs/ui/Alignment/AlignmentButton/index.js +4 -2
  48. package/dist/cjs/ui/ElementBrowser/InsertMenu.js +2 -1
  49. package/dist/cjs/ui/ToolbarArrowKeyNavigationProvider/index.js +22 -9
  50. package/dist/cjs/utils/document.js +11 -2
  51. package/dist/cjs/version-wrapper.js +1 -1
  52. package/dist/cjs/version.json +1 -1
  53. package/dist/es2019/create-editor/create-plugins-list.js +3 -1
  54. package/dist/es2019/plugins/alignment/ui/ToolbarAlignment/index.js +28 -13
  55. package/dist/es2019/plugins/annotation/index.js +4 -2
  56. package/dist/es2019/plugins/annotation/ui/InlineCommentView.js +6 -2
  57. package/dist/es2019/plugins/base/pm-plugins/react-nodeview.js +8 -1
  58. package/dist/es2019/plugins/block-type/commands/delete-block-content.js +49 -0
  59. package/dist/es2019/plugins/block-type/commands/index.js +2 -1
  60. package/dist/es2019/plugins/block-type/pm-plugins/keymap.js +3 -3
  61. package/dist/es2019/plugins/block-type/ui/ToolbarBlockType/index.js +8 -4
  62. package/dist/es2019/plugins/card/nodeviews/blockCard.js +1 -1
  63. package/dist/es2019/plugins/card/nodeviews/embedCard.js +1 -2
  64. package/dist/es2019/plugins/card/pm-plugins/doc.js +19 -3
  65. package/dist/es2019/plugins/card/toolbar.js +4 -2
  66. package/dist/es2019/plugins/card/ui/EditLinkToolbar.js +5 -2
  67. package/dist/es2019/plugins/card/ui/LinkToolbarAppearance.js +15 -9
  68. package/dist/es2019/plugins/collab-edit/actions.js +1 -1
  69. package/dist/es2019/plugins/collab-edit/index.js +1 -1
  70. package/dist/es2019/plugins/collab-edit/provider/channel.js +1 -1
  71. package/dist/es2019/plugins/expand/pm-plugins/keymap.js +5 -0
  72. package/dist/es2019/plugins/floating-toolbar/ui/Select.js +2 -1
  73. package/dist/es2019/plugins/floating-toolbar/ui/Toolbar.js +18 -9
  74. package/dist/es2019/plugins/hyperlink/HyperlinkToolbarAppearance.js +1 -0
  75. package/dist/es2019/plugins/hyperlink/index.js +2 -1
  76. package/dist/es2019/plugins/hyperlink/ui/EditorLinkPicker/index.js +11 -2
  77. package/dist/es2019/plugins/hyperlink/ui/HyperlinkAddToolbar/HyperlinkAddToolbar.js +1 -5
  78. package/dist/es2019/plugins/hyperlink/ui/HyperlinkAddToolbar/index.js +6 -2
  79. package/dist/es2019/plugins/insert-block/ui/ToolbarInsertBlock/block-insert-element-browser.js +2 -1
  80. package/dist/es2019/plugins/insert-block/ui/ToolbarInsertBlock/block-insert-menu.js +2 -1
  81. package/dist/es2019/plugins/insert-block/ui/ToolbarInsertBlock/index.js +2 -1
  82. package/dist/es2019/plugins/media/commands/helpers.js +18 -1
  83. package/dist/es2019/plugins/media/nodeviews/mediaGroup.js +14 -16
  84. package/dist/es2019/plugins/media/nodeviews/mediaNodeUpdater.js +37 -13
  85. package/dist/es2019/plugins/media/nodeviews/mediaNodeView/index.js +1 -2
  86. package/dist/es2019/plugins/media/nodeviews/mediaSingle.js +1 -1
  87. package/dist/es2019/plugins/media/pm-plugins/keymap.js +45 -0
  88. package/dist/es2019/plugins/rank.js +3 -2
  89. package/dist/es2019/plugins/selection/pm-plugins/events/create-selection-between.js +79 -0
  90. package/dist/es2019/plugins/selection/pm-plugins/events/keydown.js +77 -0
  91. package/dist/es2019/plugins/selection/pm-plugins/selection-main.js +5 -55
  92. package/dist/es2019/plugins/text-color/ui/ToolbarTextColor/index.js +1 -1
  93. package/dist/es2019/plugins/text-formatting/ui/Toolbar/dropdown-menu.js +6 -2
  94. package/dist/es2019/plugins/toolbar-lists-indentation/ui/ToolbarDropdown.js +3 -2
  95. package/dist/es2019/ui/Addon/ClickAreaBlock/index.js +20 -31
  96. package/dist/es2019/ui/Addon/ClickAreaInline/index.js +20 -27
  97. package/dist/es2019/ui/Addon/click-area-helper.js +28 -6
  98. package/dist/es2019/ui/Alignment/AlignmentButton/index.js +4 -2
  99. package/dist/es2019/ui/ElementBrowser/InsertMenu.js +2 -1
  100. package/dist/es2019/ui/ToolbarArrowKeyNavigationProvider/index.js +22 -9
  101. package/dist/es2019/utils/document.js +9 -2
  102. package/dist/es2019/version-wrapper.js +1 -1
  103. package/dist/es2019/version.json +1 -1
  104. package/dist/esm/create-editor/create-plugins-list.js +3 -1
  105. package/dist/esm/plugins/alignment/ui/ToolbarAlignment/index.js +26 -13
  106. package/dist/esm/plugins/annotation/index.js +4 -2
  107. package/dist/esm/plugins/annotation/ui/InlineCommentView.js +6 -2
  108. package/dist/esm/plugins/base/pm-plugins/react-nodeview.js +8 -1
  109. package/dist/esm/plugins/block-type/commands/delete-block-content.js +46 -0
  110. package/dist/esm/plugins/block-type/commands/index.js +2 -1
  111. package/dist/esm/plugins/block-type/pm-plugins/keymap.js +3 -3
  112. package/dist/esm/plugins/block-type/ui/ToolbarBlockType/index.js +8 -4
  113. package/dist/esm/plugins/card/nodeviews/blockCard.js +1 -1
  114. package/dist/esm/plugins/card/nodeviews/embedCard.js +1 -2
  115. package/dist/esm/plugins/card/pm-plugins/doc.js +20 -3
  116. package/dist/esm/plugins/card/toolbar.js +4 -2
  117. package/dist/esm/plugins/card/ui/EditLinkToolbar.js +5 -2
  118. package/dist/esm/plugins/card/ui/LinkToolbarAppearance.js +16 -9
  119. package/dist/esm/plugins/collab-edit/actions.js +1 -1
  120. package/dist/esm/plugins/collab-edit/index.js +1 -1
  121. package/dist/esm/plugins/collab-edit/provider/channel.js +1 -1
  122. package/dist/esm/plugins/expand/pm-plugins/keymap.js +5 -0
  123. package/dist/esm/plugins/floating-toolbar/ui/Select.js +2 -1
  124. package/dist/esm/plugins/floating-toolbar/ui/Toolbar.js +18 -9
  125. package/dist/esm/plugins/hyperlink/HyperlinkToolbarAppearance.js +1 -0
  126. package/dist/esm/plugins/hyperlink/index.js +2 -1
  127. package/dist/esm/plugins/hyperlink/ui/EditorLinkPicker/index.js +15 -3
  128. package/dist/esm/plugins/hyperlink/ui/HyperlinkAddToolbar/HyperlinkAddToolbar.js +27 -22
  129. package/dist/esm/plugins/hyperlink/ui/HyperlinkAddToolbar/index.js +6 -2
  130. package/dist/esm/plugins/insert-block/ui/ToolbarInsertBlock/block-insert-element-browser.js +2 -1
  131. package/dist/esm/plugins/insert-block/ui/ToolbarInsertBlock/block-insert-menu.js +2 -1
  132. package/dist/esm/plugins/insert-block/ui/ToolbarInsertBlock/index.js +2 -1
  133. package/dist/esm/plugins/media/commands/helpers.js +20 -1
  134. package/dist/esm/plugins/media/nodeviews/mediaGroup.js +14 -16
  135. package/dist/esm/plugins/media/nodeviews/mediaNodeUpdater.js +235 -184
  136. package/dist/esm/plugins/media/nodeviews/mediaNodeView/index.js +1 -2
  137. package/dist/esm/plugins/media/nodeviews/mediaSingle.js +1 -1
  138. package/dist/esm/plugins/media/pm-plugins/keymap.js +45 -0
  139. package/dist/esm/plugins/rank.js +3 -2
  140. package/dist/esm/plugins/selection/pm-plugins/events/create-selection-between.js +76 -0
  141. package/dist/esm/plugins/selection/pm-plugins/events/keydown.js +74 -0
  142. package/dist/esm/plugins/selection/pm-plugins/selection-main.js +4 -57
  143. package/dist/esm/plugins/text-color/ui/ToolbarTextColor/index.js +1 -1
  144. package/dist/esm/plugins/text-formatting/ui/Toolbar/dropdown-menu.js +7 -2
  145. package/dist/esm/plugins/toolbar-lists-indentation/ui/ToolbarDropdown.js +4 -2
  146. package/dist/esm/ui/Addon/ClickAreaBlock/index.js +17 -58
  147. package/dist/esm/ui/Addon/ClickAreaInline/index.js +17 -53
  148. package/dist/esm/ui/Addon/click-area-helper.js +28 -6
  149. package/dist/esm/ui/Alignment/AlignmentButton/index.js +4 -2
  150. package/dist/esm/ui/ElementBrowser/InsertMenu.js +2 -1
  151. package/dist/esm/ui/ToolbarArrowKeyNavigationProvider/index.js +22 -9
  152. package/dist/esm/utils/document.js +11 -2
  153. package/dist/esm/version-wrapper.js +1 -1
  154. package/dist/esm/version.json +1 -1
  155. package/dist/types/plugins/alignment/ui/ToolbarAlignment/index.d.ts +1 -1
  156. package/dist/types/plugins/block-type/commands/delete-block-content.d.ts +10 -0
  157. package/dist/types/plugins/block-type/commands/index.d.ts +1 -0
  158. package/dist/types/plugins/card/pm-plugins/doc.d.ts +1 -1
  159. package/dist/types/plugins/card/ui/LinkToolbarAppearance.d.ts +1 -0
  160. package/dist/types/plugins/floating-toolbar/ui/Select.d.ts +1 -0
  161. package/dist/types/plugins/hyperlink/ui/EditorLinkPicker/index.d.ts +6 -1
  162. package/dist/types/plugins/hyperlink/ui/HyperlinkAddToolbar/index.d.ts +1 -1
  163. package/dist/types/plugins/insert-block/ui/ToolbarInsertBlock/block-insert-element-browser.d.ts +1 -0
  164. package/dist/types/plugins/insert-block/ui/ToolbarInsertBlock/block-insert-menu.d.ts +1 -0
  165. package/dist/types/plugins/media/commands/helpers.d.ts +1 -0
  166. package/dist/types/plugins/media/nodeviews/__mocks__/mediaNodeUpdater.d.ts +1 -0
  167. package/dist/types/plugins/media/nodeviews/mediaNodeUpdater.d.ts +3 -1
  168. package/dist/types/plugins/media/types.d.ts +2 -0
  169. package/dist/types/plugins/selection/pm-plugins/events/create-selection-between.d.ts +4 -0
  170. package/dist/types/plugins/selection/pm-plugins/events/keydown.d.ts +2 -0
  171. package/dist/types/ui/Addon/ClickAreaBlock/index.d.ts +2 -5
  172. package/dist/types/ui/Addon/ClickAreaInline/index.d.ts +2 -5
  173. package/dist/types/ui/Addon/click-area-helper.d.ts +1 -1
  174. package/dist/types/ui/Alignment/AlignmentButton/index.d.ts +1 -1
  175. package/dist/types/ui/ElementBrowser/InsertMenu.d.ts +1 -1
  176. package/dist/types/ui/ElementBrowser/types.d.ts +1 -0
  177. package/docs/0-intro.tsx +9 -0
  178. package/package.json +14 -16
  179. package/report.api.md +4 -1
@@ -4,29 +4,12 @@ import { SelectionActionTypes } from '../actions';
4
4
  import { createPluginState, getPluginState } from '../plugin-factory';
5
5
  import { selectionPluginKey } from '../types';
6
6
  import { getAllSelectionAnalyticsPayload, getCellSelectionAnalyticsPayload, getDecorations, getNodeSelectionAnalyticsPayload, getRangeSelectionAnalyticsPayload, shouldRecalcDecorations } from '../utils';
7
+ import { onKeydown } from './events/keydown';
8
+ import { onCreateSelectionBetween } from './events/create-selection-between';
7
9
  export const getInitialState = state => ({
8
10
  decorationSet: getDecorations(state.tr),
9
11
  selection: state.selection
10
12
  });
11
-
12
- const toggleContentEditable = (node, root = false) => {
13
- if (root || node.getAttribute('contenteditable') === 'true') {
14
- const wasTrue = node.getAttribute('contenteditable') === 'true';
15
- node.setAttribute('contenteditable', 'false');
16
- requestAnimationFrame(() => {
17
- if (wasTrue) {
18
- node.setAttribute('contenteditable', 'true');
19
- } else {
20
- node.removeAttribute('contenteditable');
21
- }
22
- });
23
- } // any children with contenteditable = true block selection from proceeding
24
-
25
-
26
- const children = Array.from(node.children);
27
- children.forEach(child => toggleContentEditable(child));
28
- };
29
-
30
13
  export const createPlugin = (dispatch, dispatchAnalyticsEvent, options = {}) => {
31
14
  return new SafePlugin({
32
15
  key: selectionPluginKey,
@@ -94,11 +77,14 @@ export const createPlugin = (dispatch, dispatchAnalyticsEvent, options = {}) =>
94
77
  },
95
78
 
96
79
  props: {
80
+ createSelectionBetween: onCreateSelectionBetween,
81
+
97
82
  decorations(state) {
98
83
  return getPluginState(state).decorationSet;
99
84
  },
100
85
 
101
86
  handleDOMEvents: {
87
+ keydown: onKeydown,
102
88
  // We only want to fire analytics for a click and drag range/cell selection when
103
89
  // the user has finished, otherwise we will get an event almost every time they move
104
90
  // their mouse which is too much
@@ -113,42 +99,6 @@ export const createPlugin = (dispatch, dispatchAnalyticsEvent, options = {}) =>
113
99
  }
114
100
  }
115
101
 
116
- return false;
117
- },
118
- keydown: (editorView, event) => {
119
- // Bugfix for block ReactNodeViews like table and extension
120
- // They could not be selected with Shift + ArrowDown/ArrowUp
121
- // Fixed when contenteditable = false, but then you couldn't edit their contents
122
- // Therefore, briefly set contenteditable=false to allow the selection through, then set it back to true
123
- if (event instanceof KeyboardEvent && event.shiftKey && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {
124
- const {
125
- state
126
- } = editorView; // If current depth is on the top most level, skip that
127
-
128
- if (state.selection.$head.depth <= 0) {
129
- return false;
130
- }
131
-
132
- let pos;
133
-
134
- if (event.key === 'ArrowDown') {
135
- pos = state.selection.$head.after();
136
- } else {
137
- pos = Math.max(state.selection.$head.before() - 1, 0); // block extensions only take up one position, dont need to get before()
138
-
139
- if (!editorView.nodeDOM(pos)) {
140
- pos = state.doc.resolve(pos).before();
141
- }
142
- }
143
-
144
- const node = editorView.nodeDOM(pos);
145
-
146
- if (node instanceof HTMLDivElement && node.className.includes('View-content-wrap') // class added by ReactNodeView
147
- ) {
148
- toggleContentEditable(node, true);
149
- }
150
- }
151
-
152
102
  return false;
153
103
  }
154
104
  }
@@ -171,7 +171,7 @@ export class ToolbarTextColor extends React.Component {
171
171
  zIndex: akEditorMenuZIndex,
172
172
  fitWidth: fitWidth,
173
173
  onOpenChange: this.onOpenChange,
174
- closeonTab: true,
174
+ closeOnTab: true,
175
175
  trigger: jsx(ToolbarButton, {
176
176
  buttonId: TOOLBAR_BUTTON.TEXT_COLOR,
177
177
  spacing: isReducedSpacing ? 'none' : 'default',
@@ -18,10 +18,14 @@ export const FormattingTextDropdownMenu = /*#__PURE__*/React.memo(({
18
18
  items
19
19
  }], [items]);
20
20
  const onItemActivated = useCallback(({
21
- item
21
+ item,
22
+ shouldCloseMenu = true
22
23
  }) => {
23
24
  item.command(editorView.state, editorView.dispatch);
24
- closeMenu();
25
+
26
+ if (shouldCloseMenu) {
27
+ closeMenu();
28
+ }
25
29
  }, [editorView.state, editorView.dispatch, closeMenu]);
26
30
  return /*#__PURE__*/React.createElement(DropdownMenu, {
27
31
  mountTo: popupsMountPoint,
@@ -40,9 +40,10 @@ export function ToolbarDropdown(props) {
40
40
  const items = useItems(props);
41
41
 
42
42
  const handleOnItemActivated = ({
43
- item
43
+ item,
44
+ shouldCloseMenu = true
44
45
  }) => {
45
- setIsDropdownOpen(false);
46
+ setIsDropdownOpen(!shouldCloseMenu);
46
47
  return onItemActivated({
47
48
  editorView: props.editorView,
48
49
  buttonName: item.value.name
@@ -1,5 +1,3 @@
1
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
-
3
1
  /** @jsx jsx */
4
2
  import React from 'react';
5
3
  import { css, jsx } from '@emotion/react';
@@ -8,33 +6,24 @@ const clickWrapper = css`
8
6
  flex-grow: 1;
9
7
  height: 100%;
10
8
  `;
11
- export default class ClickAreaBlock extends React.Component {
12
- constructor(...args) {
13
- super(...args);
14
-
15
- _defineProperty(this, "handleClick", event => {
16
- const {
17
- editorView: view,
18
- editorDisabled
19
- } = this.props;
20
-
21
- if (!view) {
22
- return;
23
- }
24
-
25
- if (!editorDisabled) {
26
- // if the editor is disabled -- we don't want to intercept any click events
27
- clickAreaClickHandler(view, event);
28
- }
29
- });
30
- }
31
-
32
- render() {
33
- return jsx("div", {
34
- "data-testid": "click-wrapper",
35
- css: clickWrapper,
36
- onClick: this.handleClick
37
- }, this.props.children);
38
- }
9
+ export const ClickAreaBlock = ({
10
+ editorView,
11
+ editorDisabled,
12
+ children
13
+ }) => {
14
+ const handleMouseDown = React.useCallback(event => {
15
+ if (!editorView) {
16
+ return;
17
+ }
39
18
 
40
- }
19
+ if (!editorDisabled) {
20
+ clickAreaClickHandler(editorView, event);
21
+ }
22
+ }, [editorView, editorDisabled]);
23
+ return jsx("div", {
24
+ "data-testid": "click-wrapper",
25
+ css: clickWrapper,
26
+ onMouseDown: handleMouseDown
27
+ }, children);
28
+ };
29
+ export default ClickAreaBlock;
@@ -1,5 +1,3 @@
1
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
-
3
1
  /** @jsx jsx */
4
2
  import React from 'react';
5
3
  import { css, jsx } from '@emotion/react';
@@ -7,29 +5,24 @@ import { createParagraphAtEnd } from '../../../commands';
7
5
  const clickArea = css`
8
6
  flex-grow: 1;
9
7
  `;
10
- export default class ClickAreaInline extends React.Component {
11
- constructor(...args) {
12
- super(...args);
13
-
14
- _defineProperty(this, "handleClick", event => {
15
- const {
16
- editorView
17
- } = this.props;
18
-
19
- if (editorView) {
20
- if (createParagraphAtEnd()(editorView.state, editorView.dispatch)) {
21
- editorView.focus();
22
- event.stopPropagation();
23
- }
24
- }
25
- });
26
- }
27
-
28
- render() {
29
- return jsx("div", {
30
- css: clickArea,
31
- onClick: this.handleClick
32
- });
33
- }
8
+ export const ClickAreaInline = ({
9
+ editorView,
10
+ children
11
+ }) => {
12
+ const handleMouseDown = React.useCallback(event => {
13
+ if (!editorView) {
14
+ return;
15
+ }
34
16
 
35
- }
17
+ if (createParagraphAtEnd()(editorView.state, editorView.dispatch)) {
18
+ editorView.focus();
19
+ event.stopPropagation();
20
+ }
21
+ }, [editorView]);
22
+ return jsx("div", {
23
+ "data-testid": "click-wrapper",
24
+ css: clickArea,
25
+ onMouseDown: handleMouseDown
26
+ });
27
+ };
28
+ export default ClickAreaInline;
@@ -13,6 +13,10 @@ const insideContentArea = ref => {
13
13
 
14
14
  return false;
15
15
  };
16
+
17
+ const insideProseMirrorEditableArea = ref => {
18
+ return Boolean(ref === null || ref === void 0 ? void 0 : ref.closest('.ProseMirror'));
19
+ };
16
20
  /**
17
21
  * @see ED-14699 - check if editor is inside a modal to continue to bring cursor to input when
18
22
  * any part of the editor container is clicked
@@ -37,11 +41,19 @@ export const checkForModal = target => {
37
41
  };
38
42
 
39
43
  const clickAreaClickHandler = (view, event) => {
40
- var _view$hasFocus;
44
+ var _view$hasFocus, _event$currentTarget;
41
45
 
42
- const isTargetContentArea = event.currentTarget.querySelector('.ak-editor-content-area');
43
46
  const isEditorFocused = !!(view !== null && view !== void 0 && (_view$hasFocus = view.hasFocus) !== null && _view$hasFocus !== void 0 && _view$hasFocus.call(view));
44
- const target = event.target; // @see https://product-fabric.atlassian.net/browse/ED-4287
47
+ const target = event.target;
48
+ const isTargetContentArea = target.classList.contains('ak-editor-content-area');
49
+ const isTargetChildOfContentArea = insideContentArea(target.parentNode);
50
+ const isTargetInsideEditableArea = insideProseMirrorEditableArea(target); // Any click inside ProseMirror should be managed by ProseMirror
51
+
52
+ if (isTargetInsideEditableArea) {
53
+ return false;
54
+ }
55
+
56
+ const isEventComingFromContentArea = Boolean(event.currentTarget.querySelector('.ak-editor-content-area')); // @see https://product-fabric.atlassian.net/browse/ED-4287
45
57
  // click event gets triggered twice on a checkbox (on <label> first and then on <input>)
46
58
  // by the time it gets triggered on input, PM already re-renders nodeView and detaches it from DOM
47
59
  // which doesn't pass the check !contentArea.contains(event.target)
@@ -52,10 +64,20 @@ const clickAreaClickHandler = (view, event) => {
52
64
 
53
65
  const isTextAreaClicked = target.nodeName === 'TEXTAREA';
54
66
  const isBreadcrumbClicked = !!closestElement(target, 'nav[aria-label="Breadcrumbs"]');
55
- const isTargetChildOfContentArea = insideContentArea(target.parentNode);
56
67
  const selection = window.getSelection();
57
- const isEditorPopupTextSelected = (selection === null || selection === void 0 ? void 0 : selection.type) === 'Range' && closestElement(selection === null || selection === void 0 ? void 0 : selection.anchorNode, '[data-editor-popup]');
58
- const isClickOutsideEditor = (!isTargetContentArea || !isTargetChildOfContentArea || !isEditorFocused) && !isInputClicked && !isTextAreaClicked && !isPopupClicked && !isBreadcrumbClicked && !isEditorPopupTextSelected && checkForModal(target); // click was within editor container and focus should be brought to input
68
+ const isEditorPopupTextSelected = (selection === null || selection === void 0 ? void 0 : selection.type) === 'Range' && closestElement(selection === null || selection === void 0 ? void 0 : selection.anchorNode, '[data-editor-popup]'); // This is a super workaround to find when events are coming from Confluence InlineComment modal
69
+ // We don't own those components, so we can't change them
70
+
71
+ const isEventComingFromInlineCommentPopup = Boolean(closestElement(event.currentTarget, 'div[offset]')) || Boolean(closestElement(target, 'div[offset]'));
72
+ const isButtonClicked = Boolean(closestElement(event.currentTarget, 'button')) || Boolean(closestElement(target, 'button')) || ((_event$currentTarget = event.currentTarget) === null || _event$currentTarget === void 0 ? void 0 : _event$currentTarget.nodeName) === 'BUTTON' || target.nodeName === 'BUTTON';
73
+ const isTargetInsideContentArea = Boolean(isTargetChildOfContentArea);
74
+ const isBetweenContentAreaAndEditableContent = isTargetInsideContentArea && !isTargetInsideEditableArea;
75
+ const edgeCaseScenario1 = (isBetweenContentAreaAndEditableContent || !isEventComingFromContentArea) && !isEditorFocused;
76
+ const edgeCaseScenario2 = !isTargetInsideContentArea && isEditorFocused;
77
+ const edgeCaseScenario3 = isTargetContentArea && !isTargetInsideContentArea && !isEditorFocused;
78
+ const edgeCaseScenario4 = isEventComingFromContentArea && !isTargetContentArea && !isTargetInsideContentArea && !isEditorFocused;
79
+ const edgeCases = edgeCaseScenario1 || edgeCaseScenario2 || edgeCaseScenario3 || edgeCaseScenario4;
80
+ const isClickOutsideEditor = edgeCases && !isEventComingFromInlineCommentPopup && !isButtonClicked && !isInputClicked && !isTextAreaClicked && !isPopupClicked && !isBreadcrumbClicked && !isEditorPopupTextSelected && checkForModal(target); // click was within editor container and focus should be brought to input
59
81
 
60
82
  if (isClickOutsideEditor && view) {
61
83
  outsideProsemirrorEditorClickHandler(view, event);
@@ -13,9 +13,11 @@ class AlignmentButton extends PureComponent {
13
13
  const {
14
14
  onClick,
15
15
  value
16
- } = this.props;
16
+ } = this.props; // detect if the click event comes from keyboard where screenX and screenY are 0
17
+
18
+ const isMouseEvent = e instanceof MouseEvent;
17
19
  e.preventDefault();
18
- onClick(value);
20
+ onClick(value, isMouseEvent);
19
21
  });
20
22
  }
21
23
 
@@ -21,6 +21,7 @@ import { ELEMENT_ITEM_HEIGHT } from './constants';
21
21
  const InsertMenu = ({
22
22
  editorView,
23
23
  dropdownItems,
24
+ showElementBrowserLink,
24
25
  onInsert,
25
26
  toggleVisiblity
26
27
  }) => {
@@ -40,7 +41,7 @@ const InsertMenu = ({
40
41
  value: item.value
41
42
  }), [onInsert]);
42
43
  const quickInsertDropdownItems = dropdownItems.map(transform);
43
- const viewMoreItem = quickInsertDropdownItems.pop();
44
+ const viewMoreItem = showElementBrowserLink && quickInsertDropdownItems.pop();
44
45
  const onInsertItem = useCallback(item => {
45
46
  toggleVisiblity();
46
47
 
@@ -29,18 +29,24 @@ export const ToolbarArrowKeyNavigationProvider = ({
29
29
  const wrapperRef = useRef(null);
30
30
  const selectedItemIndex = useRef(0);
31
31
  const incrementIndex = useCallback(list => {
32
- if (selectedItemIndex.current === list.length - 1) {
33
- selectedItemIndex.current = 0;
34
- } else {
35
- selectedItemIndex.current = selectedItemIndex.current + 1;
32
+ let index = 0;
33
+
34
+ if (document.activeElement) {
35
+ index = list.indexOf(document.activeElement);
36
+ index = (index + 1) % list.length;
36
37
  }
38
+
39
+ selectedItemIndex.current = index;
37
40
  }, []);
38
41
  const decrementIndex = useCallback(list => {
39
- if (selectedItemIndex.current === 0) {
40
- selectedItemIndex.current = list.length - 1;
41
- } else {
42
- selectedItemIndex.current = selectedItemIndex.current - 1;
42
+ let index = 0;
43
+
44
+ if (document.activeElement) {
45
+ index = list.indexOf(document.activeElement);
46
+ index = (list.length + index - 1) % list.length;
43
47
  }
48
+
49
+ selectedItemIndex.current = index;
44
50
  }, []);
45
51
 
46
52
  const handleArrowRight = () => {
@@ -108,12 +114,19 @@ export const ToolbarArrowKeyNavigationProvider = ({
108
114
  return;
109
115
  }
110
116
 
117
+ const menuWrapper = document.querySelector('.menu-key-handler-wrapper');
118
+
119
+ if (menuWrapper) {
120
+ // if menu wrapper exists, then a menu is open and arrow keys will be handled by MenuArrowKeyNavigationProvider
121
+ return;
122
+ }
123
+
111
124
  const filteredFocusableElements = getFilteredFocusableElements(wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current);
112
125
 
113
126
  if (!filteredFocusableElements || (filteredFocusableElements === null || filteredFocusableElements === void 0 ? void 0 : filteredFocusableElements.length) === 0) {
114
127
  return;
115
128
  } //This is kind of hack to reset the current focused toolbar item
116
- //to handle some usecases such as Tab in/out of main toolbar
129
+ //to handle some use cases such as Tab in/out of main toolbar
117
130
 
118
131
 
119
132
  if (!((_wrapperRef$current = wrapperRef.current) !== null && _wrapperRef$current !== void 0 && _wrapperRef$current.contains(targetElement))) {
@@ -217,11 +217,18 @@ export function processRawValue(schema, value, providerFactory, sanitizePrivateC
217
217
 
218
218
  if (isTransformed && dispatchAnalyticsEvent) {
219
219
  dispatchAnalyticsEvent({
220
- action: ACTION.DEDUPE_MARKS_TRANSFORMED,
220
+ action: ACTION.DEDUPE_MARKS_TRANSFORMED_V2,
221
221
  actionSubject: ACTION_SUBJECT.EDITOR,
222
222
  eventType: EVENT_TYPE.OPERATIONAL,
223
223
  attributes: {
224
- discardedMarks
224
+ /** UGC WARNING
225
+ *
226
+ * DO NOT include the `mark` attributes inside, we map here to only
227
+ * extract the mark type as that is the only non-UGC safe information
228
+ * that we can add to event-attributes
229
+ *
230
+ */
231
+ discardedMarkTypes: discardedMarks.map(mark => mark.type)
225
232
  }
226
233
  });
227
234
  }
@@ -1,5 +1,5 @@
1
1
  export const name = "@atlaskit/editor-core";
2
- export const version = "178.0.2";
2
+ export const version = "178.1.1";
3
3
  export const nextMajorVersion = () => {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-core",
3
- "version": "178.0.2",
3
+ "version": "178.1.1",
4
4
  "sideEffects": false
5
5
  }
@@ -185,6 +185,7 @@ export default function createPluginsList(props, prevProps, createAnalyticsEvent
185
185
  allowDropzoneDropLine: isFullPage,
186
186
  allowMediaSingleEditable: !isMobile,
187
187
  allowRemoteDimensionsFetch: !isMobile,
188
+ editorSelectionAPI: editorSelectionAPI,
188
189
  // This is a wild one. I didnt quite understand what the code was doing
189
190
  // so a bit of guess for now.
190
191
  allowMarkingUploadsAsIncomplete: isMobile,
@@ -261,7 +262,8 @@ export default function createPluginsList(props, prevProps, createAnalyticsEvent
261
262
  disableLayout: true
262
263
  },
263
264
  allowMediaGroup: false,
264
- isCopyPasteEnabled: true
265
+ isCopyPasteEnabled: true,
266
+ editorSelectionAPI: editorSelectionAPI
265
267
  }]);
266
268
  }
267
269
  }
@@ -43,8 +43,10 @@ export var AlignmentToolbar = /*#__PURE__*/function (_React$Component) {
43
43
  isOpen: false
44
44
  });
45
45
 
46
- _defineProperty(_assertThisInitialized(_this), "changeAlignment", function (align) {
47
- _this.toggleOpen();
46
+ _defineProperty(_assertThisInitialized(_this), "changeAlignment", function (align, togglePopup) {
47
+ if (togglePopup) {
48
+ _this.toggleOpen();
49
+ }
48
50
 
49
51
  return _this.props.changeAlignment(align);
50
52
  });
@@ -77,11 +79,10 @@ export var AlignmentToolbar = /*#__PURE__*/function (_React$Component) {
77
79
  }
78
80
  });
79
81
 
80
- _defineProperty(_assertThisInitialized(_this), "hideonEsc", function () {
82
+ _defineProperty(_assertThisInitialized(_this), "hideOnEscape", function () {
81
83
  var _this$toolbarItemRef2, _this$toolbarItemRef3;
82
84
 
83
- _this.hide(); //To set the focus on the textcolor button when the menu is closed by 'Esc' only (aria guidelines)
84
-
85
+ _this.hide();
85
86
 
86
87
  (_this$toolbarItemRef2 = _this.toolbarItemRef) === null || _this$toolbarItemRef2 === void 0 ? void 0 : (_this$toolbarItemRef3 = _this$toolbarItemRef2.current) === null || _this$toolbarItemRef3 === void 0 ? void 0 : _this$toolbarItemRef3.focus();
87
88
  });
@@ -111,17 +112,29 @@ export var AlignmentToolbar = /*#__PURE__*/function (_React$Component) {
111
112
  boundariesElement: popupsBoundariesElement,
112
113
  scrollableElement: popupsScrollableElement,
113
114
  isOpen: isOpen,
114
- handleClickOutside: function handleClickOutside(event) {
115
- return _this2.hide({
116
- isOpen: false,
117
- event: event
115
+ onOpenChange: function onOpenChange(_ref2) {
116
+ var _this2$toolbarItemRef, _this2$toolbarItemRef2;
117
+
118
+ var isOpen = _ref2.isOpen;
119
+
120
+ _this2.setState({
121
+ isOpen: isOpen
118
122
  });
123
+
124
+ (_this2$toolbarItemRef = _this2.toolbarItemRef) === null || _this2$toolbarItemRef === void 0 ? void 0 : (_this2$toolbarItemRef2 = _this2$toolbarItemRef.current) === null || _this2$toolbarItemRef2 === void 0 ? void 0 : _this2$toolbarItemRef2.focus();
125
+ },
126
+ handleClickOutside: function handleClickOutside(event) {
127
+ if (event instanceof MouseEvent) {
128
+ _this2.hide({
129
+ isOpen: false,
130
+ event: event
131
+ });
132
+ }
119
133
  },
120
- handleEscapeKeydown: this.hideonEsc,
121
- onOpenChange: this.hide,
134
+ handleEscapeKeydown: this.hideOnEscape,
122
135
  fitWidth: 112,
123
136
  fitHeight: 80,
124
- closeonTab: true,
137
+ closeOnTab: true,
125
138
  trigger: jsx(ToolbarButton, {
126
139
  spacing: isReducedSpacing ? 'none' : 'default',
127
140
  disabled: disabled,
@@ -145,7 +158,7 @@ export var AlignmentToolbar = /*#__PURE__*/function (_React$Component) {
145
158
  })
146
159
  }, jsx(Alignment, {
147
160
  onClick: function onClick(align) {
148
- return _this2.changeAlignment(align);
161
+ return _this2.changeAlignment(align, false);
149
162
  },
150
163
  selectedAlignment: pluginState.align
151
164
  })), jsx("span", {
@@ -82,11 +82,13 @@ var annotationPlugin = function annotationPlugin(annotationProviders) {
82
82
  return null;
83
83
  }
84
84
 
85
- return /*#__PURE__*/React.createElement(InlineCommentView, {
85
+ return /*#__PURE__*/React.createElement("div", {
86
+ "data-editor-popup": "true"
87
+ }, /*#__PURE__*/React.createElement(InlineCommentView, {
86
88
  providers: annotationProviders,
87
89
  editorView: editorView,
88
90
  dispatchAnalyticsEvent: dispatchAnalyticsEvent
89
- });
91
+ }));
90
92
  }
91
93
  });
92
94
  }
@@ -59,7 +59,9 @@ export function InlineCommentView(_ref) {
59
59
  selection: selection.toJSON(),
60
60
  position: position,
61
61
  docSize: editorView.state.doc.nodeSize,
62
- error: error.toString(),
62
+ error: error.toString()
63
+ },
64
+ nonPrivacySafeAttributes: {
63
65
  errorStack: error.stack || undefined
64
66
  }
65
67
  };
@@ -80,7 +82,8 @@ export function InlineCommentView(_ref) {
80
82
 
81
83
  var textSelection = state.doc.textBetween(selection.from, selection.to);
82
84
  return /*#__PURE__*/React.createElement("div", {
83
- "data-testid": AnnotationTestIds.floatingComponent
85
+ "data-testid": AnnotationTestIds.floatingComponent,
86
+ "data-editor-popup": "true"
84
87
  }, /*#__PURE__*/React.createElement(CreateComponent, {
85
88
  dom: dom,
86
89
  textSelection: textSelection,
@@ -127,6 +130,7 @@ export function InlineCommentView(_ref) {
127
130
  }
128
131
 
129
132
  return /*#__PURE__*/React.createElement(AnnotationViewWrapper, {
133
+ "data-editor-popup": "true",
130
134
  "data-testid": AnnotationTestIds.floatingComponent,
131
135
  key: getAnnotationViewKey(activeAnnotations),
132
136
  onViewed: onAnnotationViewed
@@ -48,12 +48,19 @@ export var plugin = new SafePlugin({
48
48
  key: stateKey,
49
49
  view: function view(_view) {
50
50
  var pluginState = stateKey.getState(_view.state);
51
+ var prevFrom = -1;
52
+ var prevTo = -1;
51
53
  return {
52
54
  update: function update(view) {
53
55
  var _view$state$selection = view.state.selection,
54
56
  from = _view$state$selection.from,
55
57
  to = _view$state$selection.to;
56
- pluginState.notifyNewSelection(from, to);
58
+
59
+ if (from !== prevFrom || to !== prevTo) {
60
+ pluginState.notifyNewSelection(from, to);
61
+ prevFrom = from;
62
+ prevTo = to;
63
+ }
57
64
  }
58
65
  };
59
66
  }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Prevent removing the block when deleting block content
3
+ *
4
+ * @param state EditorState<any>
5
+ * @param dispatch CommandDispatch
6
+ * @returns boolean
7
+ */
8
+ export function deleteBlockContent(isNodeAWrappingBlockNode) {
9
+ return function (state, dispatch) {
10
+ var tr = state.tr,
11
+ _state$selection = state.selection,
12
+ $from = _state$selection.$from,
13
+ $to = _state$selection.$to,
14
+ doc = state.doc;
15
+
16
+ if ($from.pos === $to.pos) {
17
+ return false;
18
+ }
19
+
20
+ var selectionCrossesWrappingBlockNode = false;
21
+ doc.nodesBetween($from.pos, $to.pos, function (node, pos) {
22
+ // Optimisation. If selection crosses wrapping block node
23
+ // short circuit the loop by returning false
24
+ if (selectionCrossesWrappingBlockNode) {
25
+ return false;
26
+ }
27
+
28
+ if (isNodeAWrappingBlockNode(node)) {
29
+ selectionCrossesWrappingBlockNode = true;
30
+ return false;
31
+ }
32
+ });
33
+
34
+ if (!selectionCrossesWrappingBlockNode) {
35
+ return false;
36
+ }
37
+
38
+ tr.delete($from.pos, $to.pos);
39
+
40
+ if (dispatch) {
41
+ dispatch(tr);
42
+ }
43
+
44
+ return true;
45
+ };
46
+ }
@@ -1,4 +1,5 @@
1
1
  export { cleanUpAtTheStartOfDocument, insertBlockType, insertBlockTypesWithAnalytics, setBlockType, setBlockTypeWithAnalytics, setHeading, setHeadingWithAnalytics, setNormalText, setNormalTextWithAnalytics } from './block-type';
2
2
  export { insertBlock } from './insert-block';
3
3
  export { isConvertableToCodeBlock, transformToCodeBlockAction } from './transform-to-code-block';
4
- export { deleteAndMoveCursor } from './delete-and-move-cursor';
4
+ export { deleteAndMoveCursor } from './delete-and-move-cursor';
5
+ export { deleteBlockContent } from './delete-block-content';
@@ -4,12 +4,12 @@ import * as keymaps from '../../../keymaps';
4
4
  import * as commands from '../../../commands';
5
5
  import * as blockTypes from '../types';
6
6
  import { keymap } from '../../../utils/keymap';
7
- import { cleanUpAtTheStartOfDocument, deleteAndMoveCursor, insertBlockTypesWithAnalytics } from '../commands';
7
+ import { cleanUpAtTheStartOfDocument, deleteAndMoveCursor, deleteBlockContent, insertBlockTypesWithAnalytics } from '../commands';
8
8
  import { deleteEmptyParagraphAndMoveBlockUp } from '../../../utils/commands';
9
9
  import { INPUT_METHOD } from '../../analytics';
10
10
  import { isNodeAWrappingBlockNode } from '../utils';
11
- var backspace = chainCommands(cleanUpAtTheStartOfDocument, deleteAndMoveCursor);
12
- var del = chainCommands(deleteEmptyParagraphAndMoveBlockUp(isNodeAWrappingBlockNode), deleteAndMoveCursor);
11
+ var backspace = chainCommands(cleanUpAtTheStartOfDocument, deleteBlockContent(isNodeAWrappingBlockNode), deleteAndMoveCursor);
12
+ var del = chainCommands(deleteEmptyParagraphAndMoveBlockUp(isNodeAWrappingBlockNode), deleteBlockContent(isNodeAWrappingBlockNode), deleteAndMoveCursor);
13
13
  export default function keymapPlugin(schema, featureFlags) {
14
14
  var list = {};
15
15
  keymaps.bindKeymapWithCommand(keymaps.insertNewLine.common, commands.insertNewLineWithAnalytics, list);