@atlaskit/editor-core 178.0.1 → 178.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) 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/list/styles.js +1 -1
  32. package/dist/cjs/plugins/media/commands/helpers.js +24 -2
  33. package/dist/cjs/plugins/media/nodeviews/mediaGroup.js +14 -16
  34. package/dist/cjs/plugins/media/nodeviews/mediaNodeUpdater.js +232 -183
  35. package/dist/cjs/plugins/media/nodeviews/mediaNodeView/index.js +1 -3
  36. package/dist/cjs/plugins/media/nodeviews/mediaSingle.js +1 -1
  37. package/dist/cjs/plugins/media/pm-plugins/keymap.js +46 -0
  38. package/dist/cjs/plugins/rank.js +3 -2
  39. package/dist/cjs/plugins/selection/pm-plugins/events/create-selection-between.js +86 -0
  40. package/dist/cjs/plugins/selection/pm-plugins/events/keydown.js +84 -0
  41. package/dist/cjs/plugins/selection/pm-plugins/selection-main.js +6 -56
  42. package/dist/cjs/plugins/text-color/ui/ToolbarTextColor/index.js +1 -1
  43. package/dist/cjs/plugins/text-formatting/ui/Toolbar/dropdown-menu.js +7 -2
  44. package/dist/cjs/plugins/toolbar-lists-indentation/ui/ToolbarDropdown.js +4 -2
  45. package/dist/cjs/ui/Addon/ClickAreaBlock/index.js +22 -61
  46. package/dist/cjs/ui/Addon/ClickAreaInline/index.js +22 -56
  47. package/dist/cjs/ui/Addon/click-area-helper.js +28 -6
  48. package/dist/cjs/ui/Alignment/AlignmentButton/index.js +4 -2
  49. package/dist/cjs/ui/ElementBrowser/InsertMenu.js +2 -1
  50. package/dist/cjs/ui/ToolbarArrowKeyNavigationProvider/index.js +22 -9
  51. package/dist/cjs/utils/document.js +11 -2
  52. package/dist/cjs/version-wrapper.js +1 -1
  53. package/dist/cjs/version.json +1 -1
  54. package/dist/es2019/create-editor/create-plugins-list.js +3 -1
  55. package/dist/es2019/plugins/alignment/ui/ToolbarAlignment/index.js +28 -13
  56. package/dist/es2019/plugins/annotation/index.js +4 -2
  57. package/dist/es2019/plugins/annotation/ui/InlineCommentView.js +6 -2
  58. package/dist/es2019/plugins/base/pm-plugins/react-nodeview.js +8 -1
  59. package/dist/es2019/plugins/block-type/commands/delete-block-content.js +49 -0
  60. package/dist/es2019/plugins/block-type/commands/index.js +2 -1
  61. package/dist/es2019/plugins/block-type/pm-plugins/keymap.js +3 -3
  62. package/dist/es2019/plugins/block-type/ui/ToolbarBlockType/index.js +8 -4
  63. package/dist/es2019/plugins/card/nodeviews/blockCard.js +1 -1
  64. package/dist/es2019/plugins/card/nodeviews/embedCard.js +1 -2
  65. package/dist/es2019/plugins/card/pm-plugins/doc.js +19 -3
  66. package/dist/es2019/plugins/card/toolbar.js +4 -2
  67. package/dist/es2019/plugins/card/ui/EditLinkToolbar.js +5 -2
  68. package/dist/es2019/plugins/card/ui/LinkToolbarAppearance.js +15 -9
  69. package/dist/es2019/plugins/collab-edit/actions.js +1 -1
  70. package/dist/es2019/plugins/collab-edit/index.js +1 -1
  71. package/dist/es2019/plugins/collab-edit/provider/channel.js +1 -1
  72. package/dist/es2019/plugins/expand/pm-plugins/keymap.js +5 -0
  73. package/dist/es2019/plugins/floating-toolbar/ui/Select.js +2 -1
  74. package/dist/es2019/plugins/floating-toolbar/ui/Toolbar.js +18 -9
  75. package/dist/es2019/plugins/hyperlink/HyperlinkToolbarAppearance.js +1 -0
  76. package/dist/es2019/plugins/hyperlink/index.js +2 -1
  77. package/dist/es2019/plugins/hyperlink/ui/EditorLinkPicker/index.js +11 -2
  78. package/dist/es2019/plugins/hyperlink/ui/HyperlinkAddToolbar/HyperlinkAddToolbar.js +1 -5
  79. package/dist/es2019/plugins/hyperlink/ui/HyperlinkAddToolbar/index.js +6 -2
  80. package/dist/es2019/plugins/insert-block/ui/ToolbarInsertBlock/block-insert-element-browser.js +2 -1
  81. package/dist/es2019/plugins/insert-block/ui/ToolbarInsertBlock/block-insert-menu.js +2 -1
  82. package/dist/es2019/plugins/insert-block/ui/ToolbarInsertBlock/index.js +2 -1
  83. package/dist/es2019/plugins/list/styles.js +15 -11
  84. package/dist/es2019/plugins/media/commands/helpers.js +18 -1
  85. package/dist/es2019/plugins/media/nodeviews/mediaGroup.js +14 -16
  86. package/dist/es2019/plugins/media/nodeviews/mediaNodeUpdater.js +37 -13
  87. package/dist/es2019/plugins/media/nodeviews/mediaNodeView/index.js +1 -2
  88. package/dist/es2019/plugins/media/nodeviews/mediaSingle.js +1 -1
  89. package/dist/es2019/plugins/media/pm-plugins/keymap.js +45 -0
  90. package/dist/es2019/plugins/rank.js +3 -2
  91. package/dist/es2019/plugins/selection/pm-plugins/events/create-selection-between.js +79 -0
  92. package/dist/es2019/plugins/selection/pm-plugins/events/keydown.js +77 -0
  93. package/dist/es2019/plugins/selection/pm-plugins/selection-main.js +5 -55
  94. package/dist/es2019/plugins/text-color/ui/ToolbarTextColor/index.js +1 -1
  95. package/dist/es2019/plugins/text-formatting/ui/Toolbar/dropdown-menu.js +6 -2
  96. package/dist/es2019/plugins/toolbar-lists-indentation/ui/ToolbarDropdown.js +3 -2
  97. package/dist/es2019/ui/Addon/ClickAreaBlock/index.js +20 -31
  98. package/dist/es2019/ui/Addon/ClickAreaInline/index.js +20 -27
  99. package/dist/es2019/ui/Addon/click-area-helper.js +28 -6
  100. package/dist/es2019/ui/Alignment/AlignmentButton/index.js +4 -2
  101. package/dist/es2019/ui/ElementBrowser/InsertMenu.js +2 -1
  102. package/dist/es2019/ui/ToolbarArrowKeyNavigationProvider/index.js +22 -9
  103. package/dist/es2019/utils/document.js +9 -2
  104. package/dist/es2019/version-wrapper.js +1 -1
  105. package/dist/es2019/version.json +1 -1
  106. package/dist/esm/create-editor/create-plugins-list.js +3 -1
  107. package/dist/esm/plugins/alignment/ui/ToolbarAlignment/index.js +26 -13
  108. package/dist/esm/plugins/annotation/index.js +4 -2
  109. package/dist/esm/plugins/annotation/ui/InlineCommentView.js +6 -2
  110. package/dist/esm/plugins/base/pm-plugins/react-nodeview.js +8 -1
  111. package/dist/esm/plugins/block-type/commands/delete-block-content.js +46 -0
  112. package/dist/esm/plugins/block-type/commands/index.js +2 -1
  113. package/dist/esm/plugins/block-type/pm-plugins/keymap.js +3 -3
  114. package/dist/esm/plugins/block-type/ui/ToolbarBlockType/index.js +8 -4
  115. package/dist/esm/plugins/card/nodeviews/blockCard.js +1 -1
  116. package/dist/esm/plugins/card/nodeviews/embedCard.js +1 -2
  117. package/dist/esm/plugins/card/pm-plugins/doc.js +20 -3
  118. package/dist/esm/plugins/card/toolbar.js +4 -2
  119. package/dist/esm/plugins/card/ui/EditLinkToolbar.js +5 -2
  120. package/dist/esm/plugins/card/ui/LinkToolbarAppearance.js +16 -9
  121. package/dist/esm/plugins/collab-edit/actions.js +1 -1
  122. package/dist/esm/plugins/collab-edit/index.js +1 -1
  123. package/dist/esm/plugins/collab-edit/provider/channel.js +1 -1
  124. package/dist/esm/plugins/expand/pm-plugins/keymap.js +5 -0
  125. package/dist/esm/plugins/floating-toolbar/ui/Select.js +2 -1
  126. package/dist/esm/plugins/floating-toolbar/ui/Toolbar.js +18 -9
  127. package/dist/esm/plugins/hyperlink/HyperlinkToolbarAppearance.js +1 -0
  128. package/dist/esm/plugins/hyperlink/index.js +2 -1
  129. package/dist/esm/plugins/hyperlink/ui/EditorLinkPicker/index.js +15 -3
  130. package/dist/esm/plugins/hyperlink/ui/HyperlinkAddToolbar/HyperlinkAddToolbar.js +27 -22
  131. package/dist/esm/plugins/hyperlink/ui/HyperlinkAddToolbar/index.js +6 -2
  132. package/dist/esm/plugins/insert-block/ui/ToolbarInsertBlock/block-insert-element-browser.js +2 -1
  133. package/dist/esm/plugins/insert-block/ui/ToolbarInsertBlock/block-insert-menu.js +2 -1
  134. package/dist/esm/plugins/insert-block/ui/ToolbarInsertBlock/index.js +2 -1
  135. package/dist/esm/plugins/list/styles.js +1 -1
  136. package/dist/esm/plugins/media/commands/helpers.js +20 -1
  137. package/dist/esm/plugins/media/nodeviews/mediaGroup.js +14 -16
  138. package/dist/esm/plugins/media/nodeviews/mediaNodeUpdater.js +235 -184
  139. package/dist/esm/plugins/media/nodeviews/mediaNodeView/index.js +1 -2
  140. package/dist/esm/plugins/media/nodeviews/mediaSingle.js +1 -1
  141. package/dist/esm/plugins/media/pm-plugins/keymap.js +45 -0
  142. package/dist/esm/plugins/rank.js +3 -2
  143. package/dist/esm/plugins/selection/pm-plugins/events/create-selection-between.js +76 -0
  144. package/dist/esm/plugins/selection/pm-plugins/events/keydown.js +74 -0
  145. package/dist/esm/plugins/selection/pm-plugins/selection-main.js +4 -57
  146. package/dist/esm/plugins/text-color/ui/ToolbarTextColor/index.js +1 -1
  147. package/dist/esm/plugins/text-formatting/ui/Toolbar/dropdown-menu.js +7 -2
  148. package/dist/esm/plugins/toolbar-lists-indentation/ui/ToolbarDropdown.js +4 -2
  149. package/dist/esm/ui/Addon/ClickAreaBlock/index.js +17 -58
  150. package/dist/esm/ui/Addon/ClickAreaInline/index.js +17 -53
  151. package/dist/esm/ui/Addon/click-area-helper.js +28 -6
  152. package/dist/esm/ui/Alignment/AlignmentButton/index.js +4 -2
  153. package/dist/esm/ui/ElementBrowser/InsertMenu.js +2 -1
  154. package/dist/esm/ui/ToolbarArrowKeyNavigationProvider/index.js +22 -9
  155. package/dist/esm/utils/document.js +11 -2
  156. package/dist/esm/version-wrapper.js +1 -1
  157. package/dist/esm/version.json +1 -1
  158. package/dist/types/plugins/alignment/ui/ToolbarAlignment/index.d.ts +1 -1
  159. package/dist/types/plugins/block-type/commands/delete-block-content.d.ts +10 -0
  160. package/dist/types/plugins/block-type/commands/index.d.ts +1 -0
  161. package/dist/types/plugins/card/pm-plugins/doc.d.ts +1 -1
  162. package/dist/types/plugins/card/ui/LinkToolbarAppearance.d.ts +1 -0
  163. package/dist/types/plugins/floating-toolbar/ui/Select.d.ts +1 -0
  164. package/dist/types/plugins/hyperlink/ui/EditorLinkPicker/index.d.ts +6 -1
  165. package/dist/types/plugins/hyperlink/ui/HyperlinkAddToolbar/index.d.ts +1 -1
  166. package/dist/types/plugins/insert-block/ui/ToolbarInsertBlock/block-insert-element-browser.d.ts +1 -0
  167. package/dist/types/plugins/insert-block/ui/ToolbarInsertBlock/block-insert-menu.d.ts +1 -0
  168. package/dist/types/plugins/media/commands/helpers.d.ts +1 -0
  169. package/dist/types/plugins/media/nodeviews/__mocks__/mediaNodeUpdater.d.ts +1 -0
  170. package/dist/types/plugins/media/nodeviews/mediaNodeUpdater.d.ts +3 -1
  171. package/dist/types/plugins/media/types.d.ts +2 -0
  172. package/dist/types/plugins/selection/pm-plugins/events/create-selection-between.d.ts +4 -0
  173. package/dist/types/plugins/selection/pm-plugins/events/keydown.d.ts +2 -0
  174. package/dist/types/ui/Addon/ClickAreaBlock/index.d.ts +2 -5
  175. package/dist/types/ui/Addon/ClickAreaInline/index.d.ts +2 -5
  176. package/dist/types/ui/Addon/click-area-helper.d.ts +1 -1
  177. package/dist/types/ui/Alignment/AlignmentButton/index.d.ts +1 -1
  178. package/dist/types/ui/ElementBrowser/InsertMenu.d.ts +1 -1
  179. package/dist/types/ui/ElementBrowser/types.d.ts +1 -0
  180. package/docs/0-intro.tsx +9 -0
  181. package/package.json +17 -19
  182. package/report.api.md +4 -1
