@atlaskit/react-ufo 3.14.0 → 3.14.2

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 (40) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/ignore-holds/index.js +62 -0
  3. package/dist/cjs/interaction-ignore/ufo-interaction-ignore.js +7 -49
  4. package/dist/cjs/segment/index.js +7 -0
  5. package/dist/cjs/segment/segment.js +3 -1
  6. package/dist/cjs/segment/third-party-segment.js +25 -0
  7. package/dist/cjs/vc/vc-observer-new/metric-calculator/fy25_03/index.js +12 -6
  8. package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +30 -6
  9. package/dist/cjs/vc/vc-observer-new/viewport-observer/utils/get-component-name-and-child-props.js +85 -0
  10. package/dist/es2019/ignore-holds/index.js +51 -0
  11. package/dist/es2019/interaction-ignore/ufo-interaction-ignore.js +7 -45
  12. package/dist/es2019/segment/index.js +2 -1
  13. package/dist/es2019/segment/segment.js +2 -1
  14. package/dist/es2019/segment/third-party-segment.js +18 -0
  15. package/dist/es2019/vc/vc-observer-new/metric-calculator/fy25_03/index.js +12 -6
  16. package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +32 -6
  17. package/dist/es2019/vc/vc-observer-new/viewport-observer/utils/get-component-name-and-child-props.js +71 -0
  18. package/dist/esm/ignore-holds/index.js +53 -0
  19. package/dist/esm/interaction-ignore/ufo-interaction-ignore.js +7 -47
  20. package/dist/esm/segment/index.js +2 -1
  21. package/dist/esm/segment/segment.js +3 -1
  22. package/dist/esm/segment/third-party-segment.js +18 -0
  23. package/dist/esm/vc/vc-observer-new/metric-calculator/fy25_03/index.js +12 -6
  24. package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +30 -6
  25. package/dist/esm/vc/vc-observer-new/viewport-observer/utils/get-component-name-and-child-props.js +76 -0
  26. package/dist/types/ignore-holds/index.d.ts +31 -0
  27. package/dist/types/interaction-ignore/ufo-interaction-ignore.d.ts +6 -21
  28. package/dist/types/segment/index.d.ts +1 -0
  29. package/dist/types/segment/segment.d.ts +4 -2
  30. package/dist/types/segment/third-party-segment.d.ts +6 -0
  31. package/dist/types/vc/vc-observer-new/types.d.ts +1 -1
  32. package/dist/types/vc/vc-observer-new/viewport-observer/utils/get-component-name-and-child-props.d.ts +15 -0
  33. package/dist/types-ts4.5/ignore-holds/index.d.ts +31 -0
  34. package/dist/types-ts4.5/interaction-ignore/ufo-interaction-ignore.d.ts +6 -21
  35. package/dist/types-ts4.5/segment/index.d.ts +1 -0
  36. package/dist/types-ts4.5/segment/segment.d.ts +4 -2
  37. package/dist/types-ts4.5/segment/third-party-segment.d.ts +6 -0
  38. package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +1 -1
  39. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/utils/get-component-name-and-child-props.d.ts +15 -0
  40. package/package.json +7 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/ufo-interaction-ignore
2
2
 
