@atlaskit/editor-core 150.0.3 → 151.0.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 (195) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/dist/cjs/actions/index.js +5 -23
  3. package/dist/cjs/create-editor/ErrorBoundary.js +113 -79
  4. package/dist/cjs/create-editor/ReactEditorView.js +145 -31
  5. package/dist/cjs/create-editor/create-plugins-list.js +4 -2
  6. package/dist/cjs/editor.js +101 -40
  7. package/dist/cjs/labs/next/presets/cxhtml.js +2 -1
  8. package/dist/cjs/plugins/analytics/types/enums.js +3 -1
  9. package/dist/cjs/plugins/base/index.js +4 -3
  10. package/dist/cjs/plugins/base/pm-plugins/frozen-editor.js +66 -36
  11. package/dist/cjs/plugins/block-type/ui/ToolbarBlockType/styled.js +3 -1
  12. package/dist/cjs/plugins/card/index.js +13 -2
  13. package/dist/cjs/plugins/card/nodeviews/embedCard.js +1 -0
  14. package/dist/cjs/plugins/card/pm-plugins/main.js +7 -2
  15. package/dist/cjs/plugins/card/pm-plugins/util/resolve.js +10 -3
  16. package/dist/cjs/plugins/code-block/toolbar.js +1 -1
  17. package/dist/cjs/plugins/emoji/styles.js +1 -1
  18. package/dist/cjs/plugins/extension/pm-plugins/main.js +1 -4
  19. package/dist/cjs/plugins/extension/toolbar.js +28 -23
  20. package/dist/cjs/plugins/feature-flags-context/feature-flags-from-props.js +8 -3
  21. package/dist/cjs/plugins/find-replace/ui/Find.js +27 -7
  22. package/dist/cjs/plugins/hyperlink/pm-plugins/keymap.js +3 -3
  23. package/dist/cjs/plugins/hyperlink/ui/HyperlinkAddToolbar/HyperlinkAddToolbar.js +7 -4
  24. package/dist/cjs/plugins/hyperlink/utils.js +6 -69
  25. package/dist/cjs/plugins/media/index.js +14 -3
  26. package/dist/cjs/plugins/media/nodeviews/mediaGroup.js +24 -10
  27. package/dist/cjs/plugins/media/nodeviews/mediaInline.js +179 -0
  28. package/dist/cjs/plugins/media/pm-plugins/main.js +18 -9
  29. package/dist/cjs/plugins/media/toolbar/index.js +49 -17
  30. package/dist/cjs/plugins/media/toolbar/utils.js +20 -2
  31. package/dist/cjs/plugins/media/utils/media-files.js +67 -1
  32. package/dist/cjs/plugins/panel/index.js +2 -3
  33. package/dist/cjs/plugins/panel/message.js +47 -0
  34. package/dist/cjs/plugins/panel/toolbar.js +64 -84
  35. package/dist/cjs/plugins/panel/utils.js +2 -2
  36. package/dist/cjs/plugins/paste/linkify-md-plugin.js +3 -3
  37. package/dist/cjs/plugins/status/styles.js +1 -1
  38. package/dist/cjs/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +18 -2
  39. package/dist/cjs/profiler/render-count.js +82 -0
  40. package/dist/cjs/ui/Appearance/Comment/Comment.js +6 -5
  41. package/dist/cjs/utils/react-hooks/use-component-renderer-tracking/index.js +55 -19
  42. package/dist/cjs/version-wrapper.js +1 -1
  43. package/dist/cjs/version.json +1 -1
  44. package/dist/es2019/actions/index.js +6 -28
  45. package/dist/es2019/create-editor/ErrorBoundary.js +73 -60
  46. package/dist/es2019/create-editor/ReactEditorView.js +130 -23
  47. package/dist/es2019/create-editor/create-plugins-list.js +4 -2
  48. package/dist/es2019/editor.js +74 -35
  49. package/dist/es2019/labs/next/presets/cxhtml.js +2 -1
  50. package/dist/es2019/plugins/analytics/types/enums.js +3 -1
  51. package/dist/es2019/plugins/base/index.js +4 -3
  52. package/dist/es2019/plugins/base/pm-plugins/frozen-editor.js +63 -35
  53. package/dist/es2019/plugins/block-type/ui/ToolbarBlockType/styled.js +2 -1
  54. package/dist/es2019/plugins/card/index.js +7 -2
  55. package/dist/es2019/plugins/card/nodeviews/embedCard.js +1 -0
  56. package/dist/es2019/plugins/card/pm-plugins/main.js +9 -2
  57. package/dist/es2019/plugins/card/pm-plugins/util/resolve.js +12 -5
  58. package/dist/es2019/plugins/code-block/toolbar.js +1 -1
  59. package/dist/es2019/plugins/emoji/styles.js +2 -0
  60. package/dist/es2019/plugins/extension/pm-plugins/main.js +1 -4
  61. package/dist/es2019/plugins/extension/toolbar.js +30 -25
  62. package/dist/es2019/plugins/feature-flags-context/feature-flags-from-props.js +8 -4
  63. package/dist/es2019/plugins/find-replace/ui/Find.js +27 -6
  64. package/dist/es2019/plugins/hyperlink/pm-plugins/keymap.js +1 -1
  65. package/dist/es2019/plugins/hyperlink/ui/HyperlinkAddToolbar/HyperlinkAddToolbar.js +7 -4
  66. package/dist/es2019/plugins/hyperlink/utils.js +3 -59
  67. package/dist/es2019/plugins/media/index.js +13 -4
  68. package/dist/es2019/plugins/media/nodeviews/mediaGroup.js +16 -7
  69. package/dist/es2019/plugins/media/nodeviews/mediaInline.js +88 -0
  70. package/dist/es2019/plugins/media/pm-plugins/main.js +20 -11
  71. package/dist/es2019/plugins/media/toolbar/index.js +44 -15
  72. package/dist/es2019/plugins/media/toolbar/utils.js +16 -0
  73. package/dist/es2019/plugins/media/utils/media-files.js +68 -2
  74. package/dist/es2019/plugins/panel/index.js +3 -4
  75. package/dist/es2019/plugins/panel/message.js +38 -0
  76. package/dist/es2019/plugins/panel/toolbar.js +52 -71
  77. package/dist/es2019/plugins/panel/utils.js +2 -2
  78. package/dist/es2019/plugins/paste/linkify-md-plugin.js +2 -2
  79. package/dist/es2019/plugins/status/styles.js +2 -0
  80. package/dist/es2019/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +18 -2
  81. package/dist/es2019/profiler/render-count.js +60 -0
  82. package/dist/es2019/ui/Appearance/Comment/Comment.js +4 -2
  83. package/dist/es2019/utils/react-hooks/use-component-renderer-tracking/index.js +51 -18
  84. package/dist/es2019/version-wrapper.js +1 -1
  85. package/dist/es2019/version.json +1 -1
  86. package/dist/esm/actions/index.js +6 -24
  87. package/dist/esm/create-editor/ErrorBoundary.js +113 -78
  88. package/dist/esm/create-editor/ReactEditorView.js +146 -31
  89. package/dist/esm/create-editor/create-plugins-list.js +4 -2
  90. package/dist/esm/editor.js +100 -40
  91. package/dist/esm/labs/next/presets/cxhtml.js +2 -1
  92. package/dist/esm/plugins/analytics/types/enums.js +3 -1
  93. package/dist/esm/plugins/base/index.js +4 -3
  94. package/dist/esm/plugins/base/pm-plugins/frozen-editor.js +64 -36
  95. package/dist/esm/plugins/block-type/ui/ToolbarBlockType/styled.js +3 -1
  96. package/dist/esm/plugins/card/index.js +13 -2
  97. package/dist/esm/plugins/card/nodeviews/embedCard.js +1 -0
  98. package/dist/esm/plugins/card/pm-plugins/main.js +7 -2
  99. package/dist/esm/plugins/card/pm-plugins/util/resolve.js +12 -5
  100. package/dist/esm/plugins/code-block/toolbar.js +1 -1
  101. package/dist/esm/plugins/emoji/styles.js +1 -1
  102. package/dist/esm/plugins/extension/pm-plugins/main.js +1 -4
  103. package/dist/esm/plugins/extension/toolbar.js +28 -23
  104. package/dist/esm/plugins/feature-flags-context/feature-flags-from-props.js +8 -4
  105. package/dist/esm/plugins/find-replace/ui/Find.js +27 -7
  106. package/dist/esm/plugins/hyperlink/pm-plugins/keymap.js +1 -1
  107. package/dist/esm/plugins/hyperlink/ui/HyperlinkAddToolbar/HyperlinkAddToolbar.js +7 -4
  108. package/dist/esm/plugins/hyperlink/utils.js +3 -59
  109. package/dist/esm/plugins/media/index.js +14 -4
  110. package/dist/esm/plugins/media/nodeviews/mediaGroup.js +24 -10
  111. package/dist/esm/plugins/media/nodeviews/mediaInline.js +147 -0
  112. package/dist/esm/plugins/media/pm-plugins/main.js +19 -11
  113. package/dist/esm/plugins/media/toolbar/index.js +47 -19
  114. package/dist/esm/plugins/media/toolbar/utils.js +15 -1
  115. package/dist/esm/plugins/media/utils/media-files.js +60 -2
  116. package/dist/esm/plugins/panel/index.js +3 -4
  117. package/dist/esm/plugins/panel/message.js +38 -0
  118. package/dist/esm/plugins/panel/toolbar.js +57 -77
  119. package/dist/esm/plugins/panel/utils.js +2 -2
  120. package/dist/esm/plugins/paste/linkify-md-plugin.js +2 -2
  121. package/dist/esm/plugins/status/styles.js +1 -1
  122. package/dist/esm/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +18 -2
  123. package/dist/esm/profiler/render-count.js +57 -0
  124. package/dist/esm/ui/Appearance/Comment/Comment.js +6 -5
  125. package/dist/esm/utils/react-hooks/use-component-renderer-tracking/index.js +53 -20
  126. package/dist/esm/version-wrapper.js +1 -1
  127. package/dist/esm/version.json +1 -1
  128. package/dist/types/create-editor/ErrorBoundary.d.ts +6 -6
  129. package/dist/types/create-editor/ReactEditorView.d.ts +15 -3
  130. package/dist/types/editor.d.ts +2 -0
  131. package/dist/types/plugins/analytics/index.d.ts +1 -1
  132. package/dist/types/plugins/analytics/types/enums.d.ts +4 -2
  133. package/dist/types/plugins/analytics/types/events.d.ts +7 -2
  134. package/dist/types/plugins/analytics/types/general-events.d.ts +4 -1
  135. package/dist/types/plugins/analytics/types/index.d.ts +1 -1
  136. package/dist/types/plugins/analytics/types/insert-events.d.ts +6 -1
  137. package/dist/types/plugins/analytics/types/link-tool-bar-events.d.ts +1 -0
  138. package/dist/types/plugins/base/index.d.ts +1 -0
  139. package/dist/types/plugins/base/pm-plugins/frozen-editor.d.ts +3 -2
  140. package/dist/types/plugins/card/pm-plugins/main.d.ts +2 -3
  141. package/dist/types/plugins/card/pm-plugins/util/resolve.d.ts +2 -1
  142. package/dist/types/plugins/card/types.d.ts +6 -0
  143. package/dist/types/plugins/extension/types.d.ts +0 -2
  144. package/dist/types/plugins/feature-flags-context/get-enabled-feature-flag-keys.d.ts +1 -1
  145. package/dist/types/plugins/floating-toolbar/types.d.ts +1 -1
  146. package/dist/types/plugins/floating-toolbar/ui/Select.d.ts +1 -1
  147. package/dist/types/plugins/hyperlink/utils.d.ts +0 -21
  148. package/dist/types/plugins/media/nodeviews/mediaInline.d.ts +27 -0
  149. package/dist/types/plugins/media/pm-plugins/main.d.ts +2 -2
  150. package/dist/types/plugins/media/toolbar/utils.d.ts +2 -0
  151. package/dist/types/plugins/media/utils/media-files.d.ts +8 -0
  152. package/dist/types/plugins/panel/message.d.ts +37 -0
  153. package/dist/types/plugins/panel/toolbar.d.ts +4 -37
  154. package/dist/types/plugins/panel/types.d.ts +1 -0
  155. package/dist/types/profiler/render-count.d.ts +14 -0
  156. package/dist/types/types/feature-flags.d.ts +8 -0
  157. package/dist/types/ui/LinkSearch/types.d.ts +1 -0
  158. package/dist/types/utils/react-hooks/use-component-renderer-tracking/index.d.ts +17 -1
  159. package/package.json +19 -16
  160. package/dist/cjs/plugins/caption/nodeviews/index.test.js +0 -135
  161. package/dist/cjs/plugins/caption/pm-plugins/keymap.test.js +0 -203
  162. package/dist/cjs/plugins/caption/pm-plugins/main.test.js +0 -141
  163. package/dist/cjs/plugins/code-block/language-list.test.js +0 -74
  164. package/dist/cjs/plugins/extension/ui/SaveIndicator/SaveIndicator.test.js +0 -101
  165. package/dist/cjs/plugins/floating-toolbar/ui/EmojiPickerButton.test.js +0 -98
  166. package/dist/cjs/plugins/media/commands/captions.test.js +0 -149
  167. package/dist/cjs/plugins/media/commands/linking.test.js +0 -296
  168. package/dist/cjs/plugins/media/ui/CaptionPlaceholder/index.test.js +0 -50
  169. package/dist/cjs/plugins/panel/toolbar.test.js +0 -250
  170. package/dist/cjs/ui/ColorPickerButton/index.test.js +0 -123
  171. package/dist/cjs/ui/PortalProvider/index.test.js +0 -139
  172. package/dist/es2019/plugins/caption/nodeviews/index.test.js +0 -122
  173. package/dist/es2019/plugins/caption/pm-plugins/keymap.test.js +0 -193
  174. package/dist/es2019/plugins/caption/pm-plugins/main.test.js +0 -132
  175. package/dist/es2019/plugins/code-block/language-list.test.js +0 -69
  176. package/dist/es2019/plugins/extension/ui/SaveIndicator/SaveIndicator.test.js +0 -83
  177. package/dist/es2019/plugins/floating-toolbar/ui/EmojiPickerButton.test.js +0 -85
  178. package/dist/es2019/plugins/media/commands/captions.test.js +0 -126
  179. package/dist/es2019/plugins/media/commands/linking.test.js +0 -208
  180. package/dist/es2019/plugins/media/ui/CaptionPlaceholder/index.test.js +0 -41
  181. package/dist/es2019/plugins/panel/toolbar.test.js +0 -200
  182. package/dist/es2019/ui/ColorPickerButton/index.test.js +0 -88
  183. package/dist/es2019/ui/PortalProvider/index.test.js +0 -115
  184. package/dist/esm/plugins/caption/nodeviews/index.test.js +0 -125
  185. package/dist/esm/plugins/caption/pm-plugins/keymap.test.js +0 -195
  186. package/dist/esm/plugins/caption/pm-plugins/main.test.js +0 -124
  187. package/dist/esm/plugins/code-block/language-list.test.js +0 -71
  188. package/dist/esm/plugins/extension/ui/SaveIndicator/SaveIndicator.test.js +0 -92
  189. package/dist/esm/plugins/floating-toolbar/ui/EmojiPickerButton.test.js +0 -85
  190. package/dist/esm/plugins/media/commands/captions.test.js +0 -135
  191. package/dist/esm/plugins/media/commands/linking.test.js +0 -268
  192. package/dist/esm/plugins/media/ui/CaptionPlaceholder/index.test.js +0 -41
  193. package/dist/esm/plugins/panel/toolbar.test.js +0 -230
  194. package/dist/esm/ui/ColorPickerButton/index.test.js +0 -107
  195. package/dist/esm/ui/PortalProvider/index.test.js +0 -129
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
- import { findParentNodeOfType, removeSelectedNode } from 'prosemirror-utils';
2
+ import { NodeSelection } from 'prosemirror-state';
3
+ import { findParentNodeOfType, removeSelectedNode, safeInsert } from 'prosemirror-utils';
3
4
  import RemoveIcon from '@atlaskit/icon/glyph/editor/remove';
