@atlaskit/editor-core 182.0.3 → 182.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/.eslintrc.js +2 -0
  2. package/CHANGELOG.md +47 -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/pm-plugins/main.js +5 -4
  45. package/dist/cjs/plugins/media/utils/media-single.js +1 -4
  46. package/dist/cjs/plugins/panel/pm-plugins/keymaps.js +2 -1
  47. package/dist/cjs/plugins/paste/handlers.js +5 -5
  48. package/dist/cjs/plugins/paste/index.js +4 -2
  49. package/dist/cjs/plugins/paste/pm-plugins/main.js +6 -4
  50. package/dist/cjs/plugins/rule/commands.js +2 -2
  51. package/dist/cjs/plugins/rule/index.js +5 -4
  52. package/dist/cjs/plugins/rule/pm-plugins/input-rule.js +6 -8
  53. package/dist/cjs/plugins/rule/pm-plugins/keymap.js +2 -2
  54. package/dist/cjs/plugins/text-color/index.js +5 -2
  55. package/dist/cjs/plugins/text-color/ui/ToolbarTextColor/index.js +3 -4
  56. package/dist/cjs/plugins/text-formatting/ui/Toolbar/toolbar-messages.js +10 -0
  57. package/dist/cjs/ui/Appearance/Comment/Comment.js +2 -0
  58. package/dist/cjs/ui/Appearance/FullPage/FullPage.js +2 -4
  59. package/dist/cjs/ui/Appearance/FullPage/FullPageToolbar.js +2 -0
  60. package/dist/cjs/ui/ColorPalette/index.js +6 -0
  61. package/dist/cjs/ui/ConfigPanel/ConfigPanel.js +15 -10
  62. package/dist/cjs/ui/ConfigPanel/ConfigPanelFieldsLoader.js +3 -1
  63. package/dist/cjs/ui/ConfigPanel/Fields/ColorPicker.js +248 -17
  64. package/dist/cjs/ui/ConfigPanel/FormContent.js +12 -6
  65. package/dist/cjs/ui/ConfigPanel/utils.js +2 -12
  66. package/dist/cjs/ui/ContentStyles/index.js +2 -5
  67. package/dist/cjs/ui/MediaAndEmbedsToolbar/index.js +16 -8
  68. package/dist/cjs/utils/document.js +5 -3
  69. package/dist/cjs/version-wrapper.js +1 -1
  70. package/dist/cjs/version.json +1 -1
  71. package/dist/es2019/actions/index.js +10 -4
  72. package/dist/es2019/analytics-api/attach-payload-into-transaction.js +2 -1
  73. package/dist/es2019/create-editor/ErrorBoundary.js +1 -13
  74. package/dist/es2019/create-editor/ReactEditorViewInternal.js +2 -2
  75. package/dist/es2019/editor-next/editor-internal.js +2 -1
  76. package/dist/es2019/editor-next/index.js +5 -1
  77. package/dist/es2019/editor.js +5 -2
  78. package/dist/es2019/keymaps/index.js +1 -1
  79. package/dist/es2019/labs/next/internal/hooks/use-editor/index.js +4 -6
  80. package/dist/es2019/labs/next/presets/default.js +1 -2
  81. package/dist/es2019/plugins/card/index.js +15 -5
  82. package/dist/es2019/plugins/card/pm-plugins/actions.js +4 -0
  83. package/dist/es2019/plugins/card/pm-plugins/analytics/create-analytics-queue.js +38 -0
  84. package/dist/es2019/plugins/card/pm-plugins/analytics/events-from-tr.js +316 -0
  85. package/dist/es2019/plugins/card/pm-plugins/analytics/index.js +2 -0
  86. package/dist/es2019/plugins/card/pm-plugins/analytics/types.js +1 -0
  87. package/dist/es2019/plugins/card/pm-plugins/analytics/utils.js +124 -0
  88. package/dist/es2019/plugins/card/pm-plugins/doc.js +94 -20
  89. package/dist/es2019/plugins/card/pm-plugins/main.js +17 -8
  90. package/dist/es2019/plugins/card/pm-plugins/reducers.js +8 -0
  91. package/dist/es2019/plugins/card/pm-plugins/util/resolve.js +3 -7
  92. package/dist/es2019/plugins/card/toolbar.js +16 -8
  93. package/dist/es2019/plugins/card/ui/EditLinkToolbar.js +13 -9
  94. package/dist/es2019/plugins/card/ui/EditorSmartCardEventsNext.js +180 -0
  95. package/dist/es2019/plugins/card/ui/LinkToolbarAppearance.js +11 -2
  96. package/dist/es2019/plugins/card/utils.js +6 -2
  97. package/dist/es2019/plugins/extension/context-panel.js +3 -2
  98. package/dist/es2019/plugins/extension/index.js +45 -41
  99. package/dist/es2019/plugins/help-dialog/ui/index.js +17 -1
  100. package/dist/es2019/plugins/hyperlink/Toolbar.js +13 -4
  101. package/dist/es2019/plugins/hyperlink/commands.js +9 -6
  102. package/dist/es2019/plugins/hyperlink/pm-plugins/input-rule.js +4 -0
  103. package/dist/es2019/plugins/hyperlink/ui/HyperlinkAddToolbar/index.js +2 -2
  104. package/dist/es2019/plugins/index.js +0 -1
  105. package/dist/es2019/plugins/insert-block/index.js +96 -91
  106. package/dist/es2019/plugins/insert-block/ui/ToolbarInsertBlock/index.js +3 -2
  107. package/dist/es2019/plugins/media/index.js +202 -198
  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/Comment/Comment.js +2 -0
  122. package/dist/es2019/ui/Appearance/FullPage/FullPage.js +2 -4
  123. package/dist/es2019/ui/Appearance/FullPage/FullPageToolbar.js +2 -0
  124. package/dist/es2019/ui/ColorPalette/index.js +2 -2
  125. package/dist/es2019/ui/ConfigPanel/ConfigPanel.js +8 -4
  126. package/dist/es2019/ui/ConfigPanel/ConfigPanelFieldsLoader.js +3 -1
  127. package/dist/es2019/ui/ConfigPanel/Fields/ColorPicker.js +238 -13
  128. package/dist/es2019/ui/ConfigPanel/FormContent.js +12 -6
  129. package/dist/es2019/ui/ConfigPanel/utils.js +1 -11
  130. package/dist/es2019/ui/ContentStyles/index.js +2 -5
  131. package/dist/es2019/ui/MediaAndEmbedsToolbar/index.js +12 -10
  132. package/dist/es2019/utils/document.js +5 -3
  133. package/dist/es2019/version-wrapper.js +1 -1
  134. package/dist/es2019/version.json +1 -1
  135. package/dist/esm/actions/index.js +17 -6
  136. package/dist/esm/analytics-api/attach-payload-into-transaction.js +2 -1
  137. package/dist/esm/create-editor/ErrorBoundary.js +1 -16
  138. package/dist/esm/create-editor/ReactEditorViewInternal.js +2 -2
  139. package/dist/esm/editor-next/editor-internal.js +2 -1
  140. package/dist/esm/editor-next/index.js +5 -1
  141. package/dist/esm/editor.js +9 -5
  142. package/dist/esm/keymaps/index.js +1 -1
  143. package/dist/esm/labs/next/internal/hooks/use-editor/index.js +4 -6
  144. package/dist/esm/labs/next/presets/default.js +1 -2
  145. package/dist/esm/plugins/card/index.js +13 -5
  146. package/dist/esm/plugins/card/pm-plugins/actions.js +8 -0
  147. package/dist/esm/plugins/card/pm-plugins/analytics/create-analytics-queue.js +41 -0
  148. package/dist/esm/plugins/card/pm-plugins/analytics/events-from-tr.js +328 -0
  149. package/dist/esm/plugins/card/pm-plugins/analytics/index.js +2 -0
  150. package/dist/esm/plugins/card/pm-plugins/analytics/types.js +1 -0
  151. package/dist/esm/plugins/card/pm-plugins/analytics/utils.js +124 -0
  152. package/dist/esm/plugins/card/pm-plugins/doc.js +98 -22
  153. package/dist/esm/plugins/card/pm-plugins/main.js +16 -10
  154. package/dist/esm/plugins/card/pm-plugins/reducers.js +7 -0
  155. package/dist/esm/plugins/card/pm-plugins/util/resolve.js +3 -7
  156. package/dist/esm/plugins/card/toolbar.js +18 -8
  157. package/dist/esm/plugins/card/ui/EditLinkToolbar.js +13 -9
  158. package/dist/esm/plugins/card/ui/EditorSmartCardEventsNext.js +191 -0
  159. package/dist/esm/plugins/card/ui/LinkToolbarAppearance.js +12 -4
  160. package/dist/esm/plugins/card/utils.js +4 -2
  161. package/dist/esm/plugins/extension/context-panel.js +3 -2
  162. package/dist/esm/plugins/extension/index.js +4 -1
  163. package/dist/esm/plugins/help-dialog/ui/index.js +29 -8
  164. package/dist/esm/plugins/hyperlink/Toolbar.js +13 -3
  165. package/dist/esm/plugins/hyperlink/commands.js +9 -5
  166. package/dist/esm/plugins/hyperlink/pm-plugins/input-rule.js +4 -0
  167. package/dist/esm/plugins/hyperlink/ui/HyperlinkAddToolbar/index.js +2 -2
  168. package/dist/esm/plugins/index.js +0 -1
  169. package/dist/esm/plugins/insert-block/index.js +5 -1
  170. package/dist/esm/plugins/insert-block/ui/ToolbarInsertBlock/index.js +25 -23
  171. package/dist/esm/plugins/media/index.js +9 -5
  172. package/dist/esm/plugins/media/pm-plugins/main.js +5 -4
  173. package/dist/esm/plugins/media/utils/media-single.js +1 -4
  174. package/dist/esm/plugins/panel/pm-plugins/keymaps.js +3 -2
  175. package/dist/esm/plugins/paste/handlers.js +6 -6
  176. package/dist/esm/plugins/paste/index.js +4 -2
  177. package/dist/esm/plugins/paste/pm-plugins/main.js +7 -5
  178. package/dist/esm/plugins/rule/commands.js +2 -2
  179. package/dist/esm/plugins/rule/index.js +5 -4
  180. package/dist/esm/plugins/rule/pm-plugins/input-rule.js +6 -8
  181. package/dist/esm/plugins/rule/pm-plugins/keymap.js +2 -2
  182. package/dist/esm/plugins/text-color/index.js +5 -2
  183. package/dist/esm/plugins/text-color/ui/ToolbarTextColor/index.js +3 -4
  184. package/dist/esm/plugins/text-formatting/ui/Toolbar/toolbar-messages.js +10 -0
  185. package/dist/esm/ui/Appearance/Comment/Comment.js +2 -0
  186. package/dist/esm/ui/Appearance/FullPage/FullPage.js +2 -4
  187. package/dist/esm/ui/Appearance/FullPage/FullPageToolbar.js +2 -0
  188. package/dist/esm/ui/ColorPalette/index.js +2 -2
  189. package/dist/esm/ui/ConfigPanel/ConfigPanel.js +15 -10
  190. package/dist/esm/ui/ConfigPanel/ConfigPanelFieldsLoader.js +3 -1
  191. package/dist/esm/ui/ConfigPanel/Fields/ColorPicker.js +244 -19
  192. package/dist/esm/ui/ConfigPanel/FormContent.js +12 -6
  193. package/dist/esm/ui/ConfigPanel/utils.js +0 -10
  194. package/dist/esm/ui/ContentStyles/index.js +2 -5
  195. package/dist/esm/ui/MediaAndEmbedsToolbar/index.js +16 -8
  196. package/dist/esm/utils/document.js +5 -3
  197. package/dist/esm/version-wrapper.js +1 -1
  198. package/dist/esm/version.json +1 -1
  199. package/dist/types/actions/index.d.ts +3 -2
  200. package/dist/types/create-editor/ErrorBoundary.d.ts +2 -2
  201. package/dist/types/editor-next/index.d.ts +1 -0
  202. package/dist/types/editor.d.ts +1 -0
  203. package/dist/types/keymaps/index.d.ts +1 -1
  204. package/dist/types/labs/next/internal/hooks/use-editor/index.d.ts +2 -1
  205. package/dist/types/labs/next/presets/cxhtml.d.ts +1 -5
  206. package/dist/types/labs/next/presets/default.d.ts +2 -10
  207. package/dist/types/labs/next/presets/mobile.d.ts +1 -5
  208. package/dist/types/plugins/card/pm-plugins/actions.d.ts +2 -1
  209. package/dist/types/plugins/card/pm-plugins/analytics/create-analytics-queue.d.ts +10 -0
  210. package/dist/types/plugins/card/pm-plugins/analytics/events-from-tr.d.ts +17 -0
  211. package/dist/types/plugins/card/pm-plugins/analytics/index.d.ts +2 -0
  212. package/dist/types/plugins/card/pm-plugins/analytics/types.d.ts +10 -0
  213. package/dist/types/plugins/card/pm-plugins/analytics/utils.d.ts +26 -0
  214. package/dist/types/plugins/card/pm-plugins/doc.d.ts +8 -7
  215. package/dist/types/plugins/card/pm-plugins/main.d.ts +1 -1
  216. package/dist/types/plugins/card/pm-plugins/util/resolve.d.ts +2 -2
  217. package/dist/types/plugins/card/pm-plugins/util/state.d.ts +3 -0
  218. package/dist/types/plugins/card/types.d.ts +81 -7
  219. package/dist/types/plugins/card/ui/EditLinkToolbar.d.ts +2 -1
  220. package/dist/types/plugins/card/ui/EditorSmartCardEventsNext.d.ts +18 -0
  221. package/dist/types/plugins/card/utils.d.ts +1 -1
  222. package/dist/types/plugins/extension/context-panel.d.ts +2 -1
  223. package/dist/types/plugins/extension/index.d.ts +2 -0
  224. package/dist/types/plugins/hyperlink/commands.d.ts +3 -2
  225. package/dist/types/plugins/hyperlink/ui/HyperlinkAddToolbar/index.d.ts +2 -1
  226. package/dist/types/plugins/index.d.ts +0 -1
  227. package/dist/types/plugins/insert-block/index.d.ts +2 -0
  228. package/dist/types/plugins/insert-block/ui/ToolbarInsertBlock/types.d.ts +2 -1
  229. package/dist/types/plugins/media/index.d.ts +2 -0
  230. package/dist/types/plugins/media/pm-plugins/main.d.ts +3 -2
  231. package/dist/types/plugins/media/utils/media-single.d.ts +1 -1
  232. package/dist/types/plugins/paste/index.d.ts +2 -0
  233. package/dist/types/plugins/paste/pm-plugins/main.d.ts +2 -1
  234. package/dist/types/plugins/rule/commands.d.ts +2 -1
  235. package/dist/types/plugins/rule/index.d.ts +5 -1
  236. package/dist/types/plugins/rule/pm-plugins/input-rule.d.ts +1 -1
  237. package/dist/types/plugins/rule/pm-plugins/keymap.d.ts +2 -1
  238. package/dist/types/plugins/text-color/index.d.ts +2 -0
  239. package/dist/types/plugins/text-color/ui/ToolbarTextColor/index.d.ts +2 -0
  240. package/dist/types/plugins/text-formatting/ui/Toolbar/toolbar-messages.d.ts +10 -0
  241. package/dist/types/types/editor-appearance-component.d.ts +1 -1
  242. package/dist/types/types/editor-props.d.ts +1 -0
  243. package/dist/types/ui/Appearance/FullPage/FullPage.d.ts +2 -0
  244. package/dist/types/ui/ColorPalette/index.d.ts +2 -2
  245. package/dist/types/ui/ConfigPanel/ConfigPanel.d.ts +3 -1
  246. package/dist/types/ui/ConfigPanel/ConfigPanelFieldsLoader.d.ts +3 -1
  247. package/dist/types/ui/ConfigPanel/Fields/ColorPicker.d.ts +12 -1
  248. package/dist/types/ui/ConfigPanel/FormContent.d.ts +2 -2
  249. package/dist/types/ui/ConfigPanel/types.d.ts +3 -0
  250. package/dist/types/ui/ConfigPanel/utils.d.ts +0 -1
  251. package/dist/types/ui/MediaAndEmbedsToolbar/index.d.ts +1 -1
  252. package/package.json +15 -14
  253. package/report.api.md +10 -0
  254. package/dist/cjs/plugins/feature-flags-context/get-enabled-feature-flag-keys.js +0 -12
  255. package/dist/cjs/plugins/feature-flags-context/get-feature-flags.js +0 -11
  256. package/dist/cjs/plugins/feature-flags-context/index.js +0 -50
  257. package/dist/cjs/plugins/feature-flags-context/plugin-key.js +0 -9
  258. package/dist/es2019/plugins/feature-flags-context/get-enabled-feature-flag-keys.js +0 -1
  259. package/dist/es2019/plugins/feature-flags-context/get-feature-flags.js +0 -2
  260. package/dist/es2019/plugins/feature-flags-context/index.js +0 -29
  261. package/dist/es2019/plugins/feature-flags-context/plugin-key.js +0 -2
  262. package/dist/esm/plugins/feature-flags-context/get-enabled-feature-flag-keys.js +0 -1
  263. package/dist/esm/plugins/feature-flags-context/get-feature-flags.js +0 -4
  264. package/dist/esm/plugins/feature-flags-context/index.js +0 -40
  265. package/dist/esm/plugins/feature-flags-context/plugin-key.js +0 -2
  266. package/dist/types/plugins/feature-flags-context/get-enabled-feature-flag-keys.d.ts +0 -1
  267. package/dist/types/plugins/feature-flags-context/get-feature-flags.d.ts +0 -3
  268. package/dist/types/plugins/feature-flags-context/index.d.ts +0 -9
  269. package/dist/types/plugins/feature-flags-context/plugin-key.d.ts +0 -2
