@atlaskit/react-ufo 5.2.9 → 5.2.10

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 (51) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/cjs/interaction-metrics/index.js +1 -0
  3. package/dist/cjs/interaction-metrics-init/index.js +2 -1
  4. package/dist/cjs/vc/index.js +4 -2
  5. package/dist/cjs/vc/vc-observer-new/index.js +10 -4
  6. package/dist/cjs/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +84 -29
  7. package/dist/cjs/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.js +164 -0
  8. package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +173 -34
  9. package/dist/cjs/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +1 -1
  10. package/dist/cjs/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +2 -1
  11. package/dist/es2019/interaction-metrics/index.js +1 -0
  12. package/dist/es2019/interaction-metrics-init/index.js +2 -1
  13. package/dist/es2019/vc/index.js +4 -2
  14. package/dist/es2019/vc/vc-observer-new/index.js +10 -5
  15. package/dist/es2019/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +61 -7
  16. package/dist/es2019/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.js +138 -0
  17. package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +145 -10
  18. package/dist/es2019/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +1 -1
  19. package/dist/es2019/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +2 -1
  20. package/dist/esm/interaction-metrics/index.js +1 -0
  21. package/dist/esm/interaction-metrics-init/index.js +2 -1
  22. package/dist/esm/vc/index.js +4 -2
  23. package/dist/esm/vc/vc-observer-new/index.js +10 -4
  24. package/dist/esm/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +84 -29
  25. package/dist/esm/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.js +158 -0
  26. package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +173 -34
  27. package/dist/esm/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +1 -1
  28. package/dist/esm/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +2 -1
  29. package/dist/types/common/vc/types.d.ts +55 -0
  30. package/dist/types/config/index.d.ts +1 -0
  31. package/dist/types/vc/types.d.ts +2 -0
  32. package/dist/types/vc/vc-observer-new/index.d.ts +2 -0
  33. package/dist/types/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +1 -1
  34. package/dist/types/vc/vc-observer-new/metric-calculator/types.d.ts +1 -0
  35. package/dist/types/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.d.ts +31 -0
  36. package/dist/types/vc/vc-observer-new/types.d.ts +2 -0
  37. package/dist/types/vc/vc-observer-new/viewport-observer/index.d.ts +3 -1
  38. package/dist/types/vc/vc-observer-new/viewport-observer/mutation-observer/index.d.ts +1 -0
  39. package/dist/types/vc/vc-observer-new/viewport-observer/types.d.ts +5 -2
  40. package/dist/types-ts4.5/common/vc/types.d.ts +55 -0
  41. package/dist/types-ts4.5/config/index.d.ts +1 -0
  42. package/dist/types-ts4.5/vc/types.d.ts +2 -0
  43. package/dist/types-ts4.5/vc/vc-observer-new/index.d.ts +2 -0
  44. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +1 -1
  45. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/types.d.ts +1 -0
  46. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.d.ts +31 -0
  47. package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +2 -0
  48. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/index.d.ts +3 -1
  49. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/mutation-observer/index.d.ts +1 -0
  50. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/types.d.ts +5 -2
  51. package/package.json +1 -1
@@ -12,6 +12,7 @@ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r)
12
12
  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; }
13
13
  import { fg } from '@atlaskit/platform-feature-flags';
14
14
  import { calculateTTVCPercentilesWithDebugInfo } from './percentile-calc';
15
+ import { detectLayoutShiftCause } from './utils/detect-layout-shift-cause';
15
16
  import getViewportHeight from './utils/get-viewport-height';
16
17
  import getViewportWidth from './utils/get-viewport-width';
17
18
 