4
5
  import DownloadIcon from '@atlaskit/icon/glyph/download';
5
6
  import { mediaFilmstripItemDOMSelector } from '@atlaskit/media-filmstrip';
@@ -18,7 +19,8 @@ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, addAnalytics, EVENT_TYPE } f
18
19
  import { messages } from '@atlaskit/media-ui';
19
20
  import { messages as cardMessages } from '../../card/messages';
20
21
  import { FilePreviewItem } from './filePreviewItem';
21
- import { downloadMedia } from './utils';
22
+ import { downloadMedia, removeMediaGroupNode } from './utils';
23
+ import { Fragment } from 'prosemirror-model';
22
24
 
23
25
  const remove = (state, dispatch) => {
24
26
  if (dispatch) {
@@ -28,13 +30,43 @@ const remove = (state, dispatch) => {
28
30
  return true;
29
31
  };
30
32
 
31
- const removeMediaCard = (state, mediaPluginState) => {
32
- const getPos = () => {
33
- const mediaOffset = state.selection.$from.parentOffset + 1;
34
- return mediaOffset;
35
- };
33
+ const handleRemoveMediaGroup = (state, dispatch) => {
34
+ const tr = removeMediaGroupNode(state);
35
+
36
+ if (dispatch) {
37
+ dispatch(tr);
38
+ }
39
+
40
+ return true;
41
+ };
42
+
43
+ const changeMediaCardToInline = (state, dispatch) => {
44
+ const {
45
+ media,
46
+ mediaInline,
47
+ paragraph
48
+ } = state.schema.nodes;
49
+ const selectedNode = state.selection instanceof NodeSelection && state.selection.node;
50
+
51
+ if (!selectedNode || !selectedNode.type === media) {
52
+ return false;
53
+ }
54
+
55
+ const mediaInlineNode = mediaInline.create({
56
+ id: selectedNode.attrs.id,
57
+ collection: selectedNode.attrs.collection
58
+ });
59
+ const space = state.schema.text(' ');
60
+ let content = Fragment.from([mediaInlineNode, space]);
61
+ const node = paragraph.createChecked({}, content);
62
+ const nodePos = state.tr.doc.resolve(state.selection.from).start() - 1;
63
+ let tr = removeMediaGroupNode(state);
64
+ tr = safeInsert(node, nodePos, true)(tr);
65
+
66
+ if (dispatch) {
67
+ dispatch(tr);
68
+ }
36
69
 
37
- mediaPluginState.handleMediaNodeRemoval(undefined, getPos);
38
70
  return true;
39
71
  };
40
72
 
@@ -48,9 +80,7 @@ const generateMediaCardFloatingToolbar = (state, intl, mediaPluginState) => {
48
80
  options: [{
49
81
  title: intl.formatMessage(cardMessages.inline),
50
82
  selected: false,
51
- onClick: () => {
52
- return true;
53
- },
83
+ onClick: changeMediaCardToInline,
54
84
  testId: 'inline-appearance'
55
85
  }, {
56
86
  title: intl.formatMessage(messages.displayThumbnail),
@@ -94,9 +124,7 @@ const generateMediaCardFloatingToolbar = (state, intl, mediaPluginState) => {
94
124
  onFocus: hoverDecoration(mediaGroup, true),
95
125
  onBlur: hoverDecoration(mediaGroup, false),
96
126
  title: intl.formatMessage(commonMessages.remove),
97
- onClick: state => {
98
- return removeMediaCard(state, mediaPluginState);
99
- },
127
+ onClick: handleRemoveMediaGroup,
100
128
  testId: 'media-toolbar-remove-button'
101
129
  }];
102
130
  return items;
@@ -210,6 +238,7 @@ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, m
210
238
  export const floatingToolbar = (state, intl, options = {}) => {
211
239
  const {
212
240
  media,
241
+ mediaInline,
213
242
  mediaSingle,
214
243
  mediaGroup
215
244
  } = state.schema.nodes;
@@ -227,7 +256,7 @@ export const floatingToolbar = (state, intl, options = {}) => {
227
256
  return;
228
257
  }
229
258
 
230
- const nodeType = allowMediaInline ? [mediaSingle, media] : [mediaSingle];
259
+ const nodeType = allowMediaInline ? [mediaInline, mediaSingle, media] : [mediaSingle];
231
260
  const baseToolbar = {
232
261
  title: 'Media floating controls',
233
262
  nodeType,
@@ -1,4 +1,5 @@
1
1
  import { getMediaClient } from '@atlaskit/media-client';
2
+ import { findParentNodeOfType, removeParentNodeOfType, removeSelectedNode } from 'prosemirror-utils';
2
3
  export const getSelectedMediaContainerNodeAttrs = mediaPluginState => {
3
4
  const selectedNode = mediaPluginState.selectedMediaContainerNode();
4
5
 
@@ -29,4 +30,19 @@ export const downloadMedia = async mediaPluginState => {
29
30
  } catch (err) {
30
31
  return false;
31
32
  }
33
+ };
34
+ export const removeMediaGroupNode = state => {
35
+ const {
36
+ mediaGroup
37
+ } = state.schema.nodes;
38
+ const mediaGroupParent = findParentNodeOfType(mediaGroup)(state.selection);
39
+ let tr = state.tr; // If it is the last media group in filmstrip, remove the entire filmstrip
40
+
41
+ if (mediaGroupParent && mediaGroupParent.node.childCount === 1) {
42
+ tr = removeParentNodeOfType(mediaGroup)(tr);
43
+ } else {
44
+ tr = removeSelectedNode(tr);
45
+ }
46
+
47
+ return tr;
32
48
  };
@@ -1,10 +1,14 @@
1
1
  import { Fragment } from 'prosemirror-model';
2
2
  import { setNodeSelection, setTextSelection, insideTableCell, isInListItem, findFarthestParentNode, isInLayoutColumn } from '../../../utils';
3
3
  import { posOfPrecedingMediaGroup, posOfMediaGroupNearby, posOfParentMediaGroup, isSelectionNonMediaBlockNode, isInsidePotentialEmptyParagraph, copyOptionalAttrsFromMediaState } from './media-common';
4
- import { safeInsert, hasParentNode } from 'prosemirror-utils';
4
+ import { canInsert, safeInsert, hasParentNode } from 'prosemirror-utils';
5
5
  import { atTheBeginningOfBlock, atTheEndOfBlock, atTheEndOfDoc, endPositionOfParent, startPositionOfParent } from '../../../utils/prosemirror/position';
6
6
  import { isSupportedInParent } from '../../../utils/nodes';
7
7
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, addAnalytics } from '../../analytics';
8
+ export const canInsertMediaInline = state => {
9
+ const node = state.schema.nodes.mediaInline.create({});
10
+ return canInsert(state.selection.$to, Fragment.from(node));
11
+ };
8
12
 
9
13
  const getInsertMediaGroupAnalytics = (mediaState, inputMethod) => {
10
14
  let media = '';
@@ -27,6 +31,21 @@ const getInsertMediaGroupAnalytics = (mediaState, inputMethod) => {
27
31
  eventType: EVENT_TYPE.TRACK
28
32
  };
29
33
  };
34
+
35
+ const getInsertMediaInlineAnalytics = (mediaState, inputMethod) => {
36
+ const media = mediaState.fileMimeType || 'unknown';
37
+ return {
38
+ action: ACTION.INSERTED,
39
+ actionSubject: ACTION_SUBJECT.DOCUMENT,
40
+ actionSubjectId: ACTION_SUBJECT_ID.MEDIA,
41
+ attributes: {
42
+ type: ACTION_SUBJECT_ID.MEDIA_INLINE,
43
+ inputMethod,
44
+ fileExtension: media
45
+ },
46
+ eventType: EVENT_TYPE.TRACK
47
+ };
48
+ };
30
49
  /**
31
50
  * Check if current editor selections is a media group or not.
32
51
  * @param state Editor state
@@ -59,6 +78,54 @@ function shouldAppendParagraph(state, node) {
59
78
  const wasMediaNode = node && node.type === media;
60
79
  return (insideTableCell(state) || isInListItem(state) || isInLayoutColumn(state) || atTheEndOfDoc(state) && (!posOfPrecedingMediaGroup(state) || isSelectionNonMediaBlockNode(state))) && !wasMediaNode;
61
80
  }
81
+ /**
82
+ * Create a new media inline to insert the new media.
83
+ * @param view Editor view
84
+ * @param mediaState Media file to be added to the editor
85
+ * @param collection Collection for the media to be added
86
+ */
87
+
88
+
89
+ export const insertMediaInlineNode = (view, mediaState, collection, inputMethod) => {
90
+ const {
91
+ state,
92
+ dispatch
93
+ } = view;
94
+ const {
95
+ schema,
96
+ tr
97
+ } = state;
98
+ const {
99
+ mediaInline
100
+ } = schema.nodes; // Do nothing if no media found
101
+
102
+ if (!mediaInline || !mediaState || collection === undefined) {
103
+ return false;
104
+ }
105
+
106
+ const {
107
+ id
108
+ } = mediaState;
109
+ const mediaInlineNode = mediaInline.create({
110
+ id,
111
+ collection
112
+ });
113
+ const space = state.schema.text(' ');
114
+ const pos = state.selection.$to.pos;
115
+ let content = Fragment.from([mediaInlineNode, space]); // Delete the selection if a selection is made
116
+
117
+ const deleteRange = findDeleteRange(state);
118
+
119
+ if (!deleteRange) {
120
+ tr.insert(pos, content);
121
+ } else {
122
+ tr.insert(pos, content).deleteRange(deleteRange.start, deleteRange.end);
123
+ }
124
+
125
+ addAnalytics(state, tr, getInsertMediaInlineAnalytics(mediaState, inputMethod));
126
+ dispatch(tr);
127
+ return true;
128
+ };
62
129
  /**
63
130
  * Insert a media into an existing media group
64
131
  * or create a new media group to insert the new media.
@@ -67,7 +134,6 @@ function shouldAppendParagraph(state, node) {
67
134
  * @param collection Collection for the media to be added
68
135
  */
69
136
 
70
-
71
137
  export const insertMediaGroupNode = (view, mediaStates, collection, inputMethod) => {
72
138
  const {
73
139
  state,
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { panel, customPanel, PanelType } from '@atlaskit/adf-schema';
2
+ import { customPanel, PanelType } from '@atlaskit/adf-schema';
3
3
  import { createPlugin } from './pm-plugins/main';
4
4
  import { getToolbarConfig } from './toolbar';
5
5
  import keymap from './pm-plugins/keymaps';
@@ -34,8 +34,7 @@ const panelPlugin = (options = {}) => ({
34
34
  name: 'panel',
35
35
 
36
36
  nodes() {
37
- //TODO: ED-10445 remove this check after emoji panels moved to full schema
38
- const panelNode = options.UNSAFE_allowCustomPanel ? customPanel : panel;
37
+ const panelNode = customPanel(!!options.UNSAFE_allowCustomPanel);
39
38
  return [{
40
39
  name: 'panel',
41
40
  node: panelNode
@@ -128,7 +127,7 @@ const panelPlugin = (options = {}) => ({
128
127
 
129
128
  }];
130
129
 
131
- if (options.UNSAFE_allowCustomPanel) {
130
+ if (options.UNSAFE_allowCustomPanelEdit && options.UNSAFE_allowCustomPanel) {
132
131
  quickInsertOptions.push({
133
132
  id: 'custompanel',
134
133
  title: formatMessage(messages.customPanel),
@@ -0,0 +1,38 @@
1
+ import { defineMessages } from 'react-intl';
2
+ export const messages = defineMessages({
3
+ info: {
4
+ id: 'fabric.editor.info',
5
+ defaultMessage: 'Info',
6
+ description: 'Panels provide a way to highlight text. The info panel has a blue background.'
7
+ },
8
+ note: {
9
+ id: 'fabric.editor.note',
10
+ defaultMessage: 'Note',
11
+ description: 'Panels provide a way to highlight text. The note panel has a purple background.'
12
+ },
13
+ success: {
14
+ id: 'fabric.editor.success',
15
+ defaultMessage: 'Success',
16
+ description: 'Panels provide a way to highlight text. The success panel has a green background.'
17
+ },
18
+ warning: {
19
+ id: 'fabric.editor.warning',
20
+ defaultMessage: 'Warning',
21
+ description: 'Panels provide a way to highlight text. The warning panel has a yellow background.'
22
+ },
23
+ error: {
24
+ id: 'fabric.editor.error',
25
+ defaultMessage: 'Error',
26
+ description: 'Panels provide a way to highlight text. The error panel has a red background.'
27
+ },
28
+ emoji: {
29
+ id: 'fabric.editor.panel.emoji',
30
+ defaultMessage: 'Add emoji',
31
+ description: 'Select the panel icon'
32
+ },
33
+ backgroundColor: {
34
+ id: 'fabric.editor.panel.backgroundColor',
35
+ defaultMessage: 'Background color',
36
+ description: 'Select the panel background color.'
37
+ }
38
+ });
@@ -1,4 +1,3 @@
1
- import { defineMessages } from 'react-intl';
2
1
  import SuccessIcon from '@atlaskit/icon/glyph/editor/success';
3
2
  import InfoIcon from '@atlaskit/icon/glyph/editor/info';
4
3
  import NoteIcon from '@atlaskit/icon/glyph/editor/note';
@@ -16,44 +15,16 @@ import { findDomRefAtPos } from 'prosemirror-utils';
16
15
  import { DEFAULT_BORDER_COLOR } from '../../ui/ColorPalette/Palettes';
17
16
  import { PanelType } from '@atlaskit/adf-schema';
18
17
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE, ACTION_SUBJECT_ID, withAnalytics } from '../analytics';
19
- export const messages = defineMessages({
20
- info: {
21
- id: 'fabric.editor.info',
22
- defaultMessage: 'Info',
23
- description: 'Panels provide a way to highlight text. The info panel has a blue background.'
24
- },
25
- note: {
26
- id: 'fabric.editor.note',
27
- defaultMessage: 'Note',
28
- description: 'Panels provide a way to highlight text. The note panel has a purple background.'
29
- },
30
- success: {
31
- id: 'fabric.editor.success',
32
- defaultMessage: 'Success',
33
- description: 'Panels provide a way to highlight text. The success panel has a green background.'
34
- },
35
- warning: {
36
- id: 'fabric.editor.warning',
37
- defaultMessage: 'Warning',
38
- description: 'Panels provide a way to highlight text. The warning panel has a yellow background.'
39
- },
40
- error: {
41
- id: 'fabric.editor.error',
42
- defaultMessage: 'Error',
43
- description: 'Panels provide a way to highlight text. The error panel has a red background.'
44
- },
45
- emoji: {
46
- id: 'fabric.editor.panel.emoji',
47
- defaultMessage: 'Add emoji',
48
- description: 'Select the panel icon'
49
- },
50
- backgroundColor: {
51
- id: 'fabric.editor.panel.backgroundColor',
52
- defaultMessage: 'Background color',
53
- description: 'Select the panel background color.'
54
- }
55
- });
56
- export const getToolbarItems = (formatMessage, panelNodeType, isCustomPanelEnabled, providerFactory, activePanelType, activePanelColor, activePanelIcon) => {
18
+ import { messages } from './message';
19
+ export const panelIconMap = {
20
+ [PanelType.INFO]: ':info:',
21
+ [PanelType.NOTE]: ':note:',
22
+ [PanelType.WARNING]: ':warning:',
23
+ [PanelType.ERROR]: ':error:',
24
+ [PanelType.SUCCESS]: ':success:',
25
+ [PanelType.TIP]: ':tip:'
26
+ };
27
+ export const getToolbarItems = (formatMessage, panelNodeType, isCustomPanelEnabled, isCustomPanelEditable, providerFactory, activePanelType, activePanelColor, activePanelIcon) => {
57
28
  const items = [{
58
29
  id: 'editor.panel.info',
59
30
  type: 'button',
@@ -100,10 +71,16 @@ export const getToolbarItems = (formatMessage, panelNodeType, isCustomPanelEnabl
100
71
  }
101
72
 
102
73
  let previousColor = panelNode.node.attrs.panelColor || getPanelTypeBackground(panelNode.node.attrs.panelType);
74
+ const emojiInfo = panelNode.node.attrs.panelType;
75
+ const panelInfo = panelIconMap[emojiInfo];
76
+ const previousEmoji = panelInfo ? {
77
+ emoji: panelInfo
78
+ } : {};
103
79
 
104
80
  if (previousColor === color) {
105
81
  changePanelType(PanelType.CUSTOM, {
106
- color
82
+ color,
83
+ ...previousEmoji
107
84
  }, isCustomPanelEnabled)(state, dispatch);
108
85
  return false;
109
86
  }
@@ -119,7 +96,8 @@ export const getToolbarItems = (formatMessage, panelNodeType, isCustomPanelEnabl
119
96
  eventType: EVENT_TYPE.TRACK
120
97
  };
121
98
  withAnalytics(payload)(changePanelType(PanelType.CUSTOM, {
122
- color
99
+ color,
100
+ ...previousEmoji
123
101
  }, isCustomPanelEnabled))(state, dispatch);
124
102
  return false;
125
103
  };
@@ -188,35 +166,38 @@ export const getToolbarItems = (formatMessage, panelNodeType, isCustomPanelEnabl
188
166
  value: panelColor,
189
167
  border: DEFAULT_BORDER_COLOR
190
168
  };
191
- const colorPicker = {
192
- id: 'editor.panel.colorPicker',
193
- title: formatMessage(messages.backgroundColor),
194
- type: 'select',
195
- selectType: 'color',
196
- defaultValue: defaultPalette,
197
- options: panelBackgroundPalette,
198
- onChange: option => changeColor(option.value)
199
- };
200
- const emojiPicker = {
201
- id: 'editor.panel.emojiPicker',
202
- title: formatMessage(messages.emoji),
203
- type: 'select',
204
- selectType: 'emoji',
205
- options: [],
206
- selected: activePanelType === PanelType.CUSTOM && !!activePanelIcon,
207
- onChange: emojiShortName => changeEmoji(emojiShortName)
208
- };
209
- const removeEmojiButton = {
210
- id: 'editor.panel.removeEmoji',
211
- type: 'button',
212
- icon: RemoveEmojiIcon,
213
- onClick: removeEmoji(),
214
- title: formatMessage(commonMessages.removeEmoji),
215
- disabled: activePanelIcon ? false : true
216
- };
217
- items.push(emojiPicker, removeEmojiButton, {
218
- type: 'separator'
219
- }, colorPicker);
169
+
170
+ if (isCustomPanelEditable) {
171
+ const colorPicker = {
172
+ id: 'editor.panel.colorPicker',
173
+ title: formatMessage(messages.backgroundColor),
174
+ type: 'select',
175
+ selectType: 'color',
176
+ defaultValue: defaultPalette,
177
+ options: panelBackgroundPalette,
178
+ onChange: option => changeColor(option.value)
179
+ };
180
+ const emojiPicker = {
181
+ id: 'editor.panel.emojiPicker',
182
+ title: formatMessage(messages.emoji),
183
+ type: 'select',
184
+ selectType: 'emoji',
185
+ options: [],
186
+ selected: activePanelType === PanelType.CUSTOM && !!activePanelIcon,
187
+ onChange: emojiShortName => changeEmoji(emojiShortName)
188
+ };
189
+ const removeEmojiButton = {
190
+ id: 'editor.panel.removeEmoji',
191
+ type: 'button',
192
+ icon: RemoveEmojiIcon,
193
+ onClick: removeEmoji(),
194
+ title: formatMessage(commonMessages.removeEmoji),
195
+ disabled: activePanelIcon ? false : true
196
+ };
197
+ items.push(emojiPicker, removeEmojiButton, {
198
+ type: 'separator'
199
+ }, colorPicker);
200
+ }
220
201
  }
221
202
 
222
203
  items.push({
@@ -249,7 +230,7 @@ export const getToolbarConfig = (state, intl, options = {}, providerFactory) =>
249
230
  panelIcon
250
231
  } = panelObject.node.attrs; // force toolbar to be turned on
251
232
 
252
- const items = getToolbarItems(formatMessage, nodeType, options.UNSAFE_allowCustomPanel || false, providerFactory, panelType, options.UNSAFE_allowCustomPanel ? panelColor : undefined, options.UNSAFE_allowCustomPanel ? panelIcon : undefined);
233
+ const items = getToolbarItems(formatMessage, nodeType, options.UNSAFE_allowCustomPanel || false, options.UNSAFE_allowCustomPanel && options.UNSAFE_allowCustomPanelEdit || false, providerFactory, panelType, options.UNSAFE_allowCustomPanel ? panelColor : undefined, options.UNSAFE_allowCustomPanel ? panelIcon : undefined);
253
234
 
254
235
  const getDomRef = editorView => {
255
236
  const domAtPos = editorView.domAtPos.bind(editorView);
@@ -21,7 +21,7 @@ export const panelAttrsToDom = (attrs, allowCustomPanel) => {
21
21
  'data-panel-type': panelType || PanelType.INFO,
22
22
  style
23
23
  };
24
- const iconSpan = ['span', {
24
+ const iconDiv = ['div', {
25
25
  class: PanelSharedCssClassName.icon
26
26
  }];
27
27
  const contentDiv = ['div', {
@@ -29,7 +29,7 @@ export const panelAttrsToDom = (attrs, allowCustomPanel) => {
29
29
  }, 0];
30
30
 
31
31
  if (hasIcon) {
32
- return ['div', panelAttrs, iconSpan, contentDiv];
32
+ return ['div', panelAttrs, iconDiv, contentDiv];
33
33
  } else {
34
34
  return ['div', panelAttrs, contentDiv];
35
35
  }
@@ -1,5 +1,5 @@
1
- import LinkifyIt from 'linkify-it';
2
- import { linkifyMatch } from '../hyperlink/utils'; // modified version of the original Linkify plugin
1
+ import { linkifyMatch } from '@atlaskit/adf-schema';
2
+ import LinkifyIt from 'linkify-it'; // modified version of the original Linkify plugin
3
3
  // https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/linkify.js
4
4
 
5
5
  const arrayReplaceAt = (src, pos, newElements) => {
@@ -3,6 +3,8 @@ import { StatusSharedCssClassName } from '@atlaskit/editor-common';
3
3
  import { SelectionStyle, getSelectionStyles, akEditorDeleteBackgroundWithOpacity, akEditorDeleteBorder, akEditorSelectedBorderSize, akEditorSelectedNodeClassName } from '@atlaskit/editor-shared-styles';
4
4
  export const statusStyles = css`
5
5
  .${StatusSharedCssClassName.STATUS_CONTAINER} {
6
+ display: inline-block;
7
+
6
8
  > span {
7
9
  display: inline-block;
8
10
  cursor: pointer;
@@ -462,10 +462,26 @@ export class TableRowNodeView {
462
462
  * so it should be safe to ignore mutations that we cause
463
463
  * by updating styles and classnames on this DOM element
464
464
  *
465
- * Update: should allow mutations for row selection to avoid known issue with table selection highlight in firefox
465
+ * Update: should not ignore mutations for row selection to avoid known issue with table selection highlight in firefox
466
466
  * Related bug report: https://bugzilla.mozilla.org/show_bug.cgi?id=1289673
467
467
  * */
468
- return !(mutationRecord.type === 'selection' && mutationRecord.target.tagName === 'TR');
468
+ const isTableSelection = mutationRecord.type === 'selection' && mutationRecord.target.nodeName === 'TR';
469
+ /**
470
+ * Update: should not ignore mutations when an node is added, as this interferes with
471
+ * prosemirrors handling of some language inputs in Safari (ie. Pinyin, Hiragana).
472
+ *
473
+ * In paticular, when a composition occurs at the start of the first node inside a table cell, if the resulting mutation
474
+ * from the composition end is ignored than prosemirror will end up with; invalid table markup nesting and a misplaced
475
+ * selection and insertion.
476
+ */
477
+
478
+ const isNodeInsertion = mutationRecord.type === 'childList' && mutationRecord.target.nodeName === 'TR' && mutationRecord.addedNodes.length;
479
+
480
+ if (isTableSelection || isNodeInsertion) {
481
+ return false;
482
+ }
483
+
484
+ return true;
469
485
  }
470
486
  /* receive external events */
471
487
 
@@ -0,0 +1,60 @@
1
+ import React, { useRef } from 'react';
2
+ import uuid from 'uuid';
3
+ import { useComponentRenderTracking } from '../utils/react-hooks/use-component-renderer-tracking';
4
+ import { RenderCountProfiler as RenderCountProfilerClass } from '@atlaskit/editor-common';
5
+ export let ProfiledComponentIds;
6
+
7
+ (function (ProfiledComponentIds) {
8
+ ProfiledComponentIds["editor"] = "Editor";
9
+ ProfiledComponentIds["appearance"] = "FullPageEditor";
10
+ ProfiledComponentIds["reactEditorView"] = "ReactEditorView";
11
+ ProfiledComponentIds["contentArea"] = "FullPageContentArea";
12
+ ProfiledComponentIds["toolbar"] = "FullPageToolbar";
13
+ ProfiledComponentIds["mention"] = "MentionNodeView";
14
+ })(ProfiledComponentIds || (ProfiledComponentIds = {}));
15
+
16
+ const CoreRenderCountProfiler = ({
17
+ componentId
18
+ }) => {
19
+ const {
20
+ current: instanceId
21
+ } = useRef(uuid());
22
+
23
+ const onRender = ({
24
+ renderCount
25
+ }) => {
26
+ const profiler = RenderCountProfilerClass.getInstance({
27
+ store: window
28
+ });
29
+ profiler.setRenderCount({
30
+ componentId,
31
+ instanceId,
32
+ renderCount
33
+ });
34
+ };
35
+
36
+ useComponentRenderTracking({
37
+ onRender,
38
+ propsDiffingOptions: {
39
+ enabled: false
40
+ },
41
+ zeroBasedCount: false
42
+ });
43
+ return null;
44
+ };
45
+
46
+ export const RenderCountProfiler = ({
47
+ componentId
48
+ }) => {
49
+ const profiler = RenderCountProfilerClass.getInstance({
50
+ store: window
51
+ });
52
+
53
+ if (profiler.isEnabled()) {
54
+ return /*#__PURE__*/React.createElement(CoreRenderCountProfiler, {
55
+ componentId: componentId
56
+ });
57
+ }
58
+
59
+ return null;
60
+ };
@@ -37,7 +37,7 @@ const CommentEditor = styled.div`
37
37
  /* calc(2px + 40px + 24px + ( 20px + (32px * 2))) */
38
38
  min-height: 150px;
39
39
  height: auto;
40
- ${props => props.maxHeight ? 'max-height: ' + props.maxHeight + 'px;' : ''} background-color: white;
40
+ background-color: white;
41
41
  border: 1px solid ${N40};
42
42
  box-sizing: border-box;
43
43
  border-radius: ${borderRadius()}px;
@@ -51,6 +51,7 @@ const ContentArea = styled(ContentStyles)`
51
51
  overflow-x: hidden;
52
52
  overflow-y: auto;
53
53
  line-height: 24px;
54
+ ${props => props.maxHeight ? 'max-height: ' + props.maxHeight + 'px;' : ''};
54
55
 
55
56
  /** Hack for Bitbucket to ensure entire editorView gets drop event; see ED-3294 **/
56
57
  /** Hack for tables controlls. Otherwise marging collapse and controlls are misplaced. **/
@@ -155,7 +156,8 @@ class Editor extends React.Component {
155
156
  innerRef: ref => this.containerElement = ref,
156
157
  className: classnames('ak-editor-content-area', {
157
158
  'less-margin': width < akEditorMobileBreakoutPoint
158
- })
159
+ }),
160
+ maxHeight: maxHeight
159
161
  }, customContentComponents, /*#__PURE__*/React.createElement(PluginSlot, {
160
162
  editorView: editorView,
161
163
  editorActions: editorActions,