@atlaskit/react-ufo 3.14.5 → 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 (46) hide show
  1. package/CHANGELOG.md +16 -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 +227 -69
  8. package/dist/cjs/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +103 -44
  9. package/dist/cjs/vc/vc-observer-new/viewport-observer/utils/is-in-vc-ignore-if-no-layout-shift-marker.js +17 -0
  10. package/dist/es2019/vc/index.js +37 -5
  11. package/dist/es2019/vc/vc-observer/index.js +8 -2
  12. package/dist/es2019/vc/vc-observer/observers/index.js +11 -5
  13. package/dist/es2019/vc/vc-observer/observers/ssr-placeholders/index.js +57 -26
  14. package/dist/es2019/vc/vc-observer-new/index.js +67 -1
  15. package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +105 -25
  16. package/dist/es2019/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +44 -8
  17. package/dist/es2019/vc/vc-observer-new/viewport-observer/utils/is-in-vc-ignore-if-no-layout-shift-marker.js +11 -0
  18. package/dist/esm/vc/index.js +39 -6
  19. package/dist/esm/vc/vc-observer/index.js +10 -2
  20. package/dist/esm/vc/vc-observer/observers/index.js +12 -7
  21. package/dist/esm/vc/vc-observer/observers/ssr-placeholders/index.js +76 -40
  22. package/dist/esm/vc/vc-observer-new/index.js +84 -0
  23. package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +227 -69
  24. package/dist/esm/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +103 -44
  25. package/dist/esm/vc/vc-observer-new/viewport-observer/utils/is-in-vc-ignore-if-no-layout-shift-marker.js +11 -0
  26. package/dist/types/vc/index.d.ts +2 -0
  27. package/dist/types/vc/types.d.ts +2 -0
  28. package/dist/types/vc/vc-observer/index.d.ts +1 -0
  29. package/dist/types/vc/vc-observer/observers/index.d.ts +2 -0
  30. package/dist/types/vc/vc-observer/observers/ssr-placeholders/index.d.ts +6 -0
  31. package/dist/types/vc/vc-observer-new/index.d.ts +30 -0
  32. package/dist/types/vc/vc-observer-new/types.d.ts +1 -1
  33. package/dist/types/vc/vc-observer-new/viewport-observer/index.d.ts +5 -1
  34. package/dist/types/vc/vc-observer-new/viewport-observer/mutation-observer/index.d.ts +2 -0
  35. package/dist/types/vc/vc-observer-new/viewport-observer/utils/is-in-vc-ignore-if-no-layout-shift-marker.d.ts +6 -0
  36. package/dist/types-ts4.5/vc/index.d.ts +2 -0
  37. package/dist/types-ts4.5/vc/types.d.ts +2 -0
  38. package/dist/types-ts4.5/vc/vc-observer/index.d.ts +1 -0
  39. package/dist/types-ts4.5/vc/vc-observer/observers/index.d.ts +2 -0
  40. package/dist/types-ts4.5/vc/vc-observer/observers/ssr-placeholders/index.d.ts +6 -0
  41. package/dist/types-ts4.5/vc/vc-observer-new/index.d.ts +30 -0
  42. package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +1 -1
  43. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/index.d.ts +5 -1
  44. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/mutation-observer/index.d.ts +2 -0
  45. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/utils/is-in-vc-ignore-if-no-layout-shift-marker.d.ts +6 -0
  46. package/package.json +8 -3
@@ -1,9 +1,12 @@
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; }
9
+ import { fg } from '@atlaskit/platform-feature-flags';
7
10
  import { isContainedWithinMediaWrapper } from '../../vc-observer/media-wrapper/vc-utils';
8
11
  import isNonVisualStyleMutation from '../../vc-observer/observers/non-visual-styles/is-non-visual-style-mutation';
9
12
  import { RLLPlaceholderHandlers } from '../../vc-observer/observers/rll-placeholders';
@@ -11,13 +14,14 @@ import { createIntersectionObserver } from './intersection-observer';
11
14
  import createMutationObserver from './mutation-observer';
12
15
  import createPerformanceObserver from './performance-observer';
13
16
  import { checkThirdPartySegmentWithIgnoreReason, createMutationTypeWithIgnoredReason } from './utils/get-component-name-and-child-props';