3
+ ## 3.14.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#175460](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/175460)
8
+ [`57eff35bc7a50`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/57eff35bc7a50) -
9
+ Cleanup platform_ufo_filter_out_aui_attribute_changes flag
10
+
11
+ ## 3.14.1
12
+
13
+ ### Patch Changes
14
+
15
+ - [#175174](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/175174)
16
+ [`56303bfa2ee79`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/56303bfa2ee79) -
17
+ Add new component UFOThirdPartySegment to react-ufo
18
+
3
19
  ## 3.14.0
4
20
 
5
21
  ### Minor Changes
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = UFOIgnoreHolds;
9
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
+ var _react = _interopRequireWildcard(require("react"));
11
+ var _interactionContext = _interopRequireDefault(require("@atlaskit/interaction-context"));
12
+ 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); }
13
+ 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; }
14
+ 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; }
15
+ /**
16
+ * Prevent a subtree from holding up an interaction
17
+ * Use this when you have a component which loads in late, but
18
+ * isn't considered to be a breach of SLO
19
+ *
20
+ * ```js
21
+ * <App>
22
+ * <Main />
23
+ * <Sidebar>
24
+ * <UFOIgnoreHolds>
25
+ * <InsightsButton />
26
+ * </UFOIgnoreHolds>
27
+ * </Sidebar>
28
+ * </App>
29
+ * ```
30
+ *
31
+ * Has an `ignore` prop, to allow you to use it conditionally
32
+ * Has a `reason` prop, to specify why the hold is being ignored
33
+ */
34
+ function UFOIgnoreHolds(_ref) {
35
+ var children = _ref.children,
36
+ _ref$ignore = _ref.ignore,
37
+ ignore = _ref$ignore === void 0 ? true : _ref$ignore,
38
+ reason = _ref.reason;
39
+ var parentContext = (0, _react.useContext)(_interactionContext.default);
40
+ var ignoredInteractionContext = (0, _react.useMemo)(function () {
41
+ if (!parentContext) {
42
+ return null;
43
+ }
44
+ return _objectSpread(_objectSpread({}, parentContext), {}, {
45
+ hold: function hold() {
46
+ if (!ignore) {
47
+ return parentContext.hold.apply(parentContext, arguments);
48
+ }
49
+ }
50
+ });
51
+ }, [parentContext, ignore]);
52
+
53
+ // react-18: Use children directly
54
+ var kids = children != null ? children : null;
55
+ if (!ignoredInteractionContext) {
56
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, kids);
57
+ }
58
+ return /*#__PURE__*/_react.default.createElement(_interactionContext.default.Provider, {
59
+ value: ignoredInteractionContext
60
+ }, kids);
61
+ }
62
+ UFOIgnoreHolds.displayName = 'UFOIgnoreHolds';
@@ -1,59 +1,17 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- var _typeof = require("@babel/runtime/helpers/typeof");
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
8
7
  exports.default = UFOInteractionIgnore;
9
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
- var _react = _interopRequireWildcard(require("react"));
11
- var _interactionContext = _interopRequireDefault(require("@atlaskit/interaction-context"));
12
- 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); }
13
- 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; }
14
- 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; }
8
+ var _react = _interopRequireDefault(require("react"));
9
+ var _ignoreHolds = _interopRequireDefault(require("../ignore-holds"));
15
10
  /**
16
- * Prevent a subtree from holding up an interaction
17
- * Use this when you have a component which loads in late, but
18
- * isn't considered to be a breach of SLO
19
- *
20
- * ```js
21
- * <App>
22
- * <Main />
23
- * <Sidebar>
24
- * <UFOInteractionIgnore>
25
- * <InsightsButton />
26
- * </UFOInteractionIgnore>
27
- * </Sidebar>
28
- * </App>
29
- * ```
30
- *
31
- * Has an `ignore` prop, to allow you to use it conditionally
11
+ * Legacy wrapper component that delegates to `UFOIgnoreHolds`.
12
+ * Use `UFOIgnoreHolds` instead for new implementations.
13
+ * This component is maintained for backward compatibility only.
32
14
  */
33
- function UFOInteractionIgnore(_ref) {
34
- var children = _ref.children,
35
- _ref$ignore = _ref.ignore,
36
- ignore = _ref$ignore === void 0 ? true : _ref$ignore;
37
- var parentContext = (0, _react.useContext)(_interactionContext.default);
38
- var ignoredInteractionContext = (0, _react.useMemo)(function () {
39
- if (!parentContext) {
40
- return null;
41
- }
42
- return _objectSpread(_objectSpread({}, parentContext), {}, {
43
- hold: function hold() {
44
- if (!ignore) {
45
- return parentContext.hold.apply(parentContext, arguments);
46
- }
47
- }
48
- });
49
- }, [parentContext, ignore]);
50
-
51
- // react-18: Use children directly
52
- var kids = children != null ? children : null;
53
- if (!ignoredInteractionContext) {
54
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, kids);
55
- }
56
- return /*#__PURE__*/_react.default.createElement(_interactionContext.default.Provider, {
57
- value: ignoredInteractionContext
58
- }, kids);
15
+ function UFOInteractionIgnore(props) {
16
+ return /*#__PURE__*/_react.default.createElement(_ignoreHolds.default, props);
59
17
  }
