@atlaskit/react-ufo 4.16.7 → 4.17.0

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 (45) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cjs/interaction-metrics/index.js +7 -1
  3. package/dist/cjs/interaction-metrics/post-interaction-log.js +1 -2
  4. package/dist/cjs/vc/index.js +2 -1
  5. package/dist/cjs/vc/vc-observer-new/index.js +3 -1
  6. package/dist/cjs/vc/vc-observer-new/metric-calculator/fy25_03/index.js +7 -3
  7. package/dist/cjs/vc/vc-observer-new/metric-calculator/fy26_04/index.js +2 -2
  8. package/dist/cjs/vc/vc-observer-new/raw-data-handler/index.js +12 -5
  9. package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +26 -5
  10. package/dist/cjs/vc/vc-observer-new/viewport-observer/utils/is-contained-within-smart-answers.js +20 -0
  11. package/dist/es2019/interaction-metrics/index.js +7 -1
  12. package/dist/es2019/interaction-metrics/post-interaction-log.js +1 -2
  13. package/dist/es2019/vc/index.js +2 -1
  14. package/dist/es2019/vc/vc-observer-new/index.js +3 -1
  15. package/dist/es2019/vc/vc-observer-new/metric-calculator/fy25_03/index.js +7 -3
  16. package/dist/es2019/vc/vc-observer-new/metric-calculator/fy26_04/index.js +2 -2
  17. package/dist/es2019/vc/vc-observer-new/raw-data-handler/index.js +10 -3
  18. package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +24 -3
  19. package/dist/es2019/vc/vc-observer-new/viewport-observer/utils/is-contained-within-smart-answers.js +14 -0
  20. package/dist/esm/interaction-metrics/index.js +7 -1
  21. package/dist/esm/interaction-metrics/post-interaction-log.js +1 -2
  22. package/dist/esm/vc/index.js +2 -1
  23. package/dist/esm/vc/vc-observer-new/index.js +3 -1
  24. package/dist/esm/vc/vc-observer-new/metric-calculator/fy25_03/index.js +7 -3
  25. package/dist/esm/vc/vc-observer-new/metric-calculator/fy26_04/index.js +2 -2
  26. package/dist/esm/vc/vc-observer-new/raw-data-handler/index.js +12 -5
  27. package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +26 -5
  28. package/dist/esm/vc/vc-observer-new/viewport-observer/utils/is-contained-within-smart-answers.js +14 -0
  29. package/dist/types/config/index.d.ts +1 -0
  30. package/dist/types/vc/types.d.ts +14 -0
  31. package/dist/types/vc/vc-observer/observers/index.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/fy26_04/index.d.ts +1 -1
  34. package/dist/types/vc/vc-observer-new/types.d.ts +1 -1
  35. package/dist/types/vc/vc-observer-new/viewport-observer/index.d.ts +5 -1
  36. package/dist/types/vc/vc-observer-new/viewport-observer/utils/is-contained-within-smart-answers.d.ts +1 -0
  37. package/dist/types-ts4.5/config/index.d.ts +1 -0
  38. package/dist/types-ts4.5/vc/types.d.ts +14 -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-new/index.d.ts +2 -0
  41. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/fy26_04/index.d.ts +1 -1
  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/utils/is-contained-within-smart-answers.d.ts +1 -0
  45. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @atlaskit/ufo-interaction-ignore
2
2
 
3
+ ## 4.17.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`9f645244e3aba`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/9f645244e3aba) -
8
+ Fixed two related problems:
9
+ - The additional metric which fires on the search page was not correctly ignoring smart answer
10
+ mutations
11
+ - fy26.04 metric was not propagating argument to exclude smart answer mutations
12
+
13
+ ## 4.16.8
14
+
15
+ ### Patch Changes
16
+
17
+ - [`4272868869ef8`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/4272868869ef8) -
18
+ Updated threshold for observations and keep SSR entry
19
+
3
20
  ## 4.16.7
4
21
 
5
22
  ### Patch Changes
@@ -1147,6 +1147,7 @@ function addOnCancelCallback(id, cancelCallback) {
1147
1147
  interaction === null || interaction === void 0 || interaction.cancelCallbacks.push(cancelCallback);
1148
1148
  }
1149
1149
  function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelStack, routeName) {
1150
+ var _config$extraSearchPa, _config$extraSearchPa2;
1150
1151
  var trace = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : null;
1151
1152
  interactionExtraMetrics.reset();
1152
1153
  postInteractionLog.reset();
@@ -1174,13 +1175,18 @@ function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelS
1174
1175
  }
1175
1176
  var addFeatureFlagsToInteraction = (0, _coinflip.default)((0, _config.getCapabilityRate)('feature_flag_access'));
1176
1177
  var config = (0, _config.getConfig)();
1178
+ var searchPageConfig = (0, _platformFeatureFlags.fg)('rovo_search_page_ttvc_ignoring_smart_answers_fix') ? {
1179
+ enableSmartAnswersMutations: config === null || config === void 0 || (_config$extraSearchPa = config.extraSearchPageInteraction) === null || _config$extraSearchPa === void 0 ? void 0 : _config$extraSearchPa.enabled,
1180
+ searchPageRoute: config === null || config === void 0 || (_config$extraSearchPa2 = config.extraSearchPageInteraction) === null || _config$extraSearchPa2 === void 0 ? void 0 : _config$extraSearchPa2.searchPageRoute
1181
+ } : undefined;
1177
1182
  if (config && config.vc) {
1178
1183
  var vcOptions = {
1179
1184
  heatmapSize: config.vc.heatmapSize,
1180
1185
  oldDomUpdates: config.vc.oldDomUpdates,
1181
1186
  devToolsEnabled: config.vc.devToolsEnabled,
1182
1187
  selectorConfig: config.vc.selectorConfig,
1183
- ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder
1188
+ ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder,
1189
+ searchPageConfig: searchPageConfig
1184
1190
  };
1185
1191
  vcObserver = (0, _vc.newVCObserver)(vcOptions);
1186
1192
  }
@@ -10,7 +10,6 @@ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/
10
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
11
11
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
12
12
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
13
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
14
13
  var _config = require("../config");
15
14
  var _hiddenTiming = require("../hidden-timing");
16
15
  var _vc = require("../vc");