@@ -112,9 +113,9 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
112
113
  }, {
113
114
  key: "calculateWithDebugInfo",
114
115
  value: function () {
115
- var _calculateWithDebugInfo = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(filteredEntries, startTime, stopTime, isPostInteraction, isVCClean, interactionType, isPageVisible, interactionId, dirtyReason, allEntries, include3p, excludeSmartAnswersInSearch, interactionAbortReason, includeSSRRatio) {
116
+ var _calculateWithDebugInfo = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(filteredEntries, startTime, stopTime, isPostInteraction, isVCClean, interactionType, isPageVisible, interactionId, dirtyReason, allEntries, include3p, excludeSmartAnswersInSearch, interactionAbortReason, includeSSRRatio, reportLayoutShiftOffenders) {
116
117
  var _window, _window2, _window3, _window4, _window6;
117
- var percentiles, viewportEntries, _yield$calculateTTVCP, vcLogs, speedIndex, vcDetails, percentileIndex, entryDataBuffer, ssrRatio, _iterator4, _step4, _entry3, time, viewportPercentage, entries, elementNames, previousResult, i, percentile, enhancedVcLogs, shouldCalculate3p, shouldCalculateDebugDetails, sortedVcLogs, maxViewportPercentageAtTime, maxSoFar, _iterator5, _step5, log, getBiggestPreviousViewportPercentage, ignoredEntriesByTime, _iterator6, _step6, _entry4, _ignoredEntriesByTime, _viewportData$rect, _viewportData$previou, viewportData, timestamp, additionalVcLogs, _iterator7, _step7, _step7$value, _timestamp, ignoredEntries, _viewportPercentage, v3RevisionDebugDetails, _window5, _window5$__ufo_devtoo, _window7, _window7$__on_ufo_vc_;
118
+ var percentiles, viewportEntries, _yield$calculateTTVCP, vcLogs, speedIndex, vcDetails, percentileIndex, entryDataBuffer, ssrRatio, layoutShiftInsights, previousViewportPercentage, _iterator4, _step4, _entry3, time, viewportPercentage, entries, elementNames, layoutShiftEntries, previousResult, i, percentile, enhancedVcLogs, shouldCalculate3p, shouldCalculateDebugDetails, sortedVcLogs, maxViewportPercentageAtTime, maxSoFar, _iterator5, _step5, log, getBiggestPreviousViewportPercentage, ignoredEntriesByTime, _iterator6, _step6, _entry4, _ignoredEntriesByTime, _viewportData$rect, _viewportData$previou, viewportData, timestamp, additionalVcLogs, _iterator7, _step7, _step7$value, _timestamp, ignoredEntries, _viewportPercentage, v3RevisionDebugDetails, _window5, _window5$__ufo_devtoo, _window7, _window7$__on_ufo_vc_;
118
119
  return _regeneratorRuntime.wrap(function _callee$(_context) {
119
120
  while (1) switch (_context.prev = _context.next) {
120
121
  case 0:
@@ -138,16 +139,18 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
138
139
  percentileIndex = 0;
139
140
  entryDataBuffer = new Set();
140
141
  ssrRatio = -1;
142
+ layoutShiftInsights = null;
143
+ previousViewportPercentage = 0;
141
144
  if (!vcLogs) {
142
- _context.next = 32;
145
+ _context.next = 35;
143
146
  break;
144
147
  }
145
148
  _iterator4 = _createForOfIteratorHelper(vcLogs);
146
- _context.prev = 13;
149
+ _context.prev = 15;
147
150
  _iterator4.s();
148
- case 15:
151
+ case 17:
149
152
  if ((_step4 = _iterator4.n()).done) {
150
- _context.next = 24;
153
+ _context.next = 27;
151
154
  break;
152
155
  }
153
156
  _entry3 = _step4.value;
@@ -160,11 +163,11 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
160
163
 
161
164
  // Only process entries if we haven't reached all percentiles
162
165
  if (!(percentileIndex >= percentiles.length)) {
163
- _context.next = 21;
166
+ _context.next = 23;
164
167
  break;
165
168
  }
166
- return _context.abrupt("break", 24);
167
- case 21:
169
+ return _context.abrupt("break", 27);
170
+ case 23:
168
171
  // Check if this entry matches any checkpoint percentiles
169
172
  if (viewportPercentage >= percentiles[percentileIndex]) {
170
173
  elementNames = _toConsumableArray(new Set(entries.map(function (e) {
@@ -175,6 +178,23 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
175
178
  t: Math.round(time),
176
179
  e: elementNames
177
180
  };
181
+ if (reportLayoutShiftOffenders && percentiles[percentileIndex] === 90 && entries.some(function (e) {
182
+ return e.type === 'layout-shift';
183
+ })) {
184
+ layoutShiftEntries = entries.filter(function (e) {
185
+ return e.type === 'layout-shift';
186
+ });
187
+ layoutShiftInsights = {
188
+ layoutShiftOffendersResult: detectLayoutShiftCause({
189
+ viewportEntries: viewportEntries,
190
+ layoutShiftEntries: layoutShiftEntries,
191
+ time: time,
192
+ startTime: startTime
193
+ }),
194
+ layoutShiftEntriesCount: layoutShiftEntries.length,
195
+ layoutShiftImpact: viewportPercentage - previousViewportPercentage
196
+ };
197
+ }
178
198
  percentileIndex++;
179
199
  }
180
200
 
@@ -186,21 +206,22 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
186
206
  return entryDataBuffer.add(e);
187
207
  });
188
208
  }
189
- case 22:
190
- _context.next = 15;
209
+ previousViewportPercentage = viewportPercentage;
210
+ case 25:
211
+ _context.next = 17;
191
212
  break;
192
- case 24:
193
- _context.next = 29;
213
+ case 27:
214
+ _context.next = 32;
194
215
  break;
195
- case 26:
196
- _context.prev = 26;
197
- _context.t0 = _context["catch"](13);
198
- _iterator4.e(_context.t0);
199
216
  case 29:
200
217
  _context.prev = 29;
201
- _iterator4.f();
202
- return _context.finish(29);
218
+ _context.t0 = _context["catch"](15);
219
+ _iterator4.e(_context.t0);
203
220
  case 32:
221
+ _context.prev = 32;
222
+ _iterator4.f();
223
+ return _context.finish(32);
224
+ case 35:
204
225
  // Fill in any missing percentiles with the last known values
205
226
  previousResult = {
206
227
  t: 0,
@@ -361,15 +382,16 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
361
382
  return _context.abrupt("return", {
362
383
  vcDetails: vcDetails,
363
384
  ssrRatio: ssrRatio,
364
- speedIndex: speedIndex
385
+ speedIndex: speedIndex,
386
+ VC90layoutShiftInsights: layoutShiftInsights
365
387
  });
366
- case 44:
388
+ case 47:
367
389
  case "end":
368
390
  return _context.stop();
369
391
  }
370
- }, _callee, this, [[13, 26, 29, 32]]);
392
+ }, _callee, this, [[15, 29, 32, 35]]);
371
393
  }));
