@atlaskit/editor-plugin-card 0.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 (200) hide show
  1. package/.eslintrc.js +15 -0
  2. package/CHANGELOG.md +1 -0
  3. package/LICENSE.md +13 -0
  4. package/README.md +7 -0
  5. package/dist/cjs/index.js +12 -0
  6. package/dist/cjs/messages.js +20 -0
  7. package/dist/cjs/nodeviews/blockCard.js +164 -0
  8. package/dist/cjs/nodeviews/datasource.js +173 -0
  9. package/dist/cjs/nodeviews/embedCard.js +398 -0
  10. package/dist/cjs/nodeviews/genericCard.js +118 -0
  11. package/dist/cjs/nodeviews/inlineCard.js +132 -0
  12. package/dist/cjs/plugin.js +138 -0
  13. package/dist/cjs/pm-plugins/actions.js +122 -0
  14. package/dist/cjs/pm-plugins/analytics/create-analytics-queue.js +48 -0
  15. package/dist/cjs/pm-plugins/analytics/events-from-tr.js +359 -0
  16. package/dist/cjs/pm-plugins/analytics/index.js +19 -0
  17. package/dist/cjs/pm-plugins/analytics/types.js +5 -0
  18. package/dist/cjs/pm-plugins/analytics/utils.js +178 -0
  19. package/dist/cjs/pm-plugins/doc.js +479 -0
  20. package/dist/cjs/pm-plugins/keymap.js +64 -0
  21. package/dist/cjs/pm-plugins/main.js +212 -0
  22. package/dist/cjs/pm-plugins/mountHyperlink.js +47 -0
  23. package/dist/cjs/pm-plugins/plugin-key.js +9 -0
  24. package/dist/cjs/pm-plugins/reducers.js +111 -0
  25. package/dist/cjs/pm-plugins/shouldReplaceLink.js +35 -0
  26. package/dist/cjs/pm-plugins/util/resolve.js +59 -0
  27. package/dist/cjs/pm-plugins/util/state.js +49 -0
  28. package/dist/cjs/toolbar.js +364 -0
  29. package/dist/cjs/types.js +5 -0
  30. package/dist/cjs/ui/DatasourceModal/ModalWithState.js +25 -0
  31. package/dist/cjs/ui/DatasourceModal/index.js +60 -0
  32. package/dist/cjs/ui/EditLinkToolbar.js +258 -0
  33. package/dist/cjs/ui/EditorSmartCardEvents.js +21 -0
  34. package/dist/cjs/ui/EditorSmartCardEventsNext.js +215 -0
  35. package/dist/cjs/ui/HyperlinkToolbarAppearance.js +174 -0
  36. package/dist/cjs/ui/LayoutButton/index.js +121 -0
  37. package/dist/cjs/ui/LayoutButton/types.js +5 -0
  38. package/dist/cjs/ui/LayoutButton/utils.js +19 -0
  39. package/dist/cjs/ui/LinkToolbarAppearance.js +152 -0
  40. package/dist/cjs/ui/ResizableEmbedCard.js +364 -0
  41. package/dist/cjs/ui/SmallerEditIcon.js +22 -0
  42. package/dist/cjs/utils.js +60 -0
  43. package/dist/cjs/version.json +5 -0
  44. package/dist/es2019/index.js +1 -0
  45. package/dist/es2019/messages.js +13 -0
  46. package/dist/es2019/nodeviews/blockCard.js +131 -0
  47. package/dist/es2019/nodeviews/datasource.js +137 -0
  48. package/dist/es2019/nodeviews/embedCard.js +370 -0
  49. package/dist/es2019/nodeviews/genericCard.js +92 -0
  50. package/dist/es2019/nodeviews/inlineCard.js +113 -0
  51. package/dist/es2019/plugin.js +129 -0
  52. package/dist/es2019/pm-plugins/actions.js +57 -0
  53. package/dist/es2019/pm-plugins/analytics/create-analytics-queue.js +38 -0
  54. package/dist/es2019/pm-plugins/analytics/events-from-tr.js +339 -0
  55. package/dist/es2019/pm-plugins/analytics/index.js +2 -0
  56. package/dist/es2019/pm-plugins/analytics/types.js +1 -0
  57. package/dist/es2019/pm-plugins/analytics/utils.js +160 -0
  58. package/dist/es2019/pm-plugins/doc.js +451 -0
  59. package/dist/es2019/pm-plugins/keymap.js +59 -0
  60. package/dist/es2019/pm-plugins/main.js +208 -0
  61. package/dist/es2019/pm-plugins/mountHyperlink.js +37 -0
  62. package/dist/es2019/pm-plugins/plugin-key.js +2 -0
  63. package/dist/es2019/pm-plugins/reducers.js +110 -0
  64. package/dist/es2019/pm-plugins/shouldReplaceLink.js +25 -0
  65. package/dist/es2019/pm-plugins/util/resolve.js +50 -0
  66. package/dist/es2019/pm-plugins/util/state.js +26 -0
  67. package/dist/es2019/toolbar.js +359 -0
  68. package/dist/es2019/types.js +1 -0
  69. package/dist/es2019/ui/DatasourceModal/ModalWithState.js +19 -0
  70. package/dist/es2019/ui/DatasourceModal/index.js +48 -0
  71. package/dist/es2019/ui/EditLinkToolbar.js +226 -0
  72. package/dist/es2019/ui/EditorSmartCardEvents.js +15 -0
  73. package/dist/es2019/ui/EditorSmartCardEventsNext.js +199 -0
  74. package/dist/es2019/ui/HyperlinkToolbarAppearance.js +86 -0
  75. package/dist/es2019/ui/LayoutButton/index.js +114 -0
  76. package/dist/es2019/ui/LayoutButton/types.js +1 -0
  77. package/dist/es2019/ui/LayoutButton/utils.js +15 -0
  78. package/dist/es2019/ui/LinkToolbarAppearance.js +118 -0
  79. package/dist/es2019/ui/ResizableEmbedCard.js +335 -0
  80. package/dist/es2019/ui/SmallerEditIcon.js +14 -0
  81. package/dist/es2019/utils.js +46 -0
  82. package/dist/es2019/version.json +5 -0
  83. package/dist/esm/index.js +1 -0
  84. package/dist/esm/messages.js +13 -0
  85. package/dist/esm/nodeviews/blockCard.js +156 -0
  86. package/dist/esm/nodeviews/datasource.js +165 -0
  87. package/dist/esm/nodeviews/embedCard.js +389 -0
  88. package/dist/esm/nodeviews/genericCard.js +111 -0
  89. package/dist/esm/nodeviews/inlineCard.js +124 -0
  90. package/dist/esm/plugin.js +130 -0
  91. package/dist/esm/pm-plugins/actions.js +102 -0
  92. package/dist/esm/pm-plugins/analytics/create-analytics-queue.js +41 -0
  93. package/dist/esm/pm-plugins/analytics/events-from-tr.js +350 -0
  94. package/dist/esm/pm-plugins/analytics/index.js +2 -0
  95. package/dist/esm/pm-plugins/analytics/types.js +1 -0
  96. package/dist/esm/pm-plugins/analytics/utils.js +160 -0
  97. package/dist/esm/pm-plugins/doc.js +460 -0
  98. package/dist/esm/pm-plugins/keymap.js +58 -0
  99. package/dist/esm/pm-plugins/main.js +199 -0
  100. package/dist/esm/pm-plugins/mountHyperlink.js +39 -0
  101. package/dist/esm/pm-plugins/plugin-key.js +2 -0
  102. package/dist/esm/pm-plugins/reducers.js +103 -0
  103. package/dist/esm/pm-plugins/shouldReplaceLink.js +29 -0
  104. package/dist/esm/pm-plugins/util/resolve.js +52 -0
  105. package/dist/esm/pm-plugins/util/state.js +40 -0
  106. package/dist/esm/toolbar.js +350 -0
  107. package/dist/esm/types.js +1 -0
  108. package/dist/esm/ui/DatasourceModal/ModalWithState.js +17 -0
  109. package/dist/esm/ui/DatasourceModal/index.js +49 -0
  110. package/dist/esm/ui/EditLinkToolbar.js +244 -0
  111. package/dist/esm/ui/EditorSmartCardEvents.js +14 -0
  112. package/dist/esm/ui/EditorSmartCardEventsNext.js +203 -0
  113. package/dist/esm/ui/HyperlinkToolbarAppearance.js +163 -0
  114. package/dist/esm/ui/LayoutButton/index.js +110 -0
  115. package/dist/esm/ui/LayoutButton/types.js +1 -0
  116. package/dist/esm/ui/LayoutButton/utils.js +12 -0
  117. package/dist/esm/ui/LinkToolbarAppearance.js +141 -0
  118. package/dist/esm/ui/ResizableEmbedCard.js +358 -0
  119. package/dist/esm/ui/SmallerEditIcon.js +14 -0
  120. package/dist/esm/utils.js +48 -0
  121. package/dist/esm/version.json +5 -0
  122. package/dist/types/index.d.ts +2 -0
  123. package/dist/types/messages.d.ts +12 -0
  124. package/dist/types/nodeviews/blockCard.d.ts +26 -0
  125. package/dist/types/nodeviews/datasource.d.ts +42 -0
  126. package/dist/types/nodeviews/embedCard.d.ts +46 -0
  127. package/dist/types/nodeviews/genericCard.d.ts +37 -0
  128. package/dist/types/nodeviews/inlineCard.d.ts +23 -0
  129. package/dist/types/plugin.d.ts +24 -0
  130. package/dist/types/pm-plugins/actions.d.ts +23 -0
  131. package/dist/types/pm-plugins/analytics/create-analytics-queue.d.ts +10 -0
  132. package/dist/types/pm-plugins/analytics/events-from-tr.d.ts +17 -0
  133. package/dist/types/pm-plugins/analytics/index.d.ts +2 -0
  134. package/dist/types/pm-plugins/analytics/types.d.ts +12 -0
  135. package/dist/types/pm-plugins/analytics/utils.d.ts +32 -0
  136. package/dist/types/pm-plugins/doc.d.ts +22 -0
  137. package/dist/types/pm-plugins/keymap.d.ts +3 -0
  138. package/dist/types/pm-plugins/main.d.ts +6 -0
  139. package/dist/types/pm-plugins/mountHyperlink.d.ts +5 -0
  140. package/dist/types/pm-plugins/plugin-key.d.ts +3 -0
  141. package/dist/types/pm-plugins/reducers.d.ts +3 -0
  142. package/dist/types/pm-plugins/shouldReplaceLink.d.ts +2 -0
  143. package/dist/types/pm-plugins/util/resolve.d.ts +8 -0
  144. package/dist/types/pm-plugins/util/state.d.ts +31 -0
  145. package/dist/types/toolbar.d.ts +9 -0
  146. package/dist/types/types.d.ts +163 -0
  147. package/dist/types/ui/DatasourceModal/ModalWithState.d.ts +9 -0
  148. package/dist/types/ui/DatasourceModal/index.d.ts +11 -0
  149. package/dist/types/ui/EditLinkToolbar.d.ts +47 -0
  150. package/dist/types/ui/EditorSmartCardEvents.d.ts +5 -0
  151. package/dist/types/ui/EditorSmartCardEventsNext.d.ts +18 -0
  152. package/dist/types/ui/HyperlinkToolbarAppearance.d.ts +32 -0
  153. package/dist/types/ui/LayoutButton/index.d.ts +9 -0
  154. package/dist/types/ui/LayoutButton/types.d.ts +19 -0
  155. package/dist/types/ui/LayoutButton/utils.d.ts +5 -0
  156. package/dist/types/ui/LinkToolbarAppearance.d.ts +29 -0
  157. package/dist/types/ui/ResizableEmbedCard.d.ts +61 -0
  158. package/dist/types/ui/SmallerEditIcon.d.ts +3 -0
  159. package/dist/types/utils.d.ts +19 -0
  160. package/dist/types-ts4.5/index.d.ts +2 -0
  161. package/dist/types-ts4.5/messages.d.ts +12 -0
  162. package/dist/types-ts4.5/nodeviews/blockCard.d.ts +26 -0
  163. package/dist/types-ts4.5/nodeviews/datasource.d.ts +42 -0
  164. package/dist/types-ts4.5/nodeviews/embedCard.d.ts +46 -0
  165. package/dist/types-ts4.5/nodeviews/genericCard.d.ts +37 -0
  166. package/dist/types-ts4.5/nodeviews/inlineCard.d.ts +23 -0
  167. package/dist/types-ts4.5/plugin.d.ts +24 -0
  168. package/dist/types-ts4.5/pm-plugins/actions.d.ts +23 -0
  169. package/dist/types-ts4.5/pm-plugins/analytics/create-analytics-queue.d.ts +10 -0
  170. package/dist/types-ts4.5/pm-plugins/analytics/events-from-tr.d.ts +17 -0
  171. package/dist/types-ts4.5/pm-plugins/analytics/index.d.ts +2 -0
  172. package/dist/types-ts4.5/pm-plugins/analytics/types.d.ts +12 -0
  173. package/dist/types-ts4.5/pm-plugins/analytics/utils.d.ts +32 -0
  174. package/dist/types-ts4.5/pm-plugins/doc.d.ts +22 -0
  175. package/dist/types-ts4.5/pm-plugins/keymap.d.ts +3 -0
  176. package/dist/types-ts4.5/pm-plugins/main.d.ts +6 -0
  177. package/dist/types-ts4.5/pm-plugins/mountHyperlink.d.ts +5 -0
  178. package/dist/types-ts4.5/pm-plugins/plugin-key.d.ts +3 -0
  179. package/dist/types-ts4.5/pm-plugins/reducers.d.ts +3 -0
  180. package/dist/types-ts4.5/pm-plugins/shouldReplaceLink.d.ts +2 -0
  181. package/dist/types-ts4.5/pm-plugins/util/resolve.d.ts +8 -0
  182. package/dist/types-ts4.5/pm-plugins/util/state.d.ts +31 -0
  183. package/dist/types-ts4.5/toolbar.d.ts +9 -0
  184. package/dist/types-ts4.5/types.d.ts +163 -0
  185. package/dist/types-ts4.5/ui/DatasourceModal/ModalWithState.d.ts +9 -0
  186. package/dist/types-ts4.5/ui/DatasourceModal/index.d.ts +11 -0
  187. package/dist/types-ts4.5/ui/EditLinkToolbar.d.ts +47 -0
  188. package/dist/types-ts4.5/ui/EditorSmartCardEvents.d.ts +5 -0
  189. package/dist/types-ts4.5/ui/EditorSmartCardEventsNext.d.ts +18 -0
  190. package/dist/types-ts4.5/ui/HyperlinkToolbarAppearance.d.ts +32 -0
  191. package/dist/types-ts4.5/ui/LayoutButton/index.d.ts +9 -0
  192. package/dist/types-ts4.5/ui/LayoutButton/types.d.ts +19 -0
  193. package/dist/types-ts4.5/ui/LayoutButton/utils.d.ts +5 -0
  194. package/dist/types-ts4.5/ui/LinkToolbarAppearance.d.ts +29 -0
  195. package/dist/types-ts4.5/ui/ResizableEmbedCard.d.ts +61 -0
  196. package/dist/types-ts4.5/ui/SmallerEditIcon.d.ts +3 -0
  197. package/dist/types-ts4.5/utils.d.ts +19 -0
  198. package/package.json +126 -0
  199. package/report.api.md +146 -0
  200. package/tmp/api-report-tmp.d.ts +117 -0
