@atlaskit/editor-core 182.0.2 → 182.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 (266) hide show
  1. package/.eslintrc.js +2 -0
  2. package/CHANGELOG.md +46 -0
  3. package/README.md +20 -0
  4. package/architecture/0001-record-architecture-decisions.md +25 -0
  5. package/architecture/0002-deep-equality-check-for-getsharedstate.md +67 -0
  6. package/architecture/0003-explicit-plugin-dependencies.md +291 -0
  7. package/dist/cjs/actions/index.js +17 -6
  8. package/dist/cjs/analytics-api/attach-payload-into-transaction.js +2 -1
  9. package/dist/cjs/create-editor/ErrorBoundary.js +1 -16
  10. package/dist/cjs/create-editor/ReactEditorViewInternal.js +3 -3
  11. package/dist/cjs/editor-next/editor-internal.js +2 -1
  12. package/dist/cjs/editor-next/index.js +5 -1
  13. package/dist/cjs/editor.js +9 -5
  14. package/dist/cjs/keymaps/index.js +12 -0
  15. package/dist/cjs/labs/next/internal/hooks/use-editor/index.js +5 -7
  16. package/dist/cjs/labs/next/presets/default.js +1 -2
  17. package/dist/cjs/plugins/card/index.js +16 -5
  18. package/dist/cjs/plugins/card/pm-plugins/actions.js +10 -1
  19. package/dist/cjs/plugins/card/pm-plugins/analytics/create-analytics-queue.js +48 -0
  20. package/dist/cjs/plugins/card/pm-plugins/analytics/events-from-tr.js +337 -0
  21. package/dist/cjs/plugins/card/pm-plugins/analytics/index.js +19 -0
  22. package/dist/cjs/plugins/card/pm-plugins/analytics/types.js +5 -0
  23. package/dist/cjs/plugins/card/pm-plugins/analytics/utils.js +139 -0
  24. package/dist/cjs/plugins/card/pm-plugins/doc.js +99 -22
  25. package/dist/cjs/plugins/card/pm-plugins/main.js +16 -10
  26. package/dist/cjs/plugins/card/pm-plugins/reducers.js +7 -0
  27. package/dist/cjs/plugins/card/pm-plugins/util/resolve.js +3 -7
  28. package/dist/cjs/plugins/card/toolbar.js +18 -8
  29. package/dist/cjs/plugins/card/ui/EditLinkToolbar.js +12 -8
  30. package/dist/cjs/plugins/card/ui/EditorSmartCardEventsNext.js +202 -0
  31. package/dist/cjs/plugins/card/ui/LinkToolbarAppearance.js +12 -4
  32. package/dist/cjs/plugins/card/utils.js +4 -2
  33. package/dist/cjs/plugins/extension/context-panel.js +3 -2
  34. package/dist/cjs/plugins/extension/index.js +4 -1
  35. package/dist/cjs/plugins/help-dialog/ui/index.js +29 -8
  36. package/dist/cjs/plugins/hyperlink/Toolbar.js +12 -2
  37. package/dist/cjs/plugins/hyperlink/commands.js +9 -5
  38. package/dist/cjs/plugins/hyperlink/pm-plugins/input-rule.js +4 -0
  39. package/dist/cjs/plugins/hyperlink/ui/HyperlinkAddToolbar/index.js +2 -2
  40. package/dist/cjs/plugins/index.js +0 -7
  41. package/dist/cjs/plugins/insert-block/index.js +5 -1
  42. package/dist/cjs/plugins/insert-block/ui/ToolbarInsertBlock/index.js +25 -23
  43. package/dist/cjs/plugins/media/index.js +9 -5
  44. package/dist/cjs/plugins/media/nodeviews/mediaNodeView/media.js +7 -1
  45. package/dist/cjs/plugins/media/pm-plugins/main.js +5 -4
  46. package/dist/cjs/plugins/media/utils/media-single.js +1 -4
  47. package/dist/cjs/plugins/panel/pm-plugins/keymaps.js +2 -1
  48. package/dist/cjs/plugins/paste/handlers.js +5 -5
  49. package/dist/cjs/plugins/paste/index.js +4 -2
  50. package/dist/cjs/plugins/paste/pm-plugins/main.js +6 -4
  51. package/dist/cjs/plugins/rule/commands.js +2 -2
  52. package/dist/cjs/plugins/rule/index.js +5 -4
  53. package/dist/cjs/plugins/rule/pm-plugins/input-rule.js +6 -8
  54. package/dist/cjs/plugins/rule/pm-plugins/keymap.js +2 -2
  55. package/dist/cjs/plugins/text-color/index.js +5 -2
  56. package/dist/cjs/plugins/text-color/ui/ToolbarTextColor/index.js +3 -4
  57. package/dist/cjs/plugins/text-formatting/ui/Toolbar/toolbar-messages.js +10 -0
  58. package/dist/cjs/ui/Appearance/FullPage/FullPage.js +2 -4
  59. package/dist/cjs/ui/ColorPalette/index.js +6 -0
  60. package/dist/cjs/ui/ConfigPanel/ConfigPanel.js +15 -10
  61. package/dist/cjs/ui/ConfigPanel/ConfigPanelFieldsLoader.js +3 -1
  62. package/dist/cjs/ui/ConfigPanel/Fields/ColorPicker.js +248 -17
  63. package/dist/cjs/ui/ConfigPanel/FormContent.js +12 -6
  64. package/dist/cjs/ui/ConfigPanel/utils.js +2 -12
  65. package/dist/cjs/ui/ContentStyles/index.js +2 -5
  66. package/dist/cjs/ui/MediaAndEmbedsToolbar/index.js +16 -8
  67. package/dist/cjs/utils/document.js +5 -3
  68. package/dist/cjs/version-wrapper.js +1 -1
  69. package/dist/cjs/version.json +1 -1
  70. package/dist/es2019/actions/index.js +10 -4
  71. package/dist/es2019/analytics-api/attach-payload-into-transaction.js +2 -1
  72. package/dist/es2019/create-editor/ErrorBoundary.js +1 -13
  73. package/dist/es2019/create-editor/ReactEditorViewInternal.js +2 -2
  74. package/dist/es2019/editor-next/editor-internal.js +2 -1
  75. package/dist/es2019/editor-next/index.js +5 -1
  76. package/dist/es2019/editor.js +5 -2
  77. package/dist/es2019/keymaps/index.js +1 -1
  78. package/dist/es2019/labs/next/internal/hooks/use-editor/index.js +4 -6
  79. package/dist/es2019/labs/next/presets/default.js +1 -2
  80. package/dist/es2019/plugins/card/index.js +15 -5
  81. package/dist/es2019/plugins/card/pm-plugins/actions.js +4 -0
  82. package/dist/es2019/plugins/card/pm-plugins/analytics/create-analytics-queue.js +38 -0
  83. package/dist/es2019/plugins/card/pm-plugins/analytics/events-from-tr.js +316 -0
  84. package/dist/es2019/plugins/card/pm-plugins/analytics/index.js +2 -0
  85. package/dist/es2019/plugins/card/pm-plugins/analytics/types.js +1 -0
  86. package/dist/es2019/plugins/card/pm-plugins/analytics/utils.js +124 -0
  87. package/dist/es2019/plugins/card/pm-plugins/doc.js +94 -20
  88. package/dist/es2019/plugins/card/pm-plugins/main.js +17 -8
  89. package/dist/es2019/plugins/card/pm-plugins/reducers.js +8 -0
  90. package/dist/es2019/plugins/card/pm-plugins/util/resolve.js +3 -7
  91. package/dist/es2019/plugins/card/toolbar.js +16 -8
  92. package/dist/es2019/plugins/card/ui/EditLinkToolbar.js +13 -9
  93. package/dist/es2019/plugins/card/ui/EditorSmartCardEventsNext.js +180 -0
  94. package/dist/es2019/plugins/card/ui/LinkToolbarAppearance.js +11 -2
  95. package/dist/es2019/plugins/card/utils.js +6 -2
  96. package/dist/es2019/plugins/extension/context-panel.js +3 -2
  97. package/dist/es2019/plugins/extension/index.js +45 -41
  98. package/dist/es2019/plugins/help-dialog/ui/index.js +17 -1
  99. package/dist/es2019/plugins/hyperlink/Toolbar.js +13 -4
  100. package/dist/es2019/plugins/hyperlink/commands.js +9 -6
  101. package/dist/es2019/plugins/hyperlink/pm-plugins/input-rule.js +4 -0
  102. package/dist/es2019/plugins/hyperlink/ui/HyperlinkAddToolbar/index.js +2 -2
  103. package/dist/es2019/plugins/index.js +0 -1
  104. package/dist/es2019/plugins/insert-block/index.js +96 -91
  105. package/dist/es2019/plugins/insert-block/ui/ToolbarInsertBlock/index.js +3 -2
  106. package/dist/es2019/plugins/media/index.js +202 -198
  107. package/dist/es2019/plugins/media/nodeviews/mediaNodeView/media.js +9 -1
  108. package/dist/es2019/plugins/media/pm-plugins/main.js +5 -4
  109. package/dist/es2019/plugins/media/utils/media-single.js +1 -5
  110. package/dist/es2019/plugins/panel/pm-plugins/keymaps.js +3 -2
  111. package/dist/es2019/plugins/paste/handlers.js +6 -6
  112. package/dist/es2019/plugins/paste/index.js +18 -14
  113. package/dist/es2019/plugins/paste/pm-plugins/main.js +7 -5
  114. package/dist/es2019/plugins/rule/commands.js +2 -2
  115. package/dist/es2019/plugins/rule/index.js +49 -46
  116. package/dist/es2019/plugins/rule/pm-plugins/input-rule.js +6 -7
  117. package/dist/es2019/plugins/rule/pm-plugins/keymap.js +2 -2
  118. package/dist/es2019/plugins/text-color/index.js +49 -44
  119. package/dist/es2019/plugins/text-color/ui/ToolbarTextColor/index.js +3 -3
  120. package/dist/es2019/plugins/text-formatting/ui/Toolbar/toolbar-messages.js +10 -0
  121. package/dist/es2019/ui/Appearance/FullPage/FullPage.js +2 -4
  122. package/dist/es2019/ui/ColorPalette/index.js +2 -2
  123. package/dist/es2019/ui/ConfigPanel/ConfigPanel.js +8 -4
  124. package/dist/es2019/ui/ConfigPanel/ConfigPanelFieldsLoader.js +3 -1
  125. package/dist/es2019/ui/ConfigPanel/Fields/ColorPicker.js +238 -13
  126. package/dist/es2019/ui/ConfigPanel/FormContent.js +12 -6
  127. package/dist/es2019/ui/ConfigPanel/utils.js +1 -11
  128. package/dist/es2019/ui/ContentStyles/index.js +2 -5
  129. package/dist/es2019/ui/MediaAndEmbedsToolbar/index.js +12 -10
  130. package/dist/es2019/utils/document.js +5 -3
  131. package/dist/es2019/version-wrapper.js +1 -1
  132. package/dist/es2019/version.json +1 -1
  133. package/dist/esm/actions/index.js +17 -6
  134. package/dist/esm/analytics-api/attach-payload-into-transaction.js +2 -1
  135. package/dist/esm/create-editor/ErrorBoundary.js +1 -16
  136. package/dist/esm/create-editor/ReactEditorViewInternal.js +2 -2
  137. package/dist/esm/editor-next/editor-internal.js +2 -1
  138. package/dist/esm/editor-next/index.js +5 -1
  139. package/dist/esm/editor.js +9 -5
  140. package/dist/esm/keymaps/index.js +1 -1
  141. package/dist/esm/labs/next/internal/hooks/use-editor/index.js +4 -6
  142. package/dist/esm/labs/next/presets/default.js +1 -2
  143. package/dist/esm/plugins/card/index.js +13 -5
  144. package/dist/esm/plugins/card/pm-plugins/actions.js +8 -0
  145. package/dist/esm/plugins/card/pm-plugins/analytics/create-analytics-queue.js +41 -0
  146. package/dist/esm/plugins/card/pm-plugins/analytics/events-from-tr.js +328 -0
  147. package/dist/esm/plugins/card/pm-plugins/analytics/index.js +2 -0
  148. package/dist/esm/plugins/card/pm-plugins/analytics/types.js +1 -0
  149. package/dist/esm/plugins/card/pm-plugins/analytics/utils.js +124 -0
  150. package/dist/esm/plugins/card/pm-plugins/doc.js +98 -22
  151. package/dist/esm/plugins/card/pm-plugins/main.js +16 -10
  152. package/dist/esm/plugins/card/pm-plugins/reducers.js +7 -0
  153. package/dist/esm/plugins/card/pm-plugins/util/resolve.js +3 -7
  154. package/dist/esm/plugins/card/toolbar.js +18 -8
  155. package/dist/esm/plugins/card/ui/EditLinkToolbar.js +13 -9
  156. package/dist/esm/plugins/card/ui/EditorSmartCardEventsNext.js +191 -0
  157. package/dist/esm/plugins/card/ui/LinkToolbarAppearance.js +12 -4
  158. package/dist/esm/plugins/card/utils.js +4 -2
  159. package/dist/esm/plugins/extension/context-panel.js +3 -2
  160. package/dist/esm/plugins/extension/index.js +4 -1
  161. package/dist/esm/plugins/help-dialog/ui/index.js +29 -8
  162. package/dist/esm/plugins/hyperlink/Toolbar.js +13 -3
  163. package/dist/esm/plugins/hyperlink/commands.js +9 -5
  164. package/dist/esm/plugins/hyperlink/pm-plugins/input-rule.js +4 -0
  165. package/dist/esm/plugins/hyperlink/ui/HyperlinkAddToolbar/index.js +2 -2
  166. package/dist/esm/plugins/index.js +0 -1
  167. package/dist/esm/plugins/insert-block/index.js +5 -1
  168. package/dist/esm/plugins/insert-block/ui/ToolbarInsertBlock/index.js +25 -23
  169. package/dist/esm/plugins/media/index.js +9 -5
  170. package/dist/esm/plugins/media/nodeviews/mediaNodeView/media.js +7 -1
  171. package/dist/esm/plugins/media/pm-plugins/main.js +5 -4
  172. package/dist/esm/plugins/media/utils/media-single.js +1 -4
  173. package/dist/esm/plugins/panel/pm-plugins/keymaps.js +3 -2
  174. package/dist/esm/plugins/paste/handlers.js +6 -6
  175. package/dist/esm/plugins/paste/index.js +4 -2
  176. package/dist/esm/plugins/paste/pm-plugins/main.js +7 -5
  177. package/dist/esm/plugins/rule/commands.js +2 -2
  178. package/dist/esm/plugins/rule/index.js +5 -4
  179. package/dist/esm/plugins/rule/pm-plugins/input-rule.js +6 -8
  180. package/dist/esm/plugins/rule/pm-plugins/keymap.js +2 -2
  181. package/dist/esm/plugins/text-color/index.js +5 -2
  182. package/dist/esm/plugins/text-color/ui/ToolbarTextColor/index.js +3 -4
  183. package/dist/esm/plugins/text-formatting/ui/Toolbar/toolbar-messages.js +10 -0
  184. package/dist/esm/ui/Appearance/FullPage/FullPage.js +2 -4
  185. package/dist/esm/ui/ColorPalette/index.js +2 -2
  186. package/dist/esm/ui/ConfigPanel/ConfigPanel.js +15 -10
  187. package/dist/esm/ui/ConfigPanel/ConfigPanelFieldsLoader.js +3 -1
  188. package/dist/esm/ui/ConfigPanel/Fields/ColorPicker.js +244 -19
  189. package/dist/esm/ui/ConfigPanel/FormContent.js +12 -6
  190. package/dist/esm/ui/ConfigPanel/utils.js +0 -10
  191. package/dist/esm/ui/ContentStyles/index.js +2 -5
  192. package/dist/esm/ui/MediaAndEmbedsToolbar/index.js +16 -8
  193. package/dist/esm/utils/document.js +5 -3
  194. package/dist/esm/version-wrapper.js +1 -1
  195. package/dist/esm/version.json +1 -1
  196. package/dist/types/actions/index.d.ts +3 -2
  197. package/dist/types/create-editor/ErrorBoundary.d.ts +2 -2
  198. package/dist/types/editor-next/index.d.ts +1 -0
  199. package/dist/types/editor.d.ts +1 -0
  200. package/dist/types/keymaps/index.d.ts +1 -1
  201. package/dist/types/labs/next/internal/hooks/use-editor/index.d.ts +2 -1
  202. package/dist/types/labs/next/presets/cxhtml.d.ts +1 -5
  203. package/dist/types/labs/next/presets/default.d.ts +2 -10
  204. package/dist/types/labs/next/presets/mobile.d.ts +1 -5
  205. package/dist/types/plugins/card/pm-plugins/actions.d.ts +2 -1
  206. package/dist/types/plugins/card/pm-plugins/analytics/create-analytics-queue.d.ts +10 -0
  207. package/dist/types/plugins/card/pm-plugins/analytics/events-from-tr.d.ts +17 -0
  208. package/dist/types/plugins/card/pm-plugins/analytics/index.d.ts +2 -0
  209. package/dist/types/plugins/card/pm-plugins/analytics/types.d.ts +10 -0
  210. package/dist/types/plugins/card/pm-plugins/analytics/utils.d.ts +26 -0
  211. package/dist/types/plugins/card/pm-plugins/doc.d.ts +8 -7
  212. package/dist/types/plugins/card/pm-plugins/main.d.ts +1 -1
  213. package/dist/types/plugins/card/pm-plugins/util/resolve.d.ts +2 -2
  214. package/dist/types/plugins/card/pm-plugins/util/state.d.ts +3 -0
  215. package/dist/types/plugins/card/types.d.ts +81 -7
  216. package/dist/types/plugins/card/ui/EditLinkToolbar.d.ts +2 -1
  217. package/dist/types/plugins/card/ui/EditorSmartCardEventsNext.d.ts +18 -0
  218. package/dist/types/plugins/card/utils.d.ts +1 -1
  219. package/dist/types/plugins/extension/context-panel.d.ts +2 -1
  220. package/dist/types/plugins/extension/index.d.ts +2 -0
  221. package/dist/types/plugins/hyperlink/commands.d.ts +3 -2
  222. package/dist/types/plugins/hyperlink/ui/HyperlinkAddToolbar/index.d.ts +2 -1
  223. package/dist/types/plugins/index.d.ts +0 -1
  224. package/dist/types/plugins/insert-block/index.d.ts +2 -0
  225. package/dist/types/plugins/insert-block/ui/ToolbarInsertBlock/types.d.ts +2 -1
  226. package/dist/types/plugins/media/index.d.ts +2 -0
  227. package/dist/types/plugins/media/pm-plugins/main.d.ts +3 -2
  228. package/dist/types/plugins/media/utils/media-single.d.ts +1 -1
  229. package/dist/types/plugins/paste/index.d.ts +2 -0
  230. package/dist/types/plugins/paste/pm-plugins/main.d.ts +2 -1
  231. package/dist/types/plugins/rule/commands.d.ts +2 -1
  232. package/dist/types/plugins/rule/index.d.ts +5 -1
  233. package/dist/types/plugins/rule/pm-plugins/input-rule.d.ts +1 -1
  234. package/dist/types/plugins/rule/pm-plugins/keymap.d.ts +2 -1
  235. package/dist/types/plugins/text-color/index.d.ts +2 -0
  236. package/dist/types/plugins/text-color/ui/ToolbarTextColor/index.d.ts +2 -0
  237. package/dist/types/plugins/text-formatting/ui/Toolbar/toolbar-messages.d.ts +10 -0
  238. package/dist/types/types/editor-appearance-component.d.ts +1 -1
  239. package/dist/types/types/editor-props.d.ts +1 -0
  240. package/dist/types/ui/Appearance/FullPage/FullPage.d.ts +2 -0
  241. package/dist/types/ui/ColorPalette/index.d.ts +2 -2
  242. package/dist/types/ui/ConfigPanel/ConfigPanel.d.ts +3 -1
  243. package/dist/types/ui/ConfigPanel/ConfigPanelFieldsLoader.d.ts +3 -1
  244. package/dist/types/ui/ConfigPanel/Fields/ColorPicker.d.ts +12 -1
  245. package/dist/types/ui/ConfigPanel/FormContent.d.ts +2 -2
  246. package/dist/types/ui/ConfigPanel/types.d.ts +3 -0
  247. package/dist/types/ui/ConfigPanel/utils.d.ts +0 -1
  248. package/dist/types/ui/MediaAndEmbedsToolbar/index.d.ts +1 -1
  249. package/package.json +14 -13
  250. package/report.api.md +10 -0
  251. package/dist/cjs/plugins/feature-flags-context/get-enabled-feature-flag-keys.js +0 -12
  252. package/dist/cjs/plugins/feature-flags-context/get-feature-flags.js +0 -11
  253. package/dist/cjs/plugins/feature-flags-context/index.js +0 -50
  254. package/dist/cjs/plugins/feature-flags-context/plugin-key.js +0 -9
  255. package/dist/es2019/plugins/feature-flags-context/get-enabled-feature-flag-keys.js +0 -1
  256. package/dist/es2019/plugins/feature-flags-context/get-feature-flags.js +0 -2
  257. package/dist/es2019/plugins/feature-flags-context/index.js +0 -29
  258. package/dist/es2019/plugins/feature-flags-context/plugin-key.js +0 -2
  259. package/dist/esm/plugins/feature-flags-context/get-enabled-feature-flag-keys.js +0 -1
  260. package/dist/esm/plugins/feature-flags-context/get-feature-flags.js +0 -4
  261. package/dist/esm/plugins/feature-flags-context/index.js +0 -40
  262. package/dist/esm/plugins/feature-flags-context/plugin-key.js +0 -2
  263. package/dist/types/plugins/feature-flags-context/get-enabled-feature-flag-keys.d.ts +0 -1
  264. package/dist/types/plugins/feature-flags-context/get-feature-flags.d.ts +0 -3
  265. package/dist/types/plugins/feature-flags-context/index.d.ts +0 -9
  266. package/dist/types/plugins/feature-flags-context/plugin-key.d.ts +0 -2