17
+ import isInVCIgnoreIfNoLayoutShiftMarker from './utils/is-in-vc-ignore-if-no-layout-shift-marker';
14
18
  function isElementVisible(element) {
15
19
  if (!(element instanceof HTMLElement)) {
16
20
  return true;
17
21
  }
18
22
  try {
19
23
  var visible = element.checkVisibility({
20
- // @ts-expect-error
24
+ // @ts-ignore - visibilityProperty may not exist in all TS environments
21
25
  visibilityProperty: true,
22
26
  contentVisibilityAuto: true,
23
27
  opacityProperty: true
@@ -42,24 +46,36 @@ function sameRectDimensions(a, b) {
42
46
  }
43
47
  var createElementMutationsWatcher = function createElementMutationsWatcher(removedNodeRects) {
44
48
  return function (_ref) {
45
- var rect = _ref.rect;
49
+ var target = _ref.target,
50
+ rect = _ref.rect;
51
+ var isNoLsMarkerEnabled = fg('platform_vc_ignore_no_ls_mutation_marker');
52
+ var isInIgnoreLsMarker = isInVCIgnoreIfNoLayoutShiftMarker(target);
53
+ if (!isInIgnoreLsMarker && isNoLsMarkerEnabled) {
54
+ return 'mutation:element';
55
+ }
46
56
  var isRLLPlaceholder = RLLPlaceholderHandlers.getInstance().isRLLPlaceholderHydration(rect);
47
- if (isRLLPlaceholder) {
57
+ if (isRLLPlaceholder && (!isNoLsMarkerEnabled || isInIgnoreLsMarker)) {
48
58
  return 'mutation:rll-placeholder';
49
59
  }
50
60
  var wasDeleted = removedNodeRects.some(function (nr) {
51
61
  return sameRectDimensions(nr, rect);
52
62
  });
53
- if (wasDeleted) {
63
+ // When fg('platform_vc_ignore_no_ls_mutation_marker') is not enabled,
64
+ // no layout shift mutation is excluded as per existing fy25.03 logic
65
+ if (wasDeleted && (!isNoLsMarkerEnabled || isInIgnoreLsMarker)) {
54
66
  return 'mutation:element-replacement';
55
67
  }
56
68
  return 'mutation:element';
57
69
  };
58
70
  };
59
71
  var ViewportObserver = /*#__PURE__*/function () {
72
+ // SSR context functions
73
+
60
74
  function ViewportObserver(_ref2) {
61
75
  var _this = this;
62
- var onChange = _ref2.onChange;
76
+ var onChange = _ref2.onChange,
77
+ getSSRState = _ref2.getSSRState,
78
+ getSSRPlaceholderHandler = _ref2.getSSRPlaceholderHandler;
63
79
  _classCallCheck(this, ViewportObserver);
64
80
  _defineProperty(this, "handleIntersectionEntry", function (_ref3) {
65
81
  var target = _ref3.target,
@@ -83,60 +99,198 @@ var ViewportObserver = /*#__PURE__*/function () {
83
99
  mutationData: mutationData
84
100
  });
85
101
  });
86
- _defineProperty(this, "handleChildListMutation", function (_ref4) {
87
- var addedNodes = _ref4.addedNodes,
88
- removedNodes = _ref4.removedNodes;
89
- var removedNodeRects = removedNodes.map(function (ref) {
90
- var n = ref.deref();
91
- if (!n) {
92
- return;
93
- }
94
- return _this.mapVisibleNodeRects.get(n);
95
- });
96
- addedNodes.forEach(function (addedNodeRef) {
97
- var _this$intersectionObs4;
98
- var addedNode = addedNodeRef.deref();
99
- if (!addedNode) {
100
- return;
101
- }
102
- var sameDeletedNode = removedNodes.find(function (ref) {
103
- var n = ref.deref();
104
- if (!n || !addedNode) {
105
- 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();
106
278
  }
107
- return n.isEqualNode(addedNode);
108
- });
109
- if (sameDeletedNode) {
110
- var _this$intersectionObs;
111
- (_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, 'mutation:remount');
112
- return;
113
- }
114
- if (isContainedWithinMediaWrapper(addedNode)) {
115
- var _this$intersectionObs2;
116
- (_this$intersectionObs2 = _this.intersectionObserver) === null || _this$intersectionObs2 === void 0 || _this$intersectionObs2.watchAndTag(addedNode, 'mutation:media');
117
- return;
118
- }
119
- var _checkThirdPartySegme = checkThirdPartySegmentWithIgnoreReason(addedNode),
120
- isWithinThirdPartySegment = _checkThirdPartySegme.isWithinThirdPartySegment,
121
- ignoredReason = _checkThirdPartySegme.ignoredReason;
122
- if (isWithinThirdPartySegment) {
123
- var _this$intersectionObs3;
124
- var assignedReason = createMutationTypeWithIgnoredReason(ignoredReason || 'third-party-element');
125
- (_this$intersectionObs3 = _this.intersectionObserver) === null || _this$intersectionObs3 === void 0 || _this$intersectionObs3.watchAndTag(addedNode, assignedReason);
126
- return;
127
- }
128
- (_this$intersectionObs4 = _this.intersectionObserver) === null || _this$intersectionObs4 === void 0 || _this$intersectionObs4.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects));
129
- });
130
- });
131
- _defineProperty(this, "handleAttributeMutation", function (_ref5) {
132
- var _this$intersectionObs5;
133
- var target = _ref5.target,
134
- attributeName = _ref5.attributeName,
135
- oldValue = _ref5.oldValue,
136
- newValue = _ref5.newValue;
137
- (_this$intersectionObs5 = _this.intersectionObserver) === null || _this$intersectionObs5 === void 0 || _this$intersectionObs5.watchAndTag(target, function (_ref6) {
138
- var target = _ref6.target,
139
- 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;
140
294
  if (isContainedWithinMediaWrapper(target)) {
141
295
  return {
142
296
  type: 'mutation:media',
@@ -207,14 +361,14 @@ var ViewportObserver = /*#__PURE__*/function () {
207
361
  };
208
362
  });
209
363
  });
210
- _defineProperty(this, "handleLayoutShift", function (_ref7) {
211
- var time = _ref7.time,
212
- changedRects = _ref7.changedRects;
213
- var _iterator = _createForOfIteratorHelper(changedRects),
214
- _step;
364
+ _defineProperty(this, "handleLayoutShift", function (_ref8) {
365
+ var time = _ref8.time,
366
+ changedRects = _ref8.changedRects;
367
+ var _iterator2 = _createForOfIteratorHelper(changedRects),
368
+ _step2;
215
369
  try {
216
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
217
- var changedRect = _step.value;
370
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
371
+ var changedRect = _step2.value;
218
372
  var target = changedRect.node;
219
373
  if (target) {
220
374
  _this.onChange({
@@ -228,9 +382,9 @@ var ViewportObserver = /*#__PURE__*/function () {
228
382
  }
229
383
  }
230
384
  } catch (err) {
231
- _iterator.e(err);
385
+ _iterator2.e(err);
232
386
  } finally {
233
- _iterator.f();
387
+ _iterator2.f();
234
388
  }
235
389
  });
236
390
  this.mapVisibleNodeRects = new WeakMap();
@@ -239,6 +393,10 @@ var ViewportObserver = /*#__PURE__*/function () {
239
393
  this.intersectionObserver = null;
240
394
  this.mutationObserver = null;
241
395
  this.performanceObserver = null;
396
+
397
+ // Initialize SSR context functions
398
+ this.getSSRState = getSSRState;
399
+ this.getSSRPlaceholderHandler = getSSRPlaceholderHandler;
242
400
  }
243
401
  return _createClass(ViewportObserver, [{
244
402
  key: "initializeObservers",
@@ -282,12 +440,12 @@ var ViewportObserver = /*#__PURE__*/function () {
282
440
  }, {
283
441
  key: "stop",
284
442
  value: function stop() {
285
- var _this$mutationObserve2, _this$intersectionObs6, _this$performanceObse2;
443
+ var _this$mutationObserve2, _this$intersectionObs0, _this$performanceObse2;
286
444
  if (!this.isStarted) {
287
445
  return;
288
446
  }
289
447
  (_this$mutationObserve2 = this.mutationObserver) === null || _this$mutationObserve2 === void 0 || _this$mutationObserve2.disconnect();
290
- (_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();
291
449
  (_this$performanceObse2 = this.performanceObserver) === null || _this$performanceObse2 === void 0 || _this$performanceObse2.disconnect();
292
450
  this.isStarted = false;
293
451
  }
@@ -1,6 +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
+ // Batched mutation data for performance optimization
5
+
4
6
  function createMutationObserver(_ref) {
5
7
  var onAttributeMutation = _ref.onAttributeMutation,
6
8
  onChildListMutation = _ref.onChildListMutation,
@@ -9,63 +11,120 @@ function createMutationObserver(_ref) {
9
11
  return null;
10
12
  }
11
13
  var mutationObserverCallback = function mutationObserverCallback(mutations) {
12
- var addedNodes = [];
13
- var removedNodes = [];
14
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();
15
18
  var _iterator = _createForOfIteratorHelper(mutations),
16
19
  _step;
17
20
  try {
18
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
19
- var mut = _step.value;
20
- if (!(mut.target instanceof HTMLElement)) {
21
- continue;
22
- }
23
- if (mut.type === 'attributes') {
24
- var _mut$oldValue;
25
- /*
26
- "MutationObserver was explicitly designed to work that way, but I can't now recall the reasoning.
27
- I think it might have been something along the lines that for consistency every setAttribute call should create a record.
28
- Conceptually there is after all a mutation: there is an old value replaced with a new one,
29
- and whether or not they are the same doesn't really matter.
30
- And Custom elements should work the same way as MutationObserver."
31
- https://github.com/whatwg/dom/issues/520#issuecomment-336574796
32
- */
33
- var oldValue = (_mut$oldValue = mut.oldValue) !== null && _mut$oldValue !== void 0 ? _mut$oldValue : undefined;
34
- var newValue = mut.attributeName ? mut.target.getAttribute(mut.attributeName) : undefined;
35
- if (oldValue !== newValue) {
36
- var _mut$attributeName;
37
- onAttributeMutation({
38
- target: mut.target,
39
- attributeName: (_mut$attributeName = mut.attributeName) !== null && _mut$attributeName !== void 0 ? _mut$attributeName : 'unknown',
40
- oldValue: oldValue,
41
- newValue: newValue
42
- });
21
+ var _loop = function _loop() {
22
+ var mut = _step.value;
23
+ if (!(mut.target instanceof HTMLElement)) {
24
+ return 0; // continue
43
25
  }
44
- continue;
45
- } else if (mut.type === 'childList') {
46
- var _mut$addedNodes, _mut$removedNodes;
47
- ((_mut$addedNodes = mut.addedNodes) !== null && _mut$addedNodes !== void 0 ? _mut$addedNodes : []).forEach(function (node) {
48
- if (node instanceof HTMLElement) {
49
- addedNodes.push(new WeakRef(node));
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
+ var _mut$attributeName;
40
+ onAttributeMutation({
41
+ target: mut.target,
42
+ attributeName: (_mut$attributeName = mut.attributeName) !== null && _mut$attributeName !== void 0 ? _mut$attributeName : 'unknown',
43
+ oldValue: oldValue,
44
+ newValue: newValue
45
+ });
50
46
  }
51
- });
52
- ((_mut$removedNodes = mut.removedNodes) !== null && _mut$removedNodes !== void 0 ? _mut$removedNodes : []).forEach(function (node) {
53
- if (node instanceof HTMLElement) {
54
- removedNodes.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);
55
58
  }
56
- });
57
- }
58
- targets.push(mut.target);
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);
70
+ }
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;
59
92
  }
93
+
94
+ // Process all batched childList mutations
60
95
  } catch (err) {
61
96
  _iterator.e(err);
62
97
  } finally {
63
98
  _iterator.f();
64
99
  }
65
- onChildListMutation({
66
- addedNodes: addedNodes,
67
- removedNodes: removedNodes
68
- });
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();
127
+ }
69
128
  onMutationFinished === null || onMutationFinished === void 0 || onMutationFinished({
70
129
  targets: targets
71
130
  });
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Check if the element is in the VC ignore if no layout shift marker.
3
+ * @param element - The element to check.
4
+ * @returns True if the element has the data-vc-ignore-if-no-layout-shift attribute == 'true or its parent has it, false otherwise.
5
+ */
6
+ export default function isInVCIgnoreIfNoLayoutShiftMarker(element) {
7
+ if (!element) {
8
+ return false;
9
+ }
10
+ return element.getAttribute('data-vc-ignore-if-no-layout-shift') === 'true' || isInVCIgnoreIfNoLayoutShiftMarker(element.parentElement);
11
+ }
@@ -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;