@@ -129,7 +128,7 @@ var PostInteractionLog = exports.default = /*#__PURE__*/function () {
129
128
  return _regenerator.default.wrap(function _callee$(_context) {
130
129
  while (1) switch (_context.prev = _context.next) {
131
130
  case 0:
132
- if (!(!this.lastInteractionFinish || !this.sinkHandlerFn || !this.hasData() && !(0, _platformFeatureFlags.fg)('platform_ufo_always_send_post_interaction_log'))) {
131
+ if (!(!this.lastInteractionFinish || !this.sinkHandlerFn)) {
133
132
  _context.next = 4;
134
133
  break;
135
134
  }
@@ -45,7 +45,8 @@ var VCObserverWrapper = exports.VCObserverWrapper = /*#__PURE__*/function () {
45
45
  SSRConfig: {
46
46
  enablePageLayoutPlaceholder: (_opts$ssrEnablePageLa2 = opts.ssrEnablePageLayoutPlaceholder) !== null && _opts$ssrEnablePageLa2 !== void 0 ? _opts$ssrEnablePageLa2 : false
47
47
  },
48
- ssrPlaceholderHandler: this.ssrPlaceholderHandler
48
+ ssrPlaceholderHandler: this.ssrPlaceholderHandler,
49
+ searchPageConfig: opts.searchPageConfig
49
50
  });
50
51
  }
51
52
  if ((0, _config.isVCRevisionEnabled)('fy25.01') || (0, _config.isVCRevisionEnabled)('fy25.02')) {
@@ -109,7 +109,8 @@ var VCObserverNew = exports.default = /*#__PURE__*/function () {
109
109
  },
110
110
  getSSRPlaceholderHandler: function getSSRPlaceholderHandler() {
111
111
  return _this.getSSRPlaceholderHandler();
112
- }
112
+ },
113
+ searchPageConfig: config.searchPageConfig
113
114
  });
114
115
  this.windowEventObserver = new _windowEventObserver.default({
115
116
  onEvent: function onEvent(_ref) {
@@ -318,6 +319,7 @@ var VCObserverNew = exports.default = /*#__PURE__*/function () {
318
319
  interactionType: interactionType,
319
320
  isPostInteraction: this.isPostInteraction,
320
321
  include3p: include3p,
322
+ excludeSmartAnswersInSearch: excludeSmartAnswersInSearch,
321
323
  includeSSRRatio: includeSSRRatio,
322
324
  isPageVisible: isPageVisible,
323
325
  interactionAbortReason: interactionAbortReason
@@ -21,7 +21,7 @@ function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0,
21
21
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
22
22
  var ABORTING_WINDOW_EVENT = ['wheel', 'scroll', 'keydown', 'resize'];
23
23
  var REVISION_NO = 'fy25.03';
24
- var getConsideredEntryTypes = function getConsideredEntryTypes(include3p) {
24
+ var getConsideredEntryTypes = function getConsideredEntryTypes(include3p, excludeSmartAnswersInSearch) {
25
25
  var entryTypes = ['mutation:child-element', 'mutation:element', 'mutation:attribute', 'layout-shift', 'layout-shift:same-rect', 'window:event'];
26
26
 
27
27
  // If not exclude 3p elements from ttvc,
@@ -30,6 +30,10 @@ var getConsideredEntryTypes = function getConsideredEntryTypes(include3p) {
30
30
  entryTypes.push('mutation:third-party-element');
31
31
  entryTypes.push('mutation:third-party-attribute');
32
32
  }
33
+ if (!excludeSmartAnswersInSearch && (0, _platformFeatureFlags.fg)('rovo_search_page_ttvc_ignoring_smart_answers_fix')) {
34
+ entryTypes.push('mutation:smart-answers-element');
35
+ entryTypes.push('mutation:smart-answers-attribute');
36
+ }
33
37
  if ((0, _platformFeatureFlags.fg)('platform_ufo_enable_media_for_ttvc_v3')) {
34
38
  entryTypes.push('mutation:media');
35
39
  }
@@ -47,10 +51,10 @@ var VCCalculator_FY25_03 = exports.default = /*#__PURE__*/function (_AbstractVCC
47
51
  return (0, _createClass2.default)(VCCalculator_FY25_03, [{
48
52
  key: "isEntryIncluded",
49
53
  value: function isEntryIncluded(entry, include3p, excludeSmartAnswersInSearch) {
50
- if (!getConsideredEntryTypes(include3p).includes(entry.data.type)) {
54
+ if (!getConsideredEntryTypes(include3p, excludeSmartAnswersInSearch).includes(entry.data.type)) {
51
55
  return false;
52
56
  }
53
- if (excludeSmartAnswersInSearch && (0, _isEntrySmartAnswersInSearch.isEntrySmartAnswersInSearch)(entry)) {
57
+ if (excludeSmartAnswersInSearch && (0, _isEntrySmartAnswersInSearch.isEntrySmartAnswersInSearch)(entry) && !(0, _platformFeatureFlags.fg)('rovo_search_page_ttvc_ignoring_smart_answers_fix')) {
54
58
  return false;
55
59
  }
56
60
  if (entry.data.type === 'mutation:media' && (0, _platformFeatureFlags.fg)('media-perf-uplift-mutation-fix')) {
@@ -39,8 +39,8 @@ var VCCalculator_FY26_04 = exports.default = /*#__PURE__*/function (_VCCalculato
39
39
  (0, _inherits2.default)(VCCalculator_FY26_04, _VCCalculator_FY25_);
40
40
  return (0, _createClass2.default)(VCCalculator_FY26_04, [{
41
41
  key: "isEntryIncluded",
42
- value: function isEntryIncluded(entry, include3p) {
43
- var isEntryIncludedInV3 = _superPropGet(VCCalculator_FY26_04, "isEntryIncluded", this, 3)([entry, include3p]);
42
+ value: function isEntryIncluded(entry, include3p, excludeSmartAnswersInSearch) {
43
+ var isEntryIncludedInV3 = _superPropGet(VCCalculator_FY26_04, "isEntryIncluded", this, 3)([entry, include3p, excludeSmartAnswersInSearch]);
44
44
  if (isEntryIncludedInV3 && !getExcludedEntryTypes().includes(entry.data.type)) {
45
45
  return true;
46
46
  }
@@ -19,7 +19,7 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
19
19
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
20
20
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
21
21
  var ABORTING_WINDOW_EVENT = ['wheel', 'scroll', 'keydown', 'resize'];
22
- var MAX_OBSERVATIONS = 100;
22
+ var MAX_OBSERVATIONS = 200;
23
23
  function isWindowEventEntryData(data) {
24
24
  return data.type === 'window:event' && 'eventType' in data;
25
25
  }
@@ -59,7 +59,7 @@ var RawDataHandler = exports.default = /*#__PURE__*/function () {
59
59
  key: "getRawData",
60
60
  value: function () {
61
61
  var _getRawData = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref) {
62
- var entries, startTime, stopTime, isPageVisible, isVCClean, dirtyReason, getVCCleanStatusResult, viewportEntries, windowEventEntries, targetNameToIdMap, elementMapEntriesMap, nextElementId, typeMap, typeMapEntriesMap, nextTypeId, attributeMap, attributeEntriesMap, nextAttributeId, eventTypeMap, eventTypeMapEntriesMap, nextEventTypeId, rawObservations, rawEventObservations, firstObservation, lastObservations, referencedEids, referencedChgs, referencedAtts, _iterator, _step, observation, _iterator2, _step2, eid, _iterator3, _step3, chg, _iterator4, _step4, att, firstEventObservation, lastEventObservations, referencedEvts, _iterator5, _step5, _observation, _iterator6, _step6, evt, result;
62
+ var entries, startTime, stopTime, isPageVisible, isVCClean, dirtyReason, getVCCleanStatusResult, viewportEntries, windowEventEntries, targetNameToIdMap, elementMapEntriesMap, nextElementId, typeMap, typeMapEntriesMap, nextTypeId, attributeMap, attributeEntriesMap, nextAttributeId, eventTypeMap, eventTypeMapEntriesMap, nextEventTypeId, rawObservations, rawEventObservations, firstObservation, lastObservations, ssrEid, ssrObservation, ssrAlreadyIncluded, referencedEids, referencedChgs, referencedAtts, _iterator, _step, observation, _iterator2, _step2, eid, _iterator3, _step3, chg, _iterator4, _step4, att, firstEventObservation, lastEventObservations, referencedEvts, _iterator5, _step5, _observation, _iterator6, _step6, evt, result;
63
63
  return _regenerator.default.wrap(function _callee$(_context) {
64
64
  while (1) switch (_context.prev = _context.next) {
65
65
  case 0:
@@ -157,12 +157,19 @@ var RawDataHandler = exports.default = /*#__PURE__*/function () {
157
157
  };
158
158
  return eventObservation;
159
159
  }); // If the number of observations is greater than the maximum allowed, we need to trim the observations to the maximum allowed.
160
- // We do this by keeping the first observation and the last MAX_OBSERVATIONS observations.
160
+ // We do this by keeping the first observation, the SSR observation (if present), and the last MAX_OBSERVATIONS observations.
161
161
  // We then collect the referenced IDs from the remaining observations and remove the unreferenced entries from the maps
162
162
  if (rawObservations.length > MAX_OBSERVATIONS) {
163
163
  firstObservation = rawObservations[0];
164
- lastObservations = rawObservations.slice(-MAX_OBSERVATIONS);
165
- rawObservations = [firstObservation].concat((0, _toConsumableArray2.default)(lastObservations));
164
+ lastObservations = rawObservations.slice(-MAX_OBSERVATIONS); // Find the SSR observation by looking up the eid that corresponds to 'SSR' element name
165
+ ssrEid = targetNameToIdMap.get('SSR');
166
+ ssrObservation = ssrEid ? rawObservations.find(function (obs) {
167
+ return obs.eid === ssrEid && obs !== firstObservation;
168
+ }) : undefined; // Include SSR observation if it exists and is not already in the kept observations
169
+ ssrAlreadyIncluded = ssrObservation && lastObservations.some(function (obs) {
170
+ return obs === ssrObservation;
171
+ });
172
+ rawObservations = [firstObservation].concat((0, _toConsumableArray2.default)(ssrObservation && !ssrAlreadyIncluded ? [ssrObservation] : []), (0, _toConsumableArray2.default)(lastObservations));
166
173
 
167
174
  // Collect referenced IDs from remaining observations
168
175
  referencedEids = new Set();
@@ -20,6 +20,7 @@ var _intersectionObserver = require("./intersection-observer");
20
20
  var _mutationObserver = _interopRequireDefault(require("./mutation-observer"));
21
21
  var _performanceObserver = _interopRequireDefault(require("./performance-observer"));
22
22
  var _checkWithinComponent3 = _interopRequireWildcard(require("./utils/check-within-component"));
23
+ var _isContainedWithinSmartAnswers = require("./utils/is-contained-within-smart-answers");
23
24
  var _isElementVisible = require("./utils/is-element-visible");
24
25
  var _isInVcIgnoreIfNoLayoutShiftMarker = _interopRequireDefault(require("./utils/is-in-vc-ignore-if-no-layout-shift-marker"));
25
26
  var _isInputNameMutation = require("./utils/is-input-name-mutation");
@@ -29,7 +30,7 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
29
30
  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; } } }; }
30
31
  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; } }
31
32
  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; }
32
- var createElementMutationsWatcher = function createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, hasSameDeletedNode, timestamp, isTargetReactRoot, getSSRState, getSSRPlaceholderHandler) {
33
+ var createElementMutationsWatcher = function createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, isWithinSmartAnswersSegment, hasSameDeletedNode, timestamp, isTargetReactRoot, getSSRState, getSSRPlaceholderHandler) {
33
34
  return function (_ref) {
34
35
  var target = _ref.target,
35
36
  rect = _ref.rect;
@@ -76,6 +77,9 @@ var createElementMutationsWatcher = function createElementMutationsWatcher(remov
76
77
  if (isWithinThirdPartySegment) {
77
78
  return 'mutation:third-party-element';
78
79
  }
80
+ if (isWithinSmartAnswersSegment) {
81
+ return 'mutation:smart-answers-element';
82
+ }
79
83
  var isInIgnoreLsMarker = (0, _isInVcIgnoreIfNoLayoutShiftMarker.default)(target);
80
84
  if (!isInIgnoreLsMarker) {
81
85
  return 'mutation:element';
@@ -100,7 +104,8 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
100
104
  var _this = this;
101
105
  var onChange = _ref2.onChange,
102
106
  getSSRState = _ref2.getSSRState,
103
- getSSRPlaceholderHandler = _ref2.getSSRPlaceholderHandler;
107
+ getSSRPlaceholderHandler = _ref2.getSSRPlaceholderHandler,
108
+ searchPageConfig = _ref2.searchPageConfig;
104
109
  (0, _classCallCheck2.default)(this, ViewportObserver);
105
110
  (0, _defineProperty2.default)(this, "handleIntersectionEntry", function (_ref3) {
106
111
  var target = _ref3.target,
@@ -143,7 +148,7 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
143
148
  _context2.prev = 4;
144
149
  _loop = /*#__PURE__*/_regenerator.default.mark(function _loop() {
145
150
  var _this$getSSRState, _this$intersectionObs;
146
- var addedNodeRef, addedNode, hasSameDeletedNode, _checkWithinComponent, isWithinThirdPartySegment, isTargetReactRoot;
151
+ var addedNodeRef, addedNode, hasSameDeletedNode, _checkWithinComponent, isWithinThirdPartySegment, isWithinSmartAnswersSegment, isTargetReactRoot;
147
152
  return _regenerator.default.wrap(function _loop$(_context) {
148
153
  while (1) switch (_context.prev = _context.next) {
149
154
  case 0:
@@ -163,9 +168,10 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
163
168
  return n.isEqualNode(addedNode);
164
169
  });
165
170
  _checkWithinComponent = (0, _checkWithinComponent3.default)(addedNode, 'UFOThirdPartySegment', _this.mapIs3pResult), isWithinThirdPartySegment = _checkWithinComponent.isWithin;
171
+ isWithinSmartAnswersSegment = Boolean(_this.shouldCheckSmartAnswersMutations() && (0, _isContainedWithinSmartAnswers.isContainedWithinSmartAnswers)(addedNode));
166
172
  isTargetReactRoot = targetNode === ((_this$getSSRState = _this.getSSRState) === null || _this$getSSRState === void 0 || (_this$getSSRState = _this$getSSRState.call(_this)) === null || _this$getSSRState === void 0 ? void 0 : _this$getSSRState.reactRootElement);
167
- (_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, !!hasSameDeletedNode, timestamp, isTargetReactRoot, _this.getSSRState, _this.getSSRPlaceholderHandler));
168
- case 8:
173
+ (_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, isWithinSmartAnswersSegment, !!hasSameDeletedNode, timestamp, isTargetReactRoot, _this.getSSRState, _this.getSSRPlaceholderHandler));
174
+ case 9:
169
175
  case "end":
170
176
  return _context.stop();
171
177
  }
@@ -241,6 +247,16 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
241
247
  };
242
248
  }
243
249
  }
250
+ if (_this.shouldCheckSmartAnswersMutations() && (0, _isContainedWithinSmartAnswers.isContainedWithinSmartAnswers)(target)) {
251
+ return {
252
+ type: 'mutation:smart-answers-attribute',
253
+ mutationData: {
254
+ attributeName: attributeName,
255
+ oldValue: oldValue,
256
+ newValue: newValue
257
+ }
258
+ };
259
+ }
244
260
  if ((0, _isDndStyleMutation.default)({
245
261
  target: target,
246
262
  attributeName: attributeName,
@@ -344,6 +360,10 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
344
360
  _iterator2.f();
345
361
  }
346
362
  });
363
+ (0, _defineProperty2.default)(this, "shouldCheckSmartAnswersMutations", function () {
364
+ var _this$searchPageConfi, _this$searchPageConfi2, _window;
365
+ return ((_this$searchPageConfi = _this.searchPageConfig) === null || _this$searchPageConfi === void 0 ? void 0 : _this$searchPageConfi.enableSmartAnswersMutations) && ((_this$searchPageConfi2 = _this.searchPageConfig) === null || _this$searchPageConfi2 === void 0 ? void 0 : _this$searchPageConfi2.searchPageRoute) && ((_window = window) === null || _window === void 0 || (_window = _window.location) === null || _window === void 0 ? void 0 : _window.pathname) && window.location.pathname === _this.searchPageConfig.searchPageRoute && (0, _platformFeatureFlags.fg)('rovo_search_page_ttvc_ignoring_smart_answers_fix');
366
+ });
347
367
  this.mapVisibleNodeRects = new WeakMap();
348
368
  this.mapIs3pResult = new WeakMap();
349
369
  this.onChange = onChange;
@@ -355,6 +375,7 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
355
375
  // Initialize SSR context functions
356
376
  this.getSSRState = getSSRState;
357
377
  this.getSSRPlaceholderHandler = getSSRPlaceholderHandler;
378
+ this.searchPageConfig = searchPageConfig;
358
379
  }
359
380
  return (0, _createClass2.default)(ViewportObserver, [{
360
381
  key: "initializeObservers",
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isContainedWithinSmartAnswers = isContainedWithinSmartAnswers;
7
+ var _browserApis = require("@atlaskit/browser-apis");
8
+ function isContainedWithinSmartAnswers(node) {
9
+ var doc = (0, _browserApis.getDocument)();
10
+ if (!doc) {
11
+ return false;
12
+ }
13
+ var smartAnswersElement = doc.getElementById('search-page-smart-answers');
14
+ if (!smartAnswersElement) {
15
+ return false;
16
+ }
17
+
18
+ // When the node is the smart answer element, .contains() still returns true
19
+ return smartAnswersElement.contains(node);
20
+ }
@@ -1026,6 +1026,7 @@ export function addOnCancelCallback(id, cancelCallback) {
1026
1026
  interaction === null || interaction === void 0 ? void 0 : interaction.cancelCallbacks.push(cancelCallback);
1027
1027
  }
1028
1028
  export function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelStack, routeName, trace = null) {
1029
+ var _config$extraSearchPa, _config$extraSearchPa2;
1029
1030
  interactionExtraMetrics.reset();
1030
1031
  postInteractionLog.reset();
1031
1032
  let vcObserver;
@@ -1052,13 +1053,18 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
1052
1053
  }
1053
1054
  const addFeatureFlagsToInteraction = coinflip(getCapabilityRate('feature_flag_access'));
1054
1055
  const config = getConfig();
1056
+ const searchPageConfig = fg('rovo_search_page_ttvc_ignoring_smart_answers_fix') ? {
1057
+ enableSmartAnswersMutations: config === null || config === void 0 ? void 0 : (_config$extraSearchPa = config.extraSearchPageInteraction) === null || _config$extraSearchPa === void 0 ? void 0 : _config$extraSearchPa.enabled,
1058
+ searchPageRoute: config === null || config === void 0 ? void 0 : (_config$extraSearchPa2 = config.extraSearchPageInteraction) === null || _config$extraSearchPa2 === void 0 ? void 0 : _config$extraSearchPa2.searchPageRoute
1059
+ } : undefined;
1055
1060
  if (config && config.vc) {
1056
1061
  const vcOptions = {
1057
1062
  heatmapSize: config.vc.heatmapSize,
1058
1063
  oldDomUpdates: config.vc.oldDomUpdates,
1059
1064
  devToolsEnabled: config.vc.devToolsEnabled,
1060
1065
  selectorConfig: config.vc.selectorConfig,
1061
- ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder
1066
+ ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder,
1067
+ searchPageConfig
1062
1068
  };
1063
1069
  vcObserver = newVCObserver(vcOptions);
1064
1070
  }
@@ -1,5 +1,4 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import { fg } from '@atlaskit/platform-feature-flags';
3
2
  import { getConfig } from '../config';
4
3
  import { getPageVisibilityState } from '../hidden-timing';
5
4
  import { VCObserverWrapper } from '../vc';
@@ -93,7 +92,7 @@ export default class PostInteractionLog {
93
92
  */
94
93
  async sendPostInteractionLog() {
95
94
  var _this$vcObserver4, _config$vc, _config$vc2, _this$vcObserver5;
96
- if (!this.lastInteractionFinish || !this.sinkHandlerFn || !this.hasData() && !fg('platform_ufo_always_send_post_interaction_log')) {
95
+ if (!this.lastInteractionFinish || !this.sinkHandlerFn) {
97
96
  var _this$vcObserver3;
98
97
  this.reset();
99
98
  (_this$vcObserver3 = this.vcObserver) === null || _this$vcObserver3 === void 0 ? void 0 : _this$vcObserver3.stop();
@@ -25,7 +25,8 @@ export class VCObserverWrapper {
25
25
  SSRConfig: {
26
26
  enablePageLayoutPlaceholder: (_opts$ssrEnablePageLa2 = opts.ssrEnablePageLayoutPlaceholder) !== null && _opts$ssrEnablePageLa2 !== void 0 ? _opts$ssrEnablePageLa2 : false
27
27
  },
28
- ssrPlaceholderHandler: this.ssrPlaceholderHandler
28
+ ssrPlaceholderHandler: this.ssrPlaceholderHandler,
29
+ searchPageConfig: opts.searchPageConfig
29
30
  });
30
31
  }
31
32
  if (isVCRevisionEnabled('fy25.01') || isVCRevisionEnabled('fy25.02')) {
@@ -91,7 +91,8 @@ export default class VCObserverNew {
91
91
  },
92
92
  // Pass SSR context to ViewportObserver
93
93
  getSSRState: () => this.getSSRState(),
94
- getSSRPlaceholderHandler: () => this.getSSRPlaceholderHandler()
94
+ getSSRPlaceholderHandler: () => this.getSSRPlaceholderHandler(),
95
+ searchPageConfig: config.searchPageConfig
95
96
  });
96
97
  this.windowEventObserver = new WindowEventObserver({
97
98
  onEvent: ({
@@ -259,6 +260,7 @@ export default class VCObserverNew {
259
260
  interactionType,
260
261
  isPostInteraction: this.isPostInteraction,
261
262
  include3p,
263
+ excludeSmartAnswersInSearch,
262
264
  includeSSRRatio,
263
265
  isPageVisible,
264
266
  interactionAbortReason
@@ -7,7 +7,7 @@ import { isEntrySmartAnswersInSearch } from '../utils/is-entry-smart-answers-in-
7
7
  import isViewportEntryData from '../utils/is-viewport-entry-data';
8
8
  const ABORTING_WINDOW_EVENT = ['wheel', 'scroll', 'keydown', 'resize'];
9
9
  const REVISION_NO = 'fy25.03';
10
- const getConsideredEntryTypes = include3p => {
10
+ const getConsideredEntryTypes = (include3p, excludeSmartAnswersInSearch) => {
11
11
  const entryTypes = ['mutation:child-element', 'mutation:element', 'mutation:attribute', 'layout-shift', 'layout-shift:same-rect', 'window:event'];
12
12
 
13
13
  // If not exclude 3p elements from ttvc,
@@ -16,6 +16,10 @@ const getConsideredEntryTypes = include3p => {
16
16
  entryTypes.push('mutation:third-party-element');
17
17
  entryTypes.push('mutation:third-party-attribute');
18
18
  }
19
+ if (!excludeSmartAnswersInSearch && fg('rovo_search_page_ttvc_ignoring_smart_answers_fix')) {
20
+ entryTypes.push('mutation:smart-answers-element');
21
+ entryTypes.push('mutation:smart-answers-attribute');
22
+ }
19
23
  if (fg('platform_ufo_enable_media_for_ttvc_v3')) {
20
24
  entryTypes.push('mutation:media');
21
25
  }
@@ -29,10 +33,10 @@ export default class VCCalculator_FY25_03 extends AbstractVCCalculatorBase {
29
33
  super(revisionNo !== null && revisionNo !== void 0 ? revisionNo : REVISION_NO);
30
34
  }
31
35
  isEntryIncluded(entry, include3p, excludeSmartAnswersInSearch) {
32
- if (!getConsideredEntryTypes(include3p).includes(entry.data.type)) {
36
+ if (!getConsideredEntryTypes(include3p, excludeSmartAnswersInSearch).includes(entry.data.type)) {
33
37
  return false;
34
38
  }
35
- if (excludeSmartAnswersInSearch && isEntrySmartAnswersInSearch(entry)) {
39
+ if (excludeSmartAnswersInSearch && isEntrySmartAnswersInSearch(entry) && !fg('rovo_search_page_ttvc_ignoring_smart_answers_fix')) {
36
40
  return false;
37
41
  }
38
42
  if (entry.data.type === 'mutation:media' && fg('media-perf-uplift-mutation-fix')) {
@@ -19,8 +19,8 @@ export default class VCCalculator_FY26_04 extends VCCalculator_FY25_03 {
19
19
  constructor() {
20
20
  super('fy26.04');
21
21
  }
22
- isEntryIncluded(entry, include3p) {
23
- const isEntryIncludedInV3 = super.isEntryIncluded(entry, include3p);
22
+ isEntryIncluded(entry, include3p, excludeSmartAnswersInSearch) {
23
+ const isEntryIncludedInV3 = super.isEntryIncluded(entry, include3p, excludeSmartAnswersInSearch);
24
24
  if (isEntryIncludedInV3 && !getExcludedEntryTypes().includes(entry.data.type)) {
25
25
  return true;
26
26
  }
@@ -2,7 +2,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import getViewportHeight from '../metric-calculator/utils/get-viewport-height';
3
3
  import getViewportWidth from '../metric-calculator/utils/get-viewport-width';
4
4
  const ABORTING_WINDOW_EVENT = ['wheel', 'scroll', 'keydown', 'resize'];
5
- const MAX_OBSERVATIONS = 100;
5
+ const MAX_OBSERVATIONS = 200;
6
6
  function isWindowEventEntryData(data) {
7
7
  return data.type === 'window:event' && 'eventType' in data;
8
8
  }
@@ -137,12 +137,19 @@ export default class RawDataHandler {
137
137
  });
138
138
 
139
139
  // If the number of observations is greater than the maximum allowed, we need to trim the observations to the maximum allowed.
140
- // We do this by keeping the first observation and the last MAX_OBSERVATIONS observations.
140
+ // We do this by keeping the first observation, the SSR observation (if present), and the last MAX_OBSERVATIONS observations.
141
141
  // We then collect the referenced IDs from the remaining observations and remove the unreferenced entries from the maps
142
142
  if (rawObservations.length > MAX_OBSERVATIONS) {
143
143
  const firstObservation = rawObservations[0];
144
144
  const lastObservations = rawObservations.slice(-MAX_OBSERVATIONS);
145
- rawObservations = [firstObservation, ...lastObservations];
145
+
146
+ // Find the SSR observation by looking up the eid that corresponds to 'SSR' element name
147
+ const ssrEid = targetNameToIdMap.get('SSR');
148
+ const ssrObservation = ssrEid ? rawObservations.find(obs => obs.eid === ssrEid && obs !== firstObservation) : undefined;
149
+
150
+ // Include SSR observation if it exists and is not already in the kept observations
151
+ const ssrAlreadyIncluded = ssrObservation && lastObservations.some(obs => obs === ssrObservation);
152
+ rawObservations = [firstObservation, ...(ssrObservation && !ssrAlreadyIncluded ? [ssrObservation] : []), ...lastObservations];
146
153
 
147
154
  // Collect referenced IDs from remaining observations
148
155
  const referencedEids = new Set();
@@ -8,12 +8,13 @@ import { createIntersectionObserver } from './intersection-observer';
8
8
  import createMutationObserver from './mutation-observer';
9
9
  import createPerformanceObserver from './performance-observer';
10
10
  import checkWithinComponent, { cleanupCaches } from './utils/check-within-component';
11
+ import { isContainedWithinSmartAnswers } from './utils/is-contained-within-smart-answers';
11
12
  import { isElementVisible } from './utils/is-element-visible';
12
13
  import isInVCIgnoreIfNoLayoutShiftMarker from './utils/is-in-vc-ignore-if-no-layout-shift-marker';
13
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
- const createElementMutationsWatcher = (removedNodeRects, isWithinThirdPartySegment, hasSameDeletedNode, timestamp, isTargetReactRoot, getSSRState, getSSRPlaceholderHandler) => ({
17
+ const createElementMutationsWatcher = (removedNodeRects, isWithinThirdPartySegment, isWithinSmartAnswersSegment, hasSameDeletedNode, timestamp, isTargetReactRoot, getSSRState, getSSRPlaceholderHandler) => ({
17
18
  target,
18
19
  rect
19
20
  }) => {
@@ -60,6 +61,9 @@ const createElementMutationsWatcher = (removedNodeRects, isWithinThirdPartySegme
60
61
  if (isWithinThirdPartySegment) {
61
62
  return 'mutation:third-party-element';
62
63
  }
64
+ if (isWithinSmartAnswersSegment) {
65
+ return 'mutation:smart-answers-element';
66
+ }
63
67
  const isInIgnoreLsMarker = isInVCIgnoreIfNoLayoutShiftMarker(target);
64
68
  if (!isInIgnoreLsMarker) {
65
69
  return 'mutation:element';
@@ -80,7 +84,8 @@ export default class ViewportObserver {
80
84
  constructor({
81
85
  onChange,
82
86
  getSSRState,
83
- getSSRPlaceholderHandler
87
+ getSSRPlaceholderHandler,
88
+ searchPageConfig
84
89
  }) {
85
90
  _defineProperty(this, "handleIntersectionEntry", ({
86
91
  target,
@@ -135,8 +140,9 @@ export default class ViewportObserver {
135
140
  const {
136
141
  isWithin: isWithinThirdPartySegment
137
142
  } = checkWithinComponent(addedNode, 'UFOThirdPartySegment', this.mapIs3pResult);
143
+ const isWithinSmartAnswersSegment = Boolean(this.shouldCheckSmartAnswersMutations() && isContainedWithinSmartAnswers(addedNode));
138
144
  const isTargetReactRoot = targetNode === ((_this$getSSRState = this.getSSRState) === null || _this$getSSRState === void 0 ? void 0 : (_this$getSSRState$cal = _this$getSSRState.call(this)) === null || _this$getSSRState$cal === void 0 ? void 0 : _this$getSSRState$cal.reactRootElement);
139
- (_this$intersectionObs = this.intersectionObserver) === null || _this$intersectionObs === void 0 ? void 0 : _this$intersectionObs.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, !!hasSameDeletedNode, timestamp, isTargetReactRoot, this.getSSRState, this.getSSRPlaceholderHandler));
145
+ (_this$intersectionObs = this.intersectionObserver) === null || _this$intersectionObs === void 0 ? void 0 : _this$intersectionObs.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, isWithinSmartAnswersSegment, !!hasSameDeletedNode, timestamp, isTargetReactRoot, this.getSSRState, this.getSSRPlaceholderHandler));
140
146
  }
141
147
  });
142
148
  _defineProperty(this, "handleAttributeMutation", ({
@@ -175,6 +181,16 @@ export default class ViewportObserver {
175
181
  };
176
182
  }
177
183
  }
184
+ if (this.shouldCheckSmartAnswersMutations() && isContainedWithinSmartAnswers(target)) {
185
+ return {
186
+ type: 'mutation:smart-answers-attribute',
187
+ mutationData: {
188
+ attributeName,
189
+ oldValue,
190
+ newValue
191
+ }
192
+ };
193
+ }
178
194
  if (isDnDStyleMutation({
179
195
  target,
180
196
  attributeName,
@@ -270,6 +286,10 @@ export default class ViewportObserver {
270
286
  }
271
287
  }
272
288
  });
289
+ _defineProperty(this, "shouldCheckSmartAnswersMutations", () => {
290
+ var _this$searchPageConfi, _this$searchPageConfi2, _window, _window$location;
291
+ return ((_this$searchPageConfi = this.searchPageConfig) === null || _this$searchPageConfi === void 0 ? void 0 : _this$searchPageConfi.enableSmartAnswersMutations) && ((_this$searchPageConfi2 = this.searchPageConfig) === null || _this$searchPageConfi2 === void 0 ? void 0 : _this$searchPageConfi2.searchPageRoute) && ((_window = window) === null || _window === void 0 ? void 0 : (_window$location = _window.location) === null || _window$location === void 0 ? void 0 : _window$location.pathname) && window.location.pathname === this.searchPageConfig.searchPageRoute && fg('rovo_search_page_ttvc_ignoring_smart_answers_fix');
292
+ });
273
293
  this.mapVisibleNodeRects = new WeakMap();
274
294
  this.mapIs3pResult = new WeakMap();
275
295
  this.onChange = onChange;
@@ -281,6 +301,7 @@ export default class ViewportObserver {
281
301
  // Initialize SSR context functions
282
302
  this.getSSRState = getSSRState;
283
303
  this.getSSRPlaceholderHandler = getSSRPlaceholderHandler;
304
+ this.searchPageConfig = searchPageConfig;
284
305
  }
285
306
  initializeObservers() {
286
307
  if (this.isStarted) {
@@ -0,0 +1,14 @@
1
+ import { getDocument } from '@atlaskit/browser-apis';
2
+ export function isContainedWithinSmartAnswers(node) {
3
+ const doc = getDocument();
4
+ if (!doc) {
5
+ return false;
6
+ }
7
+ const smartAnswersElement = doc.getElementById('search-page-smart-answers');
8
+ if (!smartAnswersElement) {
9
+ return false;
10
+ }
11
+
12
+ // When the node is the smart answer element, .contains() still returns true
13
+ return smartAnswersElement.contains(node);
14
+ }
@@ -1100,6 +1100,7 @@ export function addOnCancelCallback(id, cancelCallback) {
1100
1100
  interaction === null || interaction === void 0 || interaction.cancelCallbacks.push(cancelCallback);
1101
1101
  }
1102
1102
  export function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelStack, routeName) {
1103
+ var _config$extraSearchPa, _config$extraSearchPa2;
1103
1104
  var trace = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : null;
1104
1105
  interactionExtraMetrics.reset();
1105
1106
  postInteractionLog.reset();
@@ -1127,13 +1128,18 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
1127
1128
  }
1128
1129
  var addFeatureFlagsToInteraction = coinflip(getCapabilityRate('feature_flag_access'));
1129
1130
  var config = getConfig();
1131
+ var searchPageConfig = fg('rovo_search_page_ttvc_ignoring_smart_answers_fix') ? {
1132
+ enableSmartAnswersMutations: config === null || config === void 0 || (_config$extraSearchPa = config.extraSearchPageInteraction) === null || _config$extraSearchPa === void 0 ? void 0 : _config$extraSearchPa.enabled,
1133
+ searchPageRoute: config === null || config === void 0 || (_config$extraSearchPa2 = config.extraSearchPageInteraction) === null || _config$extraSearchPa2 === void 0 ? void 0 : _config$extraSearchPa2.searchPageRoute
1134
+ } : undefined;
1130
1135
  if (config && config.vc) {
1131
1136
  var vcOptions = {
1132
1137
  heatmapSize: config.vc.heatmapSize,
1133
1138
  oldDomUpdates: config.vc.oldDomUpdates,
1134
1139
  devToolsEnabled: config.vc.devToolsEnabled,
1135
1140
  selectorConfig: config.vc.selectorConfig,
1136
- ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder
1141
+ ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder,
1142
+ searchPageConfig: searchPageConfig
1137
1143
  };
1138
1144
  vcObserver = newVCObserver(vcOptions);
1139
1145
  }
@@ -5,7 +5,6 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
5
5
  import _regeneratorRuntime from "@babel/runtime/regenerator";
6
6
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
7
7
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8
- import { fg } from '@atlaskit/platform-feature-flags';
9
8
  import { getConfig } from '../config';
10
9
  import { getPageVisibilityState } from '../hidden-timing';
11
10
  import { VCObserverWrapper } from '../vc';
@@ -122,7 +121,7 @@ var PostInteractionLog = /*#__PURE__*/function () {
122
121
  return _regeneratorRuntime.wrap(function _callee$(_context) {
123
122
  while (1) switch (_context.prev = _context.next) {
124
123
  case 0:
125
- if (!(!this.lastInteractionFinish || !this.sinkHandlerFn || !this.hasData() && !fg('platform_ufo_always_send_post_interaction_log'))) {
124
+ if (!(!this.lastInteractionFinish || !this.sinkHandlerFn)) {
126
125
  _context.next = 4;
127
126
  break;
128
127
  }
@@ -35,7 +35,8 @@ export var VCObserverWrapper = /*#__PURE__*/function () {
35
35
  SSRConfig: {
36
36
  enablePageLayoutPlaceholder: (_opts$ssrEnablePageLa2 = opts.ssrEnablePageLayoutPlaceholder) !== null && _opts$ssrEnablePageLa2 !== void 0 ? _opts$ssrEnablePageLa2 : false
37
37
  },
38
- ssrPlaceholderHandler: this.ssrPlaceholderHandler
38
+ ssrPlaceholderHandler: this.ssrPlaceholderHandler,
39
+ searchPageConfig: opts.searchPageConfig
39
40
  });
40
41
  }
41
42
  if (isVCRevisionEnabled('fy25.01') || isVCRevisionEnabled('fy25.02')) {
@@ -102,7 +102,8 @@ var VCObserverNew = /*#__PURE__*/function () {
102
102
  },
103
103
  getSSRPlaceholderHandler: function getSSRPlaceholderHandler() {
104
104
  return _this.getSSRPlaceholderHandler();
105
- }
105
+ },
106
+ searchPageConfig: config.searchPageConfig
106
107
  });
107
108
  this.windowEventObserver = new WindowEventObserver({
108
109
  onEvent: function onEvent(_ref) {
@@ -311,6 +312,7 @@ var VCObserverNew = /*#__PURE__*/function () {
311
312
  interactionType: interactionType,
312
313
  isPostInteraction: this.isPostInteraction,
313
314
  include3p: include3p,
315
+ excludeSmartAnswersInSearch: excludeSmartAnswersInSearch,
314
316
  includeSSRRatio: includeSSRRatio,
315
317
  isPageVisible: isPageVisible,
316
318
  interactionAbortReason: interactionAbortReason
@@ -14,7 +14,7 @@ import { isEntrySmartAnswersInSearch } from '../utils/is-entry-smart-answers-in-
14
14
  import isViewportEntryData from '../utils/is-viewport-entry-data';
15
15
  var ABORTING_WINDOW_EVENT = ['wheel', 'scroll', 'keydown', 'resize'];
16
16
  var REVISION_NO = 'fy25.03';
17
- var getConsideredEntryTypes = function getConsideredEntryTypes(include3p) {
17
+ var getConsideredEntryTypes = function getConsideredEntryTypes(include3p, excludeSmartAnswersInSearch) {
18
18
  var entryTypes = ['mutation:child-element', 'mutation:element', 'mutation:attribute', 'layout-shift', 'layout-shift:same-rect', 'window:event'];
19
19
 
20
20
  // If not exclude 3p elements from ttvc,
@@ -23,6 +23,10 @@ var getConsideredEntryTypes = function getConsideredEntryTypes(include3p) {
23
23
  entryTypes.push('mutation:third-party-element');
24
24
  entryTypes.push('mutation:third-party-attribute');
25
25
  }
26
+ if (!excludeSmartAnswersInSearch && fg('rovo_search_page_ttvc_ignoring_smart_answers_fix')) {
27
+ entryTypes.push('mutation:smart-answers-element');
28
+ entryTypes.push('mutation:smart-answers-attribute');
29
+ }
26
30
  if (fg('platform_ufo_enable_media_for_ttvc_v3')) {
27
31
  entryTypes.push('mutation:media');
28
32
  }
@@ -40,10 +44,10 @@ var VCCalculator_FY25_03 = /*#__PURE__*/function (_AbstractVCCalculator) {
40
44
  return _createClass(VCCalculator_FY25_03, [{
41
45
  key: "isEntryIncluded",
42
46
  value: function isEntryIncluded(entry, include3p, excludeSmartAnswersInSearch) {
43
- if (!getConsideredEntryTypes(include3p).includes(entry.data.type)) {
47
+ if (!getConsideredEntryTypes(include3p, excludeSmartAnswersInSearch).includes(entry.data.type)) {
44
48
  return false;
45
49
  }
46
- if (excludeSmartAnswersInSearch && isEntrySmartAnswersInSearch(entry)) {
50
+ if (excludeSmartAnswersInSearch && isEntrySmartAnswersInSearch(entry) && !fg('rovo_search_page_ttvc_ignoring_smart_answers_fix')) {
47
51
  return false;
48
52
  }
49
53
  if (entry.data.type === 'mutation:media' && fg('media-perf-uplift-mutation-fix')) {
@@ -32,8 +32,8 @@ var VCCalculator_FY26_04 = /*#__PURE__*/function (_VCCalculator_FY25_) {
32
32
  _inherits(VCCalculator_FY26_04, _VCCalculator_FY25_);
33
33
  return _createClass(VCCalculator_FY26_04, [{
34
34
  key: "isEntryIncluded",
35
- value: function isEntryIncluded(entry, include3p) {
36
- var isEntryIncludedInV3 = _superPropGet(VCCalculator_FY26_04, "isEntryIncluded", this, 3)([entry, include3p]);
35
+ value: function isEntryIncluded(entry, include3p, excludeSmartAnswersInSearch) {
36
+ var isEntryIncludedInV3 = _superPropGet(VCCalculator_FY26_04, "isEntryIncluded", this, 3)([entry, include3p, excludeSmartAnswersInSearch]);
37
37
  if (isEntryIncludedInV3 && !getExcludedEntryTypes().includes(entry.data.type)) {
38
38
  return true;
39
39
  }
@@ -12,7 +12,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
12
12
  import getViewportHeight from '../metric-calculator/utils/get-viewport-height';
13
13
  import getViewportWidth from '../metric-calculator/utils/get-viewport-width';
14
14
  var ABORTING_WINDOW_EVENT = ['wheel', 'scroll', 'keydown', 'resize'];
15
- var MAX_OBSERVATIONS = 100;
15
+ var MAX_OBSERVATIONS = 200;
16
16
  function isWindowEventEntryData(data) {
17
17
  return data.type === 'window:event' && 'eventType' in data;
18
18
  }
@@ -52,7 +52,7 @@ var RawDataHandler = /*#__PURE__*/function () {
52
52
  key: "getRawData",
53
53
  value: function () {
54
54
  var _getRawData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
55
- var entries, startTime, stopTime, isPageVisible, isVCClean, dirtyReason, getVCCleanStatusResult, viewportEntries, windowEventEntries, targetNameToIdMap, elementMapEntriesMap, nextElementId, typeMap, typeMapEntriesMap, nextTypeId, attributeMap, attributeEntriesMap, nextAttributeId, eventTypeMap, eventTypeMapEntriesMap, nextEventTypeId, rawObservations, rawEventObservations, firstObservation, lastObservations, referencedEids, referencedChgs, referencedAtts, _iterator, _step, observation, _iterator2, _step2, eid, _iterator3, _step3, chg, _iterator4, _step4, att, firstEventObservation, lastEventObservations, referencedEvts, _iterator5, _step5, _observation, _iterator6, _step6, evt, result;
55
+ var entries, startTime, stopTime, isPageVisible, isVCClean, dirtyReason, getVCCleanStatusResult, viewportEntries, windowEventEntries, targetNameToIdMap, elementMapEntriesMap, nextElementId, typeMap, typeMapEntriesMap, nextTypeId, attributeMap, attributeEntriesMap, nextAttributeId, eventTypeMap, eventTypeMapEntriesMap, nextEventTypeId, rawObservations, rawEventObservations, firstObservation, lastObservations, ssrEid, ssrObservation, ssrAlreadyIncluded, referencedEids, referencedChgs, referencedAtts, _iterator, _step, observation, _iterator2, _step2, eid, _iterator3, _step3, chg, _iterator4, _step4, att, firstEventObservation, lastEventObservations, referencedEvts, _iterator5, _step5, _observation, _iterator6, _step6, evt, result;
56
56
  return _regeneratorRuntime.wrap(function _callee$(_context) {
57
57
  while (1) switch (_context.prev = _context.next) {
58
58
  case 0:
@@ -150,12 +150,19 @@ var RawDataHandler = /*#__PURE__*/function () {
150
150
  };
151
151
  return eventObservation;
152
152
  }); // If the number of observations is greater than the maximum allowed, we need to trim the observations to the maximum allowed.
153
- // We do this by keeping the first observation and the last MAX_OBSERVATIONS observations.
153
+ // We do this by keeping the first observation, the SSR observation (if present), and the last MAX_OBSERVATIONS observations.
154
154
  // We then collect the referenced IDs from the remaining observations and remove the unreferenced entries from the maps
155
155
  if (rawObservations.length > MAX_OBSERVATIONS) {
156
156
  firstObservation = rawObservations[0];
157
- lastObservations = rawObservations.slice(-MAX_OBSERVATIONS);
158
- rawObservations = [firstObservation].concat(_toConsumableArray(lastObservations));
157
+ lastObservations = rawObservations.slice(-MAX_OBSERVATIONS); // Find the SSR observation by looking up the eid that corresponds to 'SSR' element name
158
+ ssrEid = targetNameToIdMap.get('SSR');
159
+ ssrObservation = ssrEid ? rawObservations.find(function (obs) {
160
+ return obs.eid === ssrEid && obs !== firstObservation;
161
+ }) : undefined; // Include SSR observation if it exists and is not already in the kept observations
162
+ ssrAlreadyIncluded = ssrObservation && lastObservations.some(function (obs) {
163
+ return obs === ssrObservation;
164
+ });
165
+ rawObservations = [firstObservation].concat(_toConsumableArray(ssrObservation && !ssrAlreadyIncluded ? [ssrObservation] : []), _toConsumableArray(lastObservations));
159
166
 
160
167
  // Collect referenced IDs from remaining observations
161
168
  referencedEids = new Set();
@@ -15,12 +15,13 @@ import { createIntersectionObserver } from './intersection-observer';
15
15
  import createMutationObserver from './mutation-observer';
16
16
  import createPerformanceObserver from './performance-observer';
17
17
  import checkWithinComponent, { cleanupCaches } from './utils/check-within-component';
18
+ import { isContainedWithinSmartAnswers } from './utils/is-contained-within-smart-answers';
18
19
  import { isElementVisible } from './utils/is-element-visible';
19
20
  import isInVCIgnoreIfNoLayoutShiftMarker from './utils/is-in-vc-ignore-if-no-layout-shift-marker';
20
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
- var createElementMutationsWatcher = function createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, hasSameDeletedNode, timestamp, isTargetReactRoot, getSSRState, getSSRPlaceholderHandler) {
24
+ var createElementMutationsWatcher = function createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, isWithinSmartAnswersSegment, hasSameDeletedNode, timestamp, isTargetReactRoot, getSSRState, getSSRPlaceholderHandler) {
24
25
  return function (_ref) {
25
26
  var target = _ref.target,
26
27
  rect = _ref.rect;
@@ -67,6 +68,9 @@ var createElementMutationsWatcher = function createElementMutationsWatcher(remov
67
68
  if (isWithinThirdPartySegment) {
68
69
  return 'mutation:third-party-element';
69
70
  }
71
+ if (isWithinSmartAnswersSegment) {
72
+ return 'mutation:smart-answers-element';
73
+ }
70
74
  var isInIgnoreLsMarker = isInVCIgnoreIfNoLayoutShiftMarker(target);
71
75
  if (!isInIgnoreLsMarker) {
72
76
  return 'mutation:element';
@@ -91,7 +95,8 @@ var ViewportObserver = /*#__PURE__*/function () {
91
95
  var _this = this;
92
96
  var onChange = _ref2.onChange,
93
97
  getSSRState = _ref2.getSSRState,
94
- getSSRPlaceholderHandler = _ref2.getSSRPlaceholderHandler;
98
+ getSSRPlaceholderHandler = _ref2.getSSRPlaceholderHandler,
99
+ searchPageConfig = _ref2.searchPageConfig;
95
100
  _classCallCheck(this, ViewportObserver);
96
101
  _defineProperty(this, "handleIntersectionEntry", function (_ref3) {
97
102
  var target = _ref3.target,
@@ -134,7 +139,7 @@ var ViewportObserver = /*#__PURE__*/function () {
134
139
  _context2.prev = 4;
135
140
  _loop = /*#__PURE__*/_regeneratorRuntime.mark(function _loop() {
136
141
  var _this$getSSRState, _this$intersectionObs;
137
- var addedNodeRef, addedNode, hasSameDeletedNode, _checkWithinComponent, isWithinThirdPartySegment, isTargetReactRoot;
142
+ var addedNodeRef, addedNode, hasSameDeletedNode, _checkWithinComponent, isWithinThirdPartySegment, isWithinSmartAnswersSegment, isTargetReactRoot;
138
143
  return _regeneratorRuntime.wrap(function _loop$(_context) {
139
144
  while (1) switch (_context.prev = _context.next) {
140
145
  case 0:
@@ -154,9 +159,10 @@ var ViewportObserver = /*#__PURE__*/function () {
154
159
  return n.isEqualNode(addedNode);
155
160
  });
156
161
  _checkWithinComponent = checkWithinComponent(addedNode, 'UFOThirdPartySegment', _this.mapIs3pResult), isWithinThirdPartySegment = _checkWithinComponent.isWithin;
162
+ isWithinSmartAnswersSegment = Boolean(_this.shouldCheckSmartAnswersMutations() && isContainedWithinSmartAnswers(addedNode));
157
163
  isTargetReactRoot = targetNode === ((_this$getSSRState = _this.getSSRState) === null || _this$getSSRState === void 0 || (_this$getSSRState = _this$getSSRState.call(_this)) === null || _this$getSSRState === void 0 ? void 0 : _this$getSSRState.reactRootElement);
158
- (_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, !!hasSameDeletedNode, timestamp, isTargetReactRoot, _this.getSSRState, _this.getSSRPlaceholderHandler));
159
- case 8:
164
+ (_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, isWithinSmartAnswersSegment, !!hasSameDeletedNode, timestamp, isTargetReactRoot, _this.getSSRState, _this.getSSRPlaceholderHandler));
165
+ case 9:
160
166
  case "end":
161
167
  return _context.stop();
162
168
  }
@@ -232,6 +238,16 @@ var ViewportObserver = /*#__PURE__*/function () {
232
238
  };
233
239
  }
234
240
  }
241
+ if (_this.shouldCheckSmartAnswersMutations() && isContainedWithinSmartAnswers(target)) {
242
+ return {
243
+ type: 'mutation:smart-answers-attribute',
244
+ mutationData: {
245
+ attributeName: attributeName,
246
+ oldValue: oldValue,
247
+ newValue: newValue
248
+ }
249
+ };
250
+ }
235
251
  if (isDnDStyleMutation({
236
252
  target: target,
237
253
  attributeName: attributeName,
@@ -335,6 +351,10 @@ var ViewportObserver = /*#__PURE__*/function () {
335
351
  _iterator2.f();
336
352
  }
337
353
  });
354
+ _defineProperty(this, "shouldCheckSmartAnswersMutations", function () {
355
+ var _this$searchPageConfi, _this$searchPageConfi2, _window;
356
+ return ((_this$searchPageConfi = _this.searchPageConfig) === null || _this$searchPageConfi === void 0 ? void 0 : _this$searchPageConfi.enableSmartAnswersMutations) && ((_this$searchPageConfi2 = _this.searchPageConfig) === null || _this$searchPageConfi2 === void 0 ? void 0 : _this$searchPageConfi2.searchPageRoute) && ((_window = window) === null || _window === void 0 || (_window = _window.location) === null || _window === void 0 ? void 0 : _window.pathname) && window.location.pathname === _this.searchPageConfig.searchPageRoute && fg('rovo_search_page_ttvc_ignoring_smart_answers_fix');
357
+ });
338
358
  this.mapVisibleNodeRects = new WeakMap();
339
359
  this.mapIs3pResult = new WeakMap();
340
360
  this.onChange = onChange;
@@ -346,6 +366,7 @@ var ViewportObserver = /*#__PURE__*/function () {
346
366
  // Initialize SSR context functions
347
367
  this.getSSRState = getSSRState;
348
368
  this.getSSRPlaceholderHandler = getSSRPlaceholderHandler;
369
+ this.searchPageConfig = searchPageConfig;
349
370
  }
350
371
  return _createClass(ViewportObserver, [{
351
372
  key: "initializeObservers",
@@ -0,0 +1,14 @@
1
+ import { getDocument } from '@atlaskit/browser-apis';
2
+ export function isContainedWithinSmartAnswers(node) {
3
+ var doc = getDocument();
4
+ if (!doc) {
5
+ return false;
6
+ }
7
+ var smartAnswersElement = doc.getElementById('search-page-smart-answers');
8
+ if (!smartAnswersElement) {
9
+ return false;
10
+ }
11
+
12
+ // When the node is the smart answer element, .contains() still returns true
13
+ return smartAnswersElement.contains(node);
14
+ }
@@ -174,6 +174,7 @@ export type Config = {
174
174
  readonly extraSearchPageInteraction?: {
175
175
  readonly enabled: boolean;
176
176
  readonly searchPageMetricName: string;
177
+ readonly searchPageRoute: string;
177
178
  };
178
179
  readonly enableVCRawDataRates?: {
179
180
  readonly enabled?: boolean;
@@ -27,6 +27,19 @@ export type SelectorConfig = {
27
27
  className: boolean;
28
28
  dataVC?: boolean;
29
29
  };
30
+ export type SearchPageConfig = {
31
+ /**
32
+ * Whether to enable detection of smart answers mutations
33
+ */
34
+ enableSmartAnswersMutations?: boolean;
35
+ /**
36
+ * Route of the search page. If this is not specified, then all other VC
37
+ * configurations related to the search page will be ignored. This is
38
+ * done to ensure that search page specific computations are not performed
39
+ * for non-search page interactions.
40
+ */
41
+ searchPageRoute?: string;
42
+ };
30
43
  export type VCObserverOptions = {
31
44
  heatmapSize?: number | undefined;
32
45
  oldDomUpdates?: boolean | undefined;
@@ -35,6 +48,7 @@ export type VCObserverOptions = {
35
48
  isPostInteraction?: boolean;
36
49
  ssrEnablePageLayoutPlaceholder?: boolean;
37
50
  ssrPlaceholderHandler?: any;
51
+ searchPageConfig?: SearchPageConfig;
38
52
  };
39
53
  export interface VCObserverInterface {
40
54
  start(startArg: {
@@ -1,3 +1,4 @@
1
+ import type { SearchPageConfig } from '../../types';
1
2
  import { SSRPlaceholderHandlers } from './ssr-placeholders';
2
3
  import type { BrowserObservers, Callback } from './types';
3
4
  export type { ObservedMutationType } from './types';
@@ -14,6 +15,7 @@ type ConstructorOptions = {
14
15
  enablePageLayoutPlaceholder: boolean;
15
16
  };
16
17
  ssrPlaceholderHandler?: SSRPlaceholderHandlers | null;
18
+ searchPageConfig?: SearchPageConfig;
17
19
  };
18
20
  export declare class Observers implements BrowserObservers {
19
21
  private intersectionObserver;
@@ -1,4 +1,5 @@
1
1
  import { type RevisionPayloadEntry } from '../../common/vc/types';
2
+ import type { SearchPageConfig } from '../types';
2
3
  import { SSRPlaceholderHandlers } from '../vc-observer/observers/ssr-placeholders';
3
4
  import { type SelectorConfig } from './get-element-name';
4
5
  import type { VCObserverGetVCResultParam } from './types';
@@ -9,6 +10,7 @@ export type VCObserverNewConfig = {
9
10
  enablePageLayoutPlaceholder?: boolean;
10
11
  };
11
12
  ssrPlaceholderHandler?: SSRPlaceholderHandlers | null;
13
+ searchPageConfig?: SearchPageConfig;
12
14
  };
13
15
  declare const SSRState: {
14
16
  readonly normal: 1;
@@ -2,5 +2,5 @@ import type { VCObserverEntry } from '../../types';
2
2
  import VCCalculator_FY25_03 from '../fy25_03';
3
3
  export default class VCCalculator_FY26_04 extends VCCalculator_FY25_03 {
4
4
  constructor();
5
- protected isEntryIncluded(entry: VCObserverEntry, include3p?: boolean): boolean;
5
+ protected isEntryIncluded(entry: VCObserverEntry, include3p?: boolean, excludeSmartAnswersInSearch?: boolean): boolean;
6
6
  }
@@ -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: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';
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:smart-answers-element' | 'mutation:smart-answers-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;
@@ -1,3 +1,4 @@
1
+ import type { SearchPageConfig } from '../../types';
1
2
  import { type VCObserverEntryType } from '../types';
2
3
  import { type MutationData } from './types';
3
4
  export type ViewPortObserverConstructorArgs = {
@@ -12,6 +13,7 @@ export type ViewPortObserverConstructorArgs = {
12
13
  }): void;
13
14
  getSSRState?: () => any;
14
15
  getSSRPlaceholderHandler?: () => any;
16
+ searchPageConfig?: SearchPageConfig;
15
17
  };
16
18
  export default class ViewportObserver {
17
19
  private intersectionObserver;
@@ -21,14 +23,16 @@ export default class ViewportObserver {
21
23
  private mapIs3pResult;
22
24
  private onChange;
23
25
  private isStarted;
26
+ private searchPageConfig;
24
27
  private getSSRState?;
25
28
  private getSSRPlaceholderHandler?;
26
- constructor({ onChange, getSSRState, getSSRPlaceholderHandler, }: ViewPortObserverConstructorArgs);
29
+ constructor({ onChange, getSSRState, getSSRPlaceholderHandler, searchPageConfig, }: ViewPortObserverConstructorArgs);
27
30
  private handleIntersectionEntry;
28
31
  private handleChildListMutation;
29
32
  private handleAttributeMutation;
30
33
  private handleLayoutShift;
31
34
  private initializeObservers;
35
+ private shouldCheckSmartAnswersMutations;
32
36
  start(): void;
33
37
  stop(): void;
34
38
  }
@@ -0,0 +1 @@
1
+ export declare function isContainedWithinSmartAnswers(node: HTMLElement): boolean;
@@ -174,6 +174,7 @@ export type Config = {
174
174
  readonly extraSearchPageInteraction?: {
175
175
  readonly enabled: boolean;
176
176
  readonly searchPageMetricName: string;
177
+ readonly searchPageRoute: string;
177
178
  };
178
179
  readonly enableVCRawDataRates?: {
179
180
  readonly enabled?: boolean;
@@ -27,6 +27,19 @@ export type SelectorConfig = {
27
27
  className: boolean;
28
28
  dataVC?: boolean;
29
29
  };
30
+ export type SearchPageConfig = {
31
+ /**
32
+ * Whether to enable detection of smart answers mutations
33
+ */
34
+ enableSmartAnswersMutations?: boolean;
35
+ /**
36
+ * Route of the search page. If this is not specified, then all other VC
37
+ * configurations related to the search page will be ignored. This is
38
+ * done to ensure that search page specific computations are not performed
39
+ * for non-search page interactions.
40
+ */
41
+ searchPageRoute?: string;
42
+ };
30
43
  export type VCObserverOptions = {
31
44
  heatmapSize?: number | undefined;
32
45
  oldDomUpdates?: boolean | undefined;
@@ -35,6 +48,7 @@ export type VCObserverOptions = {
35
48
  isPostInteraction?: boolean;
36
49
  ssrEnablePageLayoutPlaceholder?: boolean;
37
50
  ssrPlaceholderHandler?: any;
51
+ searchPageConfig?: SearchPageConfig;
38
52
  };
39
53
  export interface VCObserverInterface {
40
54
  start(startArg: {
@@ -1,3 +1,4 @@
1
+ import type { SearchPageConfig } from '../../types';
1
2
  import { SSRPlaceholderHandlers } from './ssr-placeholders';
2
3
  import type { BrowserObservers, Callback } from './types';
3
4
  export type { ObservedMutationType } from './types';
@@ -14,6 +15,7 @@ type ConstructorOptions = {
14
15
  enablePageLayoutPlaceholder: boolean;
15
16
  };
16
17
  ssrPlaceholderHandler?: SSRPlaceholderHandlers | null;
18
+ searchPageConfig?: SearchPageConfig;
17
19
  };
18
20
  export declare class Observers implements BrowserObservers {
19
21
  private intersectionObserver;
@@ -1,4 +1,5 @@
1
1
  import { type RevisionPayloadEntry } from '../../common/vc/types';
2
+ import type { SearchPageConfig } from '../types';
2
3
  import { SSRPlaceholderHandlers } from '../vc-observer/observers/ssr-placeholders';
3
4
  import { type SelectorConfig } from './get-element-name';
4
5
  import type { VCObserverGetVCResultParam } from './types';
@@ -9,6 +10,7 @@ export type VCObserverNewConfig = {
9
10
  enablePageLayoutPlaceholder?: boolean;
10
11
  };
11
12
  ssrPlaceholderHandler?: SSRPlaceholderHandlers | null;
13
+ searchPageConfig?: SearchPageConfig;
12
14
  };
13
15
  declare const SSRState: {
14
16
  readonly normal: 1;
@@ -2,5 +2,5 @@ import type { VCObserverEntry } from '../../types';
2
2
  import VCCalculator_FY25_03 from '../fy25_03';
3
3
  export default class VCCalculator_FY26_04 extends VCCalculator_FY25_03 {
4
4
  constructor();
5
- protected isEntryIncluded(entry: VCObserverEntry, include3p?: boolean): boolean;
5
+ protected isEntryIncluded(entry: VCObserverEntry, include3p?: boolean, excludeSmartAnswersInSearch?: boolean): boolean;
6
6
  }
@@ -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: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';
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:smart-answers-element' | 'mutation:smart-answers-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;
@@ -1,3 +1,4 @@
1
+ import type { SearchPageConfig } from '../../types';
1
2
  import { type VCObserverEntryType } from '../types';
2
3
  import { type MutationData } from './types';
3
4
  export type ViewPortObserverConstructorArgs = {
@@ -12,6 +13,7 @@ export type ViewPortObserverConstructorArgs = {
12
13
  }): void;
13
14
  getSSRState?: () => any;
14
15
  getSSRPlaceholderHandler?: () => any;
16
+ searchPageConfig?: SearchPageConfig;
15
17
  };
16
18
  export default class ViewportObserver {
17
19
  private intersectionObserver;
@@ -21,14 +23,16 @@ export default class ViewportObserver {
21
23
  private mapIs3pResult;
22
24
  private onChange;
23
25
  private isStarted;
26
+ private searchPageConfig;
24
27
  private getSSRState?;
25
28
  private getSSRPlaceholderHandler?;
26
- constructor({ onChange, getSSRState, getSSRPlaceholderHandler, }: ViewPortObserverConstructorArgs);
29
+ constructor({ onChange, getSSRState, getSSRPlaceholderHandler, searchPageConfig, }: ViewPortObserverConstructorArgs);
27
30
  private handleIntersectionEntry;
28
31
  private handleChildListMutation;
29
32
  private handleAttributeMutation;
30
33
  private handleLayoutShift;
31
34
  private initializeObservers;
35
+ private shouldCheckSmartAnswersMutations;
32
36
  start(): void;
33
37
  stop(): void;
34
38
  }
@@ -0,0 +1 @@
1
+ export declare function isContainedWithinSmartAnswers(node: HTMLElement): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/react-ufo",
3
- "version": "4.16.7",
3
+ "version": "4.17.0",
4
4
  "description": "Parts of React UFO that are publicly available",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -168,9 +168,6 @@
168
168
  "platform_ufo_enable_finish_interaction_transition": {
169
169
  "type": "boolean"
170
170
  },
171
- "platform_ufo_always_send_post_interaction_log": {
172
- "type": "boolean"
173
- },
174
171
  "platform_ufo_drop_prior_fg_interactions": {
175
172
  "type": "boolean"
176
173
  },
@@ -212,6 +209,9 @@
212
209
  },
213
210
  "platform_enable_better_page_visibility": {
214
211
  "type": "boolean"
212
+ },
213
+ "rovo_search_page_ttvc_ignoring_smart_answers_fix": {
214
+ "type": "boolean"
215
215
  }
216
216
  }
217
217
  }