@atlaskit/react-ufo 3.14.6 → 3.14.7

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 (41) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/cjs/vc/index.js +39 -6
  3. package/dist/cjs/vc/vc-observer/index.js +10 -2
  4. package/dist/cjs/vc/vc-observer/observers/index.js +12 -7
  5. package/dist/cjs/vc/vc-observer/observers/ssr-placeholders/index.js +76 -40
  6. package/dist/cjs/vc/vc-observer-new/index.js +84 -0
  7. package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +214 -71
  8. package/dist/cjs/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +97 -59
  9. package/dist/es2019/vc/index.js +37 -5
  10. package/dist/es2019/vc/vc-observer/index.js +8 -2
  11. package/dist/es2019/vc/vc-observer/observers/index.js +11 -5
  12. package/dist/es2019/vc/vc-observer/observers/ssr-placeholders/index.js +57 -26
  13. package/dist/es2019/vc/vc-observer-new/index.js +67 -1
  14. package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +87 -22
  15. package/dist/es2019/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +50 -34
  16. package/dist/esm/vc/index.js +39 -6
  17. package/dist/esm/vc/vc-observer/index.js +10 -2
  18. package/dist/esm/vc/vc-observer/observers/index.js +12 -7
  19. package/dist/esm/vc/vc-observer/observers/ssr-placeholders/index.js +76 -40
  20. package/dist/esm/vc/vc-observer-new/index.js +84 -0
  21. package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +214 -71
  22. package/dist/esm/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +97 -59
  23. package/dist/types/vc/index.d.ts +2 -0
  24. package/dist/types/vc/types.d.ts +2 -0
  25. package/dist/types/vc/vc-observer/index.d.ts +1 -0
  26. package/dist/types/vc/vc-observer/observers/index.d.ts +2 -0
  27. package/dist/types/vc/vc-observer/observers/ssr-placeholders/index.d.ts +6 -0
  28. package/dist/types/vc/vc-observer-new/index.d.ts +30 -0
  29. package/dist/types/vc/vc-observer-new/types.d.ts +1 -1
  30. package/dist/types/vc/vc-observer-new/viewport-observer/index.d.ts +5 -1
  31. package/dist/types/vc/vc-observer-new/viewport-observer/mutation-observer/index.d.ts +2 -0
  32. package/dist/types-ts4.5/vc/index.d.ts +2 -0
  33. package/dist/types-ts4.5/vc/types.d.ts +2 -0
  34. package/dist/types-ts4.5/vc/vc-observer/index.d.ts +1 -0
  35. package/dist/types-ts4.5/vc/vc-observer/observers/index.d.ts +2 -0
  36. package/dist/types-ts4.5/vc/vc-observer/observers/ssr-placeholders/index.d.ts +6 -0
  37. package/dist/types-ts4.5/vc/vc-observer-new/index.d.ts +30 -0
  38. package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +1 -1
  39. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/index.d.ts +5 -1
  40. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/mutation-observer/index.d.ts +2 -0
  41. package/package.json +5 -3
@@ -1,6 +1,8 @@
1
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
1
2
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
3
  import _createClass from "@babel/runtime/helpers/createClass";
3
4
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
5
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
4
6
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
5
7
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
6
8
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
@@ -19,7 +21,7 @@ function isElementVisible(element) {
19
21
  }