@@ -15,6 +15,7 @@ import { defaultProps, propTypes } from './editor-next/utils/editorPropTypes';
15
15
  import trackEditorActions from './editor-next/utils/trackEditorActions';
16
16
  import onEditorCreated from './editor-next/utils/onEditorCreated';
17
17
  import deprecationWarnings from './editor-next/utils/deprecationWarnings';
18
+ import { createFeatureFlagsFromProps } from './create-editor/feature-flags-from-props';
18
19
  import { fireAnalyticsEvent } from '@atlaskit/editor-common/analytics';
19
20
  import prepareQuickInsertProvider from './utils/prepare-quick-insert-provider';
20
21
  import prepareExtensionProvider from './utils/prepare-extension-provider';
@@ -46,6 +47,9 @@ export default class Editor extends React.Component {
46
47
  return (_this$props$onSave = (_this$props = this.props).onSave) === null || _this$props$onSave === void 0 ? void 0 : _this$props$onSave.call(_this$props, view);
47
48
  });
48
49
  _defineProperty(this, "handleAnalyticsEvent", data => fireAnalyticsEvent(this.createAnalyticsEvent)(data));
50
+ _defineProperty(this, "getFeatureFlags", () => {
51
+ return createFeatureFlagsFromProps(this.props);
52
+ });
49
53
  _defineProperty(this, "getExperienceStore", () => this.experienceStore);
