@atlaskit/editor-common 88.6.1 → 88.7.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 (75) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/cjs/analytics/fire-analytics-event.js +2 -2
  3. package/dist/cjs/element-browser/components/CategoryList.js +2 -2
  4. package/dist/cjs/element-browser/components/ElementList/ElementList.js +2 -2
  5. package/dist/cjs/element-browser/components/ElementSearch.js +2 -2
  6. package/dist/cjs/element-browser/components/StatelessElementBrowser.js +4 -3
  7. package/dist/cjs/lazy-node-view/index.js +89 -11
  8. package/dist/cjs/lazy-node-view/node-view.js +27 -7
  9. package/dist/cjs/link/ConfigureLinkOverlay/Dropdown.js +2 -2
  10. package/dist/cjs/link/ConfigureLinkOverlay/index.js +2 -2
  11. package/dist/cjs/link/ConfigureLinkOverlay/useLinkOverlayAnalyticsEvents.js +6 -6
  12. package/dist/cjs/link/LinkPicker/EditorLinkPicker/index.js +2 -2
  13. package/dist/cjs/link/LinkPicker/HyperlinkAddToolbar/HyperlinkAddToolbar.js +2 -2
  14. package/dist/cjs/media-inline/media-inline-image-card.js +2 -2
  15. package/dist/cjs/monitoring/error.js +1 -1
  16. package/dist/cjs/ui/DropList/index.js +7 -5
  17. package/dist/cjs/ui/WithCreateAnalyticsEvent/index.js +2 -2
  18. package/dist/cjs/ui-menu/ColorPickerButton/index.js +4 -3
  19. package/dist/cjs/ui-menu/ToolbarButton/index.js +2 -2
  20. package/dist/es2019/analytics/fire-analytics-event.js +1 -1
  21. package/dist/es2019/element-browser/components/CategoryList.js +1 -1
  22. package/dist/es2019/element-browser/components/ElementList/ElementList.js +1 -1
  23. package/dist/es2019/element-browser/components/ElementSearch.js +1 -1
  24. package/dist/es2019/element-browser/components/StatelessElementBrowser.js +2 -1
  25. package/dist/es2019/lazy-node-view/index.js +81 -11
  26. package/dist/es2019/lazy-node-view/node-view.js +25 -6
  27. package/dist/es2019/link/ConfigureLinkOverlay/Dropdown.js +1 -1
  28. package/dist/es2019/link/ConfigureLinkOverlay/index.js +1 -1
  29. package/dist/es2019/link/ConfigureLinkOverlay/useLinkOverlayAnalyticsEvents.js +2 -2
  30. package/dist/es2019/link/LinkPicker/EditorLinkPicker/index.js +1 -1
  31. package/dist/es2019/link/LinkPicker/HyperlinkAddToolbar/HyperlinkAddToolbar.js +1 -1
  32. package/dist/es2019/media-inline/media-inline-image-card.js +1 -1
  33. package/dist/es2019/monitoring/error.js +1 -1
  34. package/dist/es2019/ui/DropList/index.js +4 -2
  35. package/dist/es2019/ui/WithCreateAnalyticsEvent/index.js +1 -1
  36. package/dist/es2019/ui-menu/ColorPickerButton/index.js +2 -1
  37. package/dist/es2019/ui-menu/ToolbarButton/index.js +1 -1
  38. package/dist/esm/analytics/fire-analytics-event.js +1 -1
  39. package/dist/esm/element-browser/components/CategoryList.js +1 -1
  40. package/dist/esm/element-browser/components/ElementList/ElementList.js +1 -1
  41. package/dist/esm/element-browser/components/ElementSearch.js +1 -1
  42. package/dist/esm/element-browser/components/StatelessElementBrowser.js +2 -1
  43. package/dist/esm/lazy-node-view/index.js +85 -11
  44. package/dist/esm/lazy-node-view/node-view.js +27 -7
  45. package/dist/esm/link/ConfigureLinkOverlay/Dropdown.js +1 -1
  46. package/dist/esm/link/ConfigureLinkOverlay/index.js +1 -1
  47. package/dist/esm/link/ConfigureLinkOverlay/useLinkOverlayAnalyticsEvents.js +2 -2
  48. package/dist/esm/link/LinkPicker/EditorLinkPicker/index.js +1 -1
  49. package/dist/esm/link/LinkPicker/HyperlinkAddToolbar/HyperlinkAddToolbar.js +1 -1
  50. package/dist/esm/media-inline/media-inline-image-card.js +1 -1
  51. package/dist/esm/monitoring/error.js +1 -1
  52. package/dist/esm/ui/DropList/index.js +4 -2
  53. package/dist/esm/ui/WithCreateAnalyticsEvent/index.js +1 -1
  54. package/dist/esm/ui-menu/ColorPickerButton/index.js +2 -1
  55. package/dist/esm/ui-menu/ToolbarButton/index.js +1 -1
  56. package/dist/types/analytics/fire-analytics-event.d.ts +1 -1
  57. package/dist/types/analytics/types/events.d.ts +1 -1
  58. package/dist/types/element-browser/components/ElementSearch.d.ts +1 -1
  59. package/dist/types/lazy-node-view/index.d.ts +18 -1
  60. package/dist/types/lazy-node-view/node-view.d.ts +4 -5
  61. package/dist/types/link/ConfigureLinkOverlay/Dropdown.d.ts +1 -1
  62. package/dist/types/link/ConfigureLinkOverlay/index.d.ts +1 -1
  63. package/dist/types-ts4.5/analytics/fire-analytics-event.d.ts +1 -1
  64. package/dist/types-ts4.5/analytics/types/events.d.ts +1 -1
  65. package/dist/types-ts4.5/element-browser/components/ElementSearch.d.ts +1 -1
  66. package/dist/types-ts4.5/lazy-node-view/index.d.ts +18 -1
  67. package/dist/types-ts4.5/lazy-node-view/node-view.d.ts +4 -5
  68. package/dist/types-ts4.5/link/ConfigureLinkOverlay/Dropdown.d.ts +1 -1
  69. package/dist/types-ts4.5/link/ConfigureLinkOverlay/index.d.ts +1 -1
  70. package/package.json +1 -1
  71. package/dist/cjs/lazy-node-view/replace-node-views.js +0 -173
  72. package/dist/es2019/lazy-node-view/replace-node-views.js +0 -166
  73. package/dist/esm/lazy-node-view/replace-node-views.js +0 -166
  74. package/dist/types/lazy-node-view/replace-node-views.d.ts +0 -34
  75. package/dist/types-ts4.5/lazy-node-view/replace-node-views.d.ts +0 -34
