@atlaskit/react-ufo 4.15.7 → 4.15.9

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 (33) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/api-reference.md +1188 -0
  3. package/dist/cjs/create-post-interaction-log-payload/get-late-mutations.js +2 -3
  4. package/dist/cjs/vc/vc-observer-new/index.js +1 -1
  5. package/dist/cjs/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +11 -7
  6. package/dist/cjs/vc/vc-observer-new/metric-calculator/fy25_03/index.js +5 -0
  7. package/dist/cjs/vc/vc-observer-new/metric-calculator/vcnext/index.js +3 -0
  8. package/dist/cjs/vc/vc-observer-new/raw-data-handler/index.js +1 -1
  9. package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +16 -0
  10. package/dist/cjs/vc/vc-observer-new/viewport-observer/utils/is-input-name-mutation.js +19 -0
  11. package/dist/es2019/create-post-interaction-log-payload/get-late-mutations.js +2 -3
  12. package/dist/es2019/vc/vc-observer-new/index.js +1 -1
  13. package/dist/es2019/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +11 -7
  14. package/dist/es2019/vc/vc-observer-new/metric-calculator/fy25_03/index.js +5 -0
  15. package/dist/es2019/vc/vc-observer-new/metric-calculator/vcnext/index.js +3 -0
  16. package/dist/es2019/vc/vc-observer-new/raw-data-handler/index.js +1 -1
  17. package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +16 -0
  18. package/dist/es2019/vc/vc-observer-new/viewport-observer/utils/is-input-name-mutation.js +15 -0
  19. package/dist/esm/create-post-interaction-log-payload/get-late-mutations.js +2 -3
  20. package/dist/esm/vc/vc-observer-new/index.js +1 -1
  21. package/dist/esm/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +11 -7
  22. package/dist/esm/vc/vc-observer-new/metric-calculator/fy25_03/index.js +5 -0
  23. package/dist/esm/vc/vc-observer-new/metric-calculator/vcnext/index.js +3 -0
  24. package/dist/esm/vc/vc-observer-new/raw-data-handler/index.js +1 -1
  25. package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +16 -0
  26. package/dist/esm/vc/vc-observer-new/viewport-observer/utils/is-input-name-mutation.js +14 -0
  27. package/dist/types/common/vc/types.d.ts +1 -1
  28. package/dist/types/vc/vc-observer-new/types.d.ts +1 -1
  29. package/dist/types/vc/vc-observer-new/viewport-observer/utils/is-input-name-mutation.d.ts +6 -0
  30. package/dist/types-ts4.5/common/vc/types.d.ts +1 -1
  31. package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +1 -1
  32. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/utils/is-input-name-mutation.d.ts +6 -0
  33. package/package.json +5 -2
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
8
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; } } }; }
9
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; } }
10
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; }
@@ -38,9 +37,9 @@ function getLateMutations(vcDetails) {
38
37
  element: element,
39
38
  viewportHeatmapPercentage: (postInteractionFinishVCRatios === null || postInteractionFinishVCRatios === void 0 ? void 0 : postInteractionFinishVCRatios[element]) || 0
40
39
  };