@@ -1,13 +1,14 @@
1
1
  import { NodeSelection, TextSelection } from 'prosemirror-state';
2
2
  import { closeHistory } from 'prosemirror-history';
3
3
  import { isSafeUrl } from '@atlaskit/adf-schema';
4
+ import { addLinkMetadata } from '@atlaskit/editor-common/card';
4
5
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, addAnalytics, EVENT_TYPE, INPUT_METHOD } from '../../../plugins/analytics';
5
6
  import { SMART_LINK_TYPE } from '../../../plugins/analytics/types/node-events';
6
7
  import { getLinkCreationAnalyticsEvent } from '../../../plugins/hyperlink/analytics';
7
8
  import { nodesBetweenChanged, processRawValue } from '../../../utils';
8
9
  import { unlinkPayload } from '../../../utils/linking-utils';
9
10
  import { isFromCurrentDomain } from '../../hyperlink/utils';
10
- import { appearanceForNodeType } from '../utils';
11
+ import { appearanceForNodeType, selectedCardAppearance } from '../utils';
11
12
  import { queueCards, resolveCard } from './actions';
12
13
  import { pluginKey } from './plugin-key';
13
14
  import { shouldReplaceLink } from './shouldReplaceLink';
@@ -46,7 +47,7 @@ function replaceLinksToCards(tr, cardAdf, schema, request) {
46
47
  tr.replaceWith(pos, pos + (node.text || url).length, nodes);
47
48
  return $pos.node($pos.depth - 1).type.name;
48
49
  }