372
- function calculateWithDebugInfo(_x, _x2, _x3, _x4, _x5, _x6, _x7, _x8, _x9, _x0, _x1, _x10, _x11, _x12) {
394
+ function calculateWithDebugInfo(_x, _x2, _x3, _x4, _x5, _x6, _x7, _x8, _x9, _x0, _x1, _x10, _x11, _x12, _x13) {
373
395
  return _calculateWithDebugInfo.apply(this, arguments);
374
396
  }
375
397
  return calculateWithDebugInfo;
@@ -381,11 +403,11 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
381
403
  var _this = this,
382
404
  _vcDetails$90$t,
383
405
  _vcDetails$;
384
- var startTime, stopTime, orderedEntries, interactionId, isPostInteraction, include3p, excludeSmartAnswersInSearch, includeSSRRatio, interactionType, isPageVisible, interactionAbortReason, filteredEntries, isVCClean, dirtyReason, getVCCleanStatusResult, _yield$this$calculate, vcDetails, ssrRatio, speedIndex, result;
406
+ var startTime, stopTime, orderedEntries, interactionId, isPostInteraction, include3p, excludeSmartAnswersInSearch, includeSSRRatio, interactionType, isPageVisible, interactionAbortReason, reportLayoutShiftOffenders, filteredEntries, isVCClean, dirtyReason, getVCCleanStatusResult, _yield$this$calculate, vcDetails, ssrRatio, speedIndex, VC90layoutShiftInsights, layoutShiftInsightsPayload, _layoutShiftOffenders, _layoutShiftOffenders2, _layoutShiftOffenders3, layoutShiftOffendersResult, layoutShiftEntriesCount, layoutShiftImpact, result;
385
407
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
386
408
  while (1) switch (_context2.prev = _context2.next) {
387
409
  case 0:
388
- startTime = _ref.startTime, stopTime = _ref.stopTime, orderedEntries = _ref.orderedEntries, interactionId = _ref.interactionId, isPostInteraction = _ref.isPostInteraction, include3p = _ref.include3p, excludeSmartAnswersInSearch = _ref.excludeSmartAnswersInSearch, includeSSRRatio = _ref.includeSSRRatio, interactionType = _ref.interactionType, isPageVisible = _ref.isPageVisible, interactionAbortReason = _ref.interactionAbortReason;
410
+ startTime = _ref.startTime, stopTime = _ref.stopTime, orderedEntries = _ref.orderedEntries, interactionId = _ref.interactionId, isPostInteraction = _ref.isPostInteraction, include3p = _ref.include3p, excludeSmartAnswersInSearch = _ref.excludeSmartAnswersInSearch, includeSSRRatio = _ref.includeSSRRatio, interactionType = _ref.interactionType, isPageVisible = _ref.isPageVisible, interactionAbortReason = _ref.interactionAbortReason, reportLayoutShiftOffenders = _ref.reportLayoutShiftOffenders;
389
411
  filteredEntries = orderedEntries.filter(function (entry) {
390
412
  return _this.isEntryIncluded(entry, include3p, excludeSmartAnswersInSearch);
391
413
  });
@@ -405,17 +427,50 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
405
427
  });