@@ -4,6 +4,13 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
+ Object.defineProperty(exports, "UFOThirdPartySegment", {
8
+ enumerable: true,
9
+ get: function get() {
10
+ return _thirdPartySegment.UFOThirdPartySegment;
11
+ }
12
+ });
7
13
  exports.default = void 0;
8
14
  var _segment = _interopRequireDefault(require("./segment"));
15
+ var _thirdPartySegment = require("./third-party-segment");
9
16
  var _default = exports.default = _segment.default;
@@ -41,7 +41,9 @@ function UFOSegment(_ref) {
41
41
  var segmentName = _ref.name,
42
42
  children = _ref.children,
43
43
  _ref$mode = _ref.mode,
44
- mode = _ref$mode === void 0 ? 'single' : _ref$mode;
44
+ mode = _ref$mode === void 0 ? 'single' : _ref$mode,
45
+ _ref$type = _ref.type,
46
+ type = _ref$type === void 0 ? 'first-party' : _ref$type;
45
47
  var parentContext = (0, _react.useContext)(_interactionContext.default);
46
48
  var segmentIdMap = (0, _react.useMemo)(function () {
47
49
  if (!(parentContext !== null && parentContext !== void 0 && parentContext.segmentIdMap)) {
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.UFOThirdPartySegment = UFOThirdPartySegment;
8
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
10
+ var _react = _interopRequireDefault(require("react"));
11
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
12
+ var _ignoreHolds = _interopRequireDefault(require("../ignore-holds"));
13
+ var _segment = _interopRequireDefault(require("./segment"));
14
+ var _excluded = ["children"];
15
+ function UFOThirdPartySegment(props) {
16
+ var children = props.children,
17
+ otherProps = (0, _objectWithoutProperties2.default)(props, _excluded);
18
+ return /*#__PURE__*/_react.default.createElement(_segment.default, (0, _extends2.default)({
19
+ type: "third-party"
20
+ }, otherProps), /*#__PURE__*/_react.default.createElement(_ignoreHolds.default, {
21
+ ignore: (0, _platformFeatureFlags.fg)('platform_ufo_exclude_3p_elements_from_ttai'),
22
+ reason: "third-party-element"
23
+ }, children));
24
+ }
25
+ UFOThirdPartySegment.displayName = 'UFOThirdPartySegment';
@@ -17,7 +17,16 @@ function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0,
17
17
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
18
18
  var ABORTING_WINDOW_EVENT = ['wheel', 'scroll', 'keydown', 'resize'];
19
19
  var REVISION_NO = 'fy25.03';
20
- var CONSIDERED_ENTRY_TYPE = ['mutation:child-element', 'mutation:element', 'mutation:attribute', 'layout-shift', 'window:event'];
20
+ var getConsideredEntryTypes = function getConsideredEntryTypes() {
21
+ var entryTypes = ['mutation:child-element', 'mutation:element', 'mutation:attribute', 'layout-shift', 'window:event'];
22
+
23
+ // If not exclude 3p elements from ttvc,
24
+ // including the tags into the ConsideredEntryTypes so that it won't be ignored for TTVC calculation
25
+ if (!(0, _platformFeatureFlags.fg)('platform_ufo_exclude_3p_elements_from_ttvc')) {
26
+ entryTypes.push('mutation:third-party-element');
27
+ }
28
+ return entryTypes;
29
+ };
21
30
 
22
31
  // TODO: AFO-3523
23
32
  // Those are the attributes we have found when testing the 'fy25.03' manually.
@@ -35,7 +44,7 @@ var VCCalculator_FY25_03 = exports.default = /*#__PURE__*/function (_AbstractVCC
35
44
  return (0, _createClass2.default)(VCCalculator_FY25_03, [{
36
45
  key: "isEntryIncluded",
37
46
  value: function isEntryIncluded(entry) {
38
- if (!CONSIDERED_ENTRY_TYPE.includes(entry.data.type)) {
47
+ if (!getConsideredEntryTypes().includes(entry.data.type)) {
39
48
  return false;
40
49
  }
41
50
  if (entry.data.type === 'mutation:attribute') {
@@ -44,10 +53,7 @@ var VCCalculator_FY25_03 = exports.default = /*#__PURE__*/function (_AbstractVCC
44
53
  if (!attributeName || KNOWN_ATTRIBUTES_THAT_DOES_NOT_CAUSE_LAYOUT_SHIFTS.includes(attributeName)) {
45
54
  return false;
46
55
  }
47
- if (attributeName === 'data-aui-version' && (0, _platformFeatureFlags.fg)('platform_ufo_filter_out_aui_attribute_changes')) {
48
- return false;
49
- }
50
- if (attributeName === 'data-testid' || attributeName === 'data-vc' || attributeName === 'data-ssr-placeholder' || attributeName === 'data-ssr-placeholder-replace' || attributeName === 'data-vc-nvs' || attributeName === 'data-media-vc-wrapper' || (attributeName === 'data-renderer-start-pos' || attributeName === 'data-table-local-id' || attributeName === 'spellcheck') && (0, _platformFeatureFlags.fg)('platform_ufo_ignore_extra_attributes') || attributeName === 'data-auto-scrollable' || attributeName === 'id' || attributeName === 'tabindex' || NON_VISUAL_ARIA_ATTRIBUTES.includes(attributeName)) {
56
+ if (attributeName === 'data-aui-version' || attributeName === 'data-testid' || attributeName === 'data-vc' || attributeName === 'data-ssr-placeholder' || attributeName === 'data-ssr-placeholder-replace' || attributeName === 'data-vc-nvs' || attributeName === 'data-media-vc-wrapper' || (attributeName === 'data-renderer-start-pos' || attributeName === 'data-table-local-id' || attributeName === 'spellcheck') && (0, _platformFeatureFlags.fg)('platform_ufo_ignore_extra_attributes') || attributeName === 'data-auto-scrollable' || attributeName === 'id' || attributeName === 'tabindex' || NON_VISUAL_ARIA_ATTRIBUTES.includes(attributeName)) {
51
57
  return false;
52
58
  }
53
59
  return true;
@@ -14,6 +14,7 @@ var _rllPlaceholders = require("../../vc-observer/observers/rll-placeholders");
14
14
  var _intersectionObserver = require("./intersection-observer");
15
15
  var _mutationObserver = _interopRequireDefault(require("./mutation-observer"));
16
16
  var _performanceObserver = _interopRequireDefault(require("./performance-observer"));
17
+ var _getComponentNameAndChildProps = require("./utils/get-component-name-and-child-props");
17
18
  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; } } }; }
18
19
  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; } }
19
20
  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; }
@@ -100,7 +101,7 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
100
101
  return _this.mapVisibleNodeRects.get(n);
101
102
  });
102
103
  addedNodes.forEach(function (addedNodeRef) {
103
- var _this$intersectionObs3;
104
+ var _this$intersectionObs4;
104
105
  var addedNode = addedNodeRef.deref();
105
106
  if (!addedNode) {
106
107
  return;
@@ -122,16 +123,25 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
122
123
  (_this$intersectionObs2 = _this.intersectionObserver) === null || _this$intersectionObs2 === void 0 || _this$intersectionObs2.watchAndTag(addedNode, 'mutation:media');
123
124
  return;
124
125
  }
125
- (_this$intersectionObs3 = _this.intersectionObserver) === null || _this$intersectionObs3 === void 0 || _this$intersectionObs3.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects));
126
+ var _checkThirdPartySegme = (0, _getComponentNameAndChildProps.checkThirdPartySegmentWithIgnoreReason)(addedNode),
127
+ isWithinThirdPartySegment = _checkThirdPartySegme.isWithinThirdPartySegment,
128
+ ignoredReason = _checkThirdPartySegme.ignoredReason;
129
+ if (isWithinThirdPartySegment) {
130
+ var _this$intersectionObs3;
131
+ var assignedReason = (0, _getComponentNameAndChildProps.createMutationTypeWithIgnoredReason)(ignoredReason || 'third-party-element');
132
+ (_this$intersectionObs3 = _this.intersectionObserver) === null || _this$intersectionObs3 === void 0 || _this$intersectionObs3.watchAndTag(addedNode, assignedReason);
133
+ return;
134
+ }
135
+ (_this$intersectionObs4 = _this.intersectionObserver) === null || _this$intersectionObs4 === void 0 || _this$intersectionObs4.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects));
126
136
  });