49
- export const replaceQueuedUrlWithCard = (url, cardData, analyticsAction, createAnalyticsEvent) => (editorState, dispatch) => {
50
+ export const replaceQueuedUrlWithCard = (url, cardData, analyticsAction) => (editorState, dispatch) => {
50
51
  const state = pluginKey.getState(editorState);
51
52
  if (!state) {
52
53
  return false;
@@ -73,15 +74,22 @@ export const replaceQueuedUrlWithCard = (url, cardData, analyticsAction, createA
73
74
  if (state.smartLinkEvents) {
74
75
  state.smartLinkEvents.insertSmartLink(domainName, 'inline', state.createAnalyticsEvent);
75
76
  }
77
+
78
+ /**
79
+ * TODO:
80
+ * What if each request has a different source?
81
+ * Unlikely, but need to define behaviour.
82
+ * Ignore analytics event? take first? provide 'mixed' as well?
83
+ */
84
+ const inputMethod = requests[0].source;
85
+ const sourceEvent = requests[0].sourceEvent;
76
86
  addAnalytics(editorState, tr, {
77
87
  action: analyticsAction || ACTION.INSERTED,
78
88
  actionSubject: ACTION_SUBJECT.DOCUMENT,
79
89
  actionSubjectId: ACTION_SUBJECT_ID.SMART_LINK,
80
90
  eventType: EVENT_TYPE.TRACK,
81
91
  attributes: {
82
- inputMethod: requests[0].source /* TODO: what if each request has a different source?
83
- unlikely, but need to define behaviour.
84
- ignore analytics event? take first? provide 'mixed' as well?*/,
92
+ inputMethod,
85
93
  nodeType,
86
94
  nodeContext: nodeContext,
87
95
  fromCurrentDomain: isFromCurrentDomain(url)
@@ -90,6 +98,12 @@ export const replaceQueuedUrlWithCard = (url, cardData, analyticsAction, createA
90
98
  domainName
91
99
  }
92
100
  });
101
+ addLinkMetadata(editorState.selection, tr, {
102
+ action: analyticsAction,
103
+ inputMethod,
104
+ cardAction: 'RESOLVE',
105
+ sourceEvent
106
+ });
93
107
  }
94
108
  }
95
109
  if (dispatch) {
@@ -97,19 +111,25 @@ export const replaceQueuedUrlWithCard = (url, cardData, analyticsAction, createA
97
111
  }
98
112
  return true;
99
113
  };
100
- export const handleFallbackWithAnalytics = (url, source) => (editorState, dispatch) => {
101
- const state = pluginKey.getState(editorState);
102
- if (!state) {
114
+ export const handleFallbackWithAnalytics = request => (state, dispatch) => {
115
+ const cardState = pluginKey.getState(state);
116
+ if (!cardState) {
103
117
  return false;
104
118
  }
105
- const tr = editorState.tr;
106
- addAnalytics(editorState, tr, getLinkCreationAnalyticsEvent(source, url));
119
+ const tr = state.tr;
120
+ if (request.source !== INPUT_METHOD.FLOATING_TB) {
121
+ addAnalytics(state, tr, getLinkCreationAnalyticsEvent(request.source, request.url));
122
+ }
123
+ addLinkMetadata(state.selection, tr, {
124
+ action: request.analyticsAction,
125
+ inputMethod: request.source
126
+ });
107
127
  if (dispatch) {
108
- dispatch(resolveCard(url)(tr));
128
+ dispatch(resolveCard(request.url)(tr));
109
129
  }
110
130
  return true;
111
131
  };
112
- export const queueCardsFromChangedTr = (state, tr, source, normalizeLinkText = true) => {
132
+ export const queueCardsFromChangedTr = (state, tr, source, analyticsAction, normalizeLinkText = true, sourceEvent = undefined) => {
113
133
  const {
114
134
  schema
115
135
  } = state;
@@ -131,11 +151,51 @@ export const queueCardsFromChangedTr = (state, tr, source, normalizeLinkText = t
131
151
  pos,
132
152
  appearance: 'inline',
133
153
  compareLinkText: normalizeLinkText,
134
- source
154
+ source,
155
+ analyticsAction,
156
+ sourceEvent
157
+ });
158
+ }
159
+ return false;
160
+ });
161
+ addLinkMetadata(state.selection, tr, {
162
+ action: analyticsAction
163
+ });
164
+ return queueCards(requests)(tr);
165
+ };
166
+ export const queueCardFromChangedTr = (state, tr, source, analyticsAction, normalizeLinkText = true, sourceEvent = undefined, previousAppearance) => {
167
+ const {
168
+ schema
169
+ } = state;
170
+ const {
171
+ link
172
+ } = schema.marks;
173
+ let requests = [];
174
+ nodesBetweenChanged(tr, (node, pos) => {
175
+ if (!node.isText) {
176
+ return true;
177
+ }
178
+ const linkMark = node.marks.find(mark => mark.type === link);
179
+ if (linkMark) {
180
+ if (!shouldReplaceLink(node, normalizeLinkText)) {
181
+ return false;
182
+ }
183
+ requests.push({
184
+ url: linkMark.attrs.href,
185
+ pos,
186
+ appearance: 'inline',
187
+ previousAppearance: previousAppearance,
188
+ compareLinkText: normalizeLinkText,
189
+ source,
190
+ analyticsAction,
191
+ sourceEvent
135
192
  });
136
193
  }
137
194
  return false;
138
195
  });
196
+ addLinkMetadata(state.selection, tr, {
197
+ action: analyticsAction
198
+ });
139
199
  return queueCards(requests)(tr);
140
200
  };
141
201
  export const convertHyperlinkToSmartCard = (state, source, appearance, normalizeLinkText = true) => {
@@ -149,18 +209,21 @@ export const convertHyperlinkToSmartCard = (state, source, appearance, normalize
149
209
  state.tr.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos) => {
150
210
  const linkMark = node.marks.find(mark => mark.type === link);
151
211
  if (linkMark) {
152
- const request = {
212
+ requests.push({
153
213
  url: linkMark.attrs.href,
154
214
  pos,
155
215
  appearance,
216
+ previousAppearance: 'url',
156
217
  compareLinkText: normalizeLinkText,
157
218
  source,
158
219
  analyticsAction: ACTION.CHANGED_TYPE,
159
220
  shouldReplaceLink: true
160
- };
161
- requests.push(request);
221
+ });
162
222
  }
163
223
  });
224
+ addLinkMetadata(state.selection, state.tr, {
225
+ action: ACTION.CHANGED_TYPE
226
+ });
164
227
  return queueCards(requests)(state.tr);
165
228
  };
166
229
  export const changeSelectedCardToLink = (text, href, sendAnalytics, node, pos) => (state, dispatch) => {
@@ -211,13 +274,14 @@ export const changeSelectedCardToLinkFallback = (text, href, sendAnalytics, node
211
274
  }
212
275
  return true;
213
276
  };
214
- export const updateCard = href => (state, dispatch) => {
277
+ export const updateCard = (href, sourceEvent) => (state, dispatch) => {
215
278
  const selectedNode = state.selection instanceof NodeSelection && state.selection.node;
216
279
  if (!selectedNode) {
217
280
  return false;
218
281
  }
282
+ const cardAppearance = selectedCardAppearance(state);
219
283
  const tr = cardToLinkWithTransaction(state, href, href);
220
- queueCardsFromChangedTr(state, tr, INPUT_METHOD.MANUAL);
284
+ queueCardFromChangedTr(state, tr, INPUT_METHOD.MANUAL, ACTION.UPDATED, undefined, sourceEvent, cardAppearance);
221
285
  if (dispatch) {
222
286
  dispatch(tr.scrollIntoView());
223
287
  }
@@ -253,7 +317,11 @@ export const changeSelectedCardToText = text => (state, dispatch) => {
253
317
  }
254
318
  const tr = state.tr.replaceSelectionWith(state.schema.text(text), false);
255
319
  if (dispatch) {
256
- dispatch(addAnalytics(state, tr.scrollIntoView(), unlinkPayload(ACTION_SUBJECT_ID.CARD_INLINE)));
320
+ addLinkMetadata(state.selection, tr, {
321
+ action: ACTION.UNLINK
322
+ });
323
+ addAnalytics(state, tr.scrollIntoView(), unlinkPayload(ACTION_SUBJECT_ID.CARD_INLINE));
324
+ dispatch(tr);
257
325
  }
258
326
  return true;
259
327
  };
@@ -263,8 +331,11 @@ export const setSelectedCardAppearance = appearance => (state, dispatch) => {
263
331
  if (!selectedNode) {
264
332
  // When there is no selected node, we insert a new one
265
333
  // and replace the existing blue link
266
- const tr = convertHyperlinkToSmartCard(state, INPUT_METHOD.MANUAL, appearance);
334
+ const tr = convertHyperlinkToSmartCard(state, INPUT_METHOD.FLOATING_TB, appearance);
267
335
  if (dispatch) {
336
+ addLinkMetadata(state.selection, tr, {
337
+ action: ACTION.CHANGED_TYPE
338
+ });
268
339
  dispatch(tr.scrollIntoView());
269
340
  }
270
341
  return false;
@@ -303,6 +374,9 @@ export const setSelectedCardAppearance = appearance => (state, dispatch) => {
303
374
  previousType: appearanceForNodeType(selectedNode.type)
304
375
  }
305
376
  });
377
+ addLinkMetadata(state.selection, tr, {
378
+ action: ACTION.CHANGED_TYPE
379
+ });
306
380
  if (dispatch) {
307
381
  dispatch(tr.scrollIntoView());
308
382
  }
@@ -8,8 +8,13 @@ import { pluginKey } from './plugin-key';
8
8
  import reducer from './reducers';
9
9
  import { handleProvider, resolveWithProvider } from './util/resolve';
10
10
  import { getNewRequests, getPluginState, getPluginStateWithUpdatedPos } from './util/state';
11
+ import { createAnalyticsQueue, eventsFromTransaction } from './analytics';
11
12
  export { pluginKey } from './plugin-key';
12
13
  export const createPlugin = options => pmPluginFactoryParams => {
14
+ const {
15
+ lpAnalyticsEventsNext
16
+ } = pmPluginFactoryParams.featureFlags;
17
+ const analyticsQueue = createAnalyticsQueue(!!lpAnalyticsEventsNext);
13
18
  const {
14
19
  editorAppearance,
15
20
  platform,
@@ -28,25 +33,31 @@ export const createPlugin = options => pmPluginFactoryParams => {
28
33
  cards: [],
29
34
  showLinkingToolbar: false,
30
35
  smartLinkEvents: undefined,
36
+ smartLinkEventsNext: undefined,
31
37
  createAnalyticsEvent,
32
38
  editorAppearance
33
39
  };
34
40
  },
35
- apply(tr, pluginState) {
41
+ apply(tr, pluginState, prevEditorState) {
36
42
  // Update all the positions of outstanding requests and
37
43
  // cards in the plugin state.
38
44
  const pluginStateWithUpdatedPos = getPluginStateWithUpdatedPos(pluginState, tr);
45
+
39
46
  // apply any actions
40
47
  const meta = tr.getMeta(pluginKey);
48
+ const events = eventsFromTransaction(tr, prevEditorState);
49
+ analyticsQueue.push(...events);
41
50
  if (meta) {
42
- const nextPluginState = reducer(pluginStateWithUpdatedPos, meta);
43
- return nextPluginState;
51
+ const nextState = reducer(pluginStateWithUpdatedPos, meta);
52
+ if (!pluginState.smartLinkEventsNext && nextState.smartLinkEventsNext) {
53
+ analyticsQueue.setCallbacks(nextState.smartLinkEventsNext);
54
+ }
55
+ return nextState;
44
56
  }
45
57
  return pluginStateWithUpdatedPos;
46
58
  }
47
59
  },
48
60
  view(view) {
49
- const outstandingRequests = {};
50
61
  const subscriptionHandler = (name, provider) => handleProvider(name, provider, view);
51
62
  const rafCancellationCallbacks = [];
52
63
  pmPluginFactoryParams.providerFactory.subscribe('cardProvider', subscriptionHandler);
@@ -71,16 +82,14 @@ export const createPlugin = options => pmPluginFactoryParams => {
71
82
  * By using this approach, the browser is free to schedule the resolution of the promises below in between rendering/network/
72
83
  * other tasks as per common implementations of the JavaScript event loop in browsers.
73
84
  */
74
- const invoke = rafSchedule(() => resolveWithProvider(view, outstandingRequests, provider, request, options));
85
+ const invoke = rafSchedule(() => resolveWithProvider(view, provider, request, options));
75
86
  rafCancellationCallbacks.push(invoke.cancel);
76
87
  invoke();
77
88
  });
78
89
  }
90
+ analyticsQueue.flush();
79
91
  },
80
92
  destroy() {
81
- // Cancel all outstanding requests
82
- Object.keys(outstandingRequests).forEach(url => Promise.reject(outstandingRequests[url]));
83
-
84
93
  // Cancel any outstanding raf callbacks.
85
94
  rafCancellationCallbacks.forEach(cancellationCallback => cancellationCallback());
86
95
  pmPluginFactoryParams.providerFactory.unsubscribe('cardProvider', subscriptionHandler);
@@ -34,6 +34,12 @@ const registerEvents = (state, action) => {
34
34
  smartLinkEvents: action.smartLinkEvents
35
35
  };
36
36
  };
37
+ const registerEventsNext = (state, action) => {
38
+ return {
39
+ ...state,
40
+ smartLinkEventsNext: action.smartLinkEvents
41
+ };
42
+ };
37
43
  const setLinkToolbar = (state, action) => {
38
44
  return {
39
45
  ...state,
@@ -52,6 +58,8 @@ export default ((state, action) => {
52
58
  return register(state, action);
53
59
  case 'REGISTER_EVENTS':
54
60
  return registerEvents(state, action);
61
+ case 'REGISTER_EVENTS_NEXT':
62
+ return registerEventsNext(state, action);
55
63
  case 'SHOW_LINK_TOOLBAR':
56
64
  case 'HIDE_LINK_TOOLBAR':
57
65
  return setLinkToolbar(state, action);
@@ -5,18 +5,14 @@ import { replaceQueuedUrlWithCard, handleFallbackWithAnalytics } from '../doc';
5
5
  // ============================================================================ //
6
6
  // Used for all interactions with the EditorCardProvider.
7
7
  // ============================================================================ //
8
- export const resolveWithProvider = (view, outstandingRequests, provider, request, options) => {
8
+ export const resolveWithProvider = (view, provider, request, options) => {
9
9
  // When user manually changes appearance from blue link to smart link, we should respect that,
10
10
  let shouldForceAppearance =
11
11
  // This flag is set to true only in one place atm:
12
12
  // packages/editor/editor-core/src/plugins/card/pm-plugins/doc.ts @ convertHyperlinkToSmartCard
13
13
  // Which is used when user switching from URL to smart link appearance.
14
14
  !!request.shouldReplaceLink;
15
- const handleResolve = provider.resolve(request.url, request.appearance, shouldForceAppearance).then(resolvedCard => {
16
- delete outstandingRequests[request.url];
17
- return resolvedCard;
18
- }).then(handleResolved(view, request, options), handleRejected(view, request));
19
- outstandingRequests[request.url] = handleResolve;
15
+ const handleResolve = provider.resolve(request.url, request.appearance, shouldForceAppearance).then(handleResolved(view, request, options), handleRejected(view, request));
20
16
  return handleResolve;
21
17
  };
22
18
  const updateCardType = (resolvedCard, options) => {
@@ -34,7 +30,7 @@ const handleResolved = (view, request, options) => resolvedCard => {
34
30
  return resolvedCard;
35
31
  };
36
32
  const handleRejected = (view, request) => () => {
37
- handleFallbackWithAnalytics(request.url, request.source)(view.state, view.dispatch);
33
+ handleFallbackWithAnalytics(request)(view.state, view.dispatch);
38
34
  };
39
35
 
40
36
  // listen for card provider changes
@@ -10,6 +10,7 @@ import { linkToolbarMessages, linkMessages } from '../../messages';
10
10
  import commonMessages from '../../messages';
11
11
  import { hoverDecoration } from '../base/pm-plugins/decoration';
12
12
  import { changeSelectedCardToText } from './pm-plugins/doc';
13
+ import { commandWithMetadata } from '@atlaskit/editor-common/card';
13
14
  import { pluginKey } from './pm-plugins/main';
14
15
  import { richMediaClassName } from '@atlaskit/editor-common/styles';
15
16
  import { buildEditLinkToolbar, editLink, editLinkToolbarConfig } from './ui/EditLinkToolbar';
@@ -20,7 +21,7 @@ import { messages } from './messages';
20
21
  import buildLayoutButtons from '../../ui/MediaAndEmbedsToolbar';
21
22
  import { buildOpenedSettingsPayload, buildVisitedLinkPayload } from '../../utils/linking-utils';
22
23
  import { FLOATING_TOOLBAR_LINKPICKER_CLASSNAME } from './styles';
23
- export const removeCard = (state, dispatch) => {
24
+ export const removeCard = commandWithMetadata((state, dispatch) => {
24
25
  if (!(state.selection instanceof NodeSelection)) {
25
26
  return false;
26
27
  }
@@ -39,7 +40,9 @@ export const removeCard = (state, dispatch) => {
39
40
  dispatch(addAnalytics(state, removeSelectedNode(state.tr), payload));
40
41
  }
41
42
  return true;
42
- };
43
+ }, {
44
+ action: ACTION.DELETED
45
+ });
43
46
  export const visitCardLink = (state, dispatch) => {
44
47
  if (!(state.selection instanceof NodeSelection)) {
45
48
  return false;
@@ -135,13 +138,18 @@ const unlinkCard = (node, state) => {
135
138
  const displayInfo = displayInfoForCard(node, findCardInfo(state));
136
139
  const text = displayInfo.title || displayInfo.url;
137
140
  if (text) {
138
- return changeSelectedCardToText(text);
141
+ return commandWithMetadata(changeSelectedCardToText(text), {
142
+ action: ACTION.UNLINK
143
+ });
139
144
  }
140
145
  return () => false;
141
146
  };
142
- const buildAlignmentOptions = (state, intl) => {
143
- return buildLayoutButtons(state, intl, state.schema.nodes.embedCard, true, true);
147
+ const buildAlignmentOptions = (state, intl, cardOptions) => {
148
+ return buildLayoutButtons(state, intl, state.schema.nodes.embedCard, true, true, cardOptions === null || cardOptions === void 0 ? void 0 : cardOptions.allowWrapping, cardOptions === null || cardOptions === void 0 ? void 0 : cardOptions.allowAlignment);
144
149
  };
150
+ const withToolbarMetadata = command => commandWithMetadata(command, {
151
+ inputMethod: INPUT_METHOD.FLOATING_TB
152
+ });
145
153
  const generateToolbarItems = (state, featureFlags, intl, providerFactory, cardOptions, platform, linkPicker) => node => {
146
154
  const {
147
155
  url
@@ -214,10 +222,10 @@ const generateToolbarItems = (state, featureFlags, intl, providerFactory, cardOp
214
222
  onFocus: hoverDecoration(node.type, true),
215
223
  onBlur: hoverDecoration(node.type, false),
216
224
  title: intl.formatMessage(commonMessages.remove),
217
- onClick: removeCard
225
+ onClick: withToolbarMetadata(removeCard)
218
226
  }];
219
227
  if (currentAppearance === 'embed') {
220
- const alignmentOptions = buildAlignmentOptions(state, intl);
228
+ const alignmentOptions = buildAlignmentOptions(state, intl, cardOptions);
221
229
  if (alignmentOptions.length) {
222
230
  alignmentOptions.push({
223
231
  type: 'separator'
@@ -261,7 +269,7 @@ const getUnlinkButtonGroup = (state, intl, node, inlineCard) => {
261
269
  type: 'button',
262
270
  title: intl.formatMessage(linkToolbarMessages.unlink),
263
271
  icon: UnlinkIcon,
264
- onClick: unlinkCard(node, state)
272
+ onClick: withToolbarMetadata(unlinkCard(node, state))
265
273
  }, {
266
274
  type: 'separator'
267
275
  }] : [];
@@ -1,15 +1,16 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import React from 'react';
3
+ import { withOuterListeners } from '@atlaskit/editor-common/ui';
4
+ import { commandWithMetadata } from '@atlaskit/editor-common/card';
3
5
  import HyperlinkToolbar from '../../hyperlink/ui/HyperlinkAddToolbar';
4
6
  import { showLinkToolbar, hideLinkToolbar } from '../pm-plugins/actions';
5
- import { addAnalytics, INPUT_METHOD } from '../../analytics';
7
+ import { addAnalytics, INPUT_METHOD, ACTION } from '../../analytics';
6
8
  import { LINKPICKER_HEIGHT_IN_PX, RECENT_SEARCH_HEIGHT_IN_PX, RECENT_SEARCH_WIDTH_IN_PX } from '../../../ui/LinkSearch/ToolbarComponents';
7
9
  import { changeSelectedCardToLink, updateCard } from '../pm-plugins/doc';
8
10
  import { findCardInfo, displayInfoForCard } from '../utils';
9
11
  import { NodeSelection } from 'prosemirror-state';
10
12
  import { buildEditLinkPayload } from '../../../utils/linking-utils';
11
13
  import { forceFocusSelector } from '../../floating-toolbar/pm-plugins/force-focus';
12
- import { withOuterListeners } from '@atlaskit/editor-common/ui';
13
14
  import { linkToolbarMessages } from '../../../messages';
14
15
  const HyperLinkToolbarWithListeners = withOuterListeners(HyperlinkToolbar);
15
16
  export class EditLinkToolbar extends React.Component {
@@ -60,10 +61,10 @@ export class EditLinkToolbar extends React.Component {
60
61
  ,
61
62
  invokeMethod: INPUT_METHOD.FLOATING_TB,
62
63
  featureFlags: featureFlags,
63
- onSubmit: (href, title, displayText) => {
64
+ onSubmit: (href, title, displayText, _, analytic) => {
64
65
  this.hideLinkToolbar();
65
66
  if (onSubmit) {
66
- onSubmit(href, displayText || title);
67
+ onSubmit(href, displayText || title, analytic);
67
68
  }
68
69
  }
69
70
  });
@@ -104,19 +105,22 @@ export const buildEditLinkToolbar = ({
104
105
  text: displayInfo.title || '',
105
106
  node: node,
106
107
  featureFlags: featureFlags,
107
- onSubmit: (newHref, newText) => {
108
+ onSubmit: (newHref, newText, analytic) => {
108
109
  const urlChanged = newHref !== displayInfo.url;
109
110
  const titleChanged = newText !== displayInfo.title;
110
111
 
111
112
  // If the title is changed in a smartlink, convert to standard blue hyperlink
112
113
  // (even if the url was also changed) - we don't want to lose the custom title.
113
114
  if (titleChanged) {
114
- return changeSelectedCardToLink(newText, newHref)(view.state, view.dispatch);
115
- } else if (urlChanged) {
115
+ return commandWithMetadata(changeSelectedCardToLink(newText, newHref), {
116
+ action: ACTION.UPDATED,
117
+ sourceEvent: analytic
118
+ })(view.state, view.dispatch);
119
+ }
120
+ if (urlChanged) {
116
121
  // If *only* the url is changed in a smart link, reresolve
117
- return updateCard(newHref)(view.state, view.dispatch);
122
+ return updateCard(newHref, analytic)(view.state, view.dispatch);
118
123
  }
119
- return;
120
124
  }
121
125
  });
122
126
  }
@@ -0,0 +1,180 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import React from 'react';
3
+ import { useEffect, useMemo } from 'react';
4
+ import PropTypes from 'prop-types';
5
+ import { useSmartLinkLifecycleAnalytics } from '@atlaskit/link-analytics';
6
+ import { INPUT_METHOD, ACTION } from '@atlaskit/editor-common/analytics';
7
+ import { UIAnalyticsEvent } from '@atlaskit/analytics-next';
8
+ import { registerSmartCardEventsNext } from '../pm-plugins/actions';
9
+ /**
10
+ * If the metadata is for a history event,
11
+ * returns undo/redo instead of instead of what fn(metadata) would have otherwise
12
+ * returned
13
+ */
14
+ const withHistoryMethod = fn => {
15
+ return metadata => {
16
+ const {
17
+ isUndo,
18
+ isRedo
19
+ } = metadata;
20
+ if (isUndo) {
21
+ return 'undo';
22
+ }
23
+ if (isRedo) {
24
+ return 'redo';
25
+ }
26
+ return fn(metadata);
27
+ };
28
+ };
29
+ const getMethod = withHistoryMethod(({
30
+ inputMethod,
31
+ sourceEvent
32
+ }) => {
33
+ /**
34
+ * If sourceEvent is present, don't provide a custom method
35
+ */
36
+ if (sourceEvent) {
37
+ return;
38
+ }
39
+ switch (inputMethod) {
40
+ case INPUT_METHOD.CLIPBOARD:
41
+ return 'editor_paste';
42
+ case INPUT_METHOD.FLOATING_TB:
43
+ return 'editor_floatingToolbar';
44
+ case INPUT_METHOD.AUTO_DETECT:
45
+ return 'editor_type';
46
+ default:
47
+ return 'unknown';
48
+ }
49
+ });
50
+ const getUpdateType = withHistoryMethod(({
51
+ action,
52
+ sourceEvent
53
+ }) => {
54
+ /**
55
+ * If sourceEvent is present, don't provide a custom method
56
+ */
57
+ if (sourceEvent) {
58
+ return;
59
+ }
60
+ switch (action) {
61
+ case ACTION.CHANGED_TYPE:
62
+ return 'display_update';
63
+ case ACTION.UPDATED:
64
+ return 'link_update';
65
+ default:
66
+ return 'unknown';
67
+ }
68
+ });
69
+ const getDeleteType = withHistoryMethod(({
70
+ action
71
+ }) => {
72
+ if (action === ACTION.UNLINK) {
73
+ return 'unlink';
74
+ }
75
+ return 'delete';
76
+ });
77
+ const getSourceEventFromMetadata = metadata => {
78
+ return metadata.sourceEvent instanceof UIAnalyticsEvent ? metadata.sourceEvent : null;
79
+ };
80
+
81
+ /**
82
+ * Set display category as `link` if not displaying the link as a smart card
83
+ */
84
+ const displayCategoryFromDisplay = display => {
85
+ if (display === 'url') {
86
+ return 'link';
87
+ }
88
+ };
89
+
90
+ /**
91
+ * Binds the @atlaskit/link-analytics callbacks
92
+ * to the editor card plugin state events callbacks interfaces
93
+ */
94
+ export const EventsBinding = ({
95
+ editorView
96
+ }) => {
97
+ /**
98
+ * These callbacks internally use window.requestIdleCallback/requestAnimationFrame
99
+ * to defer any heavy operations involving network
100
+ *
101
+ * The callbacks themselves should not be deferred, they should be called syncronously the moment
102
+ * the events take place.
103
+ */
104
+ const {
105
+ linkCreated,
106
+ linkUpdated,
107
+ linkDeleted
108
+ } = useSmartLinkLifecycleAnalytics();
109
+ const events = useMemo(() => {
110
+ return {
111
+ created: ({
112
+ url,
113
+ display,
114
+ ...metadata
115
+ }) => {
116
+ linkCreated({
117
+ url,
118
+ displayCategory: displayCategoryFromDisplay(display)
119
+ }, getSourceEventFromMetadata(metadata), {
120
+ display,
121
+ creationMethod: getMethod(metadata)
122
+ });
123
+ },
124
+ updated: ({
125
+ url,
126
+ display,
127
+ previousDisplay,
128
+ ...metadata
129
+ }) => {
130
+ linkUpdated({
131
+ url,
132
+ displayCategory: displayCategoryFromDisplay(display)
133
+ }, getSourceEventFromMetadata(metadata), {
134
+ display,
135
+ previousDisplay,
136
+ updateMethod: getMethod(metadata),
137
+ updateType: getUpdateType(metadata)
138
+ });
139
+ },
140
+ deleted: ({
141
+ url,
142
+ display,
143
+ ...metadata
144
+ }) => {
145
+ linkDeleted({
146
+ url,
147
+ displayCategory: displayCategoryFromDisplay(display)
148
+ }, getSourceEventFromMetadata(metadata), {
149
+ display,
150
+ deleteMethod: getMethod(metadata),
151
+ deleteType: getDeleteType(metadata)
152
+ });
153
+ }
154
+ };
155
+ }, [linkCreated, linkUpdated, linkDeleted]);
156
+ useEffect(() => {
157
+ editorView.dispatch(registerSmartCardEventsNext(events)(editorView.state.tr));
158
+ }, [events, editorView]);
159
+ return null;
160
+ };
161
+ export class EditorSmartCardEventsNext extends React.PureComponent {
162
+ render() {
163
+ const cardContext = this.context.contextAdapter.card;
164
+
165
+ /**
166
+ * The analytics hook needs to be able to communicate with the card context
167
+ * If we can't access it, don't mount the event bindings
168
+ * This effectively entirely disables all tracking behaviour
169
+ */
170
+ if (!cardContext) {
171
+ return null;
172
+ }
173
+ return /*#__PURE__*/React.createElement(cardContext.Provider, {
174
+ value: cardContext.value
175
+ }, /*#__PURE__*/React.createElement(EventsBinding, this.props));
176
+ }
177
+ }
178
+ _defineProperty(EditorSmartCardEventsNext, "contextTypes", {
179
+ contextAdapter: PropTypes.object
180
+ });