406
428
  case 7:
407
429
  _context2.next = 9;
408
- return this.calculateWithDebugInfo(filteredEntries, startTime, stopTime, isPostInteraction, isVCClean, interactionType, isPageVisible, interactionId, dirtyReason, orderedEntries, include3p, excludeSmartAnswersInSearch, interactionAbortReason, includeSSRRatio);
430
+ return this.calculateWithDebugInfo(filteredEntries, startTime, stopTime, isPostInteraction, isVCClean, interactionType, isPageVisible, interactionId, dirtyReason, orderedEntries, include3p, excludeSmartAnswersInSearch, interactionAbortReason, includeSSRRatio, reportLayoutShiftOffenders);
409
431
  case 9:
410
432
  _yield$this$calculate = _context2.sent;
411
433
  vcDetails = _yield$this$calculate.vcDetails;
412
434
  ssrRatio = _yield$this$calculate.ssrRatio;
413
435
  speedIndex = _yield$this$calculate.speedIndex;
436
+ VC90layoutShiftInsights = _yield$this$calculate.VC90layoutShiftInsights;
437
+ if (VC90layoutShiftInsights !== null && reportLayoutShiftOffenders) {
438
+ layoutShiftOffendersResult = VC90layoutShiftInsights.layoutShiftOffendersResult, layoutShiftEntriesCount = VC90layoutShiftInsights.layoutShiftEntriesCount, layoutShiftImpact = VC90layoutShiftInsights.layoutShiftImpact;
439
+ layoutShiftInsightsPayload = {
440
+ impact: layoutShiftImpact,
441
+ sources: layoutShiftEntriesCount !== null && layoutShiftEntriesCount !== void 0 ? layoutShiftEntriesCount : 0,
442
+ same: {
443
+ dir: (_layoutShiftOffenders = layoutShiftOffendersResult === null || layoutShiftOffendersResult === void 0 ? void 0 : layoutShiftOffendersResult.layoutShiftVariables.allMovedSameWay) !== null && _layoutShiftOffenders !== void 0 ? _layoutShiftOffenders : false,
444
+ dist: (_layoutShiftOffenders2 = layoutShiftOffendersResult === null || layoutShiftOffendersResult === void 0 ? void 0 : layoutShiftOffendersResult.layoutShiftVariables.allMovedSameAmount) !== null && _layoutShiftOffenders2 !== void 0 ? _layoutShiftOffenders2 : false
445
+ },
446
+ total_mut: (_layoutShiftOffenders3 = layoutShiftOffendersResult === null || layoutShiftOffendersResult === void 0 ? void 0 : layoutShiftOffendersResult.layoutShiftOffenders.length) !== null && _layoutShiftOffenders3 !== void 0 ? _layoutShiftOffenders3 : 0,
447
+ mut: layoutShiftOffendersResult === null || layoutShiftOffendersResult === void 0 ? void 0 : layoutShiftOffendersResult.layoutShiftOffenders.sort(function (a, b) {
448
+ return Math.abs(a.distanceToLS) - Math.abs(b.distanceToLS);
449
+ }).slice(0, 5).map(function (offender) {
450
+ return {
451
+ e: offender.offender,
452
+ size: -1,
453
+ // @todo: calculate size
454
+ attr: {
455
+ t_before: offender.happenedBefore,
456
+ t_distance: offender.distanceToLS,
457
+ p_above: offender.isAbove,
458
+ p_left: offender.isLeft,
459
+ p_right: offender.isRight,
460
+ p_h_overlap: offender.hasHorizontalOverlap,
461
+ p_v_overlap: offender.hasVerticalOverlap,
462
+ p_same_offset: offender.matchesLayoutShiftDelta ? 'all' : 'none'
463
+ }
464
+ };
465
+ })
466
+ };
467
+ }
414
468
  result = {
415
469
  revision: this.revisionNo,
416
470
  clean: true,
417
471
  'metric:vc90': (_vcDetails$90$t = vcDetails === null || vcDetails === void 0 || (_vcDetails$ = vcDetails['90']) === null || _vcDetails$ === void 0 ? void 0 : _vcDetails$.t) !== null && _vcDetails$90$t !== void 0 ? _vcDetails$90$t : null,
418
- vcDetails: vcDetails !== null && vcDetails !== void 0 ? vcDetails : undefined
472
+ vcDetails: vcDetails !== null && vcDetails !== void 0 ? vcDetails : undefined,
473
+ 'vc90:ls': layoutShiftInsightsPayload !== null && layoutShiftInsightsPayload !== void 0 ? layoutShiftInsightsPayload : undefined
419
474
  };