20
22
  try {
21
23
  var visible = element.checkVisibility({
22
- // @ts-expect-error
24
+ // @ts-ignore - visibilityProperty may not exist in all TS environments
23
25
  visibilityProperty: true,
24
26
  contentVisibilityAuto: true,
25
27
  opacityProperty: true
@@ -67,9 +69,13 @@ var createElementMutationsWatcher = function createElementMutationsWatcher(remov
67
69
  };
68
70
  };
69
71
  var ViewportObserver = /*#__PURE__*/function () {
72
+ // SSR context functions
73
+
70
74
  function ViewportObserver(_ref2) {
71
75
  var _this = this;
72
- var onChange = _ref2.onChange;
76
+ var onChange = _ref2.onChange,
77
+ getSSRState = _ref2.getSSRState,
78
+ getSSRPlaceholderHandler = _ref2.getSSRPlaceholderHandler;
73
79
  _classCallCheck(this, ViewportObserver);
74
80
  _defineProperty(this, "handleIntersectionEntry", function (_ref3) {
75
81
  var target = _ref3.target,
@@ -93,65 +99,198 @@ var ViewportObserver = /*#__PURE__*/function () {
93
99
  mutationData: mutationData
94
100
  });
95
101
  });
96
- _defineProperty(this, "handleChildListMutation", function (_ref4) {
97
- var addedNodes = _ref4.addedNodes,
98
- removedNodes = _ref4.removedNodes;
99
- var removedNodeRects = removedNodes.map(function (ref) {
100
- var n = ref.deref();
101
- if (!n) {
102
- return;
103
- }
104
- return _this.mapVisibleNodeRects.get(n);
105
- });
106
- addedNodes.forEach(function (addedNodeRef) {
107
- var _this$intersectionObs4;
108
- var addedNode = addedNodeRef.deref();
109
- if (!addedNode) {
110
- return;
111
- }
112
- var sameDeletedNode = removedNodes.find(function (ref) {
113
- var n = ref.deref();
114
- if (!n || !addedNode) {
115
- return false;
102
+ _defineProperty(this, "handleChildListMutation", /*#__PURE__*/function () {
103
+ var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref4) {
104
+ var target, addedNodes, removedNodes, timestamp, removedNodeRects, targetNode, _iterator, _step, _loop, _ret;
105
+ return _regeneratorRuntime.wrap(function _callee$(_context2) {
106
+ while (1) switch (_context2.prev = _context2.next) {
107
+ case 0:
108
+ target = _ref4.target, addedNodes = _ref4.addedNodes, removedNodes = _ref4.removedNodes, timestamp = _ref4.timestamp;
109
+ removedNodeRects = removedNodes.map(function (ref) {
110
+ var n = ref.deref();
111
+ if (!n) {
112
+ return;
113
+ }
114
+ return _this.mapVisibleNodeRects.get(n);
115
+ });
116
+ targetNode = target.deref();
117
+ _iterator = _createForOfIteratorHelper(addedNodes);
118
+ _context2.prev = 4;
119
+ _loop = /*#__PURE__*/_regeneratorRuntime.mark(function _loop() {
120
+ var _this$intersectionObs8;
121
+ var addedNodeRef, addedNode, ssrState, SSRStateEnum, _this$intersectionObs, _this$intersectionObs2, ssrPlaceholderHandler, result, _this$intersectionObs3, _result, _this$intersectionObs4, sameDeletedNode, isInIgnoreLsMarker, isNoLsMarkerEnabled, _this$intersectionObs5, _this$intersectionObs6, _checkThirdPartySegme, isWithinThirdPartySegment, ignoredReason, _this$intersectionObs7, assignedReason;
122
+ return _regeneratorRuntime.wrap(function _loop$(_context) {
123
+ while (1) switch (_context.prev = _context.next) {
124
+ case 0:
125
+ addedNodeRef = _step.value;
126
+ addedNode = addedNodeRef.deref();
127
+ if (addedNode) {
128
+ _context.next = 4;
129
+ break;
130
+ }
131
+ return _context.abrupt("return", 0);
132
+ case 4:
133
+ if (!(_this.getSSRState && fg('platform_ufo_vc_v3_ssr_placeholder'))) {
134
+ _context.next = 19;
135
+ break;
136
+ }
137
+ ssrState = _this.getSSRState();
138
+ SSRStateEnum = {
139
+ normal: 1,
140
+ waitingForFirstRender: 2,
141
+ ignoring: 3
142
+ };
143
+ if (!(ssrState.state === SSRStateEnum.waitingForFirstRender && timestamp > ssrState.renderStart && targetNode === ssrState.reactRootElement)) {
144
+ _context.next = 12;
145
+ break;
146
+ }
147
+ ssrState.state = SSRStateEnum.ignoring;
148
+ if (ssrState.renderStop === -1) {
149
+ // arbitrary 500ms DOM update window
150
+ ssrState.renderStop = timestamp + 500;
151
+ }
152
+ (_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, 'ssr-hydration');
153
+ return _context.abrupt("return", 0);
154
+ case 12:
155
+ if (!(ssrState.state === SSRStateEnum.ignoring && timestamp > ssrState.renderStart && targetNode === ssrState.reactRootElement)) {
156
+ _context.next = 19;
157
+ break;
158
+ }
159
+ if (!(timestamp <= ssrState.renderStop)) {
160
+ _context.next = 18;
161
+ break;
162
+ }
163
+ (_this$intersectionObs2 = _this.intersectionObserver) === null || _this$intersectionObs2 === void 0 || _this$intersectionObs2.watchAndTag(addedNode, 'ssr-hydration');
164
+ return _context.abrupt("return", 0);
165
+ case 18:
166
+ ssrState.state = SSRStateEnum.normal;
167
+ case 19:
168
+ if (!(_this.getSSRPlaceholderHandler && fg('platform_ufo_vc_v3_ssr_placeholder'))) {
169
+ _context.next = 36;
170
+ break;
171
+ }
172
+ ssrPlaceholderHandler = _this.getSSRPlaceholderHandler();
173
+ if (!ssrPlaceholderHandler) {
174
+ _context.next = 36;
175
+ break;
176
+ }
177
+ if (!(ssrPlaceholderHandler.isPlaceholder(addedNode) || ssrPlaceholderHandler.isPlaceholderIgnored(addedNode))) {
178
+ _context.next = 29;
179
+ break;
180
+ }
181
+ _context.next = 25;
182
+ return ssrPlaceholderHandler.checkIfExistedAndSizeMatching(addedNode);
183
+ case 25:
184
+ result = _context.sent;
185
+ if (!(result !== false)) {
186
+ _context.next = 29;
187
+ break;
188
+ }
189
+ (_this$intersectionObs3 = _this.intersectionObserver) === null || _this$intersectionObs3 === void 0 || _this$intersectionObs3.watchAndTag(addedNode, 'mutation:ssr-placeholder');
190
+ return _context.abrupt("return", 0);
191
+ case 29:
192
+ if (!(ssrPlaceholderHandler.isPlaceholderReplacement(addedNode) || ssrPlaceholderHandler.isPlaceholderIgnored(addedNode))) {
193
+ _context.next = 36;
194
+ break;
195
+ }
196
+ _context.next = 32;
197
+ return ssrPlaceholderHandler.validateReactComponentMatchToPlaceholder(addedNode);
198
+ case 32:
199
+ _result = _context.sent;
200
+ if (!(_result !== false)) {
201
+ _context.next = 36;
202
+ break;
203
+ }
204
+ (_this$intersectionObs4 = _this.intersectionObserver) === null || _this$intersectionObs4 === void 0 || _this$intersectionObs4.watchAndTag(addedNode, 'mutation:ssr-placeholder');
205
+ return _context.abrupt("return", 0);
206
+ case 36:
207
+ sameDeletedNode = removedNodes.find(function (ref) {
208
+ var n = ref.deref();
209
+ if (!n || !addedNode) {
210
+ return false;
211
+ }
212
+ return n.isEqualNode(addedNode);
213
+ });
214
+ isInIgnoreLsMarker = isInVCIgnoreIfNoLayoutShiftMarker(addedNode);
215
+ isNoLsMarkerEnabled = fg('platform_vc_ignore_no_ls_mutation_marker'); // When fg('platform_vc_ignore_no_ls_mutation_marker') is not enabled,
216
+ // no layout shift mutation is excluded as per existing fy25.03 logic
217
+ if (!(sameDeletedNode && (!isNoLsMarkerEnabled || isInIgnoreLsMarker))) {
218
+ _context.next = 42;
219
+ break;
220
+ }
221
+ (_this$intersectionObs5 = _this.intersectionObserver) === null || _this$intersectionObs5 === void 0 || _this$intersectionObs5.watchAndTag(addedNode, 'mutation:remount');
222
+ return _context.abrupt("return", 0);
223
+ case 42:
224
+ if (!isContainedWithinMediaWrapper(addedNode)) {
225
+ _context.next = 45;
226
+ break;
227
+ }
228
+ (_this$intersectionObs6 = _this.intersectionObserver) === null || _this$intersectionObs6 === void 0 || _this$intersectionObs6.watchAndTag(addedNode, 'mutation:media');
229
+ return _context.abrupt("return", 0);
230
+ case 45:
231
+ _checkThirdPartySegme = checkThirdPartySegmentWithIgnoreReason(addedNode), isWithinThirdPartySegment = _checkThirdPartySegme.isWithinThirdPartySegment, ignoredReason = _checkThirdPartySegme.ignoredReason;
232
+ if (!isWithinThirdPartySegment) {
233
+ _context.next = 50;
234
+ break;
235
+ }
236
+ assignedReason = createMutationTypeWithIgnoredReason(ignoredReason || 'third-party-element');
237
+ (_this$intersectionObs7 = _this.intersectionObserver) === null || _this$intersectionObs7 === void 0 || _this$intersectionObs7.watchAndTag(addedNode, assignedReason);
238
+ return _context.abrupt("return", 0);
239
+ case 50:
240
+ (_this$intersectionObs8 = _this.intersectionObserver) === null || _this$intersectionObs8 === void 0 || _this$intersectionObs8.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects));
241
+ case 51:
242
+ case "end":
243
+ return _context.stop();
244
+ }
245
+ }, _loop);
246
+ });
247
+ _iterator.s();
248
+ case 7:
249
+ if ((_step = _iterator.n()).done) {
250
+ _context2.next = 14;
251
+ break;
252
+ }
253
+ return _context2.delegateYield(_loop(), "t0", 9);
254
+ case 9:
255
+ _ret = _context2.t0;
256
+ if (!(_ret === 0)) {
257
+ _context2.next = 12;
258
+ break;
259
+ }
260
+ return _context2.abrupt("continue", 12);
261
+ case 12:
262
+ _context2.next = 7;
263
+ break;
264
+ case 14:
265
+ _context2.next = 19;
266
+ break;
267
+ case 16:
268
+ _context2.prev = 16;
269
+ _context2.t1 = _context2["catch"](4);
270
+ _iterator.e(_context2.t1);
271
+ case 19:
272
+ _context2.prev = 19;
273
+ _iterator.f();
274
+ return _context2.finish(19);
275
+ case 22:
276
+ case "end":
277
+ return _context2.stop();
116
278
  }
117
- return n.isEqualNode(addedNode);
118
- });
119
- var isInIgnoreLsMarker = isInVCIgnoreIfNoLayoutShiftMarker(addedNode);
120
- var isNoLsMarkerEnabled = fg('platform_vc_ignore_no_ls_mutation_marker');
121
-
122
- // When fg('platform_vc_ignore_no_ls_mutation_marker') is not enabled,
123
- // no layout shift mutation is excluded as per existing fy25.03 logic
124
- if (sameDeletedNode && (!isNoLsMarkerEnabled || isInIgnoreLsMarker)) {
125
- var _this$intersectionObs;
126
- (_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, 'mutation:remount');
127
- return;
128
- }
129
- if (isContainedWithinMediaWrapper(addedNode)) {
130
- var _this$intersectionObs2;
131
- (_this$intersectionObs2 = _this.intersectionObserver) === null || _this$intersectionObs2 === void 0 || _this$intersectionObs2.watchAndTag(addedNode, 'mutation:media');
132
- return;
133
- }
134
- var _checkThirdPartySegme = checkThirdPartySegmentWithIgnoreReason(addedNode),
135
- isWithinThirdPartySegment = _checkThirdPartySegme.isWithinThirdPartySegment,
136
- ignoredReason = _checkThirdPartySegme.ignoredReason;
137
- if (isWithinThirdPartySegment) {
138
- var _this$intersectionObs3;
139
- var assignedReason = createMutationTypeWithIgnoredReason(ignoredReason || 'third-party-element');
140
- (_this$intersectionObs3 = _this.intersectionObserver) === null || _this$intersectionObs3 === void 0 || _this$intersectionObs3.watchAndTag(addedNode, assignedReason);
141
- return;
142
- }
143
- (_this$intersectionObs4 = _this.intersectionObserver) === null || _this$intersectionObs4 === void 0 || _this$intersectionObs4.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects));
144
- });
145
- });
146
- _defineProperty(this, "handleAttributeMutation", function (_ref5) {
147
- var _this$intersectionObs5;
148
- var target = _ref5.target,
149
- attributeName = _ref5.attributeName,
150
- oldValue = _ref5.oldValue,
151
- newValue = _ref5.newValue;
152
- (_this$intersectionObs5 = _this.intersectionObserver) === null || _this$intersectionObs5 === void 0 || _this$intersectionObs5.watchAndTag(target, function (_ref6) {
153
- var target = _ref6.target,
154
- rect = _ref6.rect;
279
+ }, _callee, null, [[4, 16, 19, 22]]);
280
+ }));
281
+ return function (_x) {
282
+ return _ref5.apply(this, arguments);
283
+ };
284
+ }());
285
+ _defineProperty(this, "handleAttributeMutation", function (_ref6) {
286
+ var _this$intersectionObs9;
287
+ var target = _ref6.target,
288
+ attributeName = _ref6.attributeName,
289
+ oldValue = _ref6.oldValue,
290
+ newValue = _ref6.newValue;
291
+ (_this$intersectionObs9 = _this.intersectionObserver) === null || _this$intersectionObs9 === void 0 || _this$intersectionObs9.watchAndTag(target, function (_ref7) {
292
+ var target = _ref7.target,
293
+ rect = _ref7.rect;
155
294
  if (isContainedWithinMediaWrapper(target)) {
156
295
  return {
157
296
  type: 'mutation:media',
@@ -222,14 +361,14 @@ var ViewportObserver = /*#__PURE__*/function () {
222
361
  };
223
362
  });
224
363
  });
225
- _defineProperty(this, "handleLayoutShift", function (_ref7) {
226
- var time = _ref7.time,
227
- changedRects = _ref7.changedRects;
228
- var _iterator = _createForOfIteratorHelper(changedRects),
229
- _step;
364
+ _defineProperty(this, "handleLayoutShift", function (_ref8) {
365
+ var time = _ref8.time,
366
+ changedRects = _ref8.changedRects;
367
+ var _iterator2 = _createForOfIteratorHelper(changedRects),
368
+ _step2;
230
369
  try {
231
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
232
- var changedRect = _step.value;
370
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
371
+ var changedRect = _step2.value;
233
372
  var target = changedRect.node;
234
373
  if (target) {
235
374
  _this.onChange({
@@ -243,9 +382,9 @@ var ViewportObserver = /*#__PURE__*/function () {
243
382
  }
244
383
  }
245
384
  } catch (err) {
246
- _iterator.e(err);
385
+ _iterator2.e(err);
247
386
  } finally {
248
- _iterator.f();
387
+ _iterator2.f();
249
388
  }
250
389
  });
251
390
  this.mapVisibleNodeRects = new WeakMap();
@@ -254,6 +393,10 @@ var ViewportObserver = /*#__PURE__*/function () {
254
393
  this.intersectionObserver = null;
255
394
  this.mutationObserver = null;
256
395
  this.performanceObserver = null;
396
+
397
+ // Initialize SSR context functions
398
+ this.getSSRState = getSSRState;
399
+ this.getSSRPlaceholderHandler = getSSRPlaceholderHandler;
257
400
  }
258
401
  return _createClass(ViewportObserver, [{
259
402
  key: "initializeObservers",
@@ -297,12 +440,12 @@ var ViewportObserver = /*#__PURE__*/function () {
297
440
  }, {
298
441
  key: "stop",
299
442
  value: function stop() {
300
- var _this$mutationObserve2, _this$intersectionObs6, _this$performanceObse2;
443
+ var _this$mutationObserve2, _this$intersectionObs0, _this$performanceObse2;
301
444
  if (!this.isStarted) {
302
445
  return;
303
446
  }
304
447
  (_this$mutationObserve2 = this.mutationObserver) === null || _this$mutationObserve2 === void 0 || _this$mutationObserve2.disconnect();
305
- (_this$intersectionObs6 = this.intersectionObserver) === null || _this$intersectionObs6 === void 0 || _this$intersectionObs6.disconnect();
448
+ (_this$intersectionObs0 = this.intersectionObserver) === null || _this$intersectionObs0 === void 0 || _this$intersectionObs0.disconnect();
306
449
  (_this$performanceObse2 = this.performanceObserver) === null || _this$performanceObse2 === void 0 || _this$performanceObse2.disconnect();
307
450
  this.isStarted = false;
308
451
  }
@@ -1,7 +1,8 @@
1
1
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
2
2
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
3
3
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
4
- import { fg } from '@atlaskit/platform-feature-flags';
4
+ // Batched mutation data for performance optimization
5
+
5
6
  function createMutationObserver(_ref) {
6
7
  var onAttributeMutation = _ref.onAttributeMutation,
7
8
  onChildListMutation = _ref.onChildListMutation,
@@ -10,82 +11,119 @@ function createMutationObserver(_ref) {
10
11
  return null;
11
12
  }
12
13
  var mutationObserverCallback = function mutationObserverCallback(mutations) {
13
- var addedNodes = [];
14
- var removedNodes = [];
15
- var attributeMutations = [];
16
14
  var targets = [];
15
+ // Use nested Maps for O(1) batching performance
16
+ // Short-lived Maps are safe since they're discarded after each callback
17
+ var batchedMutations = new Map();
17
18
  var _iterator = _createForOfIteratorHelper(mutations),
18
19
  _step;
19
20
  try {
20
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
21
- var _mut = _step.value;
22
- if (!(_mut.target instanceof HTMLElement)) {
23
- continue;
24
- }
25
- if (_mut.type === 'attributes') {
26
- var _mut$oldValue;
27
- /*
28
- "MutationObserver was explicitly designed to work that way, but I can't now recall the reasoning.
29
- I think it might have been something along the lines that for consistency every setAttribute call should create a record.
30
- Conceptually there is after all a mutation: there is an old value replaced with a new one,
31
- and whether or not they are the same doesn't really matter.
32
- And Custom elements should work the same way as MutationObserver."
33
- https://github.com/whatwg/dom/issues/520#issuecomment-336574796
34
- */
35
- var oldValue = (_mut$oldValue = _mut.oldValue) !== null && _mut$oldValue !== void 0 ? _mut$oldValue : undefined;
36
- var newValue = _mut.attributeName ? _mut.target.getAttribute(_mut.attributeName) : undefined;
37
- if (oldValue !== newValue) {
38
- if (fg('platform_vc_ignore_no_ls_mutation_marker')) {
21
+ var _loop = function _loop() {
22
+ var mut = _step.value;
23
+ if (!(mut.target instanceof HTMLElement)) {
24
+ return 0; // continue
25
+ }
26
+ if (mut.type === 'attributes') {
27
+ var _mut$oldValue;
28
+ /*
29
+ "MutationObserver was explicitly designed to work that way, but I can't now recall the reasoning.
30
+ I think it might have been something along the lines that for consistency every setAttribute call should create a record.
31
+ Conceptually there is after all a mutation: there is an old value replaced with a new one,
32
+ and whether or not they are the same doesn't really matter.
33
+ And Custom elements should work the same way as MutationObserver."
34
+ https://github.com/whatwg/dom/issues/520#issuecomment-336574796
35
+ */
36
+ var oldValue = (_mut$oldValue = mut.oldValue) !== null && _mut$oldValue !== void 0 ? _mut$oldValue : undefined;
37
+ var newValue = mut.attributeName ? mut.target.getAttribute(mut.attributeName) : undefined;
38
+ if (oldValue !== newValue) {
39
39
  var _mut$attributeName;
40
- attributeMutations.push({
41
- target: new WeakRef(_mut.target),
42
- attributeName: (_mut$attributeName = _mut.attributeName) !== null && _mut$attributeName !== void 0 ? _mut$attributeName : 'unknown',
43
- oldValue: oldValue,
44
- newValue: newValue
45
- });
46
- } else {
47
- var _mut$attributeName2;
48
40
  onAttributeMutation({
49
- target: _mut.target,
50
- attributeName: (_mut$attributeName2 = _mut.attributeName) !== null && _mut$attributeName2 !== void 0 ? _mut$attributeName2 : 'unknown',
41
+ target: mut.target,
42
+ attributeName: (_mut$attributeName = mut.attributeName) !== null && _mut$attributeName !== void 0 ? _mut$attributeName : 'unknown',
51
43
  oldValue: oldValue,
52
44
  newValue: newValue
53
45
  });
54
46
  }
55
- }
56
- continue;
57
- } else if (_mut.type === 'childList') {
58
- var _mut$addedNodes, _mut$removedNodes;
59
- ((_mut$addedNodes = _mut.addedNodes) !== null && _mut$addedNodes !== void 0 ? _mut$addedNodes : []).forEach(function (node) {
60
- if (node instanceof HTMLElement) {
61
- addedNodes.push(new WeakRef(node));
47
+ return 0; // continue
48
+ } else if (mut.type === 'childList') {
49
+ var _mut$addedNodes, _mut$removedNodes;
50
+ // In chromium browser MutationRecord has timestamp field, which we should use.
51
+ var timestamp = Math.round(mut.timestamp || performance.now());
52
+
53
+ // Get or create timestamp bucket
54
+ var timestampBucket = batchedMutations.get(timestamp);
55
+ if (!timestampBucket) {
56
+ timestampBucket = new Map();
57
+ batchedMutations.set(timestamp, timestampBucket);
62
58
  }
63
- });
64
- ((_mut$removedNodes = _mut.removedNodes) !== null && _mut$removedNodes !== void 0 ? _mut$removedNodes : []).forEach(function (node) {
65
- if (node instanceof HTMLElement) {
66
- removedNodes.push(new WeakRef(node));
59
+
60
+ // Get or create target batch within timestamp bucket
61
+ var batch = timestampBucket.get(mut.target);
62
+ if (!batch) {
63
+ batch = {
64
+ target: new WeakRef(mut.target),
65
+ addedNodes: [],
66
+ removedNodes: [],
67
+ timestamp: timestamp
68
+ };
69
+ timestampBucket.set(mut.target, batch);
67
70
  }
68
- });
69
- }
70
- targets.push(_mut.target);
71
+
72
+ // Accumulate added nodes
73
+ ((_mut$addedNodes = mut.addedNodes) !== null && _mut$addedNodes !== void 0 ? _mut$addedNodes : []).forEach(function (node) {
74
+ if (node instanceof HTMLElement) {
75
+ batch.addedNodes.push(new WeakRef(node));
76
+ }
77
+ });
78
+
79
+ // Accumulate removed nodes
80
+ ((_mut$removedNodes = mut.removedNodes) !== null && _mut$removedNodes !== void 0 ? _mut$removedNodes : []).forEach(function (node) {
81
+ if (node instanceof HTMLElement) {
82
+ batch.removedNodes.push(new WeakRef(node));
83
+ }
84
+ });
85
+ }
86
+ targets.push(mut.target);
87
+ },
88
+ _ret;
89
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
90
+ _ret = _loop();
91
+ if (_ret === 0) continue;
71
92
  }
93
+
94
+ // Process all batched childList mutations
72
95
  } catch (err) {
73
96
  _iterator.e(err);
74
97
  } finally {
75
98
  _iterator.f();
76
99
  }
77
- onChildListMutation({
78
- addedNodes: addedNodes,
79
- removedNodes: removedNodes
80
- });
81
- for (var _i = 0, _attributeMutations = attributeMutations; _i < _attributeMutations.length; _i++) {
82
- var mut = _attributeMutations[_i];
83
- onAttributeMutation({
84
- target: mut.target.deref(),
85
- attributeName: mut.attributeName,
86
- oldValue: mut.oldValue,
87
- newValue: mut.newValue
88
- });
100
+ var _iterator2 = _createForOfIteratorHelper(batchedMutations.values()),
101
+ _step2;
102
+ try {
103
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
104
+ var timestampBucket = _step2.value;
105
+ var _iterator3 = _createForOfIteratorHelper(timestampBucket.values()),
106
+ _step3;
107
+ try {
108
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
109
+ var batch = _step3.value;
110
+ onChildListMutation({
111
+ target: batch.target,
112
+ addedNodes: batch.addedNodes,
113
+ removedNodes: batch.removedNodes,
114
+ timestamp: batch.timestamp
115
+ });
116
+ }
117
+ } catch (err) {
118
+ _iterator3.e(err);
119
+ } finally {
120
+ _iterator3.f();
121
+ }
122
+ }
123
+ } catch (err) {
124
+ _iterator2.e(err);
125
+ } finally {
126
+ _iterator2.f();
89
127
  }
90
128
  onMutationFinished === null || onMutationFinished === void 0 || onMutationFinished({
91
129
  targets: targets
@@ -7,6 +7,7 @@ declare global {
7
7
  export declare class VCObserverWrapper implements VCObserverInterface {
8
8
  private oldVCObserver;
9
9
  private newVCObserver;
10
+ private ssrPlaceholderHandler;
10
11
  constructor(opts?: VCObserverOptions);
11
12
  private processSsrAbortListeners;
12
13
  start({ startTime, experienceKey }: {
@@ -19,6 +20,7 @@ export declare class VCObserverWrapper implements VCObserverInterface {
19
20
  setSSRElement(element: HTMLElement): void;
20
21
  setReactRootRenderStart(startTime: number): void;
21
22
  setReactRootRenderStop(stopTime: number): void;
23
+ collectSSRPlaceholders(): void;
22
24
  }
23
25
  export declare function isEnvironmentSupported(): boolean;
24
26
  export declare function getVCObserver(opts?: VCObserverOptions): VCObserverInterface;
@@ -30,6 +30,7 @@ export type VCObserverOptions = {
30
30
  v: boolean;
31
31
  h: boolean;
32
32
  };
33
+ ssrPlaceholderHandler?: any;
33
34
  };
34
35
  export interface VCObserverInterface {
35
36
  start(startArg: {
@@ -42,4 +43,5 @@ export interface VCObserverInterface {
42
43
  setSSRElement(element: HTMLElement): void;
43
44
  setReactRootRenderStart(startTime?: number): void;
44
45
  setReactRootRenderStop(stopTime?: number): void;
46
+ collectSSRPlaceholders?(): void;
45
47
  }
@@ -74,6 +74,7 @@ export declare class VCObserver implements VCObserverInterface {
74
74
  setSSRElement(element: HTMLElement): void;
75
75
  setReactRootRenderStart(startTime?: number): void;
76
76
  setReactRootRenderStop(stopTime?: number): void;
77
+ collectSSRPlaceholders(): void;
77
78
  private handleUpdate;
78
79
  private setAbortReason;
79
80
  private resetState;
@@ -1,3 +1,4 @@
1
+ import { SSRPlaceholderHandlers } from './ssr-placeholders';
1
2
  import type { BrowserObservers, Callback } from './types';
2
3
  export type { ObservedMutationType } from './types';
3
4
  export type SelectorConfig = {
@@ -16,6 +17,7 @@ type ConstructorOptions = {
16
17
  h: boolean;
17
18
  };
18
19
  };
20
+ ssrPlaceholderHandler?: SSRPlaceholderHandlers | null;
19
21
  };
20
22
  export declare class Observers implements BrowserObservers {
21
23
  private intersectionObserver;
@@ -25,6 +25,12 @@ export declare class SSRPlaceholderHandlers {
25
25
  private getPlaceholderId;
26
26
  private getPlaceholderReplacementId;
27
27
  clear(): void;
28
+ private collectPlaceholdersInternal;
29
+ /**
30
+ * Added this method to be utilised for testing purposes.
31
+ * In production it collection placeholder should only happens on constructor
32
+ */
33
+ collectExistingPlaceholders(): void;
28
34
  isPlaceholder(element: HTMLElement): boolean;
29
35
  isPlaceholderReplacement(element: HTMLElement): boolean;
30
36
  isPlaceholderIgnored(element: HTMLElement): boolean;