@@ -1,6 +1,12 @@
1
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
1
2
  import { LazyNodeView } from './node-view';
2
- import { queueReplaceNodeViews } from './replace-node-views';
3
3
  export { convertToInlineCss } from './css-helper';
4
+ /**
5
+ * 📢 Public Plugin Key
6
+ *
7
+ * Communication channel between LazyNodeView loader and LazyNodeViewDecorationPlugin.
8
+ */
9
+ export const lazyNodeViewDecorationPluginKey = new PluginKey('lazyNodeViewDecoration');
4
10
 
5
11
  /**
6
12
  * 📢 Public Type
@@ -14,6 +20,12 @@ export { convertToInlineCss } from './css-helper';
14
20
  * @see {withLazyLoading}
15
21
  */
16
22
 
23
+ /**
24
+ * 🧱 Internal: Editor FE Platform
25
+ *
26
+ * Caches loaded node view factory functions
27
+ */
28
+
17
29
  /**
18
30
  * 🧱 Internal: Editor FE Platform
19
31
  *
@@ -21,6 +33,33 @@ export { convertToInlineCss } from './css-helper';
21
33
  */
22
34
  const requestedNodesPerEditorView = new WeakMap();
23
35
 
36
+ /**
37
+ * 🧱 Internal: Editor FE Platform
38
+ *
39
+ * Caches loaded node view factory functions for each editor view
40
+ */
41
+ const resolvedNodesPerEditorView = new WeakMap();
42
+
43
+ /**
44
+ * 🧱 Internal: Editor FE Platform
45
+ *
46
+ * Stores editorView -> raf to debounce NodeView updates.
47
+ */
48
+ const debounceToEditorViewMap = new WeakMap();
49
+ const testOnlyIgnoreLazyNodeViewSet = new WeakSet();
50
+ /**
51
+ * 🧱 Internal: Editor FE Platform
52
+ *
53
+ * Used in tests to prevent lazy node view being replaced by a real node view.
54
+ *
55
+ * This needs to be replaced with proper implementation once LazyNodeView is converted to a plugin.
56
+ *
57
+ * @deprecated DO NOT USE THIS OUSIDE TESTS.
58
+ */
59
+ export function testOnlyIgnoreLazyNodeView(view) {
60
+ testOnlyIgnoreLazyNodeViewSet.add(view);
61
+ }
62
+
24
63
  /**
25
64
  * 📢 Public: Any EditorPlugin can use this function
26
65
  *
@@ -64,29 +103,60 @@ const requestedNodesPerEditorView = new WeakMap();
64
103
  export const withLazyLoading = ({
65
104
  nodeName,
66
105
  loader,
67
- getNodeViewOptions,
68
- dispatchAnalyticsEvent
106
+ getNodeViewOptions
69
107
  }) => {
70
108
  const createLazyNodeView = (node, view, getPos, decorations) => {
71
109
  var _node$type, _node$type$spec;
72
110
  let requestedNodes = requestedNodesPerEditorView.get(view);
73
111
  if (!requestedNodes) {
74
- requestedNodes = new Set(), requestedNodesPerEditorView.set(view, requestedNodes);
112
+ requestedNodes = new Map();
113
+ requestedNodesPerEditorView.set(view, requestedNodes);
114
+ }
115
+ const resolvedNodeViews = resolvedNodesPerEditorView.get(view);
116
+ if (!resolvedNodeViews) {
117
+ resolvedNodesPerEditorView.set(view, new Map());
75
118
  }
76
119
  const wasAlreadyRequested = requestedNodes.has(nodeName);
77
120
  if (wasAlreadyRequested) {
78
- return new LazyNodeView(node, view, getPos);
121
+ const resolvedNodeView = resolvedNodeViews === null || resolvedNodeViews === void 0 ? void 0 : resolvedNodeViews.get(nodeName);
122
+ if (resolvedNodeView && !testOnlyIgnoreLazyNodeViewSet.has(view)) {
123
+ return resolvedNodeView(node, view, getPos, decorations);
124
+ }
125
+ return new LazyNodeView(node, view, getPos, requestedNodes.get(nodeName));
79
126
  }
80
- requestedNodes.add(nodeName);
81
- loader().then(nodeViewFuncModule => {
127
+ const loaderPromise = loader().then(nodeViewFuncModule => {
128
+ var _resolvedNodesPerEdit;
82
129
  const nodeViewFunc = (node, view, getPos, decorations) => {
83
130
  return nodeViewFuncModule(node, view, getPos, decorations, getNodeViewOptions);
84
131
  };
85
- queueReplaceNodeViews(view, {
86
- nodeName,
87
- nodeViewFunc
132
+ (_resolvedNodesPerEdit = resolvedNodesPerEditorView.get(view)) === null || _resolvedNodesPerEdit === void 0 ? void 0 : _resolvedNodesPerEdit.set(nodeName, nodeViewFunc);
133
+
134
+ /**
135
+ * Triggering lazyNodeViewDecoration plugin to apply decorations
136
+ * to nodes with newly loaded NodeViews.
137
+ */
138
+ const [raf, nodeTypes] = debounceToEditorViewMap.get(view) || [null, new Set()];
139
+ if (raf) {
140
+ cancelAnimationFrame(raf);
141
+ }
142
+ nodeTypes.add(node.type.name);
143
+ const nextRaf = requestAnimationFrame(() => {
144
+ debounceToEditorViewMap.set(view, [null, new Set()]);
145
+ const tr = view.state.tr;
146
+ tr.setMeta(lazyNodeViewDecorationPluginKey, {
147
+ type: 'add',
148
+ nodeTypes
149
+ });
150
+ view.dispatch(tr);
88
151
  });
