@atlaskit/editor-common 88.6.2 → 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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/editor-common
2
2
 
3
+ ## 88.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#136261](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/136261)
8
+ [`7e900c6a2ae84`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/7e900c6a2ae84) -
9
+ Lazy node view loading without setProps
10
+
11
+ ### Patch Changes
12
+
13
+ - [#136261](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/136261)
14
+ [`7e900c6a2ae84`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/7e900c6a2ae84) -
15
+ Replace LazyNodeView without view.setProps
16
+
3
17
  ## 88.6.2
4
18
 
5
19
  ### Patch Changes
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
@@ -9,10 +10,20 @@ Object.defineProperty(exports, "convertToInlineCss", {
9
10
  return _cssHelper.convertToInlineCss;
10
11
  }
11
12
  });
13
+ exports.lazyNodeViewDecorationPluginKey = void 0;
14
+ exports.testOnlyIgnoreLazyNodeView = testOnlyIgnoreLazyNodeView;
12
15
  exports.withLazyLoading = void 0;
16
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
17
+ var _state = require("@atlaskit/editor-prosemirror/state");
13
18
  var _nodeView = require("./node-view");
14
- var _replaceNodeViews = require("./replace-node-views");
15
19
  var _cssHelper = require("./css-helper");
20
+ /**
21
+ * 📢 Public Plugin Key
22
+ *
23
+ * Communication channel between LazyNodeView loader and LazyNodeViewDecorationPlugin.
24
+ */
25
+ var lazyNodeViewDecorationPluginKey = exports.lazyNodeViewDecorationPluginKey = new _state.PluginKey('lazyNodeViewDecoration');
26
+
16
27
  /**
17
28
  * 📢 Public Type
18
29
  *
@@ -25,6 +36,12 @@ var _cssHelper = require("./css-helper");
25
36
  * @see {withLazyLoading}
26
37
  */
27
38
 
39
+ /**
40
+ * 🧱 Internal: Editor FE Platform
41
+ *
42
+ * Caches loaded node view factory functions
43
+ */
44
+
28
45
  /**
29
46
  * 🧱 Internal: Editor FE Platform
30
47
  *
@@ -32,6 +49,33 @@ var _cssHelper = require("./css-helper");
32
49
  */
33
50
  var requestedNodesPerEditorView = new WeakMap();
34
51
 