@@ -0,0 +1,129 @@
1
+ import React from 'react';
2
+ import { blockCard, embedCard, inlineCard } from '@atlaskit/adf-schema';
3
+ import { IconDatasourceJiraIssue } from '@atlaskit/editor-common/quick-insert';
4
+ import { canRenderDatasource } from '@atlaskit/editor-common/utils';
5
+ import { JIRA_LIST_OF_LINKS_DATASOURCE_ID } from '@atlaskit/link-datasource';
6
+ import { messages } from './messages';
7
+ import { hideLinkToolbar, showDatasourceModal } from './pm-plugins/actions';
8
+ import { changeSelectedCardToLink, queueCardsFromChangedTr, setSelectedCardAppearance } from './pm-plugins/doc';
9
+ import { cardKeymap } from './pm-plugins/keymap';
10
+ import { createPlugin } from './pm-plugins/main';
11
+ import { mountHyperlinkPlugin } from './pm-plugins/mountHyperlink';
12
+ import { pluginKey } from './pm-plugins/plugin-key';
13
+ import { floatingToolbar } from './toolbar';
14
+ import DatasourceModalWithState from './ui/DatasourceModal/ModalWithState';
15
+ import { EditorSmartCardEvents } from './ui/EditorSmartCardEvents';
16
+ import { EditorSmartCardEventsNext } from './ui/EditorSmartCardEventsNext';
17
+ import LayoutButton from './ui/LayoutButton';
18
+ export const cardPlugin = (options, api) => {
19
+ var _api$dependencies, _api$dependencies$fea;
20
+ const featureFlags = (api === null || api === void 0 ? void 0 : (_api$dependencies = api.dependencies) === null || _api$dependencies === void 0 ? void 0 : (_api$dependencies$fea = _api$dependencies.featureFlags) === null || _api$dependencies$fea === void 0 ? void 0 : _api$dependencies$fea.sharedState.currentState()) || {};
21
+ return {
22
+ name: 'card',
23
+ getSharedState(editorState) {
24
+ if (!editorState) {
25
+ return null;
26
+ }
27
+ return pluginKey.getState(editorState) || null;
28
+ },
29
+ nodes() {
30
+ const nodes = [{
31
+ name: 'inlineCard',
32
+ node: inlineCard
33
+ }, {
34
+ name: 'blockCard',
35
+ node: blockCard
36
+ }];
37
+ if (options.allowEmbeds) {
38
+ nodes.push({
39
+ name: 'embedCard',
40
+ node: embedCard
41
+ });
42
+ }
43
+ return nodes;
44
+ },
45
+ pmPlugins() {
46
+ var _options$allowBlockCa, _options$allowResizin, _options$useAlternati, _options$allowWrappin, _options$allowAlignme;
47
+ const allowBlockCards = (_options$allowBlockCa = options.allowBlockCards) !== null && _options$allowBlockCa !== void 0 ? _options$allowBlockCa : true;
48
+ const allowResizing = (_options$allowResizin = options.allowResizing) !== null && _options$allowResizin !== void 0 ? _options$allowResizin : true;
49
+ const useAlternativePreloader = (_options$useAlternati = options.useAlternativePreloader) !== null && _options$useAlternati !== void 0 ? _options$useAlternati : true;
50
+ const allowWrapping = (_options$allowWrappin = options.allowWrapping) !== null && _options$allowWrappin !== void 0 ? _options$allowWrappin : true;
51
+ const allowAlignment = (_options$allowAlignme = options.allowAlignment) !== null && _options$allowAlignme !== void 0 ? _options$allowAlignme : true;
52
+ const plugins = [{
53
+ name: 'card',
54
+ plugin: createPlugin({
55
+ ...options,
56
+ allowBlockCards,
57
+ allowResizing,
58
+ useAlternativePreloader,
59
+ allowWrapping,
60
+ allowAlignment
61
+ }, api)
62
+ }, {
63
+ name: 'cardHyperlink',
64
+ plugin: () => mountHyperlinkPlugin(api, options)
65
+ }];
66
+ plugins.push({
67
+ name: 'cardKeymap',
68
+ plugin: ({
69
+ featureFlags
70
+ }) => {
71
+ return cardKeymap(featureFlags);
72
+ }
73
+ });
74
+ return plugins;
75
+ },
76
+ contentComponent({
77
+ editorView,
78
+ popupsMountPoint,
79
+ popupsScrollableElement,
80
+ popupsBoundariesElement
81
+ }) {
82
+ const {
83
+ lpAnalyticsEventsNext
84
+ } = featureFlags;
85
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(EditorSmartCardEvents, {
86
+ editorView: editorView
87
+ }), lpAnalyticsEventsNext && /*#__PURE__*/React.createElement(EditorSmartCardEventsNext, {
88
+ editorView: editorView
89
+ }), /*#__PURE__*/React.createElement(LayoutButton, {
90
+ api: api,
91
+ editorView: editorView,
92
+ mountPoint: popupsMountPoint,
93
+ scrollableElement: popupsScrollableElement,
94
+ boundariesElement: popupsBoundariesElement
95
+ }), /*#__PURE__*/React.createElement(DatasourceModalWithState, {
96
+ api: api,
97
+ editorView: editorView
98
+ }));
99
+ },
100
+ actions: {
101
+ hideLinkToolbar,
102
+ queueCardsFromChangedTr,
103
+ changeSelectedCardToLink,
104
+ setSelectedCardAppearance
105
+ },
106
+ pluginsOptions: {
107
+ floatingToolbar: floatingToolbar(options, featureFlags, options.platform, options.linkPicker, api),
108
+ quickInsert: ({
109
+ formatMessage
110
+ }) => {
111
+ if (canRenderDatasource(JIRA_LIST_OF_LINKS_DATASOURCE_ID)) {
112
+ return [{
113
+ id: 'datasource',
114
+ title: formatMessage(messages.datasourceJiraIssue),
115
+ description: formatMessage(messages.datasourceJiraIssueDescription),
116
+ keywords: ['jira'],
117
+ icon: () => /*#__PURE__*/React.createElement(IconDatasourceJiraIssue, null),
118
+ action(insert) {
119
+ const tr = insert(undefined);
120
+ showDatasourceModal('jira')(tr);
121
+ return tr;
122
+ }
123
+ }];
124
+ }
125
+ return [];
126
+ }
127
+ }
128
+ };
129
+ };
@@ -0,0 +1,57 @@
1
+ import { pluginKey } from './plugin-key';
2
+ export const cardAction = (tr, action) => {
3
+ return tr.setMeta(pluginKey, action);
4
+ };
5
+ export const resolveCard = url => tr => cardAction(tr, {
6
+ type: 'RESOLVE',
7
+ url
8
+ });
9
+ export const queueCards = requests => tr => cardAction(tr, {
10
+ type: 'QUEUE',
11
+ requests: requests
12
+ });
13
+ export const registerCard = info => tr => cardAction(tr, {
14
+ type: 'REGISTER',
15
+ info
16
+ });
17
+ export const registerSmartCardEvents = smartLinkEvents => tr => cardAction(tr, {
18
+ type: 'REGISTER_EVENTS',
19
+ smartLinkEvents
20
+ });
21
+ export const registerSmartCardEventsNext = smartLinkEvents => tr => cardAction(tr, {
22
+ type: 'REGISTER_EVENTS_NEXT',
23
+ smartLinkEvents
24
+ });
25
+ export const setProvider = cardProvider => tr => cardAction(tr, {
26
+ type: 'SET_PROVIDER',
27
+ provider: cardProvider
28
+ });
29
+ export const setDatasourceTableRef = datasourceTableRef => tr => cardAction(tr, {
30
+ type: 'SET_DATASOURCE_TABLE_REF',
31
+ datasourceTableRef
32
+ });
33
+ export const setCardLayout = layout => tr => cardAction(tr, {
34
+ type: 'SET_CARD_LAYOUT',
35
+ layout
36
+ });
37
+ export const setCardLayoutAndDatasourceTableRef = ({
38
+ layout,
39
+ datasourceTableRef
40
+ }) => tr => cardAction(tr, {
41
+ type: 'SET_CARD_LAYOUT_AND_DATASOURCE_TABLE_REF',
42
+ layout,
43
+ datasourceTableRef
44
+ });
45
+ export const showLinkToolbar = tr => cardAction(tr, {
46
+ type: 'SHOW_LINK_TOOLBAR'
47
+ });
48
+ export const hideLinkToolbar = tr => cardAction(tr, {
49
+ type: 'HIDE_LINK_TOOLBAR'
50
+ });
51
+ export const showDatasourceModal = modalType => tr => cardAction(tr, {
52
+ type: 'SHOW_DATASOURCE_MODAL',
53
+ modalType
54
+ });
55
+ export const hideDatasourceModal = tr => cardAction(tr, {
56
+ type: 'HIDE_DATASOURCE_MODAL'
57
+ });
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Simple mechanism to defer analytics related callbacks
3
+ */
4
+ export const createAnalyticsQueue = (enabled = true) => {
5
+ const queue = [];
6
+ const callbacksRef = {
7
+ current: null
8
+ };
9
+ const setCallbacks = callbacks => {
10
+ callbacksRef.current = callbacks;
11
+ };
12
+ const push = (...events) => {
13
+ const callbacks = callbacksRef.current;
14
+ if (!enabled || !callbacks) {
15
+ return;
16
+ }
17
+ queue.push(...events);
18
+ };
19
+ const flush = () => {
20
+ const callbacks = callbacksRef.current;
21
+ if (!enabled || !callbacks) {
22
+ return;
23
+ }
24
+ while (queue.length) {
25
+ const event = queue.pop();
26
+ if (event) {
27
+ callbacks[event.type](event.data);
28
+ }
29
+ }
30
+ };
31
+ const getSize = () => queue.length;
32
+ return {
33
+ push,
34
+ flush,
35
+ setCallbacks,
36
+ getSize
37
+ };
38
+ };
@@ -0,0 +1,339 @@
1
+ import { AddMarkStep, RemoveMarkStep } from 'prosemirror-transform';
2
+ import { LinkMetaStep } from '@atlaskit/adf-schema/steps';
3
+ import { ACTION } from '@atlaskit/editor-common/analytics';
4
+ import { getLinkMetadataFromTransaction } from '@atlaskit/editor-common/card';
5
+ import { isLinkMark, pmHistoryPluginKey } from '@atlaskit/editor-common/utils';
6
+ import { pluginKey } from '../plugin-key';
7
+ import { getPluginState } from '../util/state';
8
+ import { appearanceForLink, areSameLinks, findLinksAtPositions, getLinkNodeContext, getLinkUrl, isLink, linkObjectFromNode } from './utils';
9
+ const findLinksInNodeRange = (doc, schema, from, to) => {
10
+ const links = [];
11
+ doc.nodesBetween(from, to, (node, pos) => {
12
+ if (isLink(schema, node)) {
13
+ const entireLinkInRange = pos >= from && pos + node.nodeSize <= to;
14
+ if (entireLinkInRange) {
15
+ const link = linkObjectFromNode(doc, schema, node, pos);
16
+ if (link) {
17
+ links.push(link);
18
+ }
19
+ }
20
+ }
21
+ });
22
+ return links;
23
+ };
24
+ export const findChangedLinks = (tr, state) => {
25
+ const schema = tr.doc.type.schema;
26
+ const removed = [];
27
+ const inserted = [];
28
+ const updated = [];
29
+ const queuedForUpgrade = isTransactionQueuedForUpgrade(tr);
30
+ const isResolveReplace = isTransactionResolveReplace(tr);
31
+
32
+ // History
33
+ const historyMeta = tr.getMeta(pmHistoryPluginKey);
34
+ const isUndo = isHistoryMeta(historyMeta) && historyMeta.redo === false;
35
+ const isRedo = isHistoryMeta(historyMeta) && historyMeta.redo === true;
36
+ const isUpdate = isUpdateTr(tr, isUndo || isRedo);
37
+ for (let i = 0; i < tr.steps.length; i++) {
38
+ var _tr$docs$i, _tr$docs;
39
+ const step = tr.steps[i];
40
+ const stepMap = step.getMap();
41
+ const removedInStep = [];
42
+ const insertedInStep = [];
43
+ const before = (_tr$docs$i = tr.docs[i]) !== null && _tr$docs$i !== void 0 ? _tr$docs$i : tr.before;
44
+ const after = (_tr$docs = tr.docs[i + 1]) !== null && _tr$docs !== void 0 ? _tr$docs : tr.doc;
45
+
46
+ /**
47
+ * AddMarkStep and RemoveMarkSteps don't produce stepMap ranges
48
+ * because there are no "changed tokens" only marks added/removed
49
+ * So have to check these manually
50
+ */
51
+ if (step instanceof AddMarkStep) {
52
+ const addMarkStep = step;
53
+ if (isLinkMark(addMarkStep.mark, schema)) {
54
+ /**
55
+ * For url text pasted on plain text
56
+ */
57
+ insertedInStep.push({
58
+ type: 'mark',
59
+ pos: addMarkStep.from,
60
+ mark: addMarkStep.mark,
61
+ nodeContext: getLinkNodeContext(after, addMarkStep.from)
62
+ });
63
+ }
64
+ }
65
+ if (step instanceof RemoveMarkStep) {
66
+ const removeMarkStep = step;
67
+ if (isLinkMark(removeMarkStep.mark, schema)) {
68
+ removedInStep.push({
69
+ type: 'mark',
70
+ pos: removeMarkStep.from,
71
+ mark: removeMarkStep.mark,
72
+ nodeContext: getLinkNodeContext(before, removeMarkStep.from)
73
+ });
74
+ }
75
+ }
76
+ stepMap.forEach((oldStart, oldEnd, newStart, newEnd) => {
77
+ var _tr$docs2;
78
+ const before = tr.docs[i];
79
+ const after = (_tr$docs2 = tr.docs[i + 1]) !== null && _tr$docs2 !== void 0 ? _tr$docs2 : tr.doc;
80
+ const removedInRange = [];
81
+ const insertedInRange = [];
82
+
83
+ // Removed
84
+ removedInRange.push(...findLinksInNodeRange(before, schema, oldStart, oldEnd));
85
+ // Inserted
86
+ insertedInRange.push(...findLinksInNodeRange(after, schema, newStart, newEnd));
87
+ removedInStep.push(...removedInRange);
88
+ insertedInStep.push(...insertedInRange);
89
+ });
90
+ const omitQueuedLinks = links => {
91
+ if (!queuedForUpgrade) {
92
+ return links;
93
+ }
94
+ /**
95
+ * Skip/filter out links that have been queued, they will be tracked later
96
+ */
97
+ const queuedPositions = getQueuedPositions(tr);
98
+ return links.filter(link => !queuedPositions.includes(link.pos));
99
+ };
100
+
101
+ /**
102
+ * Skip "deletions" when the transaction is relating to
103
+ * replacing links queued for upgrade to cards,
104
+ * because the "deleted" link has not actually been
105
+ * tracked as "created" yet
106
+ */
107
+ if (!isResolveReplace) {
108
+ removed.push(...removedInStep);
109
+ }
110
+ inserted.push(...omitQueuedLinks(insertedInStep));
111
+ }
112
+
113
+ /**
114
+ * If there are no links changed but the transaction is a "resolve" action
115
+ * Then this means we have resolved a link but it has failed to upgrade
116
+ * We should track all resolved links as now being created
117
+ */
118
+ if (inserted.length === 0 && isResolveReplace) {
119
+ const positions = getResolvePositions(tr, state);
120
+ inserted.push(...findLinksAtPositions(tr, positions));
121
+ }
122
+ if (!isUpdate) {
123
+ const {
124
+ inputMethod
125
+ } = getLinkMetadataFromTransaction(tr);
126
+ /**
127
+ * If there is no identifiable input method, and the links inserted and removed appear to be the same,
128
+ * then this transaction likely is not intended to be consided to be the insertion and removal of links
129
+ */
130
+ if (!inputMethod && areSameLinks(removed, inserted)) {
131
+ return {
132
+ removed: [],
133
+ inserted: [],
134
+ updated
135
+ };
136
+ }
137
+ return {
138
+ removed,
139
+ inserted,
140
+ updated
141
+ };
142
+ }
143
+ for (let i = 0; i < inserted.length; i++) {
144
+ if (isResolveReplace) {
145
+ const newLink = inserted[i];
146
+
147
+ // what is the 2nd argument 'assoc = -1' doing here exactly?
148
+ const mappedPos = tr.mapping.map(newLink.pos, -1);
149
+ const previousDisplay = getResolveLinkPrevDisplay(state, mappedPos);
150
+ updated.push({
151
+ inserted: inserted[i],
152
+ previous: {
153
+ display: previousDisplay
154
+ }
155
+ });
156
+ continue;
157
+ }
158
+ if (inserted.length === removed.length) {
159
+ updated.push({
160
+ removed: removed[i],
161
+ inserted: inserted[i]
162
+ });
163
+ }
164
+ }
165
+ return {
166
+ inserted: [],
167
+ removed: [],
168
+ updated
169
+ };
170
+ };
171
+
172
+ /**
173
+ * List of actions to be considered link "updates"
174
+ */
175
+ const UPDATE_ACTIONS = [ACTION.CHANGED_TYPE, ACTION.UPDATED];
176
+
177
+ /**
178
+ * Returns true if the transaction has LinkMetaSteps that indicate the transaction is
179
+ * intended to be perceived as an update to links, rather than insertion+deletion
180
+ */
181
+ const isUpdateTr = (tr, isUndoOrRedo) => {
182
+ return !!tr.steps.find(step => {
183
+ if (!(step instanceof LinkMetaStep)) {
184
+ return false;
185
+ }
186
+ const {
187
+ action,
188
+ cardAction
189
+ } = step.getMetadata();
190
+
191
+ /**
192
+ * Undo of a resolve step should be considered an update
193
+ * because the user is choosing to update the url back to the un-upgraded display
194
+ */
195
+ if (cardAction === 'RESOLVE' && isUndoOrRedo) {
196
+ return true;
197
+ }
198
+ if (!action) {
199
+ return false;
200
+ }
201
+ return UPDATE_ACTIONS.includes(action);
202
+ });
203
+ };
204
+ const hasType = pluginMeta => {
205
+ return typeof pluginMeta === 'object' && pluginMeta !== null && 'type' in pluginMeta;
206
+ };
207
+ const isTransactionQueuedForUpgrade = tr => {
208
+ const pluginMeta = tr.getMeta(pluginKey);
209
+ return isMetadataQueue(pluginMeta);
210
+ };
211
+ const isMetadataQueue = metaData => {
212
+ return hasType(metaData) && metaData.type === 'QUEUE';
213
+ };
214
+ const isTransactionResolveReplace = tr => {
215
+ const pluginMeta = tr.getMeta(pluginKey);
216
+ return isMetadataResolve(pluginMeta);
217
+ };
218
+ const isMetadataResolve = metaData => {
219
+ return hasType(metaData) && metaData.type === 'RESOLVE';
220
+ };
221
+ const isHistoryMeta = meta => {
222
+ return typeof meta === 'object' && meta !== null && 'redo' in meta;
223
+ };
224
+ const getQueuedPositions = tr => {
225
+ const pluginMeta = tr.getMeta(pluginKey);
226
+ if (!isMetadataQueue(pluginMeta)) {
227
+ return [];
228
+ }
229
+ return pluginMeta.requests.map(({
230
+ pos
231
+ }) => pos);
232
+ };
233
+ const getResolvePositions = (tr, state) => {
234
+ const cardState = getPluginState(state);
235
+ if (!cardState) {
236
+ return [];
237
+ }
238
+ const pluginMeta = tr.getMeta(pluginKey);
239
+ if (!isMetadataResolve(pluginMeta)) {
240
+ return [];
241
+ }
242
+ return cardState.requests.filter(request => request.url === pluginMeta.url).map(request => request.pos);
243
+ };
244
+ const getResolveLinkPrevDisplay = (state, pos) => {
245
+ var _cardState$requests$f;
246
+ const cardState = getPluginState(state);
247
+ if (!cardState) {
248
+ return undefined;
249
+ }
250
+ return (_cardState$requests$f = cardState.requests.find(request => request.pos === pos)) === null || _cardState$requests$f === void 0 ? void 0 : _cardState$requests$f.previousAppearance;
251
+ };
252
+ export function eventsFromTransaction(tr, state) {
253
+ const events = [];
254
+ try {
255
+ /**
256
+ * Skip transactions sent by collab (identified by 'isRemote' key)
257
+ * Skip entire document replace steps
258
+ * We are only concerned with transactions performed on the document directly by the user
259
+ */
260
+ const isRemote = tr.getMeta('isRemote');
261
+ const isReplaceDocument = tr.getMeta('replaceDocument');
262
+ if (isRemote || isReplaceDocument) {
263
+ return events;
264
+ }
265
+ const historyMeta = tr.getMeta(pmHistoryPluginKey);
266
+ const isUndo = isHistoryMeta(historyMeta) && historyMeta.redo === false;
267
+ const isRedo = isHistoryMeta(historyMeta) && historyMeta.redo === true;
268
+
269
+ /**
270
+ * Retrieve metadata from the LinkMetaStep(s) in the transaction
271
+ */
272
+ const {
273
+ action,
274
+ inputMethod,
275
+ sourceEvent
276
+ } = getLinkMetadataFromTransaction(tr);
277
+ const contextualData = {
278
+ action,
279
+ inputMethod,
280
+ sourceEvent,
281
+ isUndo,
282
+ isRedo
283
+ };
284
+ const {
285
+ removed,
286
+ inserted,
287
+ updated
288
+ } = findChangedLinks(tr, state);
289
+ const MAX_LINK_EVENTS = 50;
290
+ if ([removed, inserted, updated].some(arr => arr.length > MAX_LINK_EVENTS)) {
291
+ return [];
292
+ }
293
+ for (let i = 0; i < updated.length; i++) {
294
+ var _update$previous$disp;
295
+ const update = updated[i];
296
+ const {
297
+ inserted: link
298
+ } = update;
299
+ const url = getLinkUrl(link);
300
+ const display = appearanceForLink(link);
301
+ const previousDisplay = 'removed' in update ? appearanceForLink(update.removed) : (_update$previous$disp = update.previous.display) !== null && _update$previous$disp !== void 0 ? _update$previous$disp : 'unknown';
302
+ if (url) {
303
+ events.push({
304
+ type: 'updated',
305
+ data: {
306
+ ...contextualData,
307
+ url,
308
+ display,
309
+ previousDisplay,
310
+ nodeContext: link.nodeContext
311
+ }
312
+ });
313
+ }
314
+ }
315
+ const pushEvents = (links, type) => {
316
+ for (let i = 0; i < links.length; i++) {
317
+ const link = links[i];
318
+ const url = getLinkUrl(link);
319
+ const display = appearanceForLink(link);
320
+ if (url) {
321
+ events.push({
322
+ type,
323
+ data: {
324
+ ...contextualData,
325
+ url,
326
+ display,
327
+ nodeContext: link.nodeContext
328
+ }
329
+ });
330
+ }
331
+ }
332
+ };
333
+ pushEvents(removed, 'deleted');
334
+ pushEvents(inserted, 'created');
335
+ return events;
336
+ } catch (err) {
337
+ return events;
338
+ }
339
+ }
@@ -0,0 +1,2 @@
1
+ export { createAnalyticsQueue } from './create-analytics-queue';
2
+ export { eventsFromTransaction } from './events-from-tr';
@@ -0,0 +1 @@
1
+ export {};