41
- if (labelStacks && (0, _platformFeatureFlags.fg)('platform_ufo_enable_late_mutation_label_stacks')) {
40
+ if (labelStacks) {
42
41
  var labels = labelStacks[element];
43
- if (labels) {
42
+ if (labels && typeof labels !== 'string') {
44
43
  lateMutation.segment = labels.segment;
45
44
  lateMutation.labelStack = labels.labelStack;
46
45
  }
@@ -88,7 +88,7 @@ var VCObserverNew = exports.default = /*#__PURE__*/function () {
88
88
  oldValue: mutationData === null || mutationData === void 0 ? void 0 : mutationData.oldValue,
89
89
  newValue: mutationData === null || mutationData === void 0 ? void 0 : mutationData.newValue
90
90
  };
91
- if (element && _this.isPostInteraction && (0, _platformFeatureFlags.fg)('platform_ufo_enable_late_mutation_label_stacks')) {
91
+ if (element && (_this.isPostInteraction || (0, _platformFeatureFlags.fg)('platform_ufo_add_segment_names_to_dom_offenders'))) {
92
92
  var labelStacks = getLabelStacks(element);
93
93
  if (labelStacks) {
94
94
  Object.assign(data, {
@@ -83,7 +83,7 @@ var AbstractVCCalculatorBase = exports.default = /*#__PURE__*/function () {
83
83
  }
84
84
  }, {
85
85
  key: "getLabelStacks",
86
- value: function getLabelStacks(filteredEntries) {
86
+ value: function getLabelStacks(filteredEntries, isPostInteraction) {
87
87
  var labelStacks = {};
88
88
  var _iterator3 = _createForOfIteratorHelper(filteredEntries),
89
89
  _step3;
@@ -91,10 +91,14 @@ var AbstractVCCalculatorBase = exports.default = /*#__PURE__*/function () {
91
91
  for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
92
92
  var _entry2 = _step3.value;
93
93
  if ('elementName' in _entry2.data && _entry2.data.labelStacks) {
94
- labelStacks[_entry2.data.elementName] = {
95
- segment: _entry2.data.labelStacks.segment,
96
- labelStack: _entry2.data.labelStacks.labelStack
97
- };
94
+ if (isPostInteraction) {
95
+ labelStacks[_entry2.data.elementName] = {
96
+ segment: _entry2.data.labelStacks.segment,
97
+ labelStack: _entry2.data.labelStacks.labelStack
98
+ };
99
+ } else if ((0, _platformFeatureFlags.fg)('platform_ufo_add_segment_names_to_dom_offenders')) {
100
+ labelStacks[_entry2.data.elementName] = _entry2.data.labelStacks.labelStack;
101
+ }
98
102
  }
99
103
  }
100
104
  } catch (err) {
@@ -415,8 +419,8 @@ var AbstractVCCalculatorBase = exports.default = /*#__PURE__*/function () {
415
419
  if (ssrRatio !== -1) {
416
420
  result.ssrRatio = ssrRatio;
417
421
  }
418
- if (isPostInteraction) {
419
- result.labelStacks = this.getLabelStacks(filteredEntries);
422
+ if (isPostInteraction || (0, _platformFeatureFlags.fg)('platform_ufo_add_segment_names_to_dom_offenders')) {
423
+ result.labelStacks = this.getLabelStacks(filteredEntries, isPostInteraction);
420
424
  }
421
425
  return _context2.abrupt("return", result);
422
426
  case 17:
@@ -32,6 +32,11 @@ var getConsideredEntryTypes = function getConsideredEntryTypes(include3p) {
32
32
  if ((0, _platformFeatureFlags.fg)('platform_ufo_enable_media_for_ttvc_v3')) {
33
33
  entryTypes.push('mutation:media');
34
34
  }
35
+
36
+ // Still included as part of TTVC v3
37
+ if ((0, _platformFeatureFlags.fg)('platform_ufo_ttvc_v4_exclude_input_name_mutation')) {
38
+ entryTypes.push('mutation:attribute:non-visual-input-name');
39
+ }
35
40
  return entryTypes;
36
41
  };
37
42
 
@@ -30,6 +30,9 @@ var getConsideredEntryTypes = function getConsideredEntryTypes() {
30
30
  };
31
31
  var getExcludedEntryTypes = function getExcludedEntryTypes() {
32
32
  var excludedEntryTypes = ['layout-shift:same-rect'];
33
+ if ((0, _platformFeatureFlags.fg)('platform_ufo_ttvc_v4_exclude_input_name_mutation')) {
34
+ excludedEntryTypes.push('mutation:attribute:non-visual-input-name');
35
+ }
33
36
  return excludedEntryTypes;
34
37
  };
35
38
 
@@ -123,7 +123,7 @@ var RawDataHandler = exports.default = /*#__PURE__*/function () {
123
123
  }
124
124
  }
125
125
  var observation = _objectSpread({
126
- t: Math.round(entry.time),
126
+ t: Math.round(entry.time - startTime),
127
127
  r: [Math.round(rect.left * 10) / 10, Math.round(rect.top * 10) / 10, Math.round(rect.right * 10) / 10, Math.round(rect.bottom * 10) / 10],
128
128
  chg: chg,
129
129
  eid: eid || 0
@@ -23,6 +23,7 @@ var _checkWithinComponent3 = _interopRequireWildcard(require("./utils/check-with
23
23
  var _getMutatedElements = require("./utils/get-mutated-elements");
24
24
  var _isElementVisible = require("./utils/is-element-visible");
25
25
  var _isInVcIgnoreIfNoLayoutShiftMarker = _interopRequireDefault(require("./utils/is-in-vc-ignore-if-no-layout-shift-marker"));
26
+ var _isInputNameMutation = require("./utils/is-input-name-mutation");
26
27
  var _isSameRectDimensions = require("./utils/is-same-rect-dimensions");
27
28
  var _isSameRectSize = require("./utils/is-same-rect-size");
28
29
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
@@ -446,6 +447,21 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
446
447
  }
447
448
  };
448
449
  }
450
+ if ((0, _isInputNameMutation.isInputNameMutation)({
451
+ target: target,
452
+ attributeName: attributeName,
453
+ oldValue: oldValue,
454
+ newValue: newValue
455
+ })) {
456
+ return {
457
+ type: 'mutation:attribute:non-visual-input-name',
458
+ mutationData: {
459
+ attributeName: attributeName,
460
+ oldValue: oldValue,
461
+ newValue: newValue
462
+ }
463
+ };
464
+ }
449
465
  var isRLLPlaceholder = _rllPlaceholders.RLLPlaceholderHandlers.getInstance().isRLLPlaceholderHydration(rect);
450
466
  if (isRLLPlaceholder) {
451
467
  return {
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isInputNameMutation = isInputNameMutation;
7
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
8
+ // Detecting this is required due to a React/Chromium bug, where React itself triggers an attribute mutation for input elements
9
+ // Reference: https://atlassian.slack.com/archives/C08EK6TCUP6/p1764129900970719
10
+ function isInputNameMutation(_ref) {
11
+ var target = _ref.target,
12
+ attributeName = _ref.attributeName,
13
+ oldValue = _ref.oldValue,
14
+ newValue = _ref.newValue;
15
+ if (!(0, _platformFeatureFlags.fg)('platform_ufo_ttvc_v4_exclude_input_name_mutation')) {
16
+ return false;
17
+ }
18
+ return target instanceof HTMLInputElement && attributeName === 'name' && (oldValue === '' || newValue === '');
19
+ }
@@ -1,4 +1,3 @@
1
- import { fg } from '@atlaskit/platform-feature-flags';
2
1
  function getLateMutations(vcDetails, labelStacks = {}, lastInteractionFinish, postInteractionFinishVCRatios) {
3
2
  // Map to track which elements are already seen for each timestamp
4
3
  const seen = new Map();
@@ -22,9 +21,9 @@ function getLateMutations(vcDetails, labelStacks = {}, lastInteractionFinish, po
22
21
  element,
23
22
  viewportHeatmapPercentage: (postInteractionFinishVCRatios === null || postInteractionFinishVCRatios === void 0 ? void 0 : postInteractionFinishVCRatios[element]) || 0
24
23
  };
25
- if (labelStacks && fg('platform_ufo_enable_late_mutation_label_stacks')) {
24
+ if (labelStacks) {
26
25
  const labels = labelStacks[element];
27
- if (labels) {
26
+ if (labels && typeof labels !== 'string') {
28
27
  lateMutation.segment = labels.segment;
29
28
  lateMutation.labelStack = labels.labelStack;
30
29
  }
@@ -74,7 +74,7 @@ export default class VCObserverNew {
74
74
  oldValue: mutationData === null || mutationData === void 0 ? void 0 : mutationData.oldValue,
75
75
  newValue: mutationData === null || mutationData === void 0 ? void 0 : mutationData.newValue
76
76
  };
77
- if (element && this.isPostInteraction && fg('platform_ufo_enable_late_mutation_label_stacks')) {
77
+ if (element && (this.isPostInteraction || fg('platform_ufo_add_segment_names_to_dom_offenders'))) {
78
78
  const labelStacks = getLabelStacks(element);
79
79
  if (labelStacks) {
80
80
  Object.assign(data, {
@@ -39,14 +39,18 @@ export default class AbstractVCCalculatorBase {
39
39
  }
40
40
  return ratios;
41
41
  }
42
- getLabelStacks(filteredEntries) {
42
+ getLabelStacks(filteredEntries, isPostInteraction) {
43
43
  const labelStacks = {};
44
44
  for (const entry of filteredEntries) {
45
45
  if ('elementName' in entry.data && entry.data.labelStacks) {
46
- labelStacks[entry.data.elementName] = {
47
- segment: entry.data.labelStacks.segment,
48
- labelStack: entry.data.labelStacks.labelStack
49
- };
46
+ if (isPostInteraction) {
47
+ labelStacks[entry.data.elementName] = {
48
+ segment: entry.data.labelStacks.segment,
49
+ labelStack: entry.data.labelStacks.labelStack
50
+ };
51
+ } else if (fg('platform_ufo_add_segment_names_to_dom_offenders')) {
52
+ labelStacks[entry.data.elementName] = entry.data.labelStacks.labelStack;
53
+ }
50
54
  }
51
55
  }
52
56
  return labelStacks;
@@ -300,8 +304,8 @@ export default class AbstractVCCalculatorBase {
300
304
  if (ssrRatio !== -1) {
301
305
  result.ssrRatio = ssrRatio;
302
306
  }
303
- if (isPostInteraction) {
304
- result.labelStacks = this.getLabelStacks(filteredEntries);
307
+ if (isPostInteraction || fg('platform_ufo_add_segment_names_to_dom_offenders')) {
308
+ result.labelStacks = this.getLabelStacks(filteredEntries, isPostInteraction);
305
309
  }
306
310
  return result;
307
311
  }
@@ -18,6 +18,11 @@ const getConsideredEntryTypes = include3p => {
18
18
  if (fg('platform_ufo_enable_media_for_ttvc_v3')) {
19
19
  entryTypes.push('mutation:media');
20
20
  }
21
+
22
+ // Still included as part of TTVC v3
23
+ if (fg('platform_ufo_ttvc_v4_exclude_input_name_mutation')) {
24
+ entryTypes.push('mutation:attribute:non-visual-input-name');
25
+ }
21
26
  return entryTypes;
22
27
  };
23
28
 
@@ -15,6 +15,9 @@ const getConsideredEntryTypes = () => {
15
15
  };
16
16
  const getExcludedEntryTypes = () => {
17
17
  const excludedEntryTypes = ['layout-shift:same-rect'];
18
+ if (fg('platform_ufo_ttvc_v4_exclude_input_name_mutation')) {
19
+ excludedEntryTypes.push('mutation:attribute:non-visual-input-name');
20
+ }
18
21
  return excludedEntryTypes;
19
22
  };
20
23
 
@@ -100,7 +100,7 @@ export default class RawDataHandler {
100
100
  }
101
101
  }
102
102
  const observation = {
103
- t: Math.round(entry.time),
103
+ t: Math.round(entry.time - startTime),
104
104
  r: [Math.round(rect.left * 10) / 10, Math.round(rect.top * 10) / 10, Math.round(rect.right * 10) / 10, Math.round(rect.bottom * 10) / 10],
105
105
  chg,
106
106
  eid: eid || 0,
@@ -11,6 +11,7 @@ import checkWithinComponent, { cleanupCaches } from './utils/check-within-compon
11
11
  import { getMutatedElements } from './utils/get-mutated-elements';
12
12
  import { isElementVisible } from './utils/is-element-visible';
13
13
  import isInVCIgnoreIfNoLayoutShiftMarker from './utils/is-in-vc-ignore-if-no-layout-shift-marker';
14
+ import { isInputNameMutation } from './utils/is-input-name-mutation';
14
15
  import { isSameRectDimensions } from './utils/is-same-rect-dimensions';
15
16
  import { isSameRectSize } from './utils/is-same-rect-size';
16
17
  const createElementMutationsWatcher = removedNodeRects => ({
@@ -317,6 +318,21 @@ export default class ViewportObserver {
317
318
  }
318
319
  };
319
320
  }
321
+ if (isInputNameMutation({
322
+ target,
323
+ attributeName,
324
+ oldValue,
325
+ newValue
326
+ })) {
327
+ return {
328
+ type: 'mutation:attribute:non-visual-input-name',
329
+ mutationData: {
330
+ attributeName,
331
+ oldValue,
332
+ newValue
333
+ }
334
+ };
335
+ }
320
336
  const isRLLPlaceholder = RLLPlaceholderHandlers.getInstance().isRLLPlaceholderHydration(rect);
321
337
  if (isRLLPlaceholder) {
322
338
  return {
@@ -0,0 +1,15 @@
1
+ import { fg } from '@atlaskit/platform-feature-flags';
2
+
3
+ // Detecting this is required due to a React/Chromium bug, where React itself triggers an attribute mutation for input elements
4
+ // Reference: https://atlassian.slack.com/archives/C08EK6TCUP6/p1764129900970719
5
+ export function isInputNameMutation({
6
+ target,
7
+ attributeName,
8
+ oldValue,
9
+ newValue
10
+ }) {
11
+ if (!fg('platform_ufo_ttvc_v4_exclude_input_name_mutation')) {
12
+ return false;
13
+ }
14
+ return target instanceof HTMLInputElement && attributeName === 'name' && (oldValue === '' || newValue === '');
15
+ }
@@ -1,7 +1,6 @@
1
1
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
2
2
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
3
3
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
4
- import { fg } from '@atlaskit/platform-feature-flags';
5
4
  function getLateMutations(vcDetails) {
6
5
  var labelStacks = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7
6
  var lastInteractionFinish = arguments.length > 2 ? arguments[2] : undefined;
@@ -32,9 +31,9 @@ function getLateMutations(vcDetails) {
32
31
  element: element,
33
32
  viewportHeatmapPercentage: (postInteractionFinishVCRatios === null || postInteractionFinishVCRatios === void 0 ? void 0 : postInteractionFinishVCRatios[element]) || 0
34
33
  };
35
- if (labelStacks && fg('platform_ufo_enable_late_mutation_label_stacks')) {
34
+ if (labelStacks) {
36
35
  var labels = labelStacks[element];
37
- if (labels) {
36
+ if (labels && typeof labels !== 'string') {
38
37
  lateMutation.segment = labels.segment;
39
38
  lateMutation.labelStack = labels.labelStack;
40
39
  }
@@ -81,7 +81,7 @@ var VCObserverNew = /*#__PURE__*/function () {
81
81
  oldValue: mutationData === null || mutationData === void 0 ? void 0 : mutationData.oldValue,
82
82
  newValue: mutationData === null || mutationData === void 0 ? void 0 : mutationData.newValue
83
83
  };
84
- if (element && _this.isPostInteraction && fg('platform_ufo_enable_late_mutation_label_stacks')) {
84
+ if (element && (_this.isPostInteraction || fg('platform_ufo_add_segment_names_to_dom_offenders'))) {
85
85
  var labelStacks = getLabelStacks(element);
86
86
  if (labelStacks) {
87
87
  Object.assign(data, {
@@ -77,7 +77,7 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
77
77
  }
78
78
  }, {
79
79
  key: "getLabelStacks",
80
- value: function getLabelStacks(filteredEntries) {
80
+ value: function getLabelStacks(filteredEntries, isPostInteraction) {
81
81
  var labelStacks = {};
82
82
  var _iterator3 = _createForOfIteratorHelper(filteredEntries),
83
83
  _step3;
@@ -85,10 +85,14 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
85
85
  for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
86
86
  var _entry2 = _step3.value;
87
87
  if ('elementName' in _entry2.data && _entry2.data.labelStacks) {
88
- labelStacks[_entry2.data.elementName] = {
89
- segment: _entry2.data.labelStacks.segment,
90
- labelStack: _entry2.data.labelStacks.labelStack
91
- };
88
+ if (isPostInteraction) {
89
+ labelStacks[_entry2.data.elementName] = {
90
+ segment: _entry2.data.labelStacks.segment,
91
+ labelStack: _entry2.data.labelStacks.labelStack
92
+ };
93
+ } else if (fg('platform_ufo_add_segment_names_to_dom_offenders')) {
94
+ labelStacks[_entry2.data.elementName] = _entry2.data.labelStacks.labelStack;
95
+ }
92
96
  }
93
97
  }
94
98
  } catch (err) {
@@ -409,8 +413,8 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
409
413
  if (ssrRatio !== -1) {
410
414
  result.ssrRatio = ssrRatio;
411
415
  }
412
- if (isPostInteraction) {
413
- result.labelStacks = this.getLabelStacks(filteredEntries);
416
+ if (isPostInteraction || fg('platform_ufo_add_segment_names_to_dom_offenders')) {
417
+ result.labelStacks = this.getLabelStacks(filteredEntries, isPostInteraction);
414
418
  }
415
419
  return _context2.abrupt("return", result);
416
420
  case 17:
@@ -25,6 +25,11 @@ var getConsideredEntryTypes = function getConsideredEntryTypes(include3p) {
25
25
  if (fg('platform_ufo_enable_media_for_ttvc_v3')) {
26
26
  entryTypes.push('mutation:media');
27
27
  }
28
+
29
+ // Still included as part of TTVC v3
30
+ if (fg('platform_ufo_ttvc_v4_exclude_input_name_mutation')) {
31
+ entryTypes.push('mutation:attribute:non-visual-input-name');
32
+ }
28
33
  return entryTypes;
29
34
  };
30
35
 
@@ -24,6 +24,9 @@ var getConsideredEntryTypes = function getConsideredEntryTypes() {
24
24
  };
25
25
  var getExcludedEntryTypes = function getExcludedEntryTypes() {
26
26
  var excludedEntryTypes = ['layout-shift:same-rect'];
27
+ if (fg('platform_ufo_ttvc_v4_exclude_input_name_mutation')) {
28
+ excludedEntryTypes.push('mutation:attribute:non-visual-input-name');
29
+ }
27
30
  return excludedEntryTypes;
28
31
  };
29
32
 
@@ -116,7 +116,7 @@ var RawDataHandler = /*#__PURE__*/function () {
116
116
  }
117
117
  }
118
118
  var observation = _objectSpread({
119
- t: Math.round(entry.time),
119
+ t: Math.round(entry.time - startTime),
120
120
  r: [Math.round(rect.left * 10) / 10, Math.round(rect.top * 10) / 10, Math.round(rect.right * 10) / 10, Math.round(rect.bottom * 10) / 10],
121
121
  chg: chg,
122
122
  eid: eid || 0
@@ -18,6 +18,7 @@ import checkWithinComponent, { cleanupCaches } from './utils/check-within-compon
18
18
  import { getMutatedElements } from './utils/get-mutated-elements';
19
19
  import { isElementVisible } from './utils/is-element-visible';
20
20
  import isInVCIgnoreIfNoLayoutShiftMarker from './utils/is-in-vc-ignore-if-no-layout-shift-marker';
21
+ import { isInputNameMutation } from './utils/is-input-name-mutation';
21
22
  import { isSameRectDimensions } from './utils/is-same-rect-dimensions';
22
23
  import { isSameRectSize } from './utils/is-same-rect-size';
23
24
  var createElementMutationsWatcher = function createElementMutationsWatcher(removedNodeRects) {
@@ -437,6 +438,21 @@ var ViewportObserver = /*#__PURE__*/function () {
437
438
  }
438
439
  };
439
440
  }
441
+ if (isInputNameMutation({
442
+ target: target,
443
+ attributeName: attributeName,
444
+ oldValue: oldValue,
445
+ newValue: newValue
446
+ })) {
447
+ return {
448
+ type: 'mutation:attribute:non-visual-input-name',
449
+ mutationData: {
450
+ attributeName: attributeName,
451
+ oldValue: oldValue,
452
+ newValue: newValue
453
+ }
454
+ };
455
+ }
440
456
  var isRLLPlaceholder = RLLPlaceholderHandlers.getInstance().isRLLPlaceholderHydration(rect);
441
457
  if (isRLLPlaceholder) {
442
458
  return {
@@ -0,0 +1,14 @@
1
+ import { fg } from '@atlaskit/platform-feature-flags';
2
+
3
+ // Detecting this is required due to a React/Chromium bug, where React itself triggers an attribute mutation for input elements
4
+ // Reference: https://atlassian.slack.com/archives/C08EK6TCUP6/p1764129900970719
5
+ export function isInputNameMutation(_ref) {
6
+ var target = _ref.target,
7
+ attributeName = _ref.attributeName,
8
+ oldValue = _ref.oldValue,
9
+ newValue = _ref.newValue;
10
+ if (!fg('platform_ufo_ttvc_v4_exclude_input_name_mutation')) {
11
+ return false;
12
+ }
13
+ return target instanceof HTMLInputElement && attributeName === 'name' && (oldValue === '' || newValue === '');
14
+ }
@@ -18,7 +18,7 @@ export type VCLabelStacks = {
18
18
  [elementName: string]: {
19
19
  segment: string;
20
20
  labelStack: string;
21
- };
21
+ } | string;
22
22
  };
23
23
  export type VCRawDataType = {
24
24
  abortReasonInfo: string | null;
@@ -1,6 +1,6 @@
1
1
  import type { AbortReasonType, InteractionType } from '../../common/common/types';
2
2
  import type { ObservedWindowEvent } from './window-event-observer';
3
- export type VCObserverEntryType = 'mutation:child-element' | 'mutation:remount' | 'mutation:element' | 'mutation:element-replacement' | 'mutation:display-contents-children-element' | 'mutation:display-contents-children-attribute' | 'mutation:attribute:no-layout-shift' | 'mutation:attribute:non-visual-style' | 'mutation:attribute' | 'mutation:media' | 'mutation:rll-placeholder' | 'mutation:third-party-element' | 'mutation:third-party-attribute' | 'mutation:ssr-placeholder' | 'layout-shift' | 'layout-shift:same-rect' | 'window:event' | 'ssr-hydration' | 'unknown';
3
+ export type VCObserverEntryType = 'mutation:child-element' | 'mutation:remount' | 'mutation:element' | 'mutation:element-replacement' | 'mutation:display-contents-children-element' | 'mutation:display-contents-children-attribute' | 'mutation:attribute:no-layout-shift' | 'mutation:attribute:non-visual-style' | 'mutation:attribute:non-visual-input-name' | 'mutation:attribute' | 'mutation:media' | 'mutation:rll-placeholder' | 'mutation:third-party-element' | 'mutation:third-party-attribute' | 'mutation:ssr-placeholder' | 'layout-shift' | 'layout-shift:same-rect' | 'window:event' | 'ssr-hydration' | 'unknown';
4
4
  export type ViewportEntryData = {
5
5
  readonly type: VCObserverEntryType;
6
6
  readonly elementName: string;
@@ -0,0 +1,6 @@
1
+ export declare function isInputNameMutation({ target, attributeName, oldValue, newValue, }: {
2
+ target?: Node | null;
3
+ attributeName?: string | null;
4
+ oldValue?: string | undefined | null;
5
+ newValue?: string | undefined | null;
6
+ }): boolean;
@@ -18,7 +18,7 @@ export type VCLabelStacks = {
18
18
  [elementName: string]: {
19
19
  segment: string;
20
20
  labelStack: string;
21
- };
21
+ } | string;
22
22
  };
23
23
  export type VCRawDataType = {
24
24
  abortReasonInfo: string | null;
@@ -1,6 +1,6 @@
1
1
  import type { AbortReasonType, InteractionType } from '../../common/common/types';
2
2
  import type { ObservedWindowEvent } from './window-event-observer';
3
- export type VCObserverEntryType = 'mutation:child-element' | 'mutation:remount' | 'mutation:element' | 'mutation:element-replacement' | 'mutation:display-contents-children-element' | 'mutation:display-contents-children-attribute' | 'mutation:attribute:no-layout-shift' | 'mutation:attribute:non-visual-style' | 'mutation:attribute' | 'mutation:media' | 'mutation:rll-placeholder' | 'mutation:third-party-element' | 'mutation:third-party-attribute' | 'mutation:ssr-placeholder' | 'layout-shift' | 'layout-shift:same-rect' | 'window:event' | 'ssr-hydration' | 'unknown';
3
+ export type VCObserverEntryType = 'mutation:child-element' | 'mutation:remount' | 'mutation:element' | 'mutation:element-replacement' | 'mutation:display-contents-children-element' | 'mutation:display-contents-children-attribute' | 'mutation:attribute:no-layout-shift' | 'mutation:attribute:non-visual-style' | 'mutation:attribute:non-visual-input-name' | 'mutation:attribute' | 'mutation:media' | 'mutation:rll-placeholder' | 'mutation:third-party-element' | 'mutation:third-party-attribute' | 'mutation:ssr-placeholder' | 'layout-shift' | 'layout-shift:same-rect' | 'window:event' | 'ssr-hydration' | 'unknown';
4
4
  export type ViewportEntryData = {
5
5
  readonly type: VCObserverEntryType;
6
6
  readonly elementName: string;
@@ -0,0 +1,6 @@
1
+ export declare function isInputNameMutation({ target, attributeName, oldValue, newValue, }: {
2
+ target?: Node | null;
3
+ attributeName?: string | null;
4
+ oldValue?: string | undefined | null;
5
+ newValue?: string | undefined | null;
6
+ }): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/react-ufo",
3
- "version": "4.15.7",
3
+ "version": "4.15.9",
4
4
  "description": "Parts of React UFO that are publicly available",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -110,6 +110,9 @@
110
110
  "platform_ufo_critical_metrics_payload": {
111
111
  "type": "boolean"
112
112
  },
113
+ "platform_ufo_ttvc_v4_exclude_input_name_mutation": {
114
+ "type": "boolean"
115
+ },
113
116
  "platform_ufo_disable_vcnext_observations": {
114
117
  "type": "boolean"
115
118
  },
@@ -143,7 +146,7 @@
143
146
  "platform_ufo_enable_late_holds_post_interaction": {
144
147
  "type": "boolean"
145
148
  },
146
- "platform_ufo_enable_late_mutation_label_stacks": {
149
+ "platform_ufo_add_segment_names_to_dom_offenders": {
147
150
  "type": "boolean"
148
151
  },
149
152
  "platform_ufo_filter_cls_logs_same_rects_positions": {