52
+ /**
53
+ * 🧱 Internal: Editor FE Platform
54
+ *
55
+ * Caches loaded node view factory functions for each editor view
56
+ */
57
+ var resolvedNodesPerEditorView = new WeakMap();
58
+
59
+ /**
60
+ * 🧱 Internal: Editor FE Platform
61
+ *
62
+ * Stores editorView -> raf to debounce NodeView updates.
63
+ */
64
+ var debounceToEditorViewMap = new WeakMap();
65
+ var testOnlyIgnoreLazyNodeViewSet = new WeakSet();
66
+ /**
67
+ * 🧱 Internal: Editor FE Platform
68
+ *
69
+ * Used in tests to prevent lazy node view being replaced by a real node view.
70
+ *
71
+ * This needs to be replaced with proper implementation once LazyNodeView is converted to a plugin.
72
+ *
73
+ * @deprecated DO NOT USE THIS OUSIDE TESTS.
74
+ */
75
+ function testOnlyIgnoreLazyNodeView(view) {
76
+ testOnlyIgnoreLazyNodeViewSet.add(view);
77
+ }
78
+
35
79
  /**
36
80
  * 📢 Public: Any EditorPlugin can use this function
37
81
  *
@@ -75,28 +119,62 @@ var requestedNodesPerEditorView = new WeakMap();
75
119
  var withLazyLoading = exports.withLazyLoading = function withLazyLoading(_ref) {
76
120
  var nodeName = _ref.nodeName,
77
121
  loader = _ref.loader,
78
- getNodeViewOptions = _ref.getNodeViewOptions,
79
- dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent;
122
+ getNodeViewOptions = _ref.getNodeViewOptions;
80
123
  var createLazyNodeView = function createLazyNodeView(node, view, getPos, decorations) {
81
124
  var _node$type;
82
125
  var requestedNodes = requestedNodesPerEditorView.get(view);
83
126
  if (!requestedNodes) {
84
- requestedNodes = new Set(), requestedNodesPerEditorView.set(view, requestedNodes);
127
+ requestedNodes = new Map();
128
+ requestedNodesPerEditorView.set(view, requestedNodes);
129
+ }
130
+ var resolvedNodeViews = resolvedNodesPerEditorView.get(view);
131
+ if (!resolvedNodeViews) {
132
+ resolvedNodesPerEditorView.set(view, new Map());
85
133
  }
86
134
  var wasAlreadyRequested = requestedNodes.has(nodeName);
87
135
  if (wasAlreadyRequested) {
88
- return new _nodeView.LazyNodeView(node, view, getPos);
136
+ var resolvedNodeView = resolvedNodeViews === null || resolvedNodeViews === void 0 ? void 0 : resolvedNodeViews.get(nodeName);
137
+ if (resolvedNodeView && !testOnlyIgnoreLazyNodeViewSet.has(view)) {
138
+ return resolvedNodeView(node, view, getPos, decorations);
139
+ }
140
+ return new _nodeView.LazyNodeView(node, view, getPos, requestedNodes.get(nodeName));
89
141
  }
90
- requestedNodes.add(nodeName);
91
- loader().then(function (nodeViewFuncModule) {
142
+ var loaderPromise = loader().then(function (nodeViewFuncModule) {
143
+ var _resolvedNodesPerEdit;
92
144
  var nodeViewFunc = function nodeViewFunc(node, view, getPos, decorations) {
93
145
  return nodeViewFuncModule(node, view, getPos, decorations, getNodeViewOptions);
94
146
  };
95
- (0, _replaceNodeViews.queueReplaceNodeViews)(view, {
96
- nodeName: nodeName,
97
- nodeViewFunc: nodeViewFunc
147
+ (_resolvedNodesPerEdit = resolvedNodesPerEditorView.get(view)) === null || _resolvedNodesPerEdit === void 0 || _resolvedNodesPerEdit.set(nodeName, nodeViewFunc);
148
+
149
+ /**
150
+ * Triggering lazyNodeViewDecoration plugin to apply decorations
151
+ * to nodes with newly loaded NodeViews.
152
+ */
153
+ var _ref2 = debounceToEditorViewMap.get(view) || [null, new Set()],
154
+ _ref3 = (0, _slicedToArray2.default)(_ref2, 2),
155
+ raf = _ref3[0],
156
+ nodeTypes = _ref3[1];
157
+ if (raf) {
158
+ cancelAnimationFrame(raf);
159
+ }
160
+ nodeTypes.add(node.type.name);
161
+ var nextRaf = requestAnimationFrame(function () {
162
+ debounceToEditorViewMap.set(view, [null, new Set()]);
163
+ var tr = view.state.tr;
164
+ tr.setMeta(lazyNodeViewDecorationPluginKey, {
165
+ type: 'add',
166
+ nodeTypes: nodeTypes
167
+ });
168
+ view.dispatch(tr);
98
169
  });
170
+ debounceToEditorViewMap.set(view, [nextRaf, nodeTypes]);
171
+ /**
172
+ * END triggering LazyNodeViewDecoration plugin
173
+ */
174
+
175
+ return nodeViewFunc;
99
176
  });
177
+ requestedNodes.set(nodeName, loaderPromise);
100
178
  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') {
101
179
  // TODO: Analytics ED-23982
102
180
  // dispatchAnalyticsEvent({
@@ -109,7 +187,7 @@ var withLazyLoading = exports.withLazyLoading = function withLazyLoading(_ref) {
109
187
  // },
110
188
  // });
111
189
  }
112
- return new _nodeView.LazyNodeView(node, view, getPos);
190
+ return new _nodeView.LazyNodeView(node, view, getPos, loaderPromise);
113
191
  };
114
192
  return createLazyNodeView;
115
193
  };
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.LazyNodeView = void 0;
8
8
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
9
9
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
11
  var _memoize = _interopRequireDefault(require("lodash/memoize"));
11
12
  var _model = require("@atlaskit/editor-prosemirror/model");