50
54
  this.providerFactory = new ProviderFactory();
51
55
  deprecationWarnings(props);
@@ -213,9 +217,8 @@ export default class Editor extends React.Component {
213
217
  * and need to find a workaround.
214
218
  */
215
219
  registerEditorForActions(editorView, eventDispatcher, contentTransformer) {
216
- this.editorActions._privateRegisterEditor(editorView, eventDispatcher, contentTransformer);
220
+ this.editorActions._privateRegisterEditor(editorView, eventDispatcher, contentTransformer, this.getFeatureFlags);
217
221
  }
218
-
219
222
  /**
220
223
  * @private
221
224
  * @deprecated - Do not override this at all, this is an antipattern.
@@ -1 +1 @@
1
- export { addAltText, toggleBold, toggleItalic, toggleUnderline, toggleStrikethrough, toggleSubscript, toggleSuperscript, toggleCode, pastePlainText, clearFormatting, setNormalText, toggleHeading1, toggleHeading2, toggleHeading3, toggleHeading4, toggleHeading5, toggleHeading6, toggleOrderedList, ctrlBackSpace, toggleBulletList, toggleBlockQuote, insertNewLine, shiftBackspace, splitCodeBlock, splitListItem, insertRule, undo, moveUp, moveDown, moveLeft, moveRight, indentList, outdentList, redo, openHelp, addLink, addInlineComment, submit, enter, shiftEnter, tab, indent, outdent, backspace, deleteKey, forwardDelete, space, escape, nextCell, previousCell, shiftTab, toggleTable, addRowBefore, addRowAfter, addColumnAfter, addColumnBefore, cut, copy, paste, altPaste, find, alignLeft, tooltip, ToolTipContent, findKeymapByDescription, findShortcutByDescription, findShortcutByKeymap, makeKeymap, makeKeyMapWithCommon, bindKeymapWithCommand, findKeyMapForBrowser, DOWN, HEADING_KEYS, KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, LEFT, RIGHT, UP } from '@atlaskit/editor-common/keymaps';
1
+ export { addAltText, navToEditorToolbar, navToFloatingToolbar, toggleBold, toggleItalic, toggleUnderline, toggleStrikethrough, toggleSubscript, toggleSuperscript, toggleCode, pastePlainText, clearFormatting, setNormalText, toggleHeading1, toggleHeading2, toggleHeading3, toggleHeading4, toggleHeading5, toggleHeading6, toggleOrderedList, ctrlBackSpace, toggleBulletList, toggleBlockQuote, insertNewLine, shiftBackspace, splitCodeBlock, splitListItem, insertRule, undo, moveUp, moveDown, moveLeft, moveRight, indentList, outdentList, redo, openHelp, addLink, addInlineComment, submit, enter, shiftEnter, tab, indent, outdent, backspace, deleteKey, forwardDelete, space, escape, nextCell, previousCell, shiftTab, toggleTable, addRowBefore, addRowAfter, addColumnAfter, addColumnBefore, cut, copy, paste, altPaste, find, alignLeft, tooltip, ToolTipContent, findKeymapByDescription, findShortcutByDescription, findShortcutByKeymap, makeKeymap, makeKeyMapWithCommon, bindKeymapWithCommand, findKeyMapForBrowser, DOWN, HEADING_KEYS, KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, LEFT, RIGHT, UP } from '@atlaskit/editor-common/keymaps';
@@ -3,8 +3,7 @@ import { measureRender, getResponseEndTime, startMeasure, stopMeasure } from '@a
3
3
  import measurements from '../../../../../utils/performance/measure-enum';
4
4
  import { getNodesCount } from '../../../../../utils';
5
5
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE, PLATFORMS } from '../../../../../plugins/analytics';
6
- import { getEnabledFeatureFlagKeys } from '../../../../../plugins/feature-flags-context/get-enabled-feature-flag-keys';
7
- import { getFeatureFlags } from '../../../../../plugins/feature-flags-context/';
6
+ import { getEnabledFeatureFlagKeys } from '@atlaskit/editor-common/normalize-feature-flags';
8
7
  import { useAnalyticsHandler } from '../use-analytics';
9
8
  import { createDispatchTransaction } from './create-dispatch-transaction';
10
9
  import { createEditor } from './create-editor';
@@ -13,7 +12,7 @@ export function useEditor(config) {
13
12
  startMeasure(measurements.EDITOR_MOUNTED);
14
13
  const [editorSharedConfig, mountEditor] = useCreateEditor(config);
15
14
  useApplyEditorViewProps(editorSharedConfig, config.disabled);
16
- useHandleEditorLifecycle(editorSharedConfig);
15
+ useHandleEditorLifecycle(editorSharedConfig, config.featureFlags);
17
16
  useAnalyticsHandler(editorSharedConfig);
18
17
  return [editorSharedConfig, mountEditor];
19
18
  }
@@ -109,7 +108,7 @@ function useApplyEditorViewProps(editorSharedConfig, disabled) {
109
108
  /**
110
109
  * Handles editor component unmount
111
110
  */
112
- export function useHandleEditorLifecycle(editorSharedConfig) {
111
+ export function useHandleEditorLifecycle(editorSharedConfig, featureFlags) {
113
112
  React.useEffect(() => {
114
113
  //#region Did mount
115
114
  if (editorSharedConfig) {
@@ -124,7 +123,6 @@ export function useHandleEditorLifecycle(editorSharedConfig) {
124
123
  if (onMount) {
125
124
  onMount(editorActions);
126
125
  }
127
- const featureFlags = getFeatureFlags(editorSharedConfig.editorView.state);
128
126
  const featureFlagsEnabled = featureFlags ? getEnabledFeatureFlagKeys(featureFlags) : [];
129
127
 
130
128
  // Fire editor started event
@@ -177,5 +175,5 @@ export function useHandleEditorLifecycle(editorSharedConfig) {
177
175
  editorView.destroy();
178
176
  }
179
177
  };
180
- }, [editorSharedConfig]);
178
+ }, [editorSharedConfig, featureFlags]);
181
179
  }
@@ -12,7 +12,6 @@ import editorDisabledPlugin from '../../../plugins/editor-disabled';
12
12
  import typeAheadPlugin from '../../../plugins/type-ahead';
13
13
  import submitEditorPlugin from '../../../plugins/submit-editor';
14
14
  import fakeTextCursorPlugin from '../../../plugins/fake-text-cursor';
15
- import featureFlagsContextPlugin from '../../../plugins/feature-flags-context';
16
15
  import featureFlagsPlugin from '@atlaskit/editor-plugin-feature-flags';
17
16
  import floatingToolbarPlugin from '../../../plugins/floating-toolbar';
18
17
  import clipboardPlugin from '../../../plugins/clipboard';
@@ -44,7 +43,7 @@ export function createDefaultPreset(options) {
44
43
  return builder;
45
44
  }).add([hyperlinkPlugin, options.hyperlinkOptions]).add([textFormattingPlugin, options.textFormatting]).add(widthPlugin).add([quickInsertPlugin, options.quickInsert]).add([typeAheadPlugin, options.typeAhead || {
46
45
  createAnalyticsEvent: options.createAnalyticsEvent
47
- }]).add(unsupportedContentPlugin).add(editorDisabledPlugin).add([submitEditorPlugin, options.submitEditor]).add(fakeTextCursorPlugin).add(floatingToolbarPlugin).add([featureFlagsContextPlugin, options.featureFlags || {}]).add([selectionPlugin, options.selection]).add([codeBlockPlugin, options.codeBlock || {
46
+ }]).add(unsupportedContentPlugin).add(editorDisabledPlugin).add([submitEditorPlugin, options.submitEditor]).add(fakeTextCursorPlugin).add(floatingToolbarPlugin).add([selectionPlugin, options.selection]).add([codeBlockPlugin, options.codeBlock || {
48
47
  appearance: 'full-page'
49
48
  }]);