@@ -172,6 +172,11 @@ export function expandKeymap() {
172
172
  const {
173
173
  $from
174
174
  } = state.selection;
175
+
176
+ if ($from.depth === 0) {
177
+ return false;
178
+ }
179
+
175
180
  const $after = state.doc.resolve($from.after());
176
181
 
177
182
  if ($after.nodeAfter && ($after.nodeAfter.type === expand || $after.nodeAfter.type === nestedExpand)) {
@@ -57,6 +57,7 @@ export default function Search(props) {
57
57
  menuPortalTarget: props.mountPoint,
58
58
  onMenuOpen: onMenuOpen,
59
59
  onMenuClose: onMenuClose,
60
- "aria-label": props.ariaLabel
60
+ "aria-label": props.ariaLabel,
61
+ classNamePrefix: props.classNamePrefix
61
62
  });
62
63
  }
@@ -125,6 +125,7 @@ const ToolbarItems = /*#__PURE__*/React.memo(({
125
125
 
126
126
  case 'select':
127
127
  if (item.selectType === 'list') {
128
+ const ariaLabel = item.title || item.placeholder;
128
129
  return jsx(Select, {
129
130
  key: idx,
130
131
  dispatchCommand: dispatchCommand,
@@ -136,8 +137,10 @@ const ToolbarItems = /*#__PURE__*/React.memo(({
136
137
  defaultValue: item.defaultValue,
137
138
  placeholder: item.placeholder,
138
139
  onChange: selected => dispatchCommand(item.onChange(selected)),
140
+ ariaLabel: ariaLabel,
139
141
  filterOption: item.filterOption,
140
- setDisableParentScroll: scrollable ? setDisableScroll : undefined
142
+ setDisableParentScroll: scrollable ? setDisableScroll : undefined,
143
+ classNamePrefix: 'floating-toolbar-select'
141
144
  });
142
145
  }
143
146
 
@@ -340,15 +343,21 @@ class Toolbar extends Component {
340
343
  });
341
344
 
342
345
  _defineProperty(this, "handleEscape", event => {
343
- //If any dropdown is open inside the floating toolbar 'Esc' key should not
344
- //focus the editorview. The event cannot be stopped as dropdown is not childnode of floating toolbar
345
- if (!document.querySelector('[data-role="droplistContent"]')) {
346
- var _this$props$editorVie;
347
-
348
- (_this$props$editorVie = this.props.editorView) === null || _this$props$editorVie === void 0 ? void 0 : _this$props$editorVie.focus();
349
- event.preventDefault();
350
- event.stopPropagation();
346
+ var _this$props$editorVie;
347
+
348
+ // If any menu is open inside the floating toolbar 'Esc' key should not
349
+ // focus the editorview.
350
+ // Event can't be stopped as they are not childnodes of floating toolbar
351
+ const isDropdownOpen = !!document.querySelector('[data-role="droplistContent"]');
352
+ const isSelectMenuOpen = !!document.querySelector('.floating-toolbar-select__menu');
353
+
354
+ if (isDropdownOpen || isSelectMenuOpen) {
355
+ return;
351
356
  }
357
+
358
+ (_this$props$editorVie = this.props.editorView) === null || _this$props$editorVie === void 0 ? void 0 : _this$props$editorVie.focus();
359
+ event.preventDefault();
360
+ event.stopPropagation();
352
361
  });
353
362
 
354
363
  this.scrollContainerRef = /*#__PURE__*/React.createRef();
@@ -89,6 +89,7 @@ export class HyperlinkToolbarAppearance extends Component {
89
89
  editorView: editorView,
90
90
  editorState: editorState,
91
91
  allowEmbeds: cardOptions === null || cardOptions === void 0 ? void 0 : cardOptions.allowEmbeds,
92
+ allowBlockCards: cardOptions === null || cardOptions === void 0 ? void 0 : cardOptions.allowBlockCards,
92
93
  platform: platform
93
94
  });
94
95
  }
@@ -61,7 +61,8 @@ const hyperlinkPlugin = options => ({
61
61
  action(insert, state) {
62
62
  const tr = insert(undefined);
63
63
  tr.setMeta(stateKey, {
64
- type: LinkAction.SHOW_INSERT_TOOLBAR
64
+ type: LinkAction.SHOW_INSERT_TOOLBAR,
65
+ inputMethod: INPUT_METHOD.QUICK_INSERT
65
66
  });
66
67
  return addAnalytics(state, tr, {
67
68
  action: ACTION.INVOKED,
@@ -1,9 +1,10 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
- import React, { useCallback } from 'react';
2
+ import React, { useCallback, useMemo } from 'react';
3
3
  import { LinkPicker } from '@atlaskit/link-picker';
4
4
  import { hideLinkToolbar as cardHideLinkToolbar } from '../../../card/pm-plugins/actions';
5
5
  import { hideLinkToolbar } from '../../commands';
6
6
  import { useEscapeClickaway } from './useEscapeClickaway';
7
+ import { AnalyticsContext } from '@atlaskit/analytics-next';
7
8
  /**
8
9
  * Returns a type that matches T but where keys (K) are now optional
9
10
  */
@@ -11,6 +12,7 @@ import { useEscapeClickaway } from './useEscapeClickaway';
11
12
  export const EditorLinkPicker = ({
12
13
  view,
13
14
  onCancel,
15
+ invokeMethod = '_unknown',
14
16
  ...restProps
15
17
  }) => {
16
18
  const onEscape = useCallback(() => {
@@ -23,9 +25,16 @@ export const EditorLinkPicker = ({
23
25
  onCancel === null || onCancel === void 0 ? void 0 : onCancel();
24
26
  }, [view, onCancel]);
25
27
  const ref = useEscapeClickaway(onEscape, onClickAway);
28
+ const analyticsData = useMemo(() => ({
29
+ attributes: {
30
+ invokeMethod
31
+ }
32
+ }), [invokeMethod]);
26
33
  return /*#__PURE__*/React.createElement("div", {
27
34
  ref: ref
35
+ }, /*#__PURE__*/React.createElement(AnalyticsContext, {
36
+ data: analyticsData
28
37
  }, /*#__PURE__*/React.createElement(LinkPicker, _extends({}, restProps, {
29
38
  onCancel: onEscape
30
- })));
39
+ }))));
31
40
  };
@@ -272,16 +272,12 @@ export class HyperlinkLinkAddToolbar extends PureComponent {
272
272
  activityProvider
273
273
  } = this.state;
274
274
 
275
- if (!activityProvider) {
276
- return;
277
- }
278
-
279
275
  switch (field) {
280
276
  case 'displayUrl':
281
277
  {
282
278
  this.setState({
283
279
  [field]: '',
284
- items: limit(await activityProvider.getRecentItems())
280
+ items: !!activityProvider ? limit(await activityProvider.getRecentItems()) : []
285
281
  });
286
282
 
287
283
  if (this.urlInputContainer) {
@@ -30,7 +30,8 @@ export default class HyperlinkAddToolbar extends React.PureComponent {
30
30
  displayUrl,
31
31
  providerFactory,
32
32
  view,
33
- onCancel
33
+ onCancel,
34
+ invokeMethod
34
35
  } = this.props;
35
36
  return /*#__PURE__*/React.createElement(WithProviders, {
36
37
  providers: ['activityProvider', 'searchProvider'],
@@ -52,7 +53,10 @@ export default class HyperlinkAddToolbar extends React.PureComponent {
52
53
 
53
54
  if (lpLinkPicker) {
54
55
  return /*#__PURE__*/React.createElement(EditorLinkPicker, _extends({
55
- view: view
56
+ view: view,
57
+ invokeMethod: // Provide `invokeMethod` prop as preferred value (card plugin passes as prop) otherwise assume this
58
+ // is being used from inside the hyperlink plugin and use inputMethod from plugin state
59
+ invokeMethod !== null && invokeMethod !== void 0 ? invokeMethod : hyperlinkPluginState === null || hyperlinkPluginState === void 0 ? void 0 : hyperlinkPluginState.inputMethod
56
60
  }, linkPickerOptions, {
57
61
  url: displayUrl,
58
62
  displayText: displayText,
@@ -15,7 +15,8 @@ export const BlockInsertElementBrowser = props => {
15
15
  editorView: props.editorView,
16
16
  dropdownItems: props.items,
17
17
  onInsert: props.onInsert,
18
- toggleVisiblity: props.togglePlusMenuVisibility
18
+ toggleVisiblity: props.togglePlusMenuVisibility,
19
+ showElementBrowserLink: props.showElementBrowserLink
19
20
  })), /*#__PURE__*/React.createElement(DropDownButton, {
20
21
  "aria-expanded": props.open,
21
22
  "aria-haspopup": true,
@@ -36,7 +36,8 @@ export const BlockInsertMenu = props => {
36
36
  popupsMountPoint: props.popupsMountPoint,
37
37
  popupsScrollableElement: props.popupsScrollableElement,
38
38
  spacing: props.spacing,
39
- togglePlusMenuVisibility: props.togglePlusMenuVisibility
39
+ togglePlusMenuVisibility: props.togglePlusMenuVisibility,
40
+ showElementBrowserLink: props.showElementBrowserLink
40
41
  });
41
42
  }
42
43
 
@@ -579,7 +579,8 @@ export class ToolbarInsertBlock extends React.PureComponent {
579
579
  onInsert: this.insertInsertMenuItem,
580
580
  onOpenChange: this.onOpenChange,
581
581
  togglePlusMenuVisibility: this.togglePlusMenuVisibility,
582
- replacePlusMenuWithElementBrowser: (_this$props$replacePl = this.props.replacePlusMenuWithElementBrowser) !== null && _this$props$replacePl !== void 0 ? _this$props$replacePl : false
582
+ replacePlusMenuWithElementBrowser: (_this$props$replacePl = this.props.replacePlusMenuWithElementBrowser) !== null && _this$props$replacePl !== void 0 ? _this$props$replacePl : false,
583
+ showElementBrowserLink: this.props.showElementBrowserLink || false
583
584
  })), this.props.showSeparator && jsx("span", {
584
585
  css: separatorStyles
585
586
  }));
@@ -3,20 +3,24 @@ import { blockNodesVerticalMargin } from '@atlaskit/editor-shared-styles';
3
3
  import { browser } from '@atlaskit/editor-common/utils';
4
4
  import { codeBlockInListSafariFix } from '@atlaskit/editor-common/styles';
5
5
  export const listsStyles = css`
6
- .ProseMirror li {
7
- position: relative;
6
+ .ProseMirror {
7
+ li {
8
+ position: relative;
8
9
 
9
- > p:not(:first-child) {
10
- margin: 4px 0 0 0;
11
- }
10
+ > p:not(:first-child) {
11
+ margin: 4px 0 0 0;
12
+ }
12
13
 
13
- // In SSR the above rule will apply to all p tags because first-child would be a style tag.
14
- // The following rule resets the first p tag back to its original margin
15
- // defined in packages/editor/editor-common/src/styles/shared/paragraph.ts
16
- > style:first-child + p {
17
- margin-top: ${blockNodesVerticalMargin};
14
+ // In SSR the above rule will apply to all p tags because first-child would be a style tag.
15
+ // The following rule resets the first p tag back to its original margin
16
+ // defined in packages/editor/editor-common/src/styles/shared/paragraph.ts
17
+ > style:first-child + p {
18
+ margin-top: ${blockNodesVerticalMargin};
19
+ }
18
20
  }
19
21
 
20
- ${browser.safari ? codeBlockInListSafariFix : ''}
22
+ & :not([data-node-type='decisionList']) > li {
23
+ ${browser.safari ? codeBlockInListSafariFix : ''}
24
+ }
21
25
  }
22
26
  `;
@@ -74,7 +74,7 @@ export const updateAllMediaNodesAttrs = (id, attrs, isMediaSingle) => (state, di
74
74
  }) => {
75
75
  const pos = getPos();
76
76
 
77
- if (typeof pos === 'number' && !isMediaNode(pos, state)) {
77
+ if (isNaN(pos) || typeof pos === 'number' && !isMediaNode(pos, state)) {
78
78
  return acc;
79
79
  }
80
80
 
@@ -96,6 +96,23 @@ export const updateAllMediaNodesAttrs = (id, attrs, isMediaSingle) => (state, di
96
96
 
97
97
  return true;
98
98
  };
99
+ export const updateCurrentMediaNodeAttrs = (attrs, mediaNode) => (state, dispatch) => {
100
+ const pos = mediaNode.getPos();
101
+
102
+ if (isNaN(pos) || typeof pos === 'number' && !isMediaNode(pos, state)) {
103
+ return false;
104
+ }
105
+
106
+ const tr = state.tr;
107
+ tr.step(new SetAttrsStep(pos, attrs));
108
+ tr.setMeta('addToHistory', false);
109
+
110
+ if (dispatch) {
111
+ dispatch(tr);
112
+ }
113
+
114
+ return true;
115
+ };
99
116
  export const updateMediaNodeAttrs = (id, attrs, isMediaSingle) => (state, dispatch) => {
100
117
  const mediaPluginState = mediaPluginKey.getState(state);
101
118
  const mediaNodeWithPos = findMediaNode(mediaPluginState, id, isMediaSingle);
@@ -39,25 +39,23 @@ class MediaGroup extends React.Component {
39
39
  viewMediaClientConfig: undefined
40
40
  });
41
41
 
42
- _defineProperty(this, "updateNodeAttrs", props => {
42
+ _defineProperty(this, "updateNodeAttrs", (props, node, getPos) => {
43
43
  const {
44
44
  view,
45
45
  mediaProvider,
46
46
  contextIdentifierProvider
47
47
  } = props;
48
- this.mediaNodes.forEach(node => {
49
- const mediaNodeUpdater = new MediaNodeUpdater({
50
- view,
51
- mediaProvider,
52
- contextIdentifierProvider,
53
- node,
54
- isMediaSingle: false
55
- });
56
- mediaNodeUpdater.updateFileAttrs(false);
48
+ const mediaNodeUpdater = new MediaNodeUpdater({
49
+ view,
50
+ mediaProvider,
51
+ contextIdentifierProvider,
52
+ node,
53
+ isMediaSingle: false
57
54
  });
55
+ mediaNodeUpdater.updateNodeAttrs(getPos);
58
56
  });
59
57
 
60
- _defineProperty(this, "setMediaItems", props => {
58
+ _defineProperty(this, "setMediaItems", (props, updatedAttrs = false) => {
61
59
  const {
62
60
  node
63
61
  } = props;
@@ -68,6 +66,10 @@ class MediaGroup extends React.Component {
68
66
 
69
67
  this.mediaPluginState.setMediaGroupNode(item, getPos);
70
68
  this.mediaNodes.push(item);
69
+
70
+ if (updatedAttrs) {
71
+ this.updateNodeAttrs(props, item, getPos);
72
+ }
71
73
  });
72
74
  this.mediaPluginState.handleMediaGroupUpdate(oldMediaNodes, this.mediaNodes);
73
75
  });
@@ -198,11 +200,7 @@ class MediaGroup extends React.Component {
198
200
 
199
201
  UNSAFE_componentWillReceiveProps(props) {
200
202
  this.updateMediaClientConfig();
201
- this.setMediaItems(props);
202
-
203
- if (props.isCopyPasteEnabled !== false) {
204
- this.updateNodeAttrs(props);
205
- }
203
+ this.setMediaItems(props, props.isCopyPasteEnabled || props.isCopyPasteEnabled === undefined);
206
204
  }
207
205
 
208
206
  shouldComponentUpdate(nextProps) {
@@ -3,7 +3,7 @@ import uuidV4 from 'uuid/v4';
3
3
  import { DEFAULT_IMAGE_HEIGHT, DEFAULT_IMAGE_WIDTH } from '@atlaskit/editor-common/ui';
4
4
  import { getMediaClient, isMediaBlobUrl, getAttrsFromUrl, isImageRepresentationReady } from '@atlaskit/media-client';
5
5
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '../../analytics';
6
- import { replaceExternalMedia, updateAllMediaNodesAttrs, updateMediaNodeAttrs } from '../commands/helpers';
6
+ import { replaceExternalMedia, updateAllMediaNodesAttrs, updateCurrentMediaNodeAttrs, updateMediaNodeAttrs } from '../commands/helpers';
7
7
  export class MediaNodeUpdater {
8
8
  constructor(props) {
9
9
  _defineProperty(this, "updateContextId", async () => {
@@ -22,28 +22,30 @@ export class MediaNodeUpdater {
22
22
  }, this.props.isMediaSingle)(this.props.view.state, this.props.view.dispatch);
23
23
  });
24
24
 
25
- _defineProperty(this, "hasFileAttributesDefined", () => {
26
- const attrs = this.getAttrs();
25
+ _defineProperty(this, "hasFileAttributesDefined", attrs => {
27
26
  return attrs && attrs.type === 'file' && attrs.__fileName && attrs.__fileMimeType && attrs.__fileSize && attrs.__contextId;
28
27
  });
29
28
 
30
- _defineProperty(this, "updateFileAttrs", async (isMediaSingle = true) => {
29
+ _defineProperty(this, "getNewFileAttrsForNode", async () => {
31
30
  const attrs = this.getAttrs();
32
31
  const mediaProvider = await this.props.mediaProvider;
33
32
 
34
- if (!mediaProvider || !mediaProvider.uploadParams || !attrs || attrs.type !== 'file' || this.hasFileAttributesDefined()) {
33
+ if (!mediaProvider || !mediaProvider.uploadParams || !attrs || attrs.type !== 'file' || this.hasFileAttributesDefined(attrs)) {
35
34
  return;
36
35
  }
37
36
 
38
37
  const mediaClientConfig = mediaProvider.viewMediaClientConfig;
39
38
  const mediaClient = getMediaClient(mediaClientConfig);
40
- const options = {
41
- collectionName: attrs.collection
42
- };
43
39
  let fileState;
40
+ const {
41
+ id,
42
+ collection: collectionName
43
+ } = attrs;
44
44
 
45
45
  try {
46
- fileState = await mediaClient.file.getCurrentState(attrs.id, options);
46
+ fileState = await mediaClient.file.getCurrentState(id, {
47
+ collectionName
48
+ });
47
49
 
48
50
  if (fileState.status === 'error') {
49
51
  return;
@@ -64,11 +66,33 @@ export class MediaNodeUpdater {
64
66
  __fileSize: size,
65
67
  __contextId: contextId
66
68
  };
67
- const attrsChanged = hasPrivateAttrsChanged(attrs, newAttrs);
68
69
 
69
- if (attrsChanged) {
70
- // TODO [MS-2258]: we should pass this.props.isMediaSingle and remove hardcoded "true"
71
- updateAllMediaNodesAttrs(attrs.id, newAttrs, isMediaSingle)(this.props.view.state, this.props.view.dispatch);
70
+ if (!hasPrivateAttrsChanged(attrs, newAttrs)) {
71
+ return;
72
+ }
73
+
74
+ return newAttrs;
75
+ });
76
+
77
+ _defineProperty(this, "updateFileAttrs", async (isMediaSingle = true) => {
78
+ const newAttrs = await this.getNewFileAttrsForNode();
79
+ const {
80
+ id
81
+ } = this.getAttrs();
82
+
83
+ if (id && newAttrs) {
84
+ updateAllMediaNodesAttrs(id, newAttrs, isMediaSingle)(this.props.view.state, this.props.view.dispatch);
85
+ }
86
+ });
87
+
88
+ _defineProperty(this, "updateNodeAttrs", async getPos => {
89
+ const newAttrs = await this.getNewFileAttrsForNode();
90
+
91
+ if (newAttrs) {
92
+ updateCurrentMediaNodeAttrs(newAttrs, {
93
+ node: this.props.node,
94
+ getPos
95
+ })(this.props.view.state, this.props.view.dispatch);
72
96
  }
73
97
  });
74
98
 
@@ -1,7 +1,6 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import { WithProviders } from '@atlaskit/editor-common/provider-factory';
3
3
  import { DEFAULT_IMAGE_HEIGHT, DEFAULT_IMAGE_WIDTH } from '@atlaskit/editor-common/ui';
4
- import { browser } from '@atlaskit/editor-common/utils';
5
4
  import { NodeSelection } from 'prosemirror-state';
6
5
  import React from 'react';
7
6
  import { SelectionBasedNodeView } from '../../../../nodeviews';
@@ -91,7 +90,7 @@ class MediaNodeView extends SelectionBasedNodeView {
91
90
  createDomRef() {
92
91
  const domRef = document.createElement('div');
93
92
 
94
- if (browser.chrome && this.reactComponentProps.mediaOptions && this.reactComponentProps.mediaOptions.allowMediaSingleEditable) {
93
+ if (this.reactComponentProps.mediaOptions && this.reactComponentProps.mediaOptions.allowMediaSingleEditable) {
95
94
  // workaround Chrome bug in https://product-fabric.atlassian.net/browse/ED-5379
96
95
  // see also: https://github.com/ProseMirror/prosemirror/issues/884
97
96
  domRef.contentEditable = 'true';
@@ -385,7 +385,7 @@ class MediaSingleNodeView extends ReactNodeView {
385
385
  createDomRef() {
386
386
  const domRef = document.createElement('div');
387
387
 
388
- if (browser.chrome && this.reactComponentProps.mediaOptions && this.reactComponentProps.mediaOptions.allowMediaSingleEditable) {
388
+ if (this.reactComponentProps.mediaOptions && this.reactComponentProps.mediaOptions.allowMediaSingleEditable) {
389
389
  // workaround Chrome bug in https://product-fabric.atlassian.net/browse/ED-5379
390
390
  // see also: https://github.com/ProseMirror/prosemirror/issues/884
391
391
  domRef.contentEditable = 'true';
@@ -3,6 +3,7 @@ import { NodeSelection } from 'prosemirror-state';
3
3
  import * as keymaps from '../../../keymaps';
4
4
  import { stateKey } from '../pm-plugins/plugin-key';
5
5
  import { getMediaFeatureFlag } from '@atlaskit/media-common';
6
+ import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
6
7
  import { insertAndSelectCaptionFromMediaSinglePos, selectCaptionFromMediaSinglePos } from '../commands/captions';
7
8
  export function keymapPlugin(options) {
8
9
  const list = {};
@@ -15,6 +16,8 @@ export function keymapPlugin(options) {
15
16
  if (getMediaFeatureFlag('captions', featureFlags)) {
16
17
  keymaps.bindKeymapWithCommand(keymaps.moveDown.common, insertAndSelectCaption, list);
17
18
  keymaps.bindKeymapWithCommand(keymaps.tab.common, insertAndSelectCaption, list);
19
+ keymaps.bindKeymapWithCommand(keymaps.moveLeft.common, arrowLeftFromMediaSingle(options === null || options === void 0 ? void 0 : options.editorSelectionAPI), list);
20
+ keymaps.bindKeymapWithCommand(keymaps.moveRight.common, arrowRightFromMediaSingle(options === null || options === void 0 ? void 0 : options.editorSelectionAPI), list);
18
21
  }
19
22
 
20
23
  keymaps.bindKeymapWithCommand(keymaps.insertNewLine.common, splitMediaGroup, list);
@@ -56,4 +59,46 @@ const insertAndSelectCaption = (state, dispatch) => {
56
59
  return false;
57
60
  };
58
61
 
62
+ const arrowLeftFromMediaSingle = editorSelectionAPI => (state, dispatch) => {
63
+ const {
64
+ selection
65
+ } = state;
66
+
67
+ if (editorSelectionAPI && selection instanceof NodeSelection && selection.node.type.name === 'mediaSingle') {
68
+ const tr = editorSelectionAPI.setSelectionRelativeToNode({
69
+ selectionRelativeToNode: undefined,
70
+ selection: new GapCursorSelection(state.doc.resolve(selection.from), Side.LEFT)
71
+ })(state);
72
+
73
+ if (dispatch) {
74
+ dispatch(tr);
75
+ }
76
+
77
+ return true;
78
+ }
79
+
80
+ return false;
81
+ };
82
+
83
+ const arrowRightFromMediaSingle = editorSelectionAPI => (state, dispatch) => {
84
+ const {
85
+ selection
86
+ } = state;
87
+
88
+ if (editorSelectionAPI && selection instanceof NodeSelection && selection.node.type.name === 'mediaSingle') {
89
+ const tr = editorSelectionAPI.setSelectionRelativeToNode({
90
+ selectionRelativeToNode: undefined,
91
+ selection: new GapCursorSelection(state.doc.resolve(selection.to), Side.RIGHT)
92
+ })(state);
93
+
94
+ if (dispatch) {
95
+ dispatch(tr);
96
+ }
97
+
98
+ return true;
99
+ }
100
+
101
+ return false;
102
+ };
103
+
59
104
  export default keymapPlugin;
@@ -4,9 +4,10 @@ export default {
4
4
  'indentationKeymap', 'textColor', 'alignmentPlugin', 'listInputRule', 'listKeymap', 'codeBlock', 'codeBlockIDEKeyBindings', 'codeBlockKeyMap', 'textFormatting', 'textFormattingCursor', 'textFormattingInputRule', 'textFormattingSmartRule', 'textFormattingClear', 'textFormattingKeymap', // task/decisions keymap needs to be above table keymap so can indent actions in a table
5
5
  'tasksAndDecisionsKeyMap', // expand and table keymaps need to be above selection keymap to add their custom selection behaviour:
6
6
  // https://product-fabric.atlassian.net/wiki/spaces/E/pages/1113098008/Selection+Guide#Special-Cases
7
- 'expandKeymap', 'tableSelectionKeymap', 'tableKeymap', 'captionKeymap', // selection keymap needs to be above gap cursor keymap so it can set node selections from
7
+ 'expandKeymap', 'tableSelectionKeymap', 'tableKeymap', 'captionKeymap', // media keymap above selection keymap to allow navigating past the mediaSingle node
8
+ 'mediaKeymap', // selection keymap needs to be above gap cursor keymap so it can set node selections from
8
9
  // left/right arrows
9
- 'selectionKeymap', 'gapCursorKeymap', 'gapCursor', 'syncUrlText', 'fakeCursorToolbarPlugin', 'hyperLink', 'table', 'tableDecorations', 'hyperlinkInputRule', 'tablePMColResizing', 'hyperlinkKeymap', 'tableColResizing', 'undoRedoKeyMap', 'blockTypeKeyMap', 'tableEditing', 'filterStepsPlugin', 'pmCollab', 'collab', 'ruleInputRule', 'ruleKeymap', 'panel', 'media', 'mediaKeymap', 'mediaSingleKeymap', 'mediaEditor', 'unsupportedContent', 'jiraIssue', 'fakeTextCursor', 'helpDialog', 'helpDialogKeymap', 'macro', 'expand', 'extension', 'layout', 'contextPanel', 'floatingToolbar', 'clearMarksOnChange', 'reactNodeView', 'history', 'undoRedoPlugin', 'codeBlockIndent', 'placeholder', 'width', 'maxContentSize', 'multilineContent', 'grid', 'mobileDimensions', 'scrollGutterPlugin', 'analytics', 'findReplace', 'selection', 'avatarGroup', 'viewUpdateSubscription', 'beforePrimaryToolbar', 'inlineCode'],
10
+ 'selectionKeymap', 'gapCursorKeymap', 'gapCursor', 'syncUrlText', 'fakeCursorToolbarPlugin', 'hyperLink', 'table', 'tableDecorations', 'hyperlinkInputRule', 'tablePMColResizing', 'hyperlinkKeymap', 'tableColResizing', 'undoRedoKeyMap', 'blockTypeKeyMap', 'tableEditing', 'filterStepsPlugin', 'pmCollab', 'collab', 'ruleInputRule', 'ruleKeymap', 'panel', 'media', 'mediaSingleKeymap', 'mediaEditor', 'unsupportedContent', 'jiraIssue', 'fakeTextCursor', 'helpDialog', 'helpDialogKeymap', 'macro', 'expand', 'extension', 'layout', 'contextPanel', 'floatingToolbar', 'clearMarksOnChange', 'reactNodeView', 'history', 'undoRedoPlugin', 'codeBlockIndent', 'placeholder', 'width', 'maxContentSize', 'multilineContent', 'grid', 'mobileDimensions', 'scrollGutterPlugin', 'analytics', 'findReplace', 'selection', 'avatarGroup', 'viewUpdateSubscription', 'beforePrimaryToolbar', 'inlineCode'],
10
11
  nodes: ['doc', 'paragraph', 'text', 'bulletList', 'orderedList', 'listItem', 'heading', 'blockquote', 'codeBlock', 'rule', 'panel', 'mention', 'confluenceUnsupportedBlock', 'confluenceUnsupportedInline', 'unsupportedBlock', 'unsupportedInline', 'confluenceJiraIssue', 'hardBreak', 'emoji', 'placeholder', 'mediaSingle', 'mediaGroup', 'table', 'expand', 'nestedExpand', 'media', 'tableHeader', 'decisionList', 'tableRow', 'decisionItem', 'tableCell', 'taskList', 'taskItem', 'extension', 'bodiedExtension', 'inlineExtension', 'layoutSection', 'layoutColumn', 'inlineCard', 'blockCard', 'embedCard'],
11
12
  marks: [// Fragment mark is both for inline and block elements
12
13
  'fragment', // Inline marks
@@ -0,0 +1,79 @@
1
+ import { NodeSelection, TextSelection } from 'prosemirror-state';
2
+
3
+ function findEmptySelectableParentNodePosition($pos, isValidPosition) {
4
+ const {
5
+ doc
6
+ } = $pos;
7
+
8
+ if ($pos.pos + 1 > doc.content.size) {
9
+ return null;
10
+ }
11
+
12
+ if ($pos.depth === 0) {
13
+ if (isValidPosition($pos)) {
14
+ return $pos;
15
+ }
16
+
17
+ return null;
18
+ }
19
+
20
+ if (isValidPosition($pos)) {
21
+ return $pos;
22
+ }
23
+
24
+ const positionLevelUp = $pos.before();
25
+ const resolvedPositionLevelUp = doc.resolve(positionLevelUp);
26
+ return findEmptySelectableParentNodePosition(resolvedPositionLevelUp, isValidPosition);
27
+ }
28
+
29
+ const checkPositionNode = $pos => {
30
+ const maybeNode = $pos.nodeAfter;
31
+
32
+ if (!maybeNode || !maybeNode.isBlock) {
33
+ return false;
34
+ }
35
+
36
+ if (maybeNode.isAtom) {
37
+ return true;
38
+ }
39
+
40
+ const isParentEmpty = maybeNode.content.size === 0 || maybeNode.textContent === '';
41
+ return isParentEmpty && NodeSelection.isSelectable(maybeNode);
42
+ };
43
+
44
+ function findNextSelectionPosition({
45
+ $targetHead,
46
+ $anchor,
47
+ doc
48
+ }) {
49
+ const direction = $anchor.pos < $targetHead.pos ? 'down' : 'up';
50
+ const maybeNextPosition = findEmptySelectableParentNodePosition($targetHead, checkPositionNode);
51
+
52
+ if (maybeNextPosition && maybeNextPosition.nodeAfter) {
53
+ const nodeAfter = maybeNextPosition.nodeAfter;
54
+ const pos = maybeNextPosition.pos;
55
+ const nextPositionToSelect = direction === 'down' ? Math.min(nodeAfter.nodeSize + pos, doc.content.size) : Math.max(pos, 0);
56
+ return doc.resolve(nextPositionToSelect);
57
+ }
58
+
59
+ return null;
60
+ }
61
+
62
+ export const onCreateSelectionBetween = (view, $anchor, $head) => {
63
+ if ($anchor.pos === $head.pos) {
64
+ return null;
65
+ }
66
+
67
+ const $nextHeadPosition = findNextSelectionPosition({
68
+ $targetHead: $head,
69
+ $anchor,
70
+ doc: view.state.doc
71
+ });
72
+
73
+ if (!$nextHeadPosition) {
74
+ return null;
75
+ }
76
+
77
+ const forcedTextSelection = TextSelection.create(view.state.doc, $anchor.pos, $nextHeadPosition.pos);
78
+ return forcedTextSelection;
79
+ };