12
13
  var getEditorLineWidth = (0, _memoize.default)(function (view) {
@@ -20,18 +21,34 @@ var getEditorLineWidth = (0, _memoize.default)(function (view) {
20
21
  * A NodeView that serves as a placeholder until the actual NodeView is loaded.
21
22
  */
22
23
  var LazyNodeView = exports.LazyNodeView = /*#__PURE__*/function () {
23
- function LazyNodeView(node, view, getPos) {
24
- var _node$type;
24
+ function LazyNodeView(_node, view, _getPos, nodeViewLoader) {
25
+ var _this = this,
26
+ _node$type;
25
27
  (0, _classCallCheck2.default)(this, LazyNodeView);
26
- this.node = node;
27
- 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') {
28
+ (0, _defineProperty2.default)(this, "update", function (node) {
29
+ var prevNode = _this.node;
30
+ _this.node = node;
31
+
32
+ // Forcing NodeView to be re-created
33
+ // so that ProseMirror can replace LazyNodeView with the real one.
34
+ if (_this.isNodeViewLoaded) {
35
+ return false;
36
+ }
37
+
38
+ // Copying some of the default NodeView update behaviour
39
+ // https://github.com/ProseMirror/prosemirror-view/blob/cfa73eb969777f63bcb39972594fd4a9110f5a93/src/viewdesc.ts#L803
40
+ return !_this.node.sameMarkup(prevNode);
41
+ });
42
+ this.node = _node;
43
+ this.isNodeViewLoaded = false;
44
+ 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') {
28
45
  this.dom = document.createElement('div');
29
46
  return;
30
47
  }
31
48
  var toDOMConfiguration = {
32
49
  editorLineWidth: getEditorLineWidth(view)
33
50
  };
34
- var fallback = _model.DOMSerializer.renderSpec(document, node.type.spec.toDOM(node,
51
+ var fallback = _model.DOMSerializer.renderSpec(document, _node.type.spec.toDOM(_node,
35
52
  // We are injecting a second parameter to be used by the toDOM lazy node view implementations
36
53
  // @ts-expect-error
37
54
  toDOMConfiguration));
@@ -40,16 +57,19 @@ var LazyNodeView = exports.LazyNodeView = /*#__PURE__*/function () {
40
57
  if (this.dom instanceof HTMLElement) {
41
58
  // This attribute is mostly used for debugging purposed
42
59
  // It will help us to found out when the node was replaced
43
- this.dom.setAttribute('data-lazy-node-view', node.type.name);
60
+ this.dom.setAttribute('data-lazy-node-view', _node.type.name);
44
61
  // This is used on Libra tests
45
62
  // We are using this to make sure all lazy noded were replaced
46
63
  // before the test started
47
64
  this.dom.setAttribute('data-lazy-node-view-fallback', 'true');
48
65
  }
66
+ nodeViewLoader.then(function () {
67
+ _this.isNodeViewLoaded = true;
68
+ });
49
69
  }
50
70
  (0, _createClass2.default)(LazyNodeView, [{
51
71
  key: "ignoreMutation",
52
- value: function ignoreMutation(mutation) {
72
+ value: function ignoreMutation() {
53
73
  if (this.node.type.isTextblock) {
54
74
  return false;
55
75
  }
@@ -17,7 +17,7 @@ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return
17
17
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
18
18
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
19
19
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
20
- var packageVersion = "88.6.2";
20
+ var packageVersion = "88.7.0";
21
21
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
22
22
  // Remove URL as it has UGC
23
23
  // TODO: Sanitise the URL instead of just removing it
@@ -25,7 +25,7 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
25
25
  * @jsx jsx
26
26
  */ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
27
27
  var packageName = "@atlaskit/editor-common";
28
- var packageVersion = "88.6.2";
28
+ var packageVersion = "88.7.0";
29
29
  var halfFocusRing = 1;
30
30
  var dropOffset = '0, 8';
31
31
  var DropList = /*#__PURE__*/function (_Component) {
@@ -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
  }
@@ -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.2";
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
@@ -14,7 +14,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
14
14
  import { N0, N50A, N60A, N900 } from '@atlaskit/theme/colors';
15
15
  import Layer from '../Layer';
16
16
  const packageName = "@atlaskit/editor-common";
17
- const packageVersion = "88.6.2";
17
+ const packageVersion = "88.7.0";
18
18
  const halfFocusRing = 1;
19
19
  const dropOffset = '0, 8';
20
20
  class DropList extends Component {
@@ -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
  };