50
49
  return preset;
@@ -1,9 +1,10 @@
1
- import React from 'react';
1
+ import React, { Fragment } from 'react';
2
2
  import { inlineCard, blockCard, embedCard } from '@atlaskit/adf-schema';
3
3
  import { createPlugin } from './pm-plugins/main';
4
4
  import { floatingToolbar } from './toolbar';
5
5
  import { EditorSmartCardEvents } from './ui/EditorSmartCardEvents';
6
6
  import { cardKeymap } from './pm-plugins/keymap';
7
+ import { EditorSmartCardEventsNext } from './ui/EditorSmartCardEventsNext';
7
8
  const cardPlugin = (options, api) => {
8
9
  var _api$dependencies, _api$dependencies$fea;
9
10
  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()) || {};
@@ -26,17 +27,21 @@ const cardPlugin = (options, api) => {
26
27
  return nodes;
27
28
  },
28
29
  pmPlugins() {
29
- var _options$allowBlockCa, _options$allowResizin, _options$useAlternati;
30
+ var _options$allowBlockCa, _options$allowResizin, _options$useAlternati, _options$allowWrappin, _options$allowAlignme;
30
31
  const allowBlockCards = (_options$allowBlockCa = options.allowBlockCards) !== null && _options$allowBlockCa !== void 0 ? _options$allowBlockCa : true;
31
32
  const allowResizing = (_options$allowResizin = options.allowResizing) !== null && _options$allowResizin !== void 0 ? _options$allowResizin : true;
32
33
  const useAlternativePreloader = (_options$useAlternati = options.useAlternativePreloader) !== null && _options$useAlternati !== void 0 ? _options$useAlternati : true;
34
+ const allowWrapping = (_options$allowWrappin = options.allowWrapping) !== null && _options$allowWrappin !== void 0 ? _options$allowWrappin : true;
35
+ const allowAlignment = (_options$allowAlignme = options.allowAlignment) !== null && _options$allowAlignme !== void 0 ? _options$allowAlignme : true;
33
36
  const plugins = [{
34
37
  name: 'card',
35
38
  plugin: createPlugin({
36
39
  ...options,
37
40
  allowBlockCards,
38
41
  allowResizing,
39
- useAlternativePreloader
42
+ useAlternativePreloader,
43
+ allowWrapping,
44
+ allowAlignment
40
45
  })
41
46
  }];
42
47
  plugins.push({
@@ -52,9 +57,14 @@ const cardPlugin = (options, api) => {
52
57
  contentComponent({
53
58
  editorView
54
59
  }) {
55
- return /*#__PURE__*/React.createElement(EditorSmartCardEvents, {
60
+ const {
61
+ lpAnalyticsEventsNext
62
+ } = featureFlags;
63
+ return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(EditorSmartCardEvents, {
56
64
  editorView: editorView
57
- });
65
+ }), lpAnalyticsEventsNext && /*#__PURE__*/React.createElement(EditorSmartCardEventsNext, {
66
+ editorView: editorView
67
+ }));
58
68
  },
59
69
  pluginsOptions: {
60
70
  floatingToolbar: floatingToolbar(options, featureFlags, options.platform, options.linkPicker)
@@ -18,6 +18,10 @@ export const registerSmartCardEvents = smartLinkEvents => tr => cardAction(tr, {
18
18
  type: 'REGISTER_EVENTS',
19
19
  smartLinkEvents
20
20
  });
21
+ export const registerSmartCardEventsNext = smartLinkEvents => tr => cardAction(tr, {
22
+ type: 'REGISTER_EVENTS_NEXT',
23
+ smartLinkEvents
24
+ });
21
25
  export const setProvider = cardProvider => tr => cardAction(tr, {
22
26
  type: 'SET_PROVIDER',
23
27
  provider: cardProvider
@@ -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,316 @@
1
+ import { AddMarkStep, RemoveMarkStep } from 'prosemirror-transform';
2
+ import { ACTION } from '@atlaskit/editor-common/analytics';
3
+ import { isLinkMark } from '@atlaskit/editor-common/utils';
4
+ import { getLinkMetadataFromTransaction } from '@atlaskit/editor-common/card';
5
+ import { LinkMetaStep } from '@atlaskit/adf-schema/steps';
6
+ import { pmHistoryPluginKey } from '../../../history/pm-history-types';
7
+ import { getPluginState } from '../util/state';
8
+ import { pluginKey } from '../plugin-key';
9
+ import { isLink, linkObjectFromNode, getLinkUrl, appearanceForLink, findLinksAtPositions } from './utils';
10
+ const findLinksInNodeRange = (node, schema, from, to) => {
11
+ const links = [];
12
+ node.nodesBetween(from, to, (node, pos) => {
13
+ if (isLink(schema, node)) {
14
+ const entireLinkInRange = pos >= from && pos + node.nodeSize <= to;
15
+ if (entireLinkInRange) {
16
+ const link = linkObjectFromNode(schema, node, pos);
17
+ if (link) {
18
+ links.push(link);
19
+ }
20
+ }
21
+ }
22
+ });
23
+ return links;
24
+ };
25
+ export const findChangedLinks = (tr, state) => {
26
+ const schema = tr.doc.type.schema;
27
+ const removed = [];
28
+ const inserted = [];
29
+ const updated = [];
30
+ const queuedForUpgrade = isTransactionQueuedForUpgrade(tr);
31
+ const isResolveReplace = isTransactionResolveReplace(tr);
32
+
33
+ // History
34
+ const historyMeta = tr.getMeta(pmHistoryPluginKey);
35
+ const isUndo = isHistoryMeta(historyMeta) && historyMeta.redo === false;
36
+ const isRedo = isHistoryMeta(historyMeta) && historyMeta.redo === true;
37
+ const isUpdate = isUpdateTr(tr, isUndo || isRedo);
38
+ for (let i = 0; i < tr.steps.length; i++) {
39
+ const step = tr.steps[i];
40
+ const stepMap = step.getMap();
41
+ const removedInStep = [];
42
+ const insertedInStep = [];
43
+
44
+ /**
45
+ * AddMarkStep and RemoveMarkSteps don't produce stepMap ranges
46
+ * because there are no "changed tokens" only marks added/removed
47
+ * So have to check these manually
48
+ */
49
+ if (step instanceof AddMarkStep) {
50
+ const addMarkStep = step;
51
+ if (isLinkMark(addMarkStep.mark, schema)) {
52
+ /**
53
+ * For url text pasted on plain text
54
+ */
55
+ insertedInStep.push({
56
+ type: 'mark',
57
+ pos: addMarkStep.from,
58
+ mark: addMarkStep.mark
59
+ });
60
+ }
61
+ }
62
+ if (step instanceof RemoveMarkStep) {
63
+ const removeMarkStep = step;
64
+ if (isLinkMark(removeMarkStep.mark, schema)) {
65
+ /**
66
+ * For url text pasted on plain text
67
+ */
68
+ removedInStep.push({
69
+ type: 'mark',
70
+ pos: removeMarkStep.from,
71
+ mark: removeMarkStep.mark
72
+ });
73
+ }
74
+ }
75
+ stepMap.forEach((oldStart, oldEnd, newStart, newEnd) => {
76
+ var _tr$docs;
77
+ const before = tr.docs[i];
78
+ const after = (_tr$docs = tr.docs[i + 1]) !== null && _tr$docs !== void 0 ? _tr$docs : tr.doc;
79
+ const removedInRange = [];
80
+ const insertedInRange = [];
81
+
82
+ // Removed
83
+ removedInRange.push(...findLinksInNodeRange(before, schema, oldStart, oldEnd));
84
+ // Inserted
85
+ insertedInRange.push(...findLinksInNodeRange(after, schema, newStart, newEnd));
86
+ removedInStep.push(...removedInRange);
87
+ insertedInStep.push(...insertedInRange);
88
+ });
89
+ const omitQueuedLinks = links => {
90
+ if (!queuedForUpgrade) {
91
+ return links;
92
+ }
93
+ /**
94
+ * Skip/filter out links that have been queued, they will be tracked later
95
+ */
96
+ const queuedPositions = getQueuedPositions(tr);
97
+ return links.filter(link => !queuedPositions.includes(link.pos));
98
+ };
99
+
100
+ /**
101
+ * Skip "deletions" when the transaction is relating to
102
+ * replacing links queued for upgrade to cards,
103
+ * because the "deleted" link has not actually been
104
+ * tracked as "created" yet
105
+ */
106
+ if (!isResolveReplace) {
107
+ removed.push(...removedInStep);
108
+ }
109
+ inserted.push(...omitQueuedLinks(insertedInStep));
110
+ }
111
+
112
+ /**
113
+ * If there are no links changed but the transaction is a "resolve" action
114
+ * Then this means we have resolved a link but it has failed to upgrade
115
+ * We should track all resolved links as now being created
116
+ */
117
+ if (inserted.length === 0 && isResolveReplace) {
118
+ const positions = getResolvePositions(tr, state);
119
+ inserted.push(...findLinksAtPositions(tr, positions));
120
+ }
121
+ if (!isUpdate) {
122
+ return {
123
+ removed,
124
+ inserted,
125
+ updated
126
+ };
127
+ }
128
+ for (let i = 0; i < inserted.length; i++) {
129
+ if (isResolveReplace) {
130
+ const newLink = inserted[i];
131
+
132
+ // what is the 2nd argument 'assoc = -1' doing here exactly?
133
+ const mappedPos = tr.mapping.map(newLink.pos, -1);
134
+ const previousDisplay = getResolveLinkPrevDisplay(state, mappedPos);
135
+ updated.push({
136
+ inserted: inserted[i],
137
+ previous: {
138
+ display: previousDisplay
139
+ }
140
+ });
141
+ continue;
142
+ }
143
+ if (inserted.length === removed.length) {
144
+ updated.push({
145
+ removed: removed[i],
146
+ inserted: inserted[i]
147
+ });
148
+ }
149
+ }
150
+ return {
151
+ inserted: [],
152
+ removed: [],
153
+ updated
154
+ };
155
+ };
156
+
157
+ /**
158
+ * List of actions to be considered link "updates"
159
+ */
160
+ const UPDATE_ACTIONS = [ACTION.CHANGED_TYPE, ACTION.UPDATED];
161
+
162
+ /**
163
+ * Returns true if the transaction has LinkMetaSteps that indicate the transaction is
164
+ * intended to be perceived as an update to links, rather than insertion+deletion
165
+ */
166
+ const isUpdateTr = (tr, isUndoOrRedo) => {
167
+ return !!tr.steps.find(step => {
168
+ if (!(step instanceof LinkMetaStep)) {
169
+ return false;
170
+ }
171
+ const {
172
+ action,
173
+ cardAction
174
+ } = step.getMetadata();
175
+
176
+ /**
177
+ * Undo of a resolve step should be considered an update
178
+ * because the user is choosing to update the url back to the un-upgraded display
179
+ */
180
+ if (cardAction === 'RESOLVE' && isUndoOrRedo) {
181
+ return true;
182
+ }
183
+ if (!action) {
184
+ return false;
185
+ }
186
+ return UPDATE_ACTIONS.includes(action);
187
+ });
188
+ };
189
+ const hasType = pluginMeta => {
190
+ return typeof pluginMeta === 'object' && pluginMeta !== null && 'type' in pluginMeta;
191
+ };
192
+ const isTransactionQueuedForUpgrade = tr => {
193
+ const pluginMeta = tr.getMeta(pluginKey);
194
+ return hasType(pluginMeta) && pluginMeta.type === 'QUEUE';
195
+ };
196
+ const isTransactionResolveReplace = tr => {
197
+ const pluginMeta = tr.getMeta(pluginKey);
198
+ return hasType(pluginMeta) && pluginMeta.type === 'RESOLVE';
199
+ };
200
+ const isHistoryMeta = meta => {
201
+ return typeof meta === 'object' && meta !== null && 'redo' in meta;
202
+ };
203
+ const getQueuedPositions = tr => {
204
+ const pluginMeta = tr.getMeta(pluginKey);
205
+ if (!isTransactionQueuedForUpgrade(tr)) {
206
+ return [];
207
+ }
208
+ return pluginMeta.requests.map(({
209
+ pos
210
+ }) => pos);
211
+ };
212
+ const getResolvePositions = (tr, state) => {
213
+ const cardState = getPluginState(state);
214
+ if (!cardState) {
215
+ return [];
216
+ }
217
+ const pluginMeta = tr.getMeta(pluginKey);
218
+ if (!isTransactionResolveReplace(tr)) {
219
+ return [];
220
+ }
221
+ return cardState.requests.filter(request => request.url === pluginMeta.url).map(request => request.pos);
222
+ };
223
+ const getResolveLinkPrevDisplay = (state, pos) => {
224
+ var _cardState$requests$f;
225
+ const cardState = getPluginState(state);
226
+ if (!cardState) {
227
+ return undefined;
228
+ }
229
+ return (_cardState$requests$f = cardState.requests.find(request => request.pos === pos)) === null || _cardState$requests$f === void 0 ? void 0 : _cardState$requests$f.previousAppearance;
230
+ };
231
+ export function eventsFromTransaction(tr, state) {
232
+ const events = [];
233
+ try {
234
+ /**
235
+ * Skip transactions sent by collab (identified by 'isRemote' key)
236
+ * Skip entire document replace steps
237
+ * We are only concerned with transactions performed on the document directly by the user
238
+ */
239
+ const isRemote = tr.getMeta('isRemote');
240
+ const isReplaceDocument = tr.getMeta('replaceDocument');
241
+ if (isRemote || isReplaceDocument) {
242
+ return events;
243
+ }
244
+ const historyMeta = tr.getMeta(pmHistoryPluginKey);
245
+ const isUndo = isHistoryMeta(historyMeta) && historyMeta.redo === false;
246
+ const isRedo = isHistoryMeta(historyMeta) && historyMeta.redo === true;
247
+
248
+ /**
249
+ * Retrieve metadata from the LinkMetaStep(s) in the transaction
250
+ */
251
+ const {
252
+ action,
253
+ inputMethod,
254
+ sourceEvent
255
+ } = getLinkMetadataFromTransaction(tr);
256
+ const contextualData = {
257
+ action,
258
+ inputMethod,
259
+ sourceEvent,
260
+ isUndo,
261
+ isRedo
262
+ };
263
+ const {
264
+ removed,
265
+ inserted,
266
+ updated
267
+ } = findChangedLinks(tr, state);
268
+ const MAX_LINK_EVENTS = 10;
269
+ if ([removed, inserted, updated].some(arr => arr.length > MAX_LINK_EVENTS)) {
270
+ return [];
271
+ }
272
+ for (let i = 0; i < updated.length; i++) {
273
+ var _update$previous$disp;
274
+ const update = updated[i];
275
+ const {
276
+ inserted: link
277
+ } = update;
278
+ const url = getLinkUrl(link);
279
+ const display = appearanceForLink(link);
280
+ const previousDisplay = 'removed' in update ? appearanceForLink(update.removed) : (_update$previous$disp = update.previous.display) !== null && _update$previous$disp !== void 0 ? _update$previous$disp : 'unknown';
281
+ if (url) {
282
+ events.push({
283
+ type: 'updated',
284
+ data: {
285
+ ...contextualData,
286
+ url,
287
+ display,
288
+ previousDisplay
289
+ }
290
+ });
291
+ }
292
+ }
293
+ const pushEvents = (links, type) => {
294
+ for (let i = 0; i < links.length; i++) {
295
+ const link = links[i];
296
+ const url = getLinkUrl(link);
297
+ const display = appearanceForLink(link);
298
+ if (url) {
299
+ events.push({
300
+ type,
301
+ data: {
302
+ ...contextualData,
303
+ url,
304
+ display
305
+ }
306
+ });
307
+ }
308
+ }
309
+ };
310
+ pushEvents(removed, 'deleted');
311
+ pushEvents(inserted, 'created');
312
+ return events;
313
+ } catch (err) {
314
+ return events;
315
+ }
316
+ }
@@ -0,0 +1,2 @@
1
+ export { createAnalyticsQueue } from './create-analytics-queue';
2
+ export { eventsFromTransaction } from './events-from-tr';
@@ -0,0 +1,124 @@
1
+ import { isLinkMark } from '@atlaskit/editor-common/utils';
2
+ import { appearanceForNodeType } from '../../utils';
3
+ /**
4
+ * Whether a node is a "link" node, ie inline card, block card, embed card
5
+ * (but not a text node with a link mark)
6
+ */
7
+ export function isLinkNode(node) {
8
+ return !!appearanceForNodeType(node.type);
9
+ }
10
+
11
+ /**
12
+ * Analytics appearance for link object
13
+ */
14
+ export function appearanceForLink(link) {
15
+ if (link.type === 'node') {
16
+ const appearance = appearanceForNodeType(link.node.type);
17
+ if (appearance) {
18
+ return appearance;
19
+ }
20
+ }
21
+ return 'url';
22
+ }
23
+ const nodeHasLinkMark = (schema, node) => {
24
+ if (node.marks) {
25
+ for (let i = 0; i < node.marks.length; i++) {
26
+ const mark = node.marks[i];
27
+ if (isLinkMark(mark, schema)) {
28
+ return true;
29
+ }
30
+ }
31
+ }
32
+ return false;
33
+ };
34
+
35
+ /**
36
+ * Determine if a node is considered to be a link
37
+ */
38
+ export const isLink = (schema, node) => {
39
+ if (isLinkNode(node)) {
40
+ return true;
41
+ }
42
+ return nodeHasLinkMark(schema, node);
43
+ };
44
+
45
+ /**
46
+ * Given a node, find all nodes and marks that are considered "links"
47
+ * @param state EditorState
48
+ * @param fragment Fragment to search
49
+ * @returns Array of nodes and marks found in the fragment that are "links"
50
+ */
51
+ export function findLinksInNode(schema, node, offset) {
52
+ const links = [];
53
+ node.descendants((node, pos) => {
54
+ // Nodes
55
+ if (isLinkNode(node)) {
56
+ links.push({
57
+ type: 'node',
58
+ pos: pos + offset,
59
+ node
60
+ });
61
+ }
62
+
63
+ // Marks
64
+ if (node.marks) {
65
+ for (let i = 0; i < node.marks.length; i++) {
66
+ const mark = node.marks[i];
67
+ if (isLinkMark(mark, schema)) {
68
+ links.push({
69
+ type: 'mark',
70
+ pos: pos + offset,
71
+ mark
72
+ });
73
+ }
74
+ }
75
+ }
76
+ });
77
+ return links;
78
+ }
79
+ export function getLinkUrl(link) {
80
+ var _link$mark$attrs;
81
+ if (link.type === 'node') {
82
+ var _link$node$attrs;
83
+ return (_link$node$attrs = link.node.attrs) === null || _link$node$attrs === void 0 ? void 0 : _link$node$attrs.url;
84
+ }
85
+ return (_link$mark$attrs = link.mark.attrs) === null || _link$mark$attrs === void 0 ? void 0 : _link$mark$attrs.href;
86
+ }
87
+ export const linkObjectFromNode = (schema, node, pos) => {
88
+ if (isLinkNode(node)) {
89
+ return {
90
+ type: 'node',
91
+ pos,
92
+ node
93
+ };
94
+ }
95
+ if (node.marks) {
96
+ for (let i = 0; i < node.marks.length; i++) {
97
+ const mark = node.marks[i];
98
+ if (isLinkMark(mark, schema)) {
99
+ return {
100
+ type: 'mark',
101
+ pos,
102
+ mark
103
+ };
104
+ }
105
+ }
106
+ }
107
+ };
108
+ export const findLinksAtPositions = (tr, positions) => {
109
+ const schema = tr.doc.type.schema;
110
+ const links = [];
111
+ for (let i = 0; i < positions.length; i++) {
112
+ const pos = positions[i];
113
+ const node = tr.doc.nodeAt(pos);
114
+ if (!node) {
115
+ continue;
116
+ }
117
+ const link = linkObjectFromNode(schema, node, pos);
118
+ if (!link) {
119
+ continue;
120
+ }
121
+ links.push(link);
122
+ }
123
+ return links;
124
+ };