@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
@@ -5,9 +5,12 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.default = void 0;
8
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
8
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
9
11
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
10
12
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
13
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
11
14
  var _vcUtils = require("../../vc-observer/media-wrapper/vc-utils");
12
15
  var _isNonVisualStyleMutation = _interopRequireDefault(require("../../vc-observer/observers/non-visual-styles/is-non-visual-style-mutation"));
13
16
  var _rllPlaceholders = require("../../vc-observer/observers/rll-placeholders");
@@ -15,6 +18,7 @@ var _intersectionObserver = require("./intersection-observer");
15
18
  var _mutationObserver = _interopRequireDefault(require("./mutation-observer"));
16
19
  var _performanceObserver = _interopRequireDefault(require("./performance-observer"));
17
20
  var _getComponentNameAndChildProps = require("./utils/get-component-name-and-child-props");
21
+ var _isInVcIgnoreIfNoLayoutShiftMarker = _interopRequireDefault(require("./utils/is-in-vc-ignore-if-no-layout-shift-marker"));
18
22
  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; } } }; }
19
23
  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; } }
20
24
  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; }
@@ -24,7 +28,7 @@ function isElementVisible(element) {
24
28
  }
25
29
  try {
26
30
  var visible = element.checkVisibility({
27
- // @ts-expect-error
31
+ // @ts-ignore - visibilityProperty may not exist in all TS environments
28
32
  visibilityProperty: true,
29
33
  contentVisibilityAuto: true,
30
34
  opacityProperty: true
@@ -49,24 +53,36 @@ function sameRectDimensions(a, b) {
49
53
  }
50
54
  var createElementMutationsWatcher = function createElementMutationsWatcher(removedNodeRects) {
51
55
  return function (_ref) {
52
- var rect = _ref.rect;
56
+ var target = _ref.target,
57
+ rect = _ref.rect;
58
+ var isNoLsMarkerEnabled = (0, _platformFeatureFlags.fg)('platform_vc_ignore_no_ls_mutation_marker');
59
+ var isInIgnoreLsMarker = (0, _isInVcIgnoreIfNoLayoutShiftMarker.default)(target);
60
+ if (!isInIgnoreLsMarker && isNoLsMarkerEnabled) {
61
+ return 'mutation:element';
62
+ }
53
63
  var isRLLPlaceholder = _rllPlaceholders.RLLPlaceholderHandlers.getInstance().isRLLPlaceholderHydration(rect);
54
- if (isRLLPlaceholder) {
64
+ if (isRLLPlaceholder && (!isNoLsMarkerEnabled || isInIgnoreLsMarker)) {
55
65
  return 'mutation:rll-placeholder';
56
66
  }
57
67
  var wasDeleted = removedNodeRects.some(function (nr) {
58
68
  return sameRectDimensions(nr, rect);
59
69
  });
60
- if (wasDeleted) {
70
+ // When fg('platform_vc_ignore_no_ls_mutation_marker') is not enabled,
71
+ // no layout shift mutation is excluded as per existing fy25.03 logic
72
+ if (wasDeleted && (!isNoLsMarkerEnabled || isInIgnoreLsMarker)) {
61
73
  return 'mutation:element-replacement';
62
74
  }
63
75
  return 'mutation:element';
64
76
  };
65
77
  };
66
78
  var ViewportObserver = exports.default = /*#__PURE__*/function () {
79
+ // SSR context functions
80
+
67
81
  function ViewportObserver(_ref2) {
68
82
  var _this = this;
69
- var onChange = _ref2.onChange;
83
+ var onChange = _ref2.onChange,
84
+ getSSRState = _ref2.getSSRState,
85
+ getSSRPlaceholderHandler = _ref2.getSSRPlaceholderHandler;
70
86
  (0, _classCallCheck2.default)(this, ViewportObserver);
71
87
  (0, _defineProperty2.default)(this, "handleIntersectionEntry", function (_ref3) {
72
88
  var target = _ref3.target,
@@ -90,60 +106,198 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
90
106
  mutationData: mutationData
91
107
  });
92
108
  });
93
- (0, _defineProperty2.default)(this, "handleChildListMutation", function (_ref4) {
94
- var addedNodes = _ref4.addedNodes,
95
- removedNodes = _ref4.removedNodes;
96
- var removedNodeRects = removedNodes.map(function (ref) {
97
- var n = ref.deref();
98
- if (!n) {
99
- return;
100
- }
101
- return _this.mapVisibleNodeRects.get(n);
102
- });
103
- addedNodes.forEach(function (addedNodeRef) {
104
- var _this$intersectionObs4;
105
- var addedNode = addedNodeRef.deref();
106
- if (!addedNode) {
107
- return;
108
- }
109
- var sameDeletedNode = removedNodes.find(function (ref) {
110
- var n = ref.deref();
111
- if (!n || !addedNode) {
112
- return false;
109
+ (0, _defineProperty2.default)(this, "handleChildListMutation", /*#__PURE__*/function () {
110
+ var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref4) {
111
+ var target, addedNodes, removedNodes, timestamp, removedNodeRects, targetNode, _iterator, _step, _loop, _ret;
112
+ return _regenerator.default.wrap(function _callee$(_context2) {
113
+ while (1) switch (_context2.prev = _context2.next) {
114
+ case 0:
115
+ target = _ref4.target, addedNodes = _ref4.addedNodes, removedNodes = _ref4.removedNodes, timestamp = _ref4.timestamp;
116
+ removedNodeRects = removedNodes.map(function (ref) {
117
+ var n = ref.deref();
118
+ if (!n) {
119
+ return;
120
+ }
121
+ return _this.mapVisibleNodeRects.get(n);
122
+ });
123
+ targetNode = target.deref();
124
+ _iterator = _createForOfIteratorHelper(addedNodes);
125
+ _context2.prev = 4;
126
+ _loop = /*#__PURE__*/_regenerator.default.mark(function _loop() {
127
+ var _this$intersectionObs8;
128
+ 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;
129
+ return _regenerator.default.wrap(function _loop$(_context) {
130
+ while (1) switch (_context.prev = _context.next) {
131
+ case 0:
132
+ addedNodeRef = _step.value;
133
+ addedNode = addedNodeRef.deref();
134
+ if (addedNode) {
135
+ _context.next = 4;
136
+ break;
137
+ }
138
+ return _context.abrupt("return", 0);
139
+ case 4:
140
+ if (!(_this.getSSRState && (0, _platformFeatureFlags.fg)('platform_ufo_vc_v3_ssr_placeholder'))) {
141
+ _context.next = 19;
142
+ break;
143
+ }
144
+ ssrState = _this.getSSRState();
145
+ SSRStateEnum = {
146
+ normal: 1,
147
+ waitingForFirstRender: 2,
148
+ ignoring: 3
149
+ };
150
+ if (!(ssrState.state === SSRStateEnum.waitingForFirstRender && timestamp > ssrState.renderStart && targetNode === ssrState.reactRootElement)) {
151
+ _context.next = 12;
152
+ break;
153
+ }
154
+ ssrState.state = SSRStateEnum.ignoring;
155
+ if (ssrState.renderStop === -1) {
156
+ // arbitrary 500ms DOM update window
157
+ ssrState.renderStop = timestamp + 500;
158
+ }
159
+ (_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, 'ssr-hydration');
160
+ return _context.abrupt("return", 0);
161
+ case 12:
162
+ if (!(ssrState.state === SSRStateEnum.ignoring && timestamp > ssrState.renderStart && targetNode === ssrState.reactRootElement)) {
163
+ _context.next = 19;
164
+ break;
165
+ }
166
+ if (!(timestamp <= ssrState.renderStop)) {
167
+ _context.next = 18;
168
+ break;
169
+ }
170
+ (_this$intersectionObs2 = _this.intersectionObserver) === null || _this$intersectionObs2 === void 0 || _this$intersectionObs2.watchAndTag(addedNode, 'ssr-hydration');
171
+ return _context.abrupt("return", 0);
172
+ case 18:
173
+ ssrState.state = SSRStateEnum.normal;
174
+ case 19:
175
+ if (!(_this.getSSRPlaceholderHandler && (0, _platformFeatureFlags.fg)('platform_ufo_vc_v3_ssr_placeholder'))) {
176
+ _context.next = 36;
177
+ break;
178
+ }
179
+ ssrPlaceholderHandler = _this.getSSRPlaceholderHandler();
180
+ if (!ssrPlaceholderHandler) {
181
+ _context.next = 36;
182
+ break;
183
+ }
184
+ if (!(ssrPlaceholderHandler.isPlaceholder(addedNode) || ssrPlaceholderHandler.isPlaceholderIgnored(addedNode))) {
185
+ _context.next = 29;
186
+ break;
187
+ }
188
+ _context.next = 25;
189
+ return ssrPlaceholderHandler.checkIfExistedAndSizeMatching(addedNode);
190
+ case 25:
191
+ result = _context.sent;
192
+ if (!(result !== false)) {
193
+ _context.next = 29;
194
+ break;
195
+ }
196
+ (_this$intersectionObs3 = _this.intersectionObserver) === null || _this$intersectionObs3 === void 0 || _this$intersectionObs3.watchAndTag(addedNode, 'mutation:ssr-placeholder');
197
+ return _context.abrupt("return", 0);
198
+ case 29:
199
+ if (!(ssrPlaceholderHandler.isPlaceholderReplacement(addedNode) || ssrPlaceholderHandler.isPlaceholderIgnored(addedNode))) {
200
+ _context.next = 36;
201
+ break;
202
+ }
203
+ _context.next = 32;
204
+ return ssrPlaceholderHandler.validateReactComponentMatchToPlaceholder(addedNode);
205
+ case 32:
206
+ _result = _context.sent;
207
+ if (!(_result !== false)) {
208
+ _context.next = 36;
209
+ break;
210
+ }
211
+ (_this$intersectionObs4 = _this.intersectionObserver) === null || _this$intersectionObs4 === void 0 || _this$intersectionObs4.watchAndTag(addedNode, 'mutation:ssr-placeholder');
212
+ return _context.abrupt("return", 0);
213
+ case 36:
214
+ sameDeletedNode = removedNodes.find(function (ref) {
215
+ var n = ref.deref();
216
+ if (!n || !addedNode) {
217
+ return false;
218
+ }
219
+ return n.isEqualNode(addedNode);
220
+ });
221
+ isInIgnoreLsMarker = (0, _isInVcIgnoreIfNoLayoutShiftMarker.default)(addedNode);
222
+ isNoLsMarkerEnabled = (0, _platformFeatureFlags.fg)('platform_vc_ignore_no_ls_mutation_marker'); // When fg('platform_vc_ignore_no_ls_mutation_marker') is not enabled,
223
+ // no layout shift mutation is excluded as per existing fy25.03 logic
224
+ if (!(sameDeletedNode && (!isNoLsMarkerEnabled || isInIgnoreLsMarker))) {
225
+ _context.next = 42;
226
+ break;
227
+ }
228
+ (_this$intersectionObs5 = _this.intersectionObserver) === null || _this$intersectionObs5 === void 0 || _this$intersectionObs5.watchAndTag(addedNode, 'mutation:remount');
229
+ return _context.abrupt("return", 0);
230
+ case 42:
231
+ if (!(0, _vcUtils.isContainedWithinMediaWrapper)(addedNode)) {
232
+ _context.next = 45;
233
+ break;
234
+ }
235
+ (_this$intersectionObs6 = _this.intersectionObserver) === null || _this$intersectionObs6 === void 0 || _this$intersectionObs6.watchAndTag(addedNode, 'mutation:media');
236
+ return _context.abrupt("return", 0);
237
+ case 45:
238
+ _checkThirdPartySegme = (0, _getComponentNameAndChildProps.checkThirdPartySegmentWithIgnoreReason)(addedNode), isWithinThirdPartySegment = _checkThirdPartySegme.isWithinThirdPartySegment, ignoredReason = _checkThirdPartySegme.ignoredReason;
239
+ if (!isWithinThirdPartySegment) {
240
+ _context.next = 50;
241
+ break;
242
+ }
243
+ assignedReason = (0, _getComponentNameAndChildProps.createMutationTypeWithIgnoredReason)(ignoredReason || 'third-party-element');
244
+ (_this$intersectionObs7 = _this.intersectionObserver) === null || _this$intersectionObs7 === void 0 || _this$intersectionObs7.watchAndTag(addedNode, assignedReason);
245
+ return _context.abrupt("return", 0);
246
+ case 50:
247
+ (_this$intersectionObs8 = _this.intersectionObserver) === null || _this$intersectionObs8 === void 0 || _this$intersectionObs8.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects));
248
+ case 51:
249
+ case "end":
250
+ return _context.stop();
251
+ }
252
+ }, _loop);
253
+ });
254
+ _iterator.s();
255
+ case 7:
256
+ if ((_step = _iterator.n()).done) {
257
+ _context2.next = 14;
258
+ break;
259
+ }
260
+ return _context2.delegateYield(_loop(), "t0", 9);
261
+ case 9:
262
+ _ret = _context2.t0;
263
+ if (!(_ret === 0)) {
264
+ _context2.next = 12;
265
+ break;
266
+ }
267
+ return _context2.abrupt("continue", 12);
268
+ case 12:
269
+ _context2.next = 7;
270
+ break;
271
+ case 14:
272
+ _context2.next = 19;
273
+ break;
274
+ case 16:
275
+ _context2.prev = 16;
276
+ _context2.t1 = _context2["catch"](4);
277
+ _iterator.e(_context2.t1);
278
+ case 19:
279
+ _context2.prev = 19;
280
+ _iterator.f();
281
+ return _context2.finish(19);
282
+ case 22:
283
+ case "end":
284
+ return _context2.stop();
113
285
  }
114
- return n.isEqualNode(addedNode);
115
- });
116
- if (sameDeletedNode) {
117
- var _this$intersectionObs;
118
- (_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, 'mutation:remount');
119
- return;
120
- }
121
- if ((0, _vcUtils.isContainedWithinMediaWrapper)(addedNode)) {
122
- var _this$intersectionObs2;
123
- (_this$intersectionObs2 = _this.intersectionObserver) === null || _this$intersectionObs2 === void 0 || _this$intersectionObs2.watchAndTag(addedNode, 'mutation:media');
124
- return;
125
- }
126
- var _checkThirdPartySegme = (0, _getComponentNameAndChildProps.checkThirdPartySegmentWithIgnoreReason)(addedNode),
127
- isWithinThirdPartySegment = _checkThirdPartySegme.isWithinThirdPartySegment,
128
- ignoredReason = _checkThirdPartySegme.ignoredReason;
129
- if (isWithinThirdPartySegment) {
130
- var _this$intersectionObs3;
131
- var assignedReason = (0, _getComponentNameAndChildProps.createMutationTypeWithIgnoredReason)(ignoredReason || 'third-party-element');
132
- (_this$intersectionObs3 = _this.intersectionObserver) === null || _this$intersectionObs3 === void 0 || _this$intersectionObs3.watchAndTag(addedNode, assignedReason);
133
- return;
134
- }
135
- (_this$intersectionObs4 = _this.intersectionObserver) === null || _this$intersectionObs4 === void 0 || _this$intersectionObs4.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects));
136
- });
137
- });
138
- (0, _defineProperty2.default)(this, "handleAttributeMutation", function (_ref5) {
139
- var _this$intersectionObs5;
140
- var target = _ref5.target,
141
- attributeName = _ref5.attributeName,
142
- oldValue = _ref5.oldValue,
143
- newValue = _ref5.newValue;
144
- (_this$intersectionObs5 = _this.intersectionObserver) === null || _this$intersectionObs5 === void 0 || _this$intersectionObs5.watchAndTag(target, function (_ref6) {
145
- var target = _ref6.target,
146
- rect = _ref6.rect;
286
+ }, _callee, null, [[4, 16, 19, 22]]);
287
+ }));
288
+ return function (_x) {
289
+ return _ref5.apply(this, arguments);
290
+ };
291
+ }());
292
+ (0, _defineProperty2.default)(this, "handleAttributeMutation", function (_ref6) {
293
+ var _this$intersectionObs9;
294
+ var target = _ref6.target,
295
+ attributeName = _ref6.attributeName,
296
+ oldValue = _ref6.oldValue,
297
+ newValue = _ref6.newValue;
298
+ (_this$intersectionObs9 = _this.intersectionObserver) === null || _this$intersectionObs9 === void 0 || _this$intersectionObs9.watchAndTag(target, function (_ref7) {
299
+ var target = _ref7.target,
300
+ rect = _ref7.rect;
147
301
  if ((0, _vcUtils.isContainedWithinMediaWrapper)(target)) {
148
302
  return {
149
303
  type: 'mutation:media',
@@ -214,14 +368,14 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
214
368
  };
215
369
  });
216
370
  });
217
- (0, _defineProperty2.default)(this, "handleLayoutShift", function (_ref7) {
218
- var time = _ref7.time,
219
- changedRects = _ref7.changedRects;
220
- var _iterator = _createForOfIteratorHelper(changedRects),
221
- _step;
371
+ (0, _defineProperty2.default)(this, "handleLayoutShift", function (_ref8) {
372
+ var time = _ref8.time,
373
+ changedRects = _ref8.changedRects;
374
+ var _iterator2 = _createForOfIteratorHelper(changedRects),
375
+ _step2;
222
376
  try {
223
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
224
- var changedRect = _step.value;
377
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
378
+ var changedRect = _step2.value;
225
379
  var target = changedRect.node;
226
380
  if (target) {
227
381
  _this.onChange({
@@ -235,9 +389,9 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
235
389
  }
236
390
  }
237
391
  } catch (err) {
238
- _iterator.e(err);
392
+ _iterator2.e(err);
239
393
  } finally {
240
- _iterator.f();
394
+ _iterator2.f();
241
395
  }
242
396
  });
243
397
  this.mapVisibleNodeRects = new WeakMap();
@@ -246,6 +400,10 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
246
400
  this.intersectionObserver = null;
247
401
  this.mutationObserver = null;
248
402
  this.performanceObserver = null;
403
+
404
+ // Initialize SSR context functions
405
+ this.getSSRState = getSSRState;
406
+ this.getSSRPlaceholderHandler = getSSRPlaceholderHandler;
249
407
  }
250
408
  return (0, _createClass2.default)(ViewportObserver, [{
251
409
  key: "initializeObservers",
@@ -289,12 +447,12 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
289
447
  }, {
290
448
  key: "stop",
291
449
  value: function stop() {
292
- var _this$mutationObserve2, _this$intersectionObs6, _this$performanceObse2;
450
+ var _this$mutationObserve2, _this$intersectionObs0, _this$performanceObse2;
293
451
  if (!this.isStarted) {
294
452
  return;
295
453
  }
296
454
  (_this$mutationObserve2 = this.mutationObserver) === null || _this$mutationObserve2 === void 0 || _this$mutationObserve2.disconnect();
297
- (_this$intersectionObs6 = this.intersectionObserver) === null || _this$intersectionObs6 === void 0 || _this$intersectionObs6.disconnect();
455
+ (_this$intersectionObs0 = this.intersectionObserver) === null || _this$intersectionObs0 === void 0 || _this$intersectionObs0.disconnect();
298
456
  (_this$performanceObse2 = this.performanceObserver) === null || _this$performanceObse2 === void 0 || _this$performanceObse2.disconnect();
299
457
  this.isStarted = false;
300
458
  }
@@ -7,6 +7,8 @@ exports.default = void 0;
7
7
  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; } } }; }
8
8
  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; } }
9
9
  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; }
10
+ // Batched mutation data for performance optimization
11
+
10
12
  function createMutationObserver(_ref) {
11
13
  var onAttributeMutation = _ref.onAttributeMutation,
12
14
  onChildListMutation = _ref.onChildListMutation,
@@ -15,63 +17,120 @@ function createMutationObserver(_ref) {
15
17
  return null;
16
18
  }
17
19
  var mutationObserverCallback = function mutationObserverCallback(mutations) {
18
- var addedNodes = [];
19
- var removedNodes = [];
20
20
  var targets = [];
21
+ // Use nested Maps for O(1) batching performance
22
+ // Short-lived Maps are safe since they're discarded after each callback
23
+ var batchedMutations = new Map();
21
24
  var _iterator = _createForOfIteratorHelper(mutations),
22
25
  _step;
23
26
  try {
24
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
25
- var mut = _step.value;
26
- if (!(mut.target instanceof HTMLElement)) {
27
- continue;
28
- }
29
- if (mut.type === 'attributes') {
30
- var _mut$oldValue;
31
- /*
32
- "MutationObserver was explicitly designed to work that way, but I can't now recall the reasoning.
33
- I think it might have been something along the lines that for consistency every setAttribute call should create a record.
34
- Conceptually there is after all a mutation: there is an old value replaced with a new one,
35
- and whether or not they are the same doesn't really matter.
36
- And Custom elements should work the same way as MutationObserver."
37
- https://github.com/whatwg/dom/issues/520#issuecomment-336574796
38
- */
39
- var oldValue = (_mut$oldValue = mut.oldValue) !== null && _mut$oldValue !== void 0 ? _mut$oldValue : undefined;
40
- var newValue = mut.attributeName ? mut.target.getAttribute(mut.attributeName) : undefined;
41
- if (oldValue !== newValue) {
42
- var _mut$attributeName;
43
- onAttributeMutation({
44
- target: mut.target,
45
- attributeName: (_mut$attributeName = mut.attributeName) !== null && _mut$attributeName !== void 0 ? _mut$attributeName : 'unknown',
46
- oldValue: oldValue,
47
- newValue: newValue
48
- });
27
+ var _loop = function _loop() {
28
+ var mut = _step.value;
29
+ if (!(mut.target instanceof HTMLElement)) {
30
+ return 0; // continue
49
31
  }
50
- continue;
51
- } else if (mut.type === 'childList') {
52
- var _mut$addedNodes, _mut$removedNodes;
53
- ((_mut$addedNodes = mut.addedNodes) !== null && _mut$addedNodes !== void 0 ? _mut$addedNodes : []).forEach(function (node) {
54
- if (node instanceof HTMLElement) {
55
- addedNodes.push(new WeakRef(node));
32
+ if (mut.type === 'attributes') {
33
+ var _mut$oldValue;
34
+ /*
35
+ "MutationObserver was explicitly designed to work that way, but I can't now recall the reasoning.
36
+ I think it might have been something along the lines that for consistency every setAttribute call should create a record.
37
+ Conceptually there is after all a mutation: there is an old value replaced with a new one,
38
+ and whether or not they are the same doesn't really matter.
39
+ And Custom elements should work the same way as MutationObserver."
40
+ https://github.com/whatwg/dom/issues/520#issuecomment-336574796
41
+ */
42
+ var oldValue = (_mut$oldValue = mut.oldValue) !== null && _mut$oldValue !== void 0 ? _mut$oldValue : undefined;
43
+ var newValue = mut.attributeName ? mut.target.getAttribute(mut.attributeName) : undefined;
44
+ if (oldValue !== newValue) {
45
+ var _mut$attributeName;
46
+ onAttributeMutation({
47
+ target: mut.target,
48
+ attributeName: (_mut$attributeName = mut.attributeName) !== null && _mut$attributeName !== void 0 ? _mut$attributeName : 'unknown',
49
+ oldValue: oldValue,
50
+ newValue: newValue
51
+ });
56
52
  }
57
- });
58
- ((_mut$removedNodes = mut.removedNodes) !== null && _mut$removedNodes !== void 0 ? _mut$removedNodes : []).forEach(function (node) {
59
- if (node instanceof HTMLElement) {
60
- removedNodes.push(new WeakRef(node));
53
+ return 0; // continue
54
+ } else if (mut.type === 'childList') {
55
+ var _mut$addedNodes, _mut$removedNodes;
56
+ // In chromium browser MutationRecord has timestamp field, which we should use.
57
+ var timestamp = Math.round(mut.timestamp || performance.now());
58
+
59
+ // Get or create timestamp bucket
60
+ var timestampBucket = batchedMutations.get(timestamp);
61
+ if (!timestampBucket) {
62
+ timestampBucket = new Map();
63
+ batchedMutations.set(timestamp, timestampBucket);
61
64
  }
62
- });
63
- }
64
- targets.push(mut.target);
65
+
66
+ // Get or create target batch within timestamp bucket
67
+ var batch = timestampBucket.get(mut.target);
68
+ if (!batch) {
69
+ batch = {
70
+ target: new WeakRef(mut.target),
71
+ addedNodes: [],
72
+ removedNodes: [],
73
+ timestamp: timestamp
74
+ };
75
+ timestampBucket.set(mut.target, batch);
76
+ }
77
+
78
+ // Accumulate added nodes
79
+ ((_mut$addedNodes = mut.addedNodes) !== null && _mut$addedNodes !== void 0 ? _mut$addedNodes : []).forEach(function (node) {
80
+ if (node instanceof HTMLElement) {
81
+ batch.addedNodes.push(new WeakRef(node));
82
+ }
83
+ });
84
+
85
+ // Accumulate removed nodes
86
+ ((_mut$removedNodes = mut.removedNodes) !== null && _mut$removedNodes !== void 0 ? _mut$removedNodes : []).forEach(function (node) {
87
+ if (node instanceof HTMLElement) {
88
+ batch.removedNodes.push(new WeakRef(node));
89
+ }
90
+ });
91
+ }
92
+ targets.push(mut.target);
93
+ },
94
+ _ret;
95
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
96
+ _ret = _loop();
97
+ if (_ret === 0) continue;
65
98
  }
99
+
100
+ // Process all batched childList mutations
66
101
  } catch (err) {
67
102
  _iterator.e(err);
68
103
  } finally {
69
104
  _iterator.f();
70
105
  }
71
- onChildListMutation({
72
- addedNodes: addedNodes,
73
- removedNodes: removedNodes
74
- });
106
+ var _iterator2 = _createForOfIteratorHelper(batchedMutations.values()),
107
+ _step2;
108
+ try {
109
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
110
+ var timestampBucket = _step2.value;
111
+ var _iterator3 = _createForOfIteratorHelper(timestampBucket.values()),
112
+ _step3;
113
+ try {
114
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
115
+ var batch = _step3.value;
116
+ onChildListMutation({
117
+ target: batch.target,
118
+ addedNodes: batch.addedNodes,
119
+ removedNodes: batch.removedNodes,
120
+ timestamp: batch.timestamp
121
+ });
122
+ }
123
+ } catch (err) {
124
+ _iterator3.e(err);
125
+ } finally {
126
+ _iterator3.f();
127
+ }
128
+ }
129
+ } catch (err) {
130
+ _iterator2.e(err);
131
+ } finally {
132
+ _iterator2.f();
133
+ }
75
134
  onMutationFinished === null || onMutationFinished === void 0 || onMutationFinished({
76
135
  targets: targets
77
136
  });
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = isInVCIgnoreIfNoLayoutShiftMarker;
7
+ /**
8
+ * Check if the element is in the VC ignore if no layout shift marker.
9
+ * @param element - The element to check.
10
+ * @returns True if the element has the data-vc-ignore-if-no-layout-shift attribute == 'true or its parent has it, false otherwise.
11
+ */
12
+ function isInVCIgnoreIfNoLayoutShiftMarker(element) {
13
+ if (!element) {
14
+ return false;
15
+ }
16
+ return element.getAttribute('data-vc-ignore-if-no-layout-shift') === 'true' || isInVCIgnoreIfNoLayoutShiftMarker(element.parentElement);
17
+ }
@@ -4,17 +4,41 @@ import { VCObserverNOOP } from './no-op-vc-observer';
4
4
  import { VCObserver } from './vc-observer';
5
5
  import VCObserverNew from './vc-observer-new';
6
6
  import { RLLPlaceholderHandlers } from './vc-observer/observers/rll-placeholders';
7
+ import { SSRPlaceholderHandlers } from './vc-observer/observers/ssr-placeholders';
7
8
  export class VCObserverWrapper {
8
9
  constructor(opts = {}) {
10
+ var _opts$ssrEnablePageLa, _opts$disableSizeAndP;
9
11
  this.newVCObserver = null;
10
12
  this.oldVCObserver = null;
13
+
14
+ // Initialize SSR placeholder handler once
15
+ this.ssrPlaceholderHandler = new SSRPlaceholderHandlers({
16
+ enablePageLayoutPlaceholder: (_opts$ssrEnablePageLa = opts.ssrEnablePageLayoutPlaceholder) !== null && _opts$ssrEnablePageLa !== void 0 ? _opts$ssrEnablePageLa : false,
17
+ disableSizeAndPositionCheck: (_opts$disableSizeAndP = opts.disableSizeAndPositionCheck) !== null && _opts$disableSizeAndP !== void 0 ? _opts$disableSizeAndP : {
18
+ v: false,
19
+ h: false
20
+ }
21
+ });
11
22
  if (isVCRevisionEnabled('fy25.03')) {
23
+ var _opts$ssrEnablePageLa2, _opts$disableSizeAndP2;
12
24
  this.newVCObserver = new VCObserverNew({
13
- selectorConfig: opts.selectorConfig
25
+ selectorConfig: opts.selectorConfig,
26
+ isPostInteraction: opts.isPostInteraction,
27
+ SSRConfig: {
28
+ enablePageLayoutPlaceholder: (_opts$ssrEnablePageLa2 = opts.ssrEnablePageLayoutPlaceholder) !== null && _opts$ssrEnablePageLa2 !== void 0 ? _opts$ssrEnablePageLa2 : false,
29
+ disableSizeAndPositionCheck: (_opts$disableSizeAndP2 = opts.disableSizeAndPositionCheck) !== null && _opts$disableSizeAndP2 !== void 0 ? _opts$disableSizeAndP2 : {
30
+ v: false,
31
+ h: false
32
+ }
33
+ },
34
+ ssrPlaceholderHandler: this.ssrPlaceholderHandler
14
35
  });
15
36
  }
16
37
  if (isVCRevisionEnabled('fy25.01') || isVCRevisionEnabled('fy25.02')) {
17
- this.oldVCObserver = new VCObserver(opts);
38
+ this.oldVCObserver = new VCObserver({
39
+ ...opts,
40
+ ssrPlaceholderHandler: this.ssrPlaceholderHandler
41
+ });
18
42
  }
19
43
  }
20
44
 
@@ -68,6 +92,8 @@ export class VCObserverWrapper {
68
92
  (_this$newVCObserver2 = this.newVCObserver) === null || _this$newVCObserver2 === void 0 ? void 0 : _this$newVCObserver2.stop();
69
93
  }
70
94
  RLLPlaceholderHandlers.getInstance().reset();
95
+ // Clear shared SSR placeholder handler
96
+ this.ssrPlaceholderHandler.clear();
71
97
  }
72
98
  getVCRawData() {
73
99
  var _this$oldVCObserver$g, _this$oldVCObserver3;
@@ -94,16 +120,22 @@ export class VCObserverWrapper {
94
120
  };
95
121
  }
96
122
  setSSRElement(element) {
97
- var _this$oldVCObserver5;
123
+ var _this$oldVCObserver5, _this$newVCObserver4;
98
124
  (_this$oldVCObserver5 = this.oldVCObserver) === null || _this$oldVCObserver5 === void 0 ? void 0 : _this$oldVCObserver5.setSSRElement(element);
125
+ (_this$newVCObserver4 = this.newVCObserver) === null || _this$newVCObserver4 === void 0 ? void 0 : _this$newVCObserver4.setReactRootElement(element);
99
126
  }
100
127
  setReactRootRenderStart(startTime) {
101
- var _this$oldVCObserver6;
128
+ var _this$oldVCObserver6, _this$newVCObserver5;
102
129
  (_this$oldVCObserver6 = this.oldVCObserver) === null || _this$oldVCObserver6 === void 0 ? void 0 : _this$oldVCObserver6.setReactRootRenderStart(startTime || performance.now());
130
+ (_this$newVCObserver5 = this.newVCObserver) === null || _this$newVCObserver5 === void 0 ? void 0 : _this$newVCObserver5.setReactRootRenderStart(startTime || performance.now());
103
131
  }
104
132
  setReactRootRenderStop(stopTime) {
105
- var _this$oldVCObserver7;
133
+ var _this$oldVCObserver7, _this$newVCObserver6;
106
134
  (_this$oldVCObserver7 = this.oldVCObserver) === null || _this$oldVCObserver7 === void 0 ? void 0 : _this$oldVCObserver7.setReactRootRenderStop(stopTime || performance.now());
135
+ (_this$newVCObserver6 = this.newVCObserver) === null || _this$newVCObserver6 === void 0 ? void 0 : _this$newVCObserver6.setReactRootRenderStop(stopTime || performance.now());
136
+ }
137
+ collectSSRPlaceholders() {
138
+ this.ssrPlaceholderHandler.collectExistingPlaceholders();
107
139
  }
108
140
  }
109
141