@atlaskit/react-ufo 3.13.26 → 3.13.28
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.
- package/CHANGELOG.md +19 -0
- package/README.md +3 -3
- package/dist/cjs/create-payload/index.js +8 -4
- package/dist/cjs/interactions-performance-observer/index.js +61 -0
- package/dist/cjs/vc/vc-observer-new/metric-calculator/fy25_03/index.js +2 -2
- package/dist/es2019/create-payload/index.js +10 -2
- package/dist/es2019/interactions-performance-observer/index.js +59 -0
- package/dist/es2019/vc/vc-observer-new/metric-calculator/fy25_03/index.js +2 -2
- package/dist/esm/create-payload/index.js +8 -4
- package/dist/esm/interactions-performance-observer/index.js +61 -0
- package/dist/esm/vc/vc-observer-new/metric-calculator/fy25_03/index.js +2 -2
- package/dist/types/common/common/types.d.ts +2 -0
- package/dist/types/create-payload/index.d.ts +512 -0
- package/dist/types-ts4.5/common/common/types.d.ts +2 -0
- package/dist/types-ts4.5/create-payload/index.d.ts +512 -0
- package/package.json +7 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @atlaskit/ufo-interaction-ignore
|
|
2
2
|
|
|
3
|
+
## 3.13.28
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#173121](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/173121)
|
|
8
|
+
[`0d5a766d0f501`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0d5a766d0f501) -
|
|
9
|
+
Track unknown interactions elements
|
|
10
|
+
|
|
11
|
+
## 3.13.27
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [#175316](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/175316)
|
|
16
|
+
[`a2a93696df1b8`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/a2a93696df1b8) -
|
|
17
|
+
Add extra non-visual attributes to UFO ignore list
|
|
18
|
+
- [#173438](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/173438)
|
|
19
|
+
[`03117ec2ea74c`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/03117ec2ea74c) -
|
|
20
|
+
Update README
|
|
21
|
+
|
|
3
22
|
## 3.13.26
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Parts of React UFO that need to be scoped within @atlaskit
|
|
|
10
10
|
|
|
11
11
|
In one terminal:
|
|
12
12
|
|
|
13
|
-
```
|
|
13
|
+
```shell
|
|
14
14
|
cd platform && nvm use && yarn
|
|
15
15
|
yarn start:rspack react-ufo
|
|
16
16
|
```
|
|
@@ -19,7 +19,7 @@ This will start the dev server, accessible via http://localhost:9000.
|
|
|
19
19
|
|
|
20
20
|
Then in a separate terminal:
|
|
21
21
|
|
|
22
|
-
```
|
|
22
|
+
```shell
|
|
23
23
|
cd platform && nvm use
|
|
24
24
|
yarn test:integration packages/react-ufo/atlaskit/__tests__/ --retries 0 --reporter list --reuse-dev-server --project=desktop-chromium --max-failures=0
|
|
25
25
|
```
|
|
@@ -35,6 +35,6 @@ increase the following:
|
|
|
35
35
|
|
|
36
36
|
Example:
|
|
37
37
|
|
|
38
|
-
```
|
|
38
|
+
```shell
|
|
39
39
|
yarn test:integration packages/react-ufo/atlaskit/__tests__/playwright/base.spec.ts --retries 0 --reporter list --reuse-dev-server --project=desktop-chromium --max-failures=0 --repeat-each 50 --workers 50
|
|
40
40
|
```
|
|
@@ -709,7 +709,7 @@ function createInteractionMetricsPayload(_x3, _x4, _x5) {
|
|
|
709
709
|
function _createInteractionMetricsPayload() {
|
|
710
710
|
_createInteractionMetricsPayload = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(interaction, interactionId, experimental) {
|
|
711
711
|
var _window$location, _config$additionalPay;
|
|
712
|
-
var interactionPayloadStart, config, end, start, ufoName, knownSegments, rate, type, abortReason, routeName, featureFlags, previousInteractionName, isPreviousInteractionAborted, abortedByInteractionName, responsiveness, pageVisibilityAtTTI, pageVisibilityAtTTAI, segments, segmentTree, isDetailedPayload, isPageLoad, calculatePageVisibilityFromTheStartOfPageLoad, moreAccuratePageVisibilityAtTTI, moreAccuratePageVisibilityAtTTAI, labelStack, getInitialPageLoadSSRMetrics, pageLoadInteractionMetrics, getDetailedInteractionMetrics, getPageLoadDetailedInteractionMetrics, newUFOName, resourceTimings, _yield$Promise$all, _yield$Promise$all2, vcMetrics, experimentalMetrics, paintMetrics, payload;
|
|
712
|
+
var interactionPayloadStart, config, end, start, ufoName, knownSegments, rate, type, abortReason, routeName, featureFlags, previousInteractionName, isPreviousInteractionAborted, abortedByInteractionName, responsiveness, unknownElementName, unknownElementHierarchy, pageVisibilityAtTTI, pageVisibilityAtTTAI, segments, segmentTree, isDetailedPayload, isPageLoad, calculatePageVisibilityFromTheStartOfPageLoad, moreAccuratePageVisibilityAtTTI, moreAccuratePageVisibilityAtTTAI, labelStack, getInitialPageLoadSSRMetrics, pageLoadInteractionMetrics, getDetailedInteractionMetrics, getPageLoadDetailedInteractionMetrics, newUFOName, resourceTimings, _yield$Promise$all, _yield$Promise$all2, vcMetrics, experimentalMetrics, paintMetrics, payload;
|
|
713
713
|
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
714
714
|
while (1) switch (_context2.prev = _context2.next) {
|
|
715
715
|
case 0:
|
|
@@ -721,7 +721,7 @@ function _createInteractionMetricsPayload() {
|
|
|
721
721
|
}
|
|
722
722
|
throw Error('UFO Configuration not provided');
|
|
723
723
|
case 4:
|
|
724
|
-
end = interaction.end, start = interaction.start, ufoName = interaction.ufoName, knownSegments = interaction.knownSegments, rate = interaction.rate, type = interaction.type, abortReason = interaction.abortReason, routeName = interaction.routeName, featureFlags = interaction.featureFlags, previousInteractionName = interaction.previousInteractionName, isPreviousInteractionAborted = interaction.isPreviousInteractionAborted, abortedByInteractionName = interaction.abortedByInteractionName, responsiveness = interaction.responsiveness;
|
|
724
|
+
end = interaction.end, start = interaction.start, ufoName = interaction.ufoName, knownSegments = interaction.knownSegments, rate = interaction.rate, type = interaction.type, abortReason = interaction.abortReason, routeName = interaction.routeName, featureFlags = interaction.featureFlags, previousInteractionName = interaction.previousInteractionName, isPreviousInteractionAborted = interaction.isPreviousInteractionAborted, abortedByInteractionName = interaction.abortedByInteractionName, responsiveness = interaction.responsiveness, unknownElementName = interaction.unknownElementName, unknownElementHierarchy = interaction.unknownElementHierarchy;
|
|
725
725
|
pageVisibilityAtTTI = getPageVisibilityUpToTTI(interaction);
|
|
726
726
|
pageVisibilityAtTTAI = (0, _getPageVisibilityUpToTtai.default)(interaction);
|
|
727
727
|
segments = config.killswitchNestedSegments ? [] : knownSegments;
|
|
@@ -825,7 +825,7 @@ function _createInteractionMetricsPayload() {
|
|
|
825
825
|
}, (0, _platformFeatureFlags.fg)('platform_ufo_report_cpu_usage') ? {
|
|
826
826
|
'event:cpu:usage': (0, _machineUtilisation.createPressureStateReport)(interaction.start, interaction.end)
|
|
827
827
|
} : {}), getBrowserMetadata()), getSSRProperties(type)), getAssetsMetrics(interaction, pageLoadInteractionMetrics === null || pageLoadInteractionMetrics === void 0 ? void 0 : pageLoadInteractionMetrics.SSRDoneTime)), getPPSMetrics(interaction)), paintMetrics), getNavigationMetrics(type)), vcMetrics), experimentalMetrics), (_config$additionalPay = config.additionalPayloadData) === null || _config$additionalPay === void 0 ? void 0 : _config$additionalPay.call(config, interaction)), getTracingContextData(interaction)), getStylesheetMetrics()), getErrorCounts(interaction)), {}, {
|
|
828
|
-
interactionMetrics: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
828
|
+
interactionMetrics: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
829
829
|
namePrefix: config.namePrefix || '',
|
|
830
830
|
segmentPrefix: config.segmentPrefix || '',
|
|
831
831
|
interactionId: interactionId,
|
|
@@ -861,7 +861,11 @@ function _createInteractionMetricsPayload() {
|
|
|
861
861
|
} : {}), labelStack), pageLoadInteractionMetrics), getDetailedInteractionMetrics(resourceTimings)), getPageLoadDetailedInteractionMetrics()), getBm3TrackerTimings(interaction)), {}, {
|
|
862
862
|
'metric:ttai': experimental ? regularTTAI || expTTAI : undefined,
|
|
863
863
|
'metric:experimental:ttai': expTTAI
|
|
864
|
-
}
|
|
864
|
+
}, unknownElementName ? {
|
|
865
|
+
unknownElementName: unknownElementName
|
|
866
|
+
} : {}), unknownElementHierarchy ? {
|
|
867
|
+
unknownElementHierarchy: unknownElementHierarchy
|
|
868
|
+
} : {}),
|
|
865
869
|
'ufo:payloadTime': (0, _roundNumber.roundEpsilon)(performance.now() - interactionPayloadStart)
|
|
866
870
|
})
|
|
867
871
|
}
|
|
@@ -6,13 +6,67 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
});
|
|
7
7
|
exports.setInteractionPerformanceEvent = exports.getPerformanceObserver = void 0;
|
|
8
8
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
9
10
|
var _interactionMetrics = require("../interaction-metrics");
|
|
11
|
+
var _getUniqueElementName = _interopRequireDefault(require("../vc/vc-observer-new/get-unique-element-name"));
|
|
10
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; }
|
|
11
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; }
|
|
12
14
|
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; } } }; }
|
|
13
15
|
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; } }
|
|
14
16
|
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; }
|
|
15
17
|
var performanceEventObserver;
|
|
18
|
+
var selectorConfig = {
|
|
19
|
+
id: true,
|
|
20
|
+
testId: true,
|
|
21
|
+
role: true,
|
|
22
|
+
className: true
|
|
23
|
+
};
|
|
24
|
+
function getTestIdName(memoizedProps) {
|
|
25
|
+
if (memoizedProps['data-testid']) {
|
|
26
|
+
return "[data-testid=".concat(memoizedProps['data-testid'], "]");
|
|
27
|
+
} else if (memoizedProps['data-test-id']) {
|
|
28
|
+
return "[data-test-id=".concat(memoizedProps['data-testid'], "]");
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
function getReactComponentHierarchy(element) {
|
|
33
|
+
var componentHierarchy = [];
|
|
34
|
+
// Function to traverse up the fiber tree
|
|
35
|
+
function traverseFiber(fiber) {
|
|
36
|
+
var currentFiber = fiber;
|
|
37
|
+
while (currentFiber) {
|
|
38
|
+
if (currentFiber.type) {
|
|
39
|
+
// Check if there's a display name or a function name
|
|
40
|
+
var componentName = currentFiber.type.displayName || currentFiber.type.name;
|
|
41
|
+
// checking when component name is bigger than the minimized name produced by react
|
|
42
|
+
if (componentName && componentName.length > 2 && !componentName.includes('Listener') && !componentName.includes('Provider')) {
|
|
43
|
+
componentHierarchy.push(componentName);
|
|
44
|
+
}
|
|
45
|
+
if (componentName === 'UFOSegment') {
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (currentFiber.memoizedProps) {
|
|
50
|
+
var dataIdInfo = getTestIdName(currentFiber.memoizedProps);
|
|
51
|
+
if (dataIdInfo) {
|
|
52
|
+
componentHierarchy.push(dataIdInfo);
|
|
53
|
+
currentFiber = null;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
currentFiber = currentFiber.return;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Access the reactFiber node from the HTML element
|
|
61
|
+
var reactFiberKey = Object.keys(element).find(function (key) {
|
|
62
|
+
return key.startsWith('__reactFiber$');
|
|
63
|
+
});
|
|
64
|
+
if (reactFiberKey) {
|
|
65
|
+
var fiber = element[reactFiberKey];
|
|
66
|
+
traverseFiber(fiber);
|
|
67
|
+
}
|
|
68
|
+
return componentHierarchy.reverse().join(' > ');
|
|
69
|
+
}
|
|
16
70
|
var getPerformanceObserver = exports.getPerformanceObserver = function getPerformanceObserver() {
|
|
17
71
|
performanceEventObserver = performanceEventObserver || new PerformanceObserver(function (entries) {
|
|
18
72
|
var list = entries.getEntries();
|
|
@@ -47,5 +101,12 @@ var setInteractionPerformanceEvent = exports.setInteractionPerformanceEvent = fu
|
|
|
47
101
|
// it means the interaction start time is not accurate, we assign
|
|
48
102
|
// this value which will match the timestamp in the event
|
|
49
103
|
interaction.start = Math.min(interaction.start, entry.startTime);
|
|
104
|
+
if (interaction.ufoName === 'unknown' && (0, _platformFeatureFlags.fg)('platform_ufo_enable_unknown_interactions_elements')) {
|
|
105
|
+
if (entry.target) {
|
|
106
|
+
var componentHierarchy = getReactComponentHierarchy(entry.target);
|
|
107
|
+
interaction.unknownElementHierarchy = componentHierarchy;
|
|
108
|
+
}
|
|
109
|
+
interaction.unknownElementName = (0, _getUniqueElementName.default)(selectorConfig, entry.target);
|
|
110
|
+
}
|
|
50
111
|
}
|
|
51
112
|
};
|
|
@@ -25,7 +25,7 @@ var CONSIDERED_ENTRY_TYPE = ['mutation:child-element', 'mutation:element', 'muta
|
|
|
25
25
|
var KNOWN_ATTRIBUTES_THAT_DOES_NOT_CAUSE_LAYOUT_SHIFTS = exports.KNOWN_ATTRIBUTES_THAT_DOES_NOT_CAUSE_LAYOUT_SHIFTS = ['data-drop-target-for-element', 'draggable'];
|
|
26
26
|
|
|
27
27
|
// Common aria attributes that don't cause visual layout shifts
|
|
28
|
-
var NON_VISUAL_ARIA_ATTRIBUTES = exports.NON_VISUAL_ARIA_ATTRIBUTES = ['aria-label', 'aria-labelledby', 'aria-describedby', 'aria-hidden', 'aria-expanded', 'aria-controls', 'aria-selected', 'aria-checked', 'aria-disabled', 'aria-required', 'aria-current', 'aria-haspopup', 'aria-pressed', 'aria-live'];
|
|
28
|
+
var NON_VISUAL_ARIA_ATTRIBUTES = exports.NON_VISUAL_ARIA_ATTRIBUTES = ['aria-label', 'aria-labelledby', 'aria-describedby', 'aria-hidden', 'aria-expanded', 'aria-controls', 'aria-selected', 'aria-checked', 'aria-disabled', 'aria-required', 'aria-current', 'aria-haspopup', 'aria-pressed', 'aria-atomic', 'aria-live'];
|
|
29
29
|
var VCCalculator_FY25_03 = exports.default = /*#__PURE__*/function (_AbstractVCCalculator) {
|
|
30
30
|
function VCCalculator_FY25_03() {
|
|
31
31
|
(0, _classCallCheck2.default)(this, VCCalculator_FY25_03);
|
|
@@ -47,7 +47,7 @@ var VCCalculator_FY25_03 = exports.default = /*#__PURE__*/function (_AbstractVCC
|
|
|
47
47
|
if (attributeName === 'data-aui-version' && (0, _platformFeatureFlags.fg)('platform_ufo_filter_out_aui_attribute_changes')) {
|
|
48
48
|
return false;
|
|
49
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-auto-scrollable' || attributeName === 'id' || attributeName === 'tabindex' || NON_VISUAL_ARIA_ATTRIBUTES.includes(attributeName)) {
|
|
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)) {
|
|
51
51
|
return false;
|
|
52
52
|
}
|
|
53
53
|
return true;
|
|
@@ -700,7 +700,9 @@ async function createInteractionMetricsPayload(interaction, interactionId, exper
|
|
|
700
700
|
previousInteractionName,
|
|
701
701
|
isPreviousInteractionAborted,
|
|
702
702
|
abortedByInteractionName,
|
|
703
|
-
responsiveness
|
|
703
|
+
responsiveness,
|
|
704
|
+
unknownElementName,
|
|
705
|
+
unknownElementHierarchy
|
|
704
706
|
} = interaction;
|
|
705
707
|
const pageVisibilityAtTTI = getPageVisibilityUpToTTI(interaction);
|
|
706
708
|
const pageVisibilityAtTTAI = getPageVisibilityUpToTTAI(interaction);
|
|
@@ -854,7 +856,13 @@ async function createInteractionMetricsPayload(interaction, interactionId, exper
|
|
|
854
856
|
...getPageLoadDetailedInteractionMetrics(),
|
|
855
857
|
...getBm3TrackerTimings(interaction),
|
|
856
858
|
'metric:ttai': experimental ? regularTTAI || expTTAI : undefined,
|
|
857
|
-
'metric:experimental:ttai': expTTAI
|
|
859
|
+
'metric:experimental:ttai': expTTAI,
|
|
860
|
+
...(unknownElementName ? {
|
|
861
|
+
unknownElementName
|
|
862
|
+
} : {}),
|
|
863
|
+
...(unknownElementHierarchy ? {
|
|
864
|
+
unknownElementHierarchy
|
|
865
|
+
} : {})
|
|
858
866
|
},
|
|
859
867
|
'ufo:payloadTime': roundEpsilon(performance.now() - interactionPayloadStart)
|
|
860
868
|
}
|
|
@@ -1,5 +1,57 @@
|
|
|
1
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
1
2
|
import { getActiveInteraction } from '../interaction-metrics';
|
|
3
|
+
import getElementName from '../vc/vc-observer-new/get-unique-element-name';
|
|
2
4
|
let performanceEventObserver;
|
|
5
|
+
const selectorConfig = {
|
|
6
|
+
id: true,
|
|
7
|
+
testId: true,
|
|
8
|
+
role: true,
|
|
9
|
+
className: true
|
|
10
|
+
};
|
|
11
|
+
function getTestIdName(memoizedProps) {
|
|
12
|
+
if (memoizedProps['data-testid']) {
|
|
13
|
+
return `[data-testid=${memoizedProps['data-testid']}]`;
|
|
14
|
+
} else if (memoizedProps['data-test-id']) {
|
|
15
|
+
return `[data-test-id=${memoizedProps['data-testid']}]`;
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
function getReactComponentHierarchy(element) {
|
|
20
|
+
const componentHierarchy = [];
|
|
21
|
+
// Function to traverse up the fiber tree
|
|
22
|
+
function traverseFiber(fiber) {
|
|
23
|
+
let currentFiber = fiber;
|
|
24
|
+
while (currentFiber) {
|
|
25
|
+
if (currentFiber.type) {
|
|
26
|
+
// Check if there's a display name or a function name
|
|
27
|
+
const componentName = currentFiber.type.displayName || currentFiber.type.name;
|
|
28
|
+
// checking when component name is bigger than the minimized name produced by react
|
|
29
|
+
if (componentName && componentName.length > 2 && !componentName.includes('Listener') && !componentName.includes('Provider')) {
|
|
30
|
+
componentHierarchy.push(componentName);
|
|
31
|
+
}
|
|
32
|
+
if (componentName === 'UFOSegment') {
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (currentFiber.memoizedProps) {
|
|
37
|
+
const dataIdInfo = getTestIdName(currentFiber.memoizedProps);
|
|
38
|
+
if (dataIdInfo) {
|
|
39
|
+
componentHierarchy.push(dataIdInfo);
|
|
40
|
+
currentFiber = null;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
currentFiber = currentFiber.return;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Access the reactFiber node from the HTML element
|
|
48
|
+
const reactFiberKey = Object.keys(element).find(key => key.startsWith('__reactFiber$'));
|
|
49
|
+
if (reactFiberKey) {
|
|
50
|
+
const fiber = element[reactFiberKey];
|
|
51
|
+
traverseFiber(fiber);
|
|
52
|
+
}
|
|
53
|
+
return componentHierarchy.reverse().join(' > ');
|
|
54
|
+
}
|
|
3
55
|
export const getPerformanceObserver = () => {
|
|
4
56
|
performanceEventObserver = performanceEventObserver || new PerformanceObserver(entries => {
|
|
5
57
|
const list = entries.getEntries();
|
|
@@ -26,5 +78,12 @@ export const setInteractionPerformanceEvent = entry => {
|
|
|
26
78
|
// it means the interaction start time is not accurate, we assign
|
|
27
79
|
// this value which will match the timestamp in the event
|
|
28
80
|
interaction.start = Math.min(interaction.start, entry.startTime);
|
|
81
|
+
if (interaction.ufoName === 'unknown' && fg('platform_ufo_enable_unknown_interactions_elements')) {
|
|
82
|
+
if (entry.target) {
|
|
83
|
+
const componentHierarchy = getReactComponentHierarchy(entry.target);
|
|
84
|
+
interaction.unknownElementHierarchy = componentHierarchy;
|
|
85
|
+
}
|
|
86
|
+
interaction.unknownElementName = getElementName(selectorConfig, entry.target);
|
|
87
|
+
}
|
|
29
88
|
}
|
|
30
89
|
};
|
|
@@ -11,7 +11,7 @@ const CONSIDERED_ENTRY_TYPE = ['mutation:child-element', 'mutation:element', 'mu
|
|
|
11
11
|
export const KNOWN_ATTRIBUTES_THAT_DOES_NOT_CAUSE_LAYOUT_SHIFTS = ['data-drop-target-for-element', 'draggable'];
|
|
12
12
|
|
|
13
13
|
// Common aria attributes that don't cause visual layout shifts
|
|
14
|
-
export const NON_VISUAL_ARIA_ATTRIBUTES = ['aria-label', 'aria-labelledby', 'aria-describedby', 'aria-hidden', 'aria-expanded', 'aria-controls', 'aria-selected', 'aria-checked', 'aria-disabled', 'aria-required', 'aria-current', 'aria-haspopup', 'aria-pressed', 'aria-live'];
|
|
14
|
+
export const NON_VISUAL_ARIA_ATTRIBUTES = ['aria-label', 'aria-labelledby', 'aria-describedby', 'aria-hidden', 'aria-expanded', 'aria-controls', 'aria-selected', 'aria-checked', 'aria-disabled', 'aria-required', 'aria-current', 'aria-haspopup', 'aria-pressed', 'aria-atomic', 'aria-live'];
|
|
15
15
|
export default class VCCalculator_FY25_03 extends AbstractVCCalculatorBase {
|
|
16
16
|
constructor() {
|
|
17
17
|
super(REVISION_NO);
|
|
@@ -29,7 +29,7 @@ export default class VCCalculator_FY25_03 extends AbstractVCCalculatorBase {
|
|
|
29
29
|
if (attributeName === 'data-aui-version' && fg('platform_ufo_filter_out_aui_attribute_changes')) {
|
|
30
30
|
return false;
|
|
31
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-auto-scrollable' || attributeName === 'id' || attributeName === 'tabindex' || NON_VISUAL_ARIA_ATTRIBUTES.includes(attributeName)) {
|
|
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)) {
|
|
33
33
|
return false;
|
|
34
34
|
}
|
|
35
35
|
return true;
|
|
@@ -699,7 +699,7 @@ function createInteractionMetricsPayload(_x3, _x4, _x5) {
|
|
|
699
699
|
function _createInteractionMetricsPayload() {
|
|
700
700
|
_createInteractionMetricsPayload = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(interaction, interactionId, experimental) {
|
|
701
701
|
var _window$location, _config$additionalPay;
|
|
702
|
-
var interactionPayloadStart, config, end, start, ufoName, knownSegments, rate, type, abortReason, routeName, featureFlags, previousInteractionName, isPreviousInteractionAborted, abortedByInteractionName, responsiveness, pageVisibilityAtTTI, pageVisibilityAtTTAI, segments, segmentTree, isDetailedPayload, isPageLoad, calculatePageVisibilityFromTheStartOfPageLoad, moreAccuratePageVisibilityAtTTI, moreAccuratePageVisibilityAtTTAI, labelStack, getInitialPageLoadSSRMetrics, pageLoadInteractionMetrics, getDetailedInteractionMetrics, getPageLoadDetailedInteractionMetrics, newUFOName, resourceTimings, _yield$Promise$all, _yield$Promise$all2, vcMetrics, experimentalMetrics, paintMetrics, payload;
|
|
702
|
+
var interactionPayloadStart, config, end, start, ufoName, knownSegments, rate, type, abortReason, routeName, featureFlags, previousInteractionName, isPreviousInteractionAborted, abortedByInteractionName, responsiveness, unknownElementName, unknownElementHierarchy, pageVisibilityAtTTI, pageVisibilityAtTTAI, segments, segmentTree, isDetailedPayload, isPageLoad, calculatePageVisibilityFromTheStartOfPageLoad, moreAccuratePageVisibilityAtTTI, moreAccuratePageVisibilityAtTTAI, labelStack, getInitialPageLoadSSRMetrics, pageLoadInteractionMetrics, getDetailedInteractionMetrics, getPageLoadDetailedInteractionMetrics, newUFOName, resourceTimings, _yield$Promise$all, _yield$Promise$all2, vcMetrics, experimentalMetrics, paintMetrics, payload;
|
|
703
703
|
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
704
704
|
while (1) switch (_context2.prev = _context2.next) {
|
|
705
705
|
case 0:
|
|
@@ -711,7 +711,7 @@ function _createInteractionMetricsPayload() {
|
|
|
711
711
|
}
|
|
712
712
|
throw Error('UFO Configuration not provided');
|
|
713
713
|
case 4:
|
|
714
|
-
end = interaction.end, start = interaction.start, ufoName = interaction.ufoName, knownSegments = interaction.knownSegments, rate = interaction.rate, type = interaction.type, abortReason = interaction.abortReason, routeName = interaction.routeName, featureFlags = interaction.featureFlags, previousInteractionName = interaction.previousInteractionName, isPreviousInteractionAborted = interaction.isPreviousInteractionAborted, abortedByInteractionName = interaction.abortedByInteractionName, responsiveness = interaction.responsiveness;
|
|
714
|
+
end = interaction.end, start = interaction.start, ufoName = interaction.ufoName, knownSegments = interaction.knownSegments, rate = interaction.rate, type = interaction.type, abortReason = interaction.abortReason, routeName = interaction.routeName, featureFlags = interaction.featureFlags, previousInteractionName = interaction.previousInteractionName, isPreviousInteractionAborted = interaction.isPreviousInteractionAborted, abortedByInteractionName = interaction.abortedByInteractionName, responsiveness = interaction.responsiveness, unknownElementName = interaction.unknownElementName, unknownElementHierarchy = interaction.unknownElementHierarchy;
|
|
715
715
|
pageVisibilityAtTTI = getPageVisibilityUpToTTI(interaction);
|
|
716
716
|
pageVisibilityAtTTAI = getPageVisibilityUpToTTAI(interaction);
|
|
717
717
|
segments = config.killswitchNestedSegments ? [] : knownSegments;
|
|
@@ -815,7 +815,7 @@ function _createInteractionMetricsPayload() {
|
|
|
815
815
|
}, fg('platform_ufo_report_cpu_usage') ? {
|
|
816
816
|
'event:cpu:usage': createPressureStateReport(interaction.start, interaction.end)
|
|
817
817
|
} : {}), getBrowserMetadata()), getSSRProperties(type)), getAssetsMetrics(interaction, pageLoadInteractionMetrics === null || pageLoadInteractionMetrics === void 0 ? void 0 : pageLoadInteractionMetrics.SSRDoneTime)), getPPSMetrics(interaction)), paintMetrics), getNavigationMetrics(type)), vcMetrics), experimentalMetrics), (_config$additionalPay = config.additionalPayloadData) === null || _config$additionalPay === void 0 ? void 0 : _config$additionalPay.call(config, interaction)), getTracingContextData(interaction)), getStylesheetMetrics()), getErrorCounts(interaction)), {}, {
|
|
818
|
-
interactionMetrics: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
818
|
+
interactionMetrics: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
819
819
|
namePrefix: config.namePrefix || '',
|
|
820
820
|
segmentPrefix: config.segmentPrefix || '',
|
|
821
821
|
interactionId: interactionId,
|
|
@@ -851,7 +851,11 @@ function _createInteractionMetricsPayload() {
|
|
|
851
851
|
} : {}), labelStack), pageLoadInteractionMetrics), getDetailedInteractionMetrics(resourceTimings)), getPageLoadDetailedInteractionMetrics()), getBm3TrackerTimings(interaction)), {}, {
|
|
852
852
|
'metric:ttai': experimental ? regularTTAI || expTTAI : undefined,
|
|
853
853
|
'metric:experimental:ttai': expTTAI
|
|
854
|
-
}
|
|
854
|
+
}, unknownElementName ? {
|
|
855
|
+
unknownElementName: unknownElementName
|
|
856
|
+
} : {}), unknownElementHierarchy ? {
|
|
857
|
+
unknownElementHierarchy: unknownElementHierarchy
|
|
858
|
+
} : {}),
|
|
855
859
|
'ufo:payloadTime': roundEpsilon(performance.now() - interactionPayloadStart)
|
|
856
860
|
})
|
|
857
861
|
}
|
|
@@ -4,8 +4,62 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
4
4
|
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; } } }; }
|
|
5
5
|
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; } }
|
|
6
6
|
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; }
|
|
7
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
7
8
|
import { getActiveInteraction } from '../interaction-metrics';
|
|
9
|
+
import getElementName from '../vc/vc-observer-new/get-unique-element-name';
|
|
8
10
|
var performanceEventObserver;
|
|
11
|
+
var selectorConfig = {
|
|
12
|
+
id: true,
|
|
13
|
+
testId: true,
|
|
14
|
+
role: true,
|
|
15
|
+
className: true
|
|
16
|
+
};
|
|
17
|
+
function getTestIdName(memoizedProps) {
|
|
18
|
+
if (memoizedProps['data-testid']) {
|
|
19
|
+
return "[data-testid=".concat(memoizedProps['data-testid'], "]");
|
|
20
|
+
} else if (memoizedProps['data-test-id']) {
|
|
21
|
+
return "[data-test-id=".concat(memoizedProps['data-testid'], "]");
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
function getReactComponentHierarchy(element) {
|
|
26
|
+
var componentHierarchy = [];
|
|
27
|
+
// Function to traverse up the fiber tree
|
|
28
|
+
function traverseFiber(fiber) {
|
|
29
|
+
var currentFiber = fiber;
|
|
30
|
+
while (currentFiber) {
|
|
31
|
+
if (currentFiber.type) {
|
|
32
|
+
// Check if there's a display name or a function name
|
|
33
|
+
var componentName = currentFiber.type.displayName || currentFiber.type.name;
|
|
34
|
+
// checking when component name is bigger than the minimized name produced by react
|
|
35
|
+
if (componentName && componentName.length > 2 && !componentName.includes('Listener') && !componentName.includes('Provider')) {
|
|
36
|
+
componentHierarchy.push(componentName);
|
|
37
|
+
}
|
|
38
|
+
if (componentName === 'UFOSegment') {
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (currentFiber.memoizedProps) {
|
|
43
|
+
var dataIdInfo = getTestIdName(currentFiber.memoizedProps);
|
|
44
|
+
if (dataIdInfo) {
|
|
45
|
+
componentHierarchy.push(dataIdInfo);
|
|
46
|
+
currentFiber = null;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
currentFiber = currentFiber.return;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Access the reactFiber node from the HTML element
|
|
54
|
+
var reactFiberKey = Object.keys(element).find(function (key) {
|
|
55
|
+
return key.startsWith('__reactFiber$');
|
|
56
|
+
});
|
|
57
|
+
if (reactFiberKey) {
|
|
58
|
+
var fiber = element[reactFiberKey];
|
|
59
|
+
traverseFiber(fiber);
|
|
60
|
+
}
|
|
61
|
+
return componentHierarchy.reverse().join(' > ');
|
|
62
|
+
}
|
|
9
63
|
export var getPerformanceObserver = function getPerformanceObserver() {
|
|
10
64
|
performanceEventObserver = performanceEventObserver || new PerformanceObserver(function (entries) {
|
|
11
65
|
var list = entries.getEntries();
|
|
@@ -40,5 +94,12 @@ export var setInteractionPerformanceEvent = function setInteractionPerformanceEv
|
|
|
40
94
|
// it means the interaction start time is not accurate, we assign
|
|
41
95
|
// this value which will match the timestamp in the event
|
|
42
96
|
interaction.start = Math.min(interaction.start, entry.startTime);
|
|
97
|
+
if (interaction.ufoName === 'unknown' && fg('platform_ufo_enable_unknown_interactions_elements')) {
|
|
98
|
+
if (entry.target) {
|
|
99
|
+
var componentHierarchy = getReactComponentHierarchy(entry.target);
|
|
100
|
+
interaction.unknownElementHierarchy = componentHierarchy;
|
|
101
|
+
}
|
|
102
|
+
interaction.unknownElementName = getElementName(selectorConfig, entry.target);
|
|
103
|
+
}
|
|
43
104
|
}
|
|
44
105
|
};
|
|
@@ -18,7 +18,7 @@ var CONSIDERED_ENTRY_TYPE = ['mutation:child-element', 'mutation:element', 'muta
|
|
|
18
18
|
export var KNOWN_ATTRIBUTES_THAT_DOES_NOT_CAUSE_LAYOUT_SHIFTS = ['data-drop-target-for-element', 'draggable'];
|
|
19
19
|
|
|
20
20
|
// Common aria attributes that don't cause visual layout shifts
|
|
21
|
-
export var NON_VISUAL_ARIA_ATTRIBUTES = ['aria-label', 'aria-labelledby', 'aria-describedby', 'aria-hidden', 'aria-expanded', 'aria-controls', 'aria-selected', 'aria-checked', 'aria-disabled', 'aria-required', 'aria-current', 'aria-haspopup', 'aria-pressed', 'aria-live'];
|
|
21
|
+
export var NON_VISUAL_ARIA_ATTRIBUTES = ['aria-label', 'aria-labelledby', 'aria-describedby', 'aria-hidden', 'aria-expanded', 'aria-controls', 'aria-selected', 'aria-checked', 'aria-disabled', 'aria-required', 'aria-current', 'aria-haspopup', 'aria-pressed', 'aria-atomic', 'aria-live'];
|
|
22
22
|
var VCCalculator_FY25_03 = /*#__PURE__*/function (_AbstractVCCalculator) {
|
|
23
23
|
function VCCalculator_FY25_03() {
|
|
24
24
|
_classCallCheck(this, VCCalculator_FY25_03);
|
|
@@ -40,7 +40,7 @@ var VCCalculator_FY25_03 = /*#__PURE__*/function (_AbstractVCCalculator) {
|
|
|
40
40
|
if (attributeName === 'data-aui-version' && fg('platform_ufo_filter_out_aui_attribute_changes')) {
|
|
41
41
|
return false;
|
|
42
42
|
}
|
|
43
|
-
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-auto-scrollable' || attributeName === 'id' || attributeName === 'tabindex' || NON_VISUAL_ARIA_ATTRIBUTES.includes(attributeName)) {
|
|
43
|
+
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)) {
|
|
44
44
|
return false;
|
|
45
45
|
}
|
|
46
46
|
return true;
|
|
@@ -161,6 +161,8 @@ export interface InteractionMetrics {
|
|
|
161
161
|
vc?: VCRawDataType | null;
|
|
162
162
|
experimentalTTAI?: number;
|
|
163
163
|
experimentalVC90?: number;
|
|
164
|
+
unknownElementName?: string;
|
|
165
|
+
unknownElementHierarchy?: string;
|
|
164
166
|
}
|
|
165
167
|
export type LoadProfilerEventInfo = {
|
|
166
168
|
identifier: string;
|