152
+ debounceToEditorViewMap.set(view, [nextRaf, nodeTypes]);
153
+ /**
154
+ * END triggering LazyNodeViewDecoration plugin
155
+ */
156
+
157
+ return nodeViewFunc;
89
158
  });
159
+ requestedNodes.set(nodeName, loaderPromise);
90
160
  if (typeof ((_node$type = node.type) === null || _node$type === void 0 ? void 0 : (_node$type$spec = _node$type.spec) === null || _node$type$spec === void 0 ? void 0 : _node$type$spec.toDOM) !== 'function') {
91
161
  // TODO: Analytics ED-23982
92
162
  // dispatchAnalyticsEvent({
@@ -99,7 +169,7 @@ export const withLazyLoading = ({
99
169
  // },
100
170
  // });
101
171
  }
102
- return new LazyNodeView(node, view, getPos);
172
+ return new LazyNodeView(node, view, getPos, loaderPromise);
103
173
  };
104
174
  return createLazyNodeView;
105
175
  };
@@ -1,3 +1,4 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
1
2
  import memoize from 'lodash/memoize';
2
3
  import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
3
4
  const getEditorLineWidth = memoize(view => {
@@ -11,17 +12,32 @@ const getEditorLineWidth = memoize(view => {
11
12
  * A NodeView that serves as a placeholder until the actual NodeView is loaded.
12
13
  */
13
14
  export class LazyNodeView {
14
- constructor(node, view, getPos) {
15
+ constructor(_node, view, _getPos, nodeViewLoader) {
15
16
  var _node$type, _node$type$spec;
16
- this.node = node;
17
- if (typeof ((_node$type = node.type) === null || _node$type === void 0 ? void 0 : (_node$type$spec = _node$type.spec) === null || _node$type$spec === void 0 ? void 0 : _node$type$spec.toDOM) !== 'function') {
17
+ _defineProperty(this, "update", node => {
18
+ const prevNode = this.node;
19
+ this.node = node;
20
+
21
+ // Forcing NodeView to be re-created
22
+ // so that ProseMirror can replace LazyNodeView with the real one.
23
+ if (this.isNodeViewLoaded) {
24
+ return false;
25
+ }
26
+
27
+ // Copying some of the default NodeView update behaviour
28
+ // https://github.com/ProseMirror/prosemirror-view/blob/cfa73eb969777f63bcb39972594fd4a9110f5a93/src/viewdesc.ts#L803
29
+ return !this.node.sameMarkup(prevNode);
30
+ });
31
+ this.node = _node;
32
+ this.isNodeViewLoaded = false;
33
+ if (typeof ((_node$type = _node.type) === null || _node$type === void 0 ? void 0 : (_node$type$spec = _node$type.spec) === null || _node$type$spec === void 0 ? void 0 : _node$type$spec.toDOM) !== 'function') {
18
34
  this.dom = document.createElement('div');
19
35
  return;
20
36
  }
21
37
  const toDOMConfiguration = {
22
38
  editorLineWidth: getEditorLineWidth(view)
23
39
  };
24
- const fallback = DOMSerializer.renderSpec(document, node.type.spec.toDOM(node,
40
+ const fallback = DOMSerializer.renderSpec(document, _node.type.spec.toDOM(_node,
25
41
  // We are injecting a second parameter to be used by the toDOM lazy node view implementations
26
42
  // @ts-expect-error
27
43
  toDOMConfiguration));
@@ -30,14 +46,17 @@ export class LazyNodeView {
30
46
  if (this.dom instanceof HTMLElement) {
31
47
  // This attribute is mostly used for debugging purposed
32
48
  // It will help us to found out when the node was replaced
33
- this.dom.setAttribute('data-lazy-node-view', node.type.name);
49
+ this.dom.setAttribute('data-lazy-node-view', _node.type.name);
34
50
  // This is used on Libra tests
35
51
  // We are using this to make sure all lazy noded were replaced
36
52
  // before the test started
37
53
  this.dom.setAttribute('data-lazy-node-view-fallback', 'true');
38
54
  }
55
+ nodeViewLoader.then(() => {
56
+ this.isNodeViewLoaded = true;
57
+ });
39
58
  }
40
- ignoreMutation(mutation) {
59
+ ignoreMutation() {
41
60
  if (this.node.type.isTextblock) {
42
61
  return false;
43
62
  }
@@ -8,7 +8,7 @@ import { useCallback } from 'react';
8
8
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
9
9
  import { jsx } from '@emotion/react';
10
10
  import { useIntl } from 'react-intl-next';
11
- import { withAnalyticsContext } from '@atlaskit/analytics-next';
11
+ import withAnalyticsContext from '@atlaskit/analytics-next/withAnalyticsContext';
12
12
  import DropdownMenu, { DropdownItem, DropdownItemGroup } from '@atlaskit/dropdown-menu';
13
13
  import ChevronDownIcon from '@atlaskit/icon/glyph/chevron-down';
14
14
  import PreferencesIcon from '@atlaskit/icon/glyph/preferences';
@@ -7,7 +7,7 @@ import { useCallback, useLayoutEffect, useState } from 'react';
7
7
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
8
8
  import { css, jsx } from '@emotion/react';
9
9
  import { useIntl } from 'react-intl-next';
10
- import { withAnalyticsContext } from '@atlaskit/analytics-next';
10
+ import withAnalyticsContext from '@atlaskit/analytics-next/withAnalyticsContext';
11
11
  import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
12
12
  import PreferencesIcon from '@atlaskit/icon/glyph/preferences';
13
13
  import { N0 } from '@atlaskit/theme/colors';
@@ -1,6 +1,6 @@
1
1
  import { useMemo } from 'react';
2
- import { FabricChannel } from '@atlaskit/analytics-listeners';
3
- import { useAnalyticsEvents } from '@atlaskit/analytics-next';
2
+ import { FabricChannel } from '@atlaskit/analytics-listeners/types';
3
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next/useAnalyticsEvents';
4
4
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '../../analytics';
5
5
  export const useLinkOverlayAnalyticsEvents = () => {
6
6
  const {
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import React, { useCallback, useEffect, useMemo, useRef } from 'react';
3
- import { AnalyticsContext } from '@atlaskit/analytics-next';
3
+ import AnalyticsContext from '@atlaskit/analytics-next/AnalyticsContext';
4
4
  import { LazyLinkPicker } from '@atlaskit/link-picker/lazy';
5
5
  import { getAnalyticsEditorAppearance } from '../../../utils';
6
6
  import { useEscapeClickaway } from './useEscapeClickaway';
@@ -12,7 +12,7 @@ import debounce from 'lodash/debounce';
12
12
  import { flushSync } from 'react-dom';
13
13
  import { defineMessages, injectIntl } from 'react-intl-next';
14
14
  import { isSafeUrl } from '@atlaskit/adf-schema';
15
- import { withAnalyticsEvents } from '@atlaskit/analytics-next';
15
+ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
16
16
  import Page16Icon from '@atlaskit/icon-object/glyph/page/16';
17
17
  import CrossCircleIcon from '@atlaskit/icon/glyph/cross-circle';
18
18
  import { Pressable, xcss } from '@atlaskit/primitives';
@@ -8,7 +8,7 @@ import { Fragment, useCallback, useEffect, useMemo, useState } from 'react';
8
8
  import { jsx } from '@emotion/react';
9
9
  import ReactDOM from 'react-dom';
10
10
  import { createIntl, injectIntl } from 'react-intl-next';
11
- import { useAnalyticsEvents } from '@atlaskit/analytics-next';
11
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next/useAnalyticsEvents';
12
12
  import { fireFailedMediaInlineEvent, fireSucceededMediaInlineEvent, MediaCardError } from '@atlaskit/media-card';
13
13
  import { FileFetcherError } from '@atlaskit/media-client';
14
14
  import { MediaClientContext } from '@atlaskit/media-client-react';
@@ -1,7 +1,7 @@
1
1
  import { isFedRamp } from './environment';
2
2
  const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
3
3
  const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
4
- const packageVersion = "88.6.1";
4
+ const packageVersion = "88.7.0";
5
5
  const sanitiseSentryEvents = (data, _hint) => {
6
6
  // Remove URL as it has UGC
7
7
  // TODO: Sanitise the URL instead of just removing it
@@ -8,11 +8,13 @@ import { Component } from 'react';
8
8
 
9
9
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
10
10
  import { css, jsx } from '@emotion/react';
11
- import { createAndFireEvent, withAnalyticsContext, withAnalyticsEvents } from '@atlaskit/analytics-next';
11
+ import createAndFireEvent from '@atlaskit/analytics-next/createAndFireEvents';
12
+ import withAnalyticsContext from '@atlaskit/analytics-next/withAnalyticsContext';
13
+ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
12
14
  import { N0, N50A, N60A, N900 } from '@atlaskit/theme/colors';
13
15
  import Layer from '../Layer';
14
16
  const packageName = "@atlaskit/editor-common";
15
- const packageVersion = "88.6.1";
17
+ const packageVersion = "88.7.0";
16
18
  const halfFocusRing = 1;
17
19
  const dropOffset = '0, 8';
18
20
  class DropList extends Component {
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { withAnalyticsEvents } from '@atlaskit/analytics-next';
2
+ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
3
3
  export const WithCreateAnalyticsEvent = withAnalyticsEvents()(class WithCreateAnalyticsEvent extends React.Component {
4
4
  render() {
5
5
  const {
@@ -6,7 +6,8 @@ import React from 'react';
6
6
 
7
7
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
8
8
  import { css, jsx } from '@emotion/react';
9
- import { withAnalyticsContext, withAnalyticsEvents } from '@atlaskit/analytics-next';
9
+ import withAnalyticsContext from '@atlaskit/analytics-next/withAnalyticsContext';
10
+ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
10
11
  import Button from '@atlaskit/button/standard-button';
11
12
  import ExpandIcon from '@atlaskit/icon/glyph/chevron-down';
12
13
  import { N0, N30A, N60A } from '@atlaskit/theme/colors';
@@ -8,7 +8,7 @@ import React, { useCallback } from 'react';
8
8
 
9
9
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
10
10
  import { css, jsx } from '@emotion/react';
11
- import { FabricChannel } from '@atlaskit/analytics-listeners';
11
+ import { FabricChannel } from '@atlaskit/analytics-listeners/types';
12
12
  import { fg } from '@atlaskit/platform-feature-flags';
13
13
  import Tooltip from '@atlaskit/tooltip';
14
14
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE, TOOLBAR_ACTION_SUBJECT_ID } from '../../analytics';
@@ -1,4 +1,4 @@
1
- import { FabricChannel } from '@atlaskit/analytics-listeners';
1
+ import { FabricChannel } from '@atlaskit/analytics-listeners/types';
2
2
  import { AnalyticsQueue } from './analytics-queue';
3
3
  export var editorAnalyticsChannel = FabricChannel.editor;
4
4
  export var fireAnalyticsEvent = function fireAnalyticsEvent(createAnalyticsEvent) {
@@ -13,7 +13,7 @@ import React, { Fragment, memo, useCallback } from 'react';
13
13
 
14
14
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
15
15
  import { css, jsx } from '@emotion/react';
16
- import { withAnalyticsContext } from '@atlaskit/analytics-next';
16
+ import withAnalyticsContext from '@atlaskit/analytics-next/withAnalyticsContext';
17
17
  import Button from '@atlaskit/button/custom-theme-button';
18
18
  import { B400, B50, N800 } from '@atlaskit/theme/colors';
19
19
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, fireAnalyticsEvent } from '../../analytics';
@@ -13,7 +13,7 @@ import { css, jsx } from '@emotion/react';
13
13
  import { Grid } from 'react-virtualized';
14
14
  import { AutoSizer } from 'react-virtualized/dist/commonjs/AutoSizer';
15
15
  import { CellMeasurer, CellMeasurerCache } from 'react-virtualized/dist/commonjs/CellMeasurer';
16
- import { withAnalyticsContext } from '@atlaskit/analytics-next';
16
+ import withAnalyticsContext from '@atlaskit/analytics-next/withAnalyticsContext';
17
17
  import { relativeFontSizeToBase16 } from '@atlaskit/editor-shared-styles';
18
18
  import { shortcutStyle } from '@atlaskit/editor-shared-styles/shortcut';
19
19
  import { ButtonItem } from '@atlaskit/menu';
@@ -8,7 +8,7 @@ import React, { memo, useLayoutEffect, useRef, useState } from 'react';
8
8
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
9
9
  import { css, jsx } from '@emotion/react';
10
10
  import { injectIntl } from 'react-intl-next';
11
- import { withAnalyticsContext } from '@atlaskit/analytics-next';
11
+ import withAnalyticsContext from '@atlaskit/analytics-next/withAnalyticsContext';
12
12
  import { relativeFontSizeToBase16 } from '@atlaskit/editor-shared-styles';
13
13
  import { shortcutStyle } from '@atlaskit/editor-shared-styles/shortcut';
14
14
  import SearchIcon from '@atlaskit/icon/glyph/search';
@@ -9,7 +9,8 @@ import React, { memo, useCallback, useEffect, useRef, useState } from 'react';
9
9
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
10
10
  import { css, jsx } from '@emotion/react';
11
11
  import { FormattedMessage } from 'react-intl-next';
12
- import { withAnalyticsContext, withAnalyticsEvents } from '@atlaskit/analytics-next';
12
+ import withAnalyticsContext from '@atlaskit/analytics-next/withAnalyticsContext';
13
+ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
13
14
  import { fg } from '@atlaskit/platform-feature-flags';
14
15
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE, fireAnalyticsEvent } from '../../analytics';
15
16
  import { DEVICE_BREAKPOINT_NUMBERS, ELEMENT_BROWSER_ID, GRID_SIZE, INLINE_SIDEBAR_HEIGHT, SIDEBAR_HEADING_WRAPPER_HEIGHT, SIDEBAR_WIDTH } from '../constants';
@@ -1,6 +1,13 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
1
3
  import { LazyNodeView } from './node-view';
2
- import { queueReplaceNodeViews } from './replace-node-views';
3
4
  export { convertToInlineCss } from './css-helper';
5
+ /**
6
+ * 📢 Public Plugin Key
7
+ *
8
+ * Communication channel between LazyNodeView loader and LazyNodeViewDecorationPlugin.
9
+ */
10
+ export var lazyNodeViewDecorationPluginKey = new PluginKey('lazyNodeViewDecoration');
4
11
 
5
12
  /**
6
13
  * 📢 Public Type
@@ -14,6 +21,12 @@ export { convertToInlineCss } from './css-helper';
14
21
  * @see {withLazyLoading}
15
22
  */
16
23
 
24
+ /**
25
+ * 🧱 Internal: Editor FE Platform
26
+ *
27
+ * Caches loaded node view factory functions
28
+ */
29
+
17
30
  /**
18
31
  * 🧱 Internal: Editor FE Platform
19
32
  *
@@ -21,6 +34,33 @@ export { convertToInlineCss } from './css-helper';
21
34
  */
22
35
  var requestedNodesPerEditorView = new WeakMap();
23
36
 
37
+ /**
38
+ * 🧱 Internal: Editor FE Platform
39
+ *
40
+ * Caches loaded node view factory functions for each editor view
41
+ */
42
+ var resolvedNodesPerEditorView = new WeakMap();
43
+
44
+ /**
45
+ * 🧱 Internal: Editor FE Platform
46
+ *
47
+ * Stores editorView -> raf to debounce NodeView updates.
48
+ */
49
+ var debounceToEditorViewMap = new WeakMap();
50
+ var testOnlyIgnoreLazyNodeViewSet = new WeakSet();
51
+ /**
52
+ * 🧱 Internal: Editor FE Platform
53
+ *
54
+ * Used in tests to prevent lazy node view being replaced by a real node view.
55
+ *
56
+ * This needs to be replaced with proper implementation once LazyNodeView is converted to a plugin.
57
+ *
58
+ * @deprecated DO NOT USE THIS OUSIDE TESTS.
59
+ */
60
+ export function testOnlyIgnoreLazyNodeView(view) {
61
+ testOnlyIgnoreLazyNodeViewSet.add(view);
62
+ }
63
+
24
64
  /**
25
65
  * 📢 Public: Any EditorPlugin can use this function
26
66
  *
@@ -64,28 +104,62 @@ var requestedNodesPerEditorView = new WeakMap();
64
104
  export var withLazyLoading = function withLazyLoading(_ref) {
65
105
  var nodeName = _ref.nodeName,
66
106
  loader = _ref.loader,
67
- getNodeViewOptions = _ref.getNodeViewOptions,
68
- dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent;
107
+ getNodeViewOptions = _ref.getNodeViewOptions;
69
108
  var createLazyNodeView = function createLazyNodeView(node, view, getPos, decorations) {
70
109
  var _node$type;
71
110
  var requestedNodes = requestedNodesPerEditorView.get(view);
72
111
  if (!requestedNodes) {
73
- requestedNodes = new Set(), requestedNodesPerEditorView.set(view, requestedNodes);
112
+ requestedNodes = new Map();
113
+ requestedNodesPerEditorView.set(view, requestedNodes);
114
+ }
115
+ var resolvedNodeViews = resolvedNodesPerEditorView.get(view);
116
+ if (!resolvedNodeViews) {
117
+ resolvedNodesPerEditorView.set(view, new Map());
74
118
  }
75
119
  var wasAlreadyRequested = requestedNodes.has(nodeName);
76
120
  if (wasAlreadyRequested) {
77
- return new LazyNodeView(node, view, getPos);
121
+ var resolvedNodeView = resolvedNodeViews === null || resolvedNodeViews === void 0 ? void 0 : resolvedNodeViews.get(nodeName);
122
+ if (resolvedNodeView && !testOnlyIgnoreLazyNodeViewSet.has(view)) {
123
+ return resolvedNodeView(node, view, getPos, decorations);
124
+ }
125
+ return new LazyNodeView(node, view, getPos, requestedNodes.get(nodeName));
78
126
  }
79
- requestedNodes.add(nodeName);
80
- loader().then(function (nodeViewFuncModule) {
127
+ var loaderPromise = loader().then(function (nodeViewFuncModule) {
128
+ var _resolvedNodesPerEdit;
81
129
  var nodeViewFunc = function nodeViewFunc(node, view, getPos, decorations) {
82
130
  return nodeViewFuncModule(node, view, getPos, decorations, getNodeViewOptions);
83
131
  };
84
- queueReplaceNodeViews(view, {
85
- nodeName: nodeName,
86
- nodeViewFunc: nodeViewFunc
132
+ (_resolvedNodesPerEdit = resolvedNodesPerEditorView.get(view)) === null || _resolvedNodesPerEdit === void 0 || _resolvedNodesPerEdit.set(nodeName, nodeViewFunc);
133
+
134
+ /**
135
+ * Triggering lazyNodeViewDecoration plugin to apply decorations
136
+ * to nodes with newly loaded NodeViews.
137
+ */
138
+ var _ref2 = debounceToEditorViewMap.get(view) || [null, new Set()],
139
+ _ref3 = _slicedToArray(_ref2, 2),
140
+ raf = _ref3[0],
141
+ nodeTypes = _ref3[1];
142
+ if (raf) {
143
+ cancelAnimationFrame(raf);
144
+ }
145
+ nodeTypes.add(node.type.name);
146
+ var nextRaf = requestAnimationFrame(function () {
147
+ debounceToEditorViewMap.set(view, [null, new Set()]);
148
+ var tr = view.state.tr;
149
+ tr.setMeta(lazyNodeViewDecorationPluginKey, {
150
+ type: 'add',
151
+ nodeTypes: nodeTypes
152
+ });
153
+ view.dispatch(tr);
87
154
  });
155
+ debounceToEditorViewMap.set(view, [nextRaf, nodeTypes]);
156
+ /**
157
+ * END triggering LazyNodeViewDecoration plugin
158
+ */
159
+
160
+ return nodeViewFunc;
88
161
  });
162
+ requestedNodes.set(nodeName, loaderPromise);
89
163
  if (typeof ((_node$type = node.type) === null || _node$type === void 0 || (_node$type = _node$type.spec) === null || _node$type === void 0 ? void 0 : _node$type.toDOM) !== 'function') {
90
164
  // TODO: Analytics ED-23982
91
165
  // dispatchAnalyticsEvent({
@@ -98,7 +172,7 @@ export var withLazyLoading = function withLazyLoading(_ref) {
98
172
  // },
99
173
  // });
100
174
  }
101
- return new LazyNodeView(node, view, getPos);
175
+ return new LazyNodeView(node, view, getPos, loaderPromise);
102
176
  };
103
177
  return createLazyNodeView;
104
178
  };
@@ -1,5 +1,6 @@
1
1
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
2
  import _createClass from "@babel/runtime/helpers/createClass";
3
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
4
  import memoize from 'lodash/memoize';
4
5
  import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
5
6
  var getEditorLineWidth = memoize(function (view) {
@@ -13,18 +14,34 @@ var getEditorLineWidth = memoize(function (view) {
13
14
  * A NodeView that serves as a placeholder until the actual NodeView is loaded.
14
15
  */
15
16
  export var LazyNodeView = /*#__PURE__*/function () {
16
- function LazyNodeView(node, view, getPos) {
17
- var _node$type;
17
+ function LazyNodeView(_node, view, _getPos, nodeViewLoader) {
18
+ var _this = this,
19
+ _node$type;
18
20
  _classCallCheck(this, LazyNodeView);
19
- this.node = node;
20
- if (typeof ((_node$type = node.type) === null || _node$type === void 0 || (_node$type = _node$type.spec) === null || _node$type === void 0 ? void 0 : _node$type.toDOM) !== 'function') {
21
+ _defineProperty(this, "update", function (node) {
22
+ var prevNode = _this.node;
23
+ _this.node = node;
24
+
25
+ // Forcing NodeView to be re-created
26
+ // so that ProseMirror can replace LazyNodeView with the real one.
27
+ if (_this.isNodeViewLoaded) {
28
+ return false;
29
+ }
30
+
31
+ // Copying some of the default NodeView update behaviour
32
+ // https://github.com/ProseMirror/prosemirror-view/blob/cfa73eb969777f63bcb39972594fd4a9110f5a93/src/viewdesc.ts#L803
33
+ return !_this.node.sameMarkup(prevNode);
34
+ });
35
+ this.node = _node;
36
+ this.isNodeViewLoaded = false;
37
+ if (typeof ((_node$type = _node.type) === null || _node$type === void 0 || (_node$type = _node$type.spec) === null || _node$type === void 0 ? void 0 : _node$type.toDOM) !== 'function') {
21
38
  this.dom = document.createElement('div');
22
39
  return;
23
40
  }
24
41
  var toDOMConfiguration = {
25
42
  editorLineWidth: getEditorLineWidth(view)
26
43
  };
27
- var fallback = DOMSerializer.renderSpec(document, node.type.spec.toDOM(node,
44
+ var fallback = DOMSerializer.renderSpec(document, _node.type.spec.toDOM(_node,
28
45
  // We are injecting a second parameter to be used by the toDOM lazy node view implementations
29
46
  // @ts-expect-error
30
47
  toDOMConfiguration));
@@ -33,16 +50,19 @@ export var LazyNodeView = /*#__PURE__*/function () {
33
50
  if (this.dom instanceof HTMLElement) {
34
51
  // This attribute is mostly used for debugging purposed
35
52
  // It will help us to found out when the node was replaced
36
- this.dom.setAttribute('data-lazy-node-view', node.type.name);
53
+ this.dom.setAttribute('data-lazy-node-view', _node.type.name);
37
54
  // This is used on Libra tests
38
55
  // We are using this to make sure all lazy noded were replaced
39
56
  // before the test started
40
57
  this.dom.setAttribute('data-lazy-node-view-fallback', 'true');
41
58
  }
59
+ nodeViewLoader.then(function () {
60
+ _this.isNodeViewLoaded = true;
61
+ });
42
62
  }
43
63
  _createClass(LazyNodeView, [{
44
64
  key: "ignoreMutation",
45
- value: function ignoreMutation(mutation) {
65
+ value: function ignoreMutation() {
46
66
  if (this.node.type.isTextblock) {
47
67
  return false;
48
68
  }
@@ -10,7 +10,7 @@ import { useCallback } from 'react';
10
10
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
11
11
  import { jsx } from '@emotion/react';
12
12
  import { useIntl } from 'react-intl-next';
13
- import { withAnalyticsContext } from '@atlaskit/analytics-next';
13
+ import withAnalyticsContext from '@atlaskit/analytics-next/withAnalyticsContext';
14
14
  import DropdownMenu, { DropdownItem, DropdownItemGroup } from '@atlaskit/dropdown-menu';
15
15
  import ChevronDownIcon from '@atlaskit/icon/glyph/chevron-down';
16
16
  import PreferencesIcon from '@atlaskit/icon/glyph/preferences';
@@ -8,7 +8,7 @@ import { useCallback, useLayoutEffect, useState } from 'react';
8
8
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
9
9
  import { css, jsx } from '@emotion/react';
10
10
  import { useIntl } from 'react-intl-next';
11
- import { withAnalyticsContext } from '@atlaskit/analytics-next';
11
+ import withAnalyticsContext from '@atlaskit/analytics-next/withAnalyticsContext';
12
12
  import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
13
13
  import PreferencesIcon from '@atlaskit/icon/glyph/preferences';
14
14
  import { N0 } from '@atlaskit/theme/colors';
@@ -1,6 +1,6 @@
1
1
  import { useMemo } from 'react';
2
- import { FabricChannel } from '@atlaskit/analytics-listeners';
3
- import { useAnalyticsEvents } from '@atlaskit/analytics-next';
2
+ import { FabricChannel } from '@atlaskit/analytics-listeners/types';
3
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next/useAnalyticsEvents';
4
4
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '../../analytics';
5
5
  export var useLinkOverlayAnalyticsEvents = function useLinkOverlayAnalyticsEvents() {
6
6
  var _useAnalyticsEvents = useAnalyticsEvents(),
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/extends";
2
2
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
3
  var _excluded = ["view", "onCancel", "invokeMethod", "editorAppearance", "onClose", "onEscapeCallback", "onClickAwayCallback"];
4
4
  import React, { useCallback, useEffect, useMemo, useRef } from 'react';
5
- import { AnalyticsContext } from '@atlaskit/analytics-next';
5
+ import AnalyticsContext from '@atlaskit/analytics-next/AnalyticsContext';
6
6
  import { LazyLinkPicker } from '@atlaskit/link-picker/lazy';
7
7
  import { getAnalyticsEditorAppearance } from '../../../utils';
8
8
  import { useEscapeClickaway } from './useEscapeClickaway';
@@ -24,7 +24,7 @@ import debounce from 'lodash/debounce';
24
24
  import { flushSync } from 'react-dom';
25
25
  import { defineMessages, injectIntl } from 'react-intl-next';
26
26
  import { isSafeUrl } from '@atlaskit/adf-schema';
27
- import { withAnalyticsEvents } from '@atlaskit/analytics-next';
27
+ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
28
28
  import Page16Icon from '@atlaskit/icon-object/glyph/page/16';
29
29
  import CrossCircleIcon from '@atlaskit/icon/glyph/cross-circle';
30
30
  import { Pressable, xcss } from '@atlaskit/primitives';
@@ -12,7 +12,7 @@ import { Fragment, useCallback, useEffect, useMemo, useState } from 'react';
12
12
  import { jsx } from '@emotion/react';
13
13
  import ReactDOM from 'react-dom';
14
14
  import { createIntl, injectIntl } from 'react-intl-next';
15
- import { useAnalyticsEvents } from '@atlaskit/analytics-next';
15
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next/useAnalyticsEvents';
16
16
  import { fireFailedMediaInlineEvent, fireSucceededMediaInlineEvent, MediaCardError } from '@atlaskit/media-card';
17
17
  import { FileFetcherError } from '@atlaskit/media-client';
18
18
  import { MediaClientContext } from '@atlaskit/media-client-react';