127
137
  });
128
138
  (0, _defineProperty2.default)(this, "handleAttributeMutation", function (_ref5) {
129
- var _this$intersectionObs4;
139
+ var _this$intersectionObs5;
130
140
  var target = _ref5.target,
131
141
  attributeName = _ref5.attributeName,
132
142
  oldValue = _ref5.oldValue,
133
143
  newValue = _ref5.newValue;
134
- (_this$intersectionObs4 = _this.intersectionObserver) === null || _this$intersectionObs4 === void 0 || _this$intersectionObs4.watchAndTag(target, function (_ref6) {
144
+ (_this$intersectionObs5 = _this.intersectionObserver) === null || _this$intersectionObs5 === void 0 || _this$intersectionObs5.watchAndTag(target, function (_ref6) {
135
145
  var target = _ref6.target,
136
146
  rect = _ref6.rect;
137
147
  if ((0, _vcUtils.isContainedWithinMediaWrapper)(target)) {
@@ -169,6 +179,20 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
169
179
  }
170
180
  };
171
181
  }
182
+ var _checkThirdPartySegme2 = (0, _getComponentNameAndChildProps.checkThirdPartySegmentWithIgnoreReason)(target),
183
+ isWithinThirdPartySegment = _checkThirdPartySegme2.isWithinThirdPartySegment,
184
+ ignoredReason = _checkThirdPartySegme2.ignoredReason;
185
+ if (isWithinThirdPartySegment) {
186
+ var assignedReason = (0, _getComponentNameAndChildProps.createMutationTypeWithIgnoredReason)(ignoredReason || 'third-party-element');
187
+ return {
188
+ type: assignedReason,
189
+ mutationData: {
190
+ attributeName: attributeName,
191
+ oldValue: oldValue,
192
+ newValue: newValue
193
+ }
194
+ };
195
+ }
172
196
  var lastElementRect = _this.mapVisibleNodeRects.get(target);
173
197
  if (lastElementRect && sameRectSize(rect, lastElementRect)) {
174
198
  return {
@@ -265,12 +289,12 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
265
289
  }, {
266
290
  key: "stop",
267
291
  value: function stop() {
268
- var _this$mutationObserve2, _this$intersectionObs5, _this$performanceObse2;
292
+ var _this$mutationObserve2, _this$intersectionObs6, _this$performanceObse2;
269
293
  if (!this.isStarted) {
270
294
  return;
271
295
  }
272
296
  (_this$mutationObserve2 = this.mutationObserver) === null || _this$mutationObserve2 === void 0 || _this$mutationObserve2.disconnect();
273
- (_this$intersectionObs5 = this.intersectionObserver) === null || _this$intersectionObs5 === void 0 || _this$intersectionObs5.disconnect();
297
+ (_this$intersectionObs6 = this.intersectionObserver) === null || _this$intersectionObs6 === void 0 || _this$intersectionObs6.disconnect();
274
298
  (_this$performanceObse2 = this.performanceObserver) === null || _this$performanceObse2 === void 0 || _this$performanceObse2.disconnect();
275
299
  this.isStarted = false;
276
300
  }
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.checkThirdPartySegmentWithIgnoreReason = checkThirdPartySegmentWithIgnoreReason;
8
+ exports.checkWithinComponentAndExtractChildProps = checkWithinComponentAndExtractChildProps;
9
+ exports.createMutationTypeWithIgnoredReason = createMutationTypeWithIgnoredReason;
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
+ var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
12
+ 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; }
13
+ 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; }
14
+ // Using the React Fiber tree to traverse up the DOM and check if a node is within a specific component
15
+ // and extract child component props if needed.
16
+ function checkWithinComponentAndExtractChildProps(node, targetComponentName, childComponentConfig) {
17
+ // Get the React fiber from the DOM node
18
+ var key = Object.keys(node).find(function (key) {
19
+ return key.startsWith('__reactFiber$') || key.startsWith('__reactInternalInstance$');
20
+ });
21
+ if (!key) {
22
+ return {
23
+ isWithin: false
24
+ };
25
+ }
26
+ var fiber = node[key];
27
+ if (!fiber) {
28
+ return {
29
+ isWithin: false
30
+ };
31
+ }
32
+
33
+ // Traverse up the fiber tree
34
+ var currentFiber = fiber;
35
+ var childProp;
36
+ while (currentFiber) {
37
+ var componentName = void 0;
38
+ if (currentFiber.type) {
39
+ if (typeof currentFiber.type === 'function') {
40
+ componentName = currentFiber.type.displayName || currentFiber.type.name;
41
+ } else if ((0, _typeof2.default)(currentFiber.type) === 'object' && (currentFiber.type.displayName || currentFiber.type.name)) {
42
+ componentName = currentFiber.type.displayName || currentFiber.type.name;
43
+ }
44
+ }
45
+
46
+ // Check if this is a child component we're looking for
47
+ if (childComponentConfig && componentName === childComponentConfig.componentName) {
48
+ var props = currentFiber.memoizedProps || currentFiber.pendingProps;
49
+ if (props && props[childComponentConfig.propName] !== undefined) {
50
+ // Overwrite with the nearest child prop (closest to the target component)
51
+ childProp = childComponentConfig.extractValue ? childComponentConfig.extractValue(props) : props[childComponentConfig.propName];
52
+ }
53
+ }
54
+
55
+ // Check if we found the target component
56
+ if (componentName === targetComponentName) {
57
+ return _objectSpread({
58
+ isWithin: true
59
+ }, childComponentConfig && {
60
+ childProp: childProp
61
+ });
62
+ }
63
+ currentFiber = currentFiber.return;
64
+ }
65
+ return {
66
+ isWithin: false
67
+ };
68
+ }
69
+
70
+ // Check if the node is within a UFOThirdPartySegment and extract any UFOIgnoreHolds reason
71
+ function checkThirdPartySegmentWithIgnoreReason(node) {
72
+ var result = checkWithinComponentAndExtractChildProps(node, 'UFOThirdPartySegment', {
73
+ componentName: 'UFOIgnoreHolds',
74
+ propName: 'reason'
75
+ });
76
+ return {
77
+ isWithinThirdPartySegment: result.isWithin,
78
+ ignoredReason: result.childProp
79
+ };
80
+ }
81
+
82
+ // Helper function to create mutation type from UFOIgnoreHoldsReason
83
+ function createMutationTypeWithIgnoredReason(reason) {
84
+ return "mutation:".concat(reason);
85
+ }
@@ -0,0 +1,51 @@
1
+ import React, { useContext, useMemo } from 'react';
2
+ import InteractionContext from '@atlaskit/interaction-context';
3
+ /**
4
+ * Prevent a subtree from holding up an interaction
5
+ * Use this when you have a component which loads in late, but
6
+ * isn't considered to be a breach of SLO
7
+ *
8
+ * ```js
9
+ * <App>
10
+ * <Main />
11
+ * <Sidebar>
12
+ * <UFOIgnoreHolds>
13
+ * <InsightsButton />
14
+ * </UFOIgnoreHolds>
15
+ * </Sidebar>
16
+ * </App>
17
+ * ```
18
+ *
19
+ * Has an `ignore` prop, to allow you to use it conditionally
20
+ * Has a `reason` prop, to specify why the hold is being ignored
21
+ */
22
+ export default function UFOIgnoreHolds({
23
+ children,
24
+ ignore = true,
25
+ reason
26
+ }) {
27
+ const parentContext = useContext(InteractionContext);
28
+ const ignoredInteractionContext = useMemo(() => {
29
+ if (!parentContext) {
30
+ return null;
31
+ }
32
+ return {
33
+ ...parentContext,
34
+ hold(...args) {
35
+ if (!ignore) {
36
+ return parentContext.hold(...args);
37
+ }
38
+ }
39
+ };
40
+ }, [parentContext, ignore]);
41
+
42
+ // react-18: Use children directly
43
+ const kids = children != null ? children : null;
44
+ if (!ignoredInteractionContext) {
45
+ return /*#__PURE__*/React.createElement(React.Fragment, null, kids);
46
+ }
47
+ return /*#__PURE__*/React.createElement(InteractionContext.Provider, {
48
+ value: ignoredInteractionContext
49
+ }, kids);
50
+ }
51
+ UFOIgnoreHolds.displayName = 'UFOIgnoreHolds';
@@ -1,49 +1,11 @@
1
- import React, { useContext, useMemo } from 'react';
2
- import InteractionContext from '@atlaskit/interaction-context';
1
+ import React from 'react';
2
+ import UFOIgnoreHolds from '../ignore-holds';
3
3
 
4
4
  /**
5
- * Prevent a subtree from holding up an interaction
6
- * Use this when you have a component which loads in late, but
7
- * isn't considered to be a breach of SLO
8
- *
9
- * ```js
10
- * <App>
11
- * <Main />
12
- * <Sidebar>
13
- * <UFOInteractionIgnore>
14
- * <InsightsButton />
15
- * </UFOInteractionIgnore>
16
- * </Sidebar>
17
- * </App>
18
- * ```
19
- *
20
- * Has an `ignore` prop, to allow you to use it conditionally
5
+ * Legacy wrapper component that delegates to `UFOIgnoreHolds`.
6
+ * Use `UFOIgnoreHolds` instead for new implementations.
7
+ * This component is maintained for backward compatibility only.
21
8
  */
22
- export default function UFOInteractionIgnore({
23
- children,
24
- ignore = true
25
- }) {
26
- const parentContext = useContext(InteractionContext);
27
- const ignoredInteractionContext = useMemo(() => {
28
- if (!parentContext) {
29
- return null;
30
- }
31
- return {
32
- ...parentContext,
33
- hold(...args) {
34
- if (!ignore) {
35
- return parentContext.hold(...args);
36
- }
37
- }
38
- };
39
- }, [parentContext, ignore]);
40
-
41
- // react-18: Use children directly
42
- const kids = children != null ? children : null;
43
- if (!ignoredInteractionContext) {
44
- return /*#__PURE__*/React.createElement(React.Fragment, null, kids);
45
- }
46
- return /*#__PURE__*/React.createElement(InteractionContext.Provider, {
47
- value: ignoredInteractionContext
48
- }, kids);
9
+ export default function UFOInteractionIgnore(props) {
10
+ return /*#__PURE__*/React.createElement(UFOIgnoreHolds, props);
49
11
  }
@@ -1,2 +1,3 @@
1
1
  import UFOSegment from './segment';
2
- export default UFOSegment;
2
+ export default UFOSegment;
3
+ export { UFOThirdPartySegment } from './third-party-segment';
@@ -20,7 +20,8 @@ const AsyncSegmentHighlight = /*#__PURE__*/lazy(() => import( /* webpackChunkNam
20
20
  export default function UFOSegment({
21
21
  name: segmentName,
22
22
  children,
23
- mode = 'single'
23
+ mode = 'single',
24
+ type = 'first-party'
24
25
  }) {
25
26
  var _getConfig2;
26
27
  const parentContext = useContext(UFOInteractionContext);
@@ -0,0 +1,18 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import React from 'react';
3
+ import { fg } from '@atlaskit/platform-feature-flags';
4
+ import UFOIgnoreHolds from '../ignore-holds';
5
+ import UFOSegment from './segment';
6
+ export function UFOThirdPartySegment(props) {
7
+ const {
8
+ children,
9
+ ...otherProps
10
+ } = props;
11
+ return /*#__PURE__*/React.createElement(UFOSegment, _extends({
12
+ type: "third-party"
13
+ }, otherProps), /*#__PURE__*/React.createElement(UFOIgnoreHolds, {
14
+ ignore: fg('platform_ufo_exclude_3p_elements_from_ttai'),
15
+ reason: "third-party-element"
16
+ }, children));
17
+ }
18
+ UFOThirdPartySegment.displayName = 'UFOThirdPartySegment';
@@ -3,7 +3,16 @@ import AbstractVCCalculatorBase from '../abstract-base-vc-calculator';
3
3
  import isViewportEntryData from '../utils/is-viewport-entry-data';
4
4
  const ABORTING_WINDOW_EVENT = ['wheel', 'scroll', 'keydown', 'resize'];
5
5
  const REVISION_NO = 'fy25.03';
6
- const CONSIDERED_ENTRY_TYPE = ['mutation:child-element', 'mutation:element', 'mutation:attribute', 'layout-shift', 'window:event'];
6
+ const getConsideredEntryTypes = () => {
7
+ const entryTypes = ['mutation:child-element', 'mutation:element', 'mutation:attribute', 'layout-shift', 'window:event'];
8
+
9
+ // If not exclude 3p elements from ttvc,
10
+ // including the tags into the ConsideredEntryTypes so that it won't be ignored for TTVC calculation
11
+ if (!fg('platform_ufo_exclude_3p_elements_from_ttvc')) {
12
+ entryTypes.push('mutation:third-party-element');
13
+ }
14
+ return entryTypes;
15
+ };
7
16
 
8
17
  // TODO: AFO-3523
9
18
  // Those are the attributes we have found when testing the 'fy25.03' manually.
@@ -17,7 +26,7 @@ export default class VCCalculator_FY25_03 extends AbstractVCCalculatorBase {
17
26
  super(REVISION_NO);
18
27
  }
19
28
  isEntryIncluded(entry) {
20
- if (!CONSIDERED_ENTRY_TYPE.includes(entry.data.type)) {
29
+ if (!getConsideredEntryTypes().includes(entry.data.type)) {
21
30
  return false;
22
31
  }
23
32
  if (entry.data.type === 'mutation:attribute') {
@@ -26,10 +35,7 @@ export default class VCCalculator_FY25_03 extends AbstractVCCalculatorBase {
26
35
  if (!attributeName || KNOWN_ATTRIBUTES_THAT_DOES_NOT_CAUSE_LAYOUT_SHIFTS.includes(attributeName)) {
27
36
  return false;
28
37
  }
29
- if (attributeName === 'data-aui-version' && fg('platform_ufo_filter_out_aui_attribute_changes')) {
30
- return false;
31
- }
32
- if (attributeName === 'data-testid' || attributeName === 'data-vc' || attributeName === 'data-ssr-placeholder' || attributeName === 'data-ssr-placeholder-replace' || attributeName === 'data-vc-nvs' || attributeName === 'data-media-vc-wrapper' || (attributeName === 'data-renderer-start-pos' || attributeName === 'data-table-local-id' || attributeName === 'spellcheck') && fg('platform_ufo_ignore_extra_attributes') || attributeName === 'data-auto-scrollable' || attributeName === 'id' || attributeName === 'tabindex' || NON_VISUAL_ARIA_ATTRIBUTES.includes(attributeName)) {
38
+ if (attributeName === 'data-aui-version' || attributeName === 'data-testid' || attributeName === 'data-vc' || attributeName === 'data-ssr-placeholder' || attributeName === 'data-ssr-placeholder-replace' || attributeName === 'data-vc-nvs' || attributeName === 'data-media-vc-wrapper' || (attributeName === 'data-renderer-start-pos' || attributeName === 'data-table-local-id' || attributeName === 'spellcheck') && fg('platform_ufo_ignore_extra_attributes') || attributeName === 'data-auto-scrollable' || attributeName === 'id' || attributeName === 'tabindex' || NON_VISUAL_ARIA_ATTRIBUTES.includes(attributeName)) {
33
39
  return false;
34
40
  }
35
41
  return true;