420
475
  result.ratios = this.calculateRatios(filteredEntries);
421
476
  if (ssrRatio !== -1) {
@@ -428,13 +483,13 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
428
483
  }
429
484
  result.labelStacks = this.getLabelStacks(filteredEntries, isPostInteraction);
430
485
  return _context2.abrupt("return", result);
431
- case 19:
486
+ case 21:
432
487
  case "end":
433
488
  return _context2.stop();
434
489
  }
435
490
  }, _callee2, this);
436
491
  }));
437
- function calculate(_x13) {
492
+ function calculate(_x14) {
438
493
  return _calculate.apply(this, arguments);
439
494
  }
440
495
  return calculate;
@@ -0,0 +1,158 @@
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
+ 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
+ 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
+ var calculateOffenderState = function calculateOffenderState(current, matchesCurrentEntry) {
5
+ // Once we know it's mixed across entries, we can short-circuit.
6
+ if (current === 'some') {
7
+ return 'some';
8
+ }
9
+ var entryState = matchesCurrentEntry ? 'all' : 'none';
10
+ if (current == null) {
11
+ return entryState;
12
+ }
13
+
14
+ // If the state flips between entries (all <-> none), it's "some".
15
+ if (current !== entryState) {
16
+ return 'some';
17
+ }
18
+ return current;
19
+ };
20
+ var calculateLayoutShiftMovement = function calculateLayoutShiftMovement(layoutShiftEntries) {
21
+ var movements = layoutShiftEntries.map(function (lsEntry) {
22
+ var rect = lsEntry.rect;
23
+ var previousRect = lsEntry.previousRect;
24
+ if (!rect || !previousRect) {
25
+ return null;
26
+ }
27
+ var dx = rect.x - previousRect.x;
28
+ var dy = rect.y - previousRect.y;
29
+ return {
30
+ dx: dx,
31
+ dy: dy,
32
+ movedX: dx !== 0,
33
+ movedY: dy !== 0,
34
+ dirX: Math.sign(dx),
35
+ dirY: Math.sign(dy),
36
+ absDx: Math.abs(dx),
37
+ absDy: Math.abs(dy)
38
+ };
39
+ });
40
+ var hasMovement = function hasMovement(m) {
41
+ return m !== null;
42
+ };
43
+ var validMovements = movements.filter(hasMovement);
44
+ var allHaveRects = layoutShiftEntries.length > 0 && validMovements.length === layoutShiftEntries.length;
45
+ if (!allHaveRects) {
46
+ return {
47
+ allHaveRects: allHaveRects,
48
+ allMovedSameWay: false,
49
+ allMovedSameAmount: false
50
+ };
51
+ }
52
+ var first = validMovements[0];
53
+ var allMovedSameWay = validMovements.every(function (m) {
54
+ return m.movedX === first.movedX && m.movedY === first.movedY && m.dirX === first.dirX && m.dirY === first.dirY;
55
+ });
56
+ var allMovedSameAmount = allMovedSameWay && validMovements.every(function (m) {
57
+ return m.absDx === first.absDx && m.absDy === first.absDy;
58
+ });
59
+ return {
60
+ allHaveRects: allHaveRects,
61
+ allMovedSameWay: allMovedSameWay,
62
+ allMovedSameAmount: allMovedSameAmount,
63
+ deltaX: first.dx,
64
+ deltaY: first.dy
65
+ };
66
+ };
67
+ export var detectLayoutShiftCause = function detectLayoutShiftCause(_ref) {
68
+ var viewportEntries = _ref.viewportEntries,
69
+ layoutShiftEntries = _ref.layoutShiftEntries,
70
+ time = _ref.time,
71
+ startTime = _ref.startTime,
72
+ _ref$offenderWindowMs = _ref.offenderWindowMs,
73
+ offenderWindowMs = _ref$offenderWindowMs === void 0 ? 250 : _ref$offenderWindowMs;
74
+ var checkpointTimestamp = startTime + time;
75
+ var filteredLSPotentialOffenders = viewportEntries.filter(function (viewportEntry) {
76
+ return (viewportEntry.time < checkpointTimestamp && viewportEntry.time > checkpointTimestamp - offenderWindowMs || viewportEntry.time > checkpointTimestamp && viewportEntry.time < checkpointTimestamp + offenderWindowMs) && viewportEntry.data.type !== 'layout-shift';
77
+ });
78
+
79
+ // Summarize whether all layout-shift entries moved in a consistent direction and by the same amount.
80
+ var layoutShiftVariables = calculateLayoutShiftMovement(layoutShiftEntries);
81
+
82
+ // Classify each offender against *all* layout-shift entries when the layout shift is consistently moving in a
83
+ // single axis (pure X or pure Y) so we can reason about whether an offender could have caused the movement.
84
+ var layoutShiftOffenders = filteredLSPotentialOffenders.reduce(function (acc, offender) {
85
+ var _offenderData$origina;
86
+ var offenderData = offender.data;
87
+ var offenderRect = offenderData.rect;
88
+ if (!offenderRect) {
89
+ return acc;
90
+ }
91
+ var offenderTimestamp = (_offenderData$origina = offenderData.originalMutationTimestamp) !== null && _offenderData$origina !== void 0 ? _offenderData$origina : offender.time;
92
+ var happenedBefore = offenderTimestamp <= checkpointTimestamp;
93
+ var offenderLeft = offenderRect.x;
94
+ var offenderRight = offenderRect.x + offenderRect.width;
95
+ var offenderTop = offenderRect.y;
96
+ var offenderBottom = offenderRect.y + offenderRect.height;
97
+ var shouldClassifyAgainstAllEntries = layoutShiftVariables.allMovedSameWay && 'deltaX' in layoutShiftVariables && 'deltaY' in layoutShiftVariables && layoutShiftVariables.deltaX === 0 !== (layoutShiftVariables.deltaY === 0);
98
+ var isAbove = null;
99
+ var isLeft = null;
100
+ var isRight = null;
101
+ var hasHorizontalOverlap = null;
102
+ var hasVerticalOverlap = null;
103
+ if (shouldClassifyAgainstAllEntries) {
104
+ var _iterator = _createForOfIteratorHelper(layoutShiftEntries),
105
+ _step;
106
+ try {
107
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
108
+ var lsEntry = _step.value;
109
+ var lsRect = lsEntry.rect;
110
+ if (!lsRect) {
111
+ continue;
112
+ }
113
+ var lsLeft = lsRect.x;
114
+ var lsRight = lsRect.x + lsRect.width;
115
+ var lsTop = lsRect.y;
116
+ var lsBottom = lsRect.y + lsRect.height;
117
+ isAbove = calculateOffenderState(isAbove, offenderBottom <= lsTop);
118
+ isLeft = calculateOffenderState(isLeft, offenderRight <= lsLeft);
119
+ isRight = calculateOffenderState(isRight, offenderLeft >= lsRight);
120
+ hasHorizontalOverlap = calculateOffenderState(hasHorizontalOverlap, offenderLeft < lsRight && offenderRight > lsLeft);
121
+ hasVerticalOverlap = calculateOffenderState(hasVerticalOverlap, offenderTop < lsBottom && offenderBottom > lsTop);
122
+ }
123
+ } catch (err) {
124
+ _iterator.e(err);
125
+ } finally {
126
+ _iterator.f();
127
+ }
128
+ }
129
+ var matchesLayoutShiftDelta = false;
130
+ if (shouldClassifyAgainstAllEntries && layoutShiftVariables.allMovedSameAmount && offenderData.previousRect) {
131
+ var dx = offenderRect.x - offenderData.previousRect.x;
132
+ var dy = offenderRect.y - offenderData.previousRect.y;
133
+ var isPureX = layoutShiftVariables.deltaX !== 0 && layoutShiftVariables.deltaY === 0;
134
+ var isPureY = layoutShiftVariables.deltaY !== 0 && layoutShiftVariables.deltaX === 0;
135
+ if (isPureX) {
136
+ matchesLayoutShiftDelta = dx === layoutShiftVariables.deltaX && dy === 0;
137
+ } else if (isPureY) {
138
+ matchesLayoutShiftDelta = dy === layoutShiftVariables.deltaY && dx === 0;
139
+ }
140
+ }
141
+ acc.push({
142
+ offender: offenderData.elementName,
143
+ happenedBefore: happenedBefore,
144
+ distanceToLS: Math.round(offenderTimestamp - checkpointTimestamp),
145
+ isAbove: isAbove !== null && isAbove !== void 0 ? isAbove : 'none',
146
+ isLeft: isLeft !== null && isLeft !== void 0 ? isLeft : 'none',
147
+ isRight: isRight !== null && isRight !== void 0 ? isRight : 'none',
148
+ hasHorizontalOverlap: hasHorizontalOverlap !== null && hasHorizontalOverlap !== void 0 ? hasHorizontalOverlap : 'none',
149
+ hasVerticalOverlap: hasVerticalOverlap !== null && hasVerticalOverlap !== void 0 ? hasVerticalOverlap : 'none',
150
+ matchesLayoutShiftDelta: matchesLayoutShiftDelta
151
+ });
152
+ return acc;
153
+ }, []);
154
+ return {
155
+ layoutShiftVariables: layoutShiftVariables,
156
+ layoutShiftOffenders: layoutShiftOffenders
157
+ };
158
+ };