@atlaskit/react-ufo 2.14.3 → 2.15.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.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/create-payload/index.js +10 -0
- package/dist/cjs/experience-trace-id-context/index.js +5 -1
- package/dist/cjs/segment/segment.js +7 -1
- package/dist/cjs/vc/vc-observer/heatmap/heatmap.js +275 -0
- package/dist/cjs/vc/vc-observer/index.js +115 -26
- package/dist/cjs/vc/vc-observer/revisions/ViewportUpdateClassifier.js +52 -0
- package/dist/cjs/vc/vc-observer/revisions/fy24_01.js +39 -0
- package/dist/cjs/vc/vc-observer/revisions/fy25_01.js +39 -0
- package/dist/cjs/vc/vc-observer/revisions/revisions.js +23 -0
- package/dist/cjs/vc/vc-observer/revisions/types.js +5 -0
- package/dist/es2019/create-payload/index.js +10 -0
- package/dist/es2019/experience-trace-id-context/index.js +4 -0
- package/dist/es2019/segment/segment.js +11 -3
- package/dist/es2019/vc/vc-observer/heatmap/heatmap.js +238 -0
- package/dist/es2019/vc/vc-observer/index.js +94 -3
- package/dist/es2019/vc/vc-observer/revisions/ViewportUpdateClassifier.js +35 -0
- package/dist/es2019/vc/vc-observer/revisions/fy24_01.js +21 -0
- package/dist/es2019/vc/vc-observer/revisions/fy25_01.js +21 -0
- package/dist/es2019/vc/vc-observer/revisions/revisions.js +19 -0
- package/dist/es2019/vc/vc-observer/revisions/types.js +1 -0
- package/dist/esm/create-payload/index.js +10 -0
- package/dist/esm/experience-trace-id-context/index.js +4 -0
- package/dist/esm/segment/segment.js +7 -1
- package/dist/esm/vc/vc-observer/heatmap/heatmap.js +268 -0
- package/dist/esm/vc/vc-observer/index.js +115 -26
- package/dist/esm/vc/vc-observer/revisions/ViewportUpdateClassifier.js +45 -0
- package/dist/esm/vc/vc-observer/revisions/fy24_01.js +32 -0
- package/dist/esm/vc/vc-observer/revisions/fy25_01.js +32 -0
- package/dist/esm/vc/vc-observer/revisions/revisions.js +17 -0
- package/dist/esm/vc/vc-observer/revisions/types.js +1 -0
- package/dist/types/common/vc/types.d.ts +27 -8
- package/dist/types/experience-trace-id-context/index.d.ts +1 -0
- package/dist/types/vc/vc-observer/heatmap/heatmap.d.ts +75 -0
- package/dist/types/vc/vc-observer/index.d.ts +5 -1
- package/dist/types/vc/vc-observer/revisions/ViewportUpdateClassifier.d.ts +25 -0
- package/dist/types/vc/vc-observer/revisions/fy24_01.d.ts +11 -0
- package/dist/types/vc/vc-observer/revisions/fy25_01.d.ts +13 -0
- package/dist/types/vc/vc-observer/revisions/revisions.d.ts +2 -0
- package/dist/types/vc/vc-observer/revisions/types.d.ts +5 -0
- package/dist/types-ts4.5/common/vc/types.d.ts +27 -8
- package/dist/types-ts4.5/experience-trace-id-context/index.d.ts +1 -0
- package/dist/types-ts4.5/vc/vc-observer/heatmap/heatmap.d.ts +75 -0
- package/dist/types-ts4.5/vc/vc-observer/index.d.ts +15 -1
- package/dist/types-ts4.5/vc/vc-observer/revisions/ViewportUpdateClassifier.d.ts +25 -0
- package/dist/types-ts4.5/vc/vc-observer/revisions/fy24_01.d.ts +11 -0
- package/dist/types-ts4.5/vc/vc-observer/revisions/fy25_01.d.ts +13 -0
- package/dist/types-ts4.5/vc/vc-observer/revisions/revisions.d.ts +2 -0
- package/dist/types-ts4.5/vc/vc-observer/revisions/types.d.ts +5 -0
- package/package.json +8 -2
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.revFY24_01Classifier = exports.FY24_01Classifier = void 0;
|
|
8
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
9
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
10
|
+
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
11
|
+
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
12
|
+
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
13
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
14
|
+
var _ViewportUpdateClassifier = require("./ViewportUpdateClassifier");
|
|
15
|
+
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
16
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
17
|
+
var legacyIgnoreReasons = ['image', 'ssr-hydration', 'editor-lazy-node-view', 'editor-container-mutation'];
|
|
18
|
+
var FY24_01Classifier = exports.FY24_01Classifier = /*#__PURE__*/function (_ViewportUpdateClassi) {
|
|
19
|
+
function FY24_01Classifier() {
|
|
20
|
+
var _this;
|
|
21
|
+
(0, _classCallCheck2.default)(this, FY24_01Classifier);
|
|
22
|
+
_this = _callSuper(this, FY24_01Classifier);
|
|
23
|
+
(0, _defineProperty2.default)(_this, "revision", 'fy24.01');
|
|
24
|
+
(0, _defineProperty2.default)(_this, "types", ['html', 'text']);
|
|
25
|
+
(0, _defineProperty2.default)(_this, "filters", [{
|
|
26
|
+
name: 'default-ignore-reasons',
|
|
27
|
+
filter: function filter(_ref) {
|
|
28
|
+
var type = _ref.type,
|
|
29
|
+
ignoreReason = _ref.ignoreReason;
|
|
30
|
+
return !ignoreReason || !legacyIgnoreReasons.includes(ignoreReason);
|
|
31
|
+
}
|
|
32
|
+
}]);
|
|
33
|
+
_this.mergeConfig();
|
|
34
|
+
return _this;
|
|
35
|
+
}
|
|
36
|
+
(0, _inherits2.default)(FY24_01Classifier, _ViewportUpdateClassi);
|
|
37
|
+
return (0, _createClass2.default)(FY24_01Classifier);
|
|
38
|
+
}(_ViewportUpdateClassifier.ViewportUpdateClassifier);
|
|
39
|
+
var revFY24_01Classifier = exports.revFY24_01Classifier = new FY24_01Classifier();
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.revFY25_01Classifier = exports.FY25_01Classifier = void 0;
|
|
8
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
9
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
10
|
+
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
11
|
+
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
12
|
+
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
13
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
14
|
+
var _fy24_ = require("./fy24_01");
|
|
15
|
+
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
16
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
17
|
+
var FY25_01Classifier = exports.FY25_01Classifier = /*#__PURE__*/function (_FY24_01Classifier) {
|
|
18
|
+
function FY25_01Classifier() {
|
|
19
|
+
var _this;
|
|
20
|
+
(0, _classCallCheck2.default)(this, FY25_01Classifier);
|
|
21
|
+
_this = _callSuper(this, FY25_01Classifier);
|
|
22
|
+
(0, _defineProperty2.default)(_this, "revision", 'fy25.01');
|
|
23
|
+
(0, _defineProperty2.default)(_this, "types", ['attr']);
|
|
24
|
+
(0, _defineProperty2.default)(_this, "filters", [{
|
|
25
|
+
name: 'not-visible',
|
|
26
|
+
filter: function filter(_ref) {
|
|
27
|
+
var type = _ref.type,
|
|
28
|
+
ignoreReason = _ref.ignoreReason;
|
|
29
|
+
return !(ignoreReason !== null && ignoreReason !== void 0 && ignoreReason.includes('not-visible'));
|
|
30
|
+
}
|
|
31
|
+
}]);
|
|
32
|
+
(0, _defineProperty2.default)(_this, "removedFilters", []);
|
|
33
|
+
_this.mergeConfig();
|
|
34
|
+
return _this;
|
|
35
|
+
}
|
|
36
|
+
(0, _inherits2.default)(FY25_01Classifier, _FY24_01Classifier);
|
|
37
|
+
return (0, _createClass2.default)(FY25_01Classifier);
|
|
38
|
+
}(_fy24_.FY24_01Classifier);
|
|
39
|
+
var revFY25_01Classifier = exports.revFY25_01Classifier = new FY25_01Classifier();
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getRevisions = void 0;
|
|
7
|
+
var _fy24_ = require("./fy24_01");
|
|
8
|
+
var _fy25_ = require("./fy25_01");
|
|
9
|
+
var Revisions = [{
|
|
10
|
+
name: 'fy24.01',
|
|
11
|
+
classifier: _fy24_.revFY24_01Classifier
|
|
12
|
+
}, {
|
|
13
|
+
name: 'fy25.01',
|
|
14
|
+
classifier: _fy25_.revFY25_01Classifier
|
|
15
|
+
}];
|
|
16
|
+
var revisionResultCache = null;
|
|
17
|
+
var getRevisions = exports.getRevisions = function getRevisions() {
|
|
18
|
+
if (revisionResultCache !== null) {
|
|
19
|
+
return revisionResultCache;
|
|
20
|
+
}
|
|
21
|
+
revisionResultCache = [].concat(Revisions);
|
|
22
|
+
return revisionResultCache;
|
|
23
|
+
};
|
|
@@ -201,6 +201,16 @@ const getVCMetrics = interaction => {
|
|
|
201
201
|
if (interactionStatus.originalInteractionStatus !== 'SUCCEEDED' || pageVisibilityUpToTTAI !== 'visible') {
|
|
202
202
|
return result;
|
|
203
203
|
}
|
|
204
|
+
if (fg('ufo_vc_multiheatmap')) {
|
|
205
|
+
var _result;
|
|
206
|
+
(_result = result[`${prefix}:vc:rev`]) === null || _result === void 0 ? void 0 : _result.forEach(element => {
|
|
207
|
+
var _element$vcDetails, _element$vcDetails$;
|
|
208
|
+
if ((_element$vcDetails = element.vcDetails) !== null && _element$vcDetails !== void 0 && (_element$vcDetails$ = _element$vcDetails['90']) !== null && _element$vcDetails$ !== void 0 && _element$vcDetails$.t) {
|
|
209
|
+
var _element$vcDetails$2;
|
|
210
|
+
element['metric:vc90'] = (_element$vcDetails$2 = element.vcDetails['90']) === null || _element$vcDetails$2 === void 0 ? void 0 : _element$vcDetails$2.t;
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
204
214
|
return {
|
|
205
215
|
...result,
|
|
206
216
|
'metric:vc90': VC['90']
|
|
@@ -28,4 +28,8 @@ export const getActiveTraceHttpRequestHeaders = _url => {
|
|
|
28
28
|
spanId
|
|
29
29
|
} = state.context;
|
|
30
30
|
return makeTraceHttpRequestHeaders(traceId, spanId);
|
|
31
|
+
};
|
|
32
|
+
export const getActiveTraceAsQueryParams = _url => {
|
|
33
|
+
const traceHeaders = getActiveTraceHttpRequestHeaders(_url);
|
|
34
|
+
return traceHeaders ? new URLSearchParams(traceHeaders).toString().toLowerCase() : null;
|
|
31
35
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { lazy, Profiler, Suspense, useCallback, useContext, useEffect, useMemo, useRef } from 'react';
|
|
2
2
|
import { unstable_NormalPriority as NormalPriority, unstable_scheduleCallback as scheduleCallback } from 'scheduler';
|
|
3
3
|
import { v4 as createUUID } from 'uuid';
|
|
4
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
4
5
|
import coinflip from '../coinflip';
|
|
5
6
|
import { getConfig, getInteractionRate } from '../config';
|
|
6
7
|
import { getActiveTrace, setInteractionActiveTrace } from '../experience-trace-id-context';
|
|
@@ -31,7 +32,9 @@ export default function UFOSegment({
|
|
|
31
32
|
}], [parentContext, segmentName, segmentId]);
|
|
32
33
|
const interactionId = useContext(UFOInteractionIDContext);
|
|
33
34
|
const interactionContext = useMemo(() => {
|
|
34
|
-
|
|
35
|
+
if (!fg('platform-ufo-add-segment-use-effect')) {
|
|
36
|
+
addSegment(labelStack);
|
|
37
|
+
}
|
|
35
38
|
let lastCompleteEndTime = 0;
|
|
36
39
|
function complete(endTime = performance.now()) {
|
|
37
40
|
if (interactionId.current) {
|
|
@@ -205,8 +208,13 @@ export default function UFOSegment({
|
|
|
205
208
|
interactionContext.onRender(phase, actualDuration, baseDuration, startTime, commitTime);
|
|
206
209
|
}
|
|
207
210
|
}, [interactionContext]);
|
|
208
|
-
useEffect(() =>
|
|
209
|
-
|
|
211
|
+
useEffect(() => {
|
|
212
|
+
if (fg('platform-ufo-add-segment-use-effect')) {
|
|
213
|
+
addSegment(labelStack);
|
|
214
|
+
}
|
|
215
|
+
return () => {
|
|
216
|
+
removeSegment(labelStack);
|
|
217
|
+
};
|
|
210
218
|
}, [interactionId, parentContext, interactionContext, labelStack]);
|
|
211
219
|
const reactProfilerId = useMemo(() => labelStack.map(l => l.name).join('/'), [labelStack]);
|
|
212
220
|
const enableSegmentHighlighting = (_getConfig2 = getConfig()) === null || _getConfig2 === void 0 ? void 0 : _getConfig2.enableSegmentHighlighting;
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
const UNUSED_SECTOR = 0;
|
|
3
|
+
export class MultiRevisionHeatmap {
|
|
4
|
+
constructor({
|
|
5
|
+
viewport,
|
|
6
|
+
revisions,
|
|
7
|
+
arraySize,
|
|
8
|
+
devToolsEnabled
|
|
9
|
+
}) {
|
|
10
|
+
_defineProperty(this, "arraySize", {
|
|
11
|
+
w: 200,
|
|
12
|
+
h: 200
|
|
13
|
+
});
|
|
14
|
+
_defineProperty(this, "mapPixelsToHeatmap", (left, top, width, height) => {
|
|
15
|
+
const {
|
|
16
|
+
w,
|
|
17
|
+
h
|
|
18
|
+
} = this.viewport;
|
|
19
|
+
const l = Math.floor(left / w * this.arraySize.w);
|
|
20
|
+
const t = Math.floor(top / h * this.arraySize.h);
|
|
21
|
+
const r = Math.ceil((left + width) / w * this.arraySize.w);
|
|
22
|
+
const b = Math.ceil((top + height) / h * this.arraySize.h);
|
|
23
|
+
|
|
24
|
+
// correct values to min - 0, max - arraySize
|
|
25
|
+
const result = {
|
|
26
|
+
l: Math.max(0, l),
|
|
27
|
+
t: Math.max(0, t),
|
|
28
|
+
r: Math.min(this.arraySize.w, r),
|
|
29
|
+
b: Math.min(this.arraySize.h, b)
|
|
30
|
+
};
|
|
31
|
+
return result;
|
|
32
|
+
});
|
|
33
|
+
_defineProperty(this, "getElementRatio", mappedValues => {
|
|
34
|
+
const {
|
|
35
|
+
r,
|
|
36
|
+
l,
|
|
37
|
+
b,
|
|
38
|
+
t
|
|
39
|
+
} = mappedValues;
|
|
40
|
+
return (r - l) * (b - t) / (this.arraySize.w * this.arraySize.h);
|
|
41
|
+
});
|
|
42
|
+
this.viewport = viewport;
|
|
43
|
+
this.revisions = revisions;
|
|
44
|
+
if (arraySize) {
|
|
45
|
+
this.arraySize = arraySize;
|
|
46
|
+
}
|
|
47
|
+
this.heatmaps = new Array(revisions.length);
|
|
48
|
+
this.componentsLogs = new Array(revisions.length);
|
|
49
|
+
this.vcRatios = new Array(revisions.length);
|
|
50
|
+
this.devToolsEnabled = devToolsEnabled || false;
|
|
51
|
+
revisions.forEach(({}, i) => {
|
|
52
|
+
this.heatmaps[i] = this.getCleanHeatmap();
|
|
53
|
+
this.componentsLogs[i] = {};
|
|
54
|
+
this.vcRatios[i] = {};
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
handleUpdate({
|
|
58
|
+
time,
|
|
59
|
+
type,
|
|
60
|
+
classification,
|
|
61
|
+
intersectionRect,
|
|
62
|
+
element,
|
|
63
|
+
targetName,
|
|
64
|
+
ignoreReason,
|
|
65
|
+
onError
|
|
66
|
+
}) {
|
|
67
|
+
const mappedValues = this.mapPixelsToHeatmap(intersectionRect.left, intersectionRect.top, intersectionRect.width, intersectionRect.height);
|
|
68
|
+
const result = this.applyChangesToHeatMap(mappedValues, time, classification);
|
|
69
|
+
if (result !== true) {
|
|
70
|
+
onError(result);
|
|
71
|
+
}
|
|
72
|
+
const componentRatio = this.getElementRatio(mappedValues);
|
|
73
|
+
this.revisions.forEach((_, i) => {
|
|
74
|
+
if (classification[i]) {
|
|
75
|
+
this.vcRatios[i][targetName] = componentRatio;
|
|
76
|
+
}
|
|
77
|
+
if (!this.componentsLogs[i][time]) {
|
|
78
|
+
this.componentsLogs[i][time] = [];
|
|
79
|
+
}
|
|
80
|
+
this.componentsLogs[i][time].push({
|
|
81
|
+
__debug__element: this.devToolsEnabled ? new WeakRef(element) : null,
|
|
82
|
+
intersectionRect,
|
|
83
|
+
targetName,
|
|
84
|
+
ignoreReason
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
getData() {
|
|
89
|
+
return {
|
|
90
|
+
heatmaps: this.heatmaps
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
getPayloadShapedData(args) {
|
|
94
|
+
const result = this.processData(args);
|
|
95
|
+
const payload = this.revisions.map((rev, i) => {
|
|
96
|
+
const vcDetails = {};
|
|
97
|
+
args.VCParts.forEach(VCPart => {
|
|
98
|
+
vcDetails[VCPart] = {
|
|
99
|
+
t: result[i].VC[VCPart] || 0,
|
|
100
|
+
e: Array.from(result[i].VCBox[VCPart] || [])
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
revision: rev.name,
|
|
105
|
+
vcDetails,
|
|
106
|
+
clean: args.clean,
|
|
107
|
+
'metric:vc90': null // will be set or not in the payload generator
|
|
108
|
+
};
|
|
109
|
+
});
|
|
110
|
+
return payload;
|
|
111
|
+
}
|
|
112
|
+
processData({
|
|
113
|
+
VCParts,
|
|
114
|
+
ssr = UNUSED_SECTOR
|
|
115
|
+
}) {
|
|
116
|
+
return this.heatmaps.map((heatmap, i) => {
|
|
117
|
+
const lastUpdate = {};
|
|
118
|
+
let totalPainted = 0;
|
|
119
|
+
let componentsLog = this.componentsLogs[i];
|
|
120
|
+
if (ssr !== UNUSED_SECTOR) {
|
|
121
|
+
var _window$document;
|
|
122
|
+
const element = {
|
|
123
|
+
__debug__element: new WeakRef((_window$document = window.document) === null || _window$document === void 0 ? void 0 : _window$document.body),
|
|
124
|
+
intersectionRect: {
|
|
125
|
+
top: 0,
|
|
126
|
+
left: 0,
|
|
127
|
+
right: 0,
|
|
128
|
+
bottom: 0,
|
|
129
|
+
x: 0,
|
|
130
|
+
y: 0,
|
|
131
|
+
width: this.viewport.w,
|
|
132
|
+
height: this.viewport.h,
|
|
133
|
+
toJSON() {
|
|
134
|
+
return {};
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
targetName: 'SSR'
|
|
138
|
+
};
|
|
139
|
+
if (!componentsLog[ssr]) {
|
|
140
|
+
componentsLog[ssr] = [];
|
|
141
|
+
}
|
|
142
|
+
componentsLog[ssr].push(element);
|
|
143
|
+
}
|
|
144
|
+
for (let i = 0; i < heatmap.length; i++) {
|
|
145
|
+
const rounded = Math.floor(heatmap[i] === UNUSED_SECTOR && ssr !== UNUSED_SECTOR ? ssr : heatmap[i]);
|
|
146
|
+
totalPainted += rounded !== UNUSED_SECTOR ? 1 : 0;
|
|
147
|
+
if (rounded !== UNUSED_SECTOR) {
|
|
148
|
+
lastUpdate[rounded] = lastUpdate[rounded] ? lastUpdate[rounded] + 1 : 1;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const entries = Object.entries(lastUpdate).map(a => [parseInt(a[0], 10), a[1]]).sort((a, b) => a[0] > b[0] ? 1 : -1);
|
|
152
|
+
const VC = MultiRevisionHeatmap.makeVCReturnObj(VCParts);
|
|
153
|
+
const VCBox = MultiRevisionHeatmap.makeVCReturnObj(VCParts);
|
|
154
|
+
entries.reduce((acc = 0, v) => {
|
|
155
|
+
const VCRatio = v[1] / totalPainted + acc;
|
|
156
|
+
const time = v[0];
|
|
157
|
+
VCParts.forEach(value => {
|
|
158
|
+
if ((VC[value] === null || VC[value] === undefined) && VCRatio >= value / 100) {
|
|
159
|
+
var _componentsLog$time;
|
|
160
|
+
VC[value] = time;
|
|
161
|
+
VCBox[value] = new Set();
|
|
162
|
+
(_componentsLog$time = componentsLog[time]) === null || _componentsLog$time === void 0 ? void 0 : _componentsLog$time.forEach(v => {
|
|
163
|
+
var _VCBox$value;
|
|
164
|
+
return (_VCBox$value = VCBox[value]) === null || _VCBox$value === void 0 ? void 0 : _VCBox$value.add(v.targetName);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
return VCRatio;
|
|
169
|
+
}, 0);
|
|
170
|
+
const VCEntries = entries.reduce((acc, [timestamp, entryPainted], i) => {
|
|
171
|
+
var _acc$abs, _componentsLog$timest;
|
|
172
|
+
const currentlyPainted = entryPainted + (((_acc$abs = acc.abs[i - 1]) === null || _acc$abs === void 0 ? void 0 : _acc$abs[1]) || 0);
|
|
173
|
+
const currentlyPaintedRatio = Math.round(currentlyPainted / totalPainted * 1000) / 10;
|
|
174
|
+
const logEntry = (_componentsLog$timest = componentsLog[timestamp]) === null || _componentsLog$timest === void 0 ? void 0 : _componentsLog$timest.map(v => v.targetName);
|
|
175
|
+
acc.abs.push([timestamp, currentlyPainted]);
|
|
176
|
+
acc.rel.push({
|
|
177
|
+
time: timestamp,
|
|
178
|
+
vc: currentlyPaintedRatio,
|
|
179
|
+
elements: logEntry
|
|
180
|
+
});
|
|
181
|
+
return acc;
|
|
182
|
+
}, {
|
|
183
|
+
abs: [],
|
|
184
|
+
rel: []
|
|
185
|
+
});
|
|
186
|
+
return {
|
|
187
|
+
VC,
|
|
188
|
+
VCBox,
|
|
189
|
+
VCEntries,
|
|
190
|
+
totalPainted
|
|
191
|
+
};
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
applyChangesToHeatMap(a, time, classification) {
|
|
195
|
+
const {
|
|
196
|
+
l,
|
|
197
|
+
t,
|
|
198
|
+
r,
|
|
199
|
+
b
|
|
200
|
+
} = a;
|
|
201
|
+
const size = classification.length;
|
|
202
|
+
for (let row = t; row < b; row++) {
|
|
203
|
+
if (this.heatmaps[0][row] === undefined) {
|
|
204
|
+
try {
|
|
205
|
+
return {
|
|
206
|
+
error: `index - ${row}`,
|
|
207
|
+
time
|
|
208
|
+
};
|
|
209
|
+
} catch (e) {
|
|
210
|
+
return {
|
|
211
|
+
error: 'row error',
|
|
212
|
+
time
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
} else {
|
|
216
|
+
for (let heatmapIndex = 0; heatmapIndex < size; heatmapIndex++) {
|
|
217
|
+
if (classification[heatmapIndex]) {
|
|
218
|
+
this.heatmaps[heatmapIndex].fill(time, this.getIndex(l, row), this.getIndex(r, row));
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
getIndex(x, y) {
|
|
226
|
+
return x + this.arraySize.w * y;
|
|
227
|
+
}
|
|
228
|
+
getCleanHeatmap() {
|
|
229
|
+
return new Uint32Array(this.arraySize.w * this.arraySize.h);
|
|
230
|
+
}
|
|
231
|
+
static makeVCReturnObj(VCParts) {
|
|
232
|
+
const vc = {};
|
|
233
|
+
VCParts.forEach(v => {
|
|
234
|
+
vc[v] = null;
|
|
235
|
+
});
|
|
236
|
+
return vc;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
@@ -2,7 +2,9 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
2
2
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
3
|
import { attachAbortListeners } from './attachAbortListeners';
|
|
4
4
|
import { getViewportHeight, getViewportWidth } from './getViewport';
|
|
5
|
+
import { MultiRevisionHeatmap } from './heatmap/heatmap';
|
|
5
6
|
import { Observers } from './observers';
|
|
7
|
+
import { getRevisions } from './revisions/revisions';
|
|
6
8
|
const abortReason = {
|
|
7
9
|
scroll: 'scroll',
|
|
8
10
|
keypress: 'keypress',
|
|
@@ -35,6 +37,7 @@ export class VCObserver {
|
|
|
35
37
|
});
|
|
36
38
|
/* heatmap */
|
|
37
39
|
_defineProperty(this, "arraySize", 0);
|
|
40
|
+
_defineProperty(this, "multiHeatmap", null);
|
|
38
41
|
_defineProperty(this, "componentsLog", {});
|
|
39
42
|
_defineProperty(this, "vcRatios", {});
|
|
40
43
|
_defineProperty(this, "active", false);
|
|
@@ -68,6 +71,7 @@ export class VCObserver {
|
|
|
68
71
|
},
|
|
69
72
|
heatmap: this.heatmap,
|
|
70
73
|
heatmapNext: this.heatmapNext,
|
|
74
|
+
multiHeatmap: this.multiHeatmap,
|
|
71
75
|
outOfBoundaryInfo: this.outOfBoundaryInfo,
|
|
72
76
|
totalTime: Math.round(this.totalTime + this.observers.getTotalTime()),
|
|
73
77
|
componentsLog: {
|
|
@@ -106,7 +110,8 @@ export class VCObserver {
|
|
|
106
110
|
componentsLog,
|
|
107
111
|
viewport,
|
|
108
112
|
devToolsEnabled,
|
|
109
|
-
ratios
|
|
113
|
+
ratios,
|
|
114
|
+
multiHeatmap
|
|
110
115
|
} = rawData;
|
|
111
116
|
if (abortReasonInfo !== null && abortReason.blocking) {
|
|
112
117
|
// exposing data to devtools
|
|
@@ -150,6 +155,7 @@ export class VCObserver {
|
|
|
150
155
|
/* empty */
|
|
151
156
|
}
|
|
152
157
|
let _componentsLog = {};
|
|
158
|
+
// eslint-disable-next-line @atlaskit/platform/ensure-feature-flag-prefix
|
|
153
159
|
if (fg('ufo-remove-vc-component-observations-after-ttai')) {
|
|
154
160
|
Object.entries(this.componentsLog).forEach(([_timestamp, value]) => {
|
|
155
161
|
const timestamp = Number(_timestamp);
|
|
@@ -207,9 +213,30 @@ export class VCObserver {
|
|
|
207
213
|
tti,
|
|
208
214
|
ttai: stop - start
|
|
209
215
|
},
|
|
216
|
+
start,
|
|
217
|
+
stop,
|
|
210
218
|
heatmap,
|
|
211
219
|
ratios
|
|
212
220
|
};
|
|
221
|
+
window.__vcNext = {
|
|
222
|
+
entries: vcNext.VCEntries.rel,
|
|
223
|
+
log: componentsLog,
|
|
224
|
+
metrics: {
|
|
225
|
+
'75': vcNext.VC['75'],
|
|
226
|
+
'80': vcNext.VC['80'],
|
|
227
|
+
'85': vcNext.VC['85'],
|
|
228
|
+
'90': vcNext.VC['90'],
|
|
229
|
+
'95': vcNext.VC['95'],
|
|
230
|
+
'98': vcNext.VC['98'],
|
|
231
|
+
'99': vcNext.VC['99'],
|
|
232
|
+
tti,
|
|
233
|
+
ttai: stop - start
|
|
234
|
+
},
|
|
235
|
+
start,
|
|
236
|
+
stop,
|
|
237
|
+
heatmap: heatmapNext,
|
|
238
|
+
ratios
|
|
239
|
+
};
|
|
213
240
|
|
|
214
241
|
// Emitting a custom event to make it available in the Chrome extension
|
|
215
242
|
window.dispatchEvent(new CustomEvent('vcReady', {
|
|
@@ -222,6 +249,15 @@ export class VCObserver {
|
|
|
222
249
|
} catch (e) {
|
|
223
250
|
/* do nothing */
|
|
224
251
|
}
|
|
252
|
+
const isMultiHeatmapEnabled = fg('ufo_vc_multiheatmap');
|
|
253
|
+
const revisionsData = isMultiHeatmapEnabled && multiHeatmap !== null ? {
|
|
254
|
+
[`${fullPrefix}vc:rev`]: multiHeatmap.getPayloadShapedData({
|
|
255
|
+
VCParts: VCObserver.VCParts.map(v => parseInt(v)),
|
|
256
|
+
ssr,
|
|
257
|
+
clean: !abortReasonInfo
|
|
258
|
+
})
|
|
259
|
+
} : null;
|
|
260
|
+
// eslint-disable-next-line @atlaskit/platform/ensure-feature-flag-prefix
|
|
225
261
|
const isCalcSpeedIndexEnabled = fg('ufo-calc-speed-index');
|
|
226
262
|
return {
|
|
227
263
|
'metrics:vc': VC,
|
|
@@ -240,12 +276,27 @@ export class VCObserver {
|
|
|
240
276
|
[`${fullPrefix}vc:next:dom`]: vcNext.VCBox,
|
|
241
277
|
//...oldDomUpdates,
|
|
242
278
|
[`${fullPrefix}vc:ignored`]: this.getIgnoredElements(componentsLog),
|
|
279
|
+
...revisionsData,
|
|
243
280
|
[`ufo:speedIndex`]: isCalcSpeedIndexEnabled ? VCEntries.speedIndex : undefined,
|
|
244
281
|
[`ufo:next:speedIndex`]: isCalcSpeedIndexEnabled ? vcNext.VCEntries.speedIndex : undefined
|
|
245
282
|
};
|
|
246
283
|
});
|
|
247
284
|
_defineProperty(this, "handleUpdate", (rawTime, intersectionRect, targetName, element, type, ignoreReason) => {
|
|
248
285
|
this.measureStart();
|
|
286
|
+
this.legacyHandleUpdate(rawTime, intersectionRect, targetName, element, type, ignoreReason);
|
|
287
|
+
if (fg('ufo_vc_multiheatmap')) {
|
|
288
|
+
this.onViewportChangeDetected({
|
|
289
|
+
timestamp: rawTime,
|
|
290
|
+
intersectionRect,
|
|
291
|
+
targetName,
|
|
292
|
+
element,
|
|
293
|
+
type,
|
|
294
|
+
ignoreReason
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
this.measureStop();
|
|
298
|
+
});
|
|
299
|
+
_defineProperty(this, "legacyHandleUpdate", (rawTime, intersectionRect, targetName, element, type, ignoreReason) => {
|
|
249
300
|
if (this.abortReason.reason === null || this.abortReason.blocking === false) {
|
|
250
301
|
const time = Math.round(rawTime - this.startTime);
|
|
251
302
|
const mappedValues = this.mapPixelsToHeatmap(intersectionRect.left, intersectionRect.top, intersectionRect.width, intersectionRect.height);
|
|
@@ -266,8 +317,39 @@ export class VCObserver {
|
|
|
266
317
|
ignoreReason
|
|
267
318
|
});
|
|
268
319
|
}
|
|
269
|
-
|
|
270
|
-
|
|
320
|
+
});
|
|
321
|
+
_defineProperty(this, "onViewportChangeDetected", ({
|
|
322
|
+
element,
|
|
323
|
+
type,
|
|
324
|
+
ignoreReason,
|
|
325
|
+
timestamp,
|
|
326
|
+
targetName,
|
|
327
|
+
intersectionRect
|
|
328
|
+
}) => {
|
|
329
|
+
if (this.multiHeatmap === null) {
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
// @todo add abort reason handling
|
|
333
|
+
const time = Math.round(timestamp - this.startTime);
|
|
334
|
+
const revisions = getRevisions();
|
|
335
|
+
const revisionsClassification = revisions.map(revision => {
|
|
336
|
+
return revision.classifier.classifyUpdate({
|
|
337
|
+
element,
|
|
338
|
+
type,
|
|
339
|
+
ignoreReason
|
|
340
|
+
});
|
|
341
|
+
}, []);
|
|
342
|
+
this.multiHeatmap.handleUpdate({
|
|
343
|
+
time,
|
|
344
|
+
targetName,
|
|
345
|
+
intersectionRect,
|
|
346
|
+
type,
|
|
347
|
+
element,
|
|
348
|
+
classification: revisionsClassification,
|
|
349
|
+
onError: error => {
|
|
350
|
+
this.setAbortReason(abortReason.error, error.time, error.error);
|
|
351
|
+
}
|
|
352
|
+
});
|
|
271
353
|
});
|
|
272
354
|
_defineProperty(this, "mapPixelsToHeatmap", (left, top, width, height) => {
|
|
273
355
|
const {
|
|
@@ -352,6 +434,13 @@ export class VCObserver {
|
|
|
352
434
|
});
|
|
353
435
|
this.heatmap = this.getCleanHeatmap();
|
|
354
436
|
this.heatmapNext = this.getCleanHeatmap();
|
|
437
|
+
if (fg('ufo_vc_multiheatmap')) {
|
|
438
|
+
this.multiHeatmap = new MultiRevisionHeatmap({
|
|
439
|
+
viewport: this.viewport,
|
|
440
|
+
revisions: getRevisions(),
|
|
441
|
+
devToolsEnabled: this.devToolsEnabled
|
|
442
|
+
});
|
|
443
|
+
}
|
|
355
444
|
this.isPostInteraction = options.isPostInteraction || false;
|
|
356
445
|
}
|
|
357
446
|
start({
|
|
@@ -428,6 +517,8 @@ export class VCObserver {
|
|
|
428
517
|
const entries = Object.entries(lastUpdate).map(a => [parseInt(a[0], 10), a[1]]).sort((a, b) => a[0] > b[0] ? 1 : -1);
|
|
429
518
|
const VC = VCObserver.makeVCReturnObj();
|
|
430
519
|
const VCBox = VCObserver.makeVCReturnObj();
|
|
520
|
+
|
|
521
|
+
// eslint-disable-next-line @atlaskit/platform/ensure-feature-flag-prefix
|
|
431
522
|
const isCalcSpeedIndexEnabled = fg('ufo-calc-speed-index');
|
|
432
523
|
entries.reduce((acc = 0, v) => {
|
|
433
524
|
const currRatio = v[1] / totalPainted;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
export class ViewportUpdateClassifier {
|
|
3
|
+
constructor() {
|
|
4
|
+
_defineProperty(this, "types", []);
|
|
5
|
+
_defineProperty(this, "filters", []);
|
|
6
|
+
_defineProperty(this, "removedFilters", []);
|
|
7
|
+
_defineProperty(this, "__combinedTypes", []);
|
|
8
|
+
_defineProperty(this, "__combinedFilters", []);
|
|
9
|
+
}
|
|
10
|
+
mergeConfig() {
|
|
11
|
+
this.__combinedTypes = [...this.types, ...((this === null || this === void 0 ? void 0 : this.__combinedTypes) || [])];
|
|
12
|
+
const previousFilters = this.removedFilters.length === 0 ? this.__combinedFilters : this.__combinedFilters.filter(filter => !this.removedFilters.includes(filter.name));
|
|
13
|
+
this.__combinedFilters = [...this.filters, ...previousFilters];
|
|
14
|
+
}
|
|
15
|
+
classifyUpdate({
|
|
16
|
+
element,
|
|
17
|
+
type,
|
|
18
|
+
tags,
|
|
19
|
+
ignoreReason
|
|
20
|
+
}) {
|
|
21
|
+
if (!this.__combinedTypes.includes(type)) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
return this.__combinedFilters.every(({
|
|
25
|
+
filter,
|
|
26
|
+
name
|
|
27
|
+
}) => {
|
|
28
|
+
return filter({
|
|
29
|
+
type,
|
|
30
|
+
tags,
|
|
31
|
+
ignoreReason
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
import { ViewportUpdateClassifier } from './ViewportUpdateClassifier';
|
|
3
|
+
const legacyIgnoreReasons = ['image', 'ssr-hydration', 'editor-lazy-node-view', 'editor-container-mutation'];
|
|
4
|
+
export class FY24_01Classifier extends ViewportUpdateClassifier {
|
|
5
|
+
constructor() {
|
|
6
|
+
super();
|
|
7
|
+
_defineProperty(this, "revision", 'fy24.01');
|
|
8
|
+
_defineProperty(this, "types", ['html', 'text']);
|
|
9
|
+
_defineProperty(this, "filters", [{
|
|
10
|
+
name: 'default-ignore-reasons',
|
|
11
|
+
filter: ({
|
|
12
|
+
type,
|
|
13
|
+
ignoreReason
|
|
14
|
+
}) => {
|
|
15
|
+
return !ignoreReason || !legacyIgnoreReasons.includes(ignoreReason);
|
|
16
|
+
}
|
|
17
|
+
}]);
|
|
18
|
+
this.mergeConfig();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export const revFY24_01Classifier = new FY24_01Classifier();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
import { FY24_01Classifier } from './fy24_01';
|
|
3
|
+
export class FY25_01Classifier extends FY24_01Classifier {
|
|
4
|
+
constructor() {
|
|
5
|
+
super();
|
|
6
|
+
_defineProperty(this, "revision", 'fy25.01');
|
|
7
|
+
_defineProperty(this, "types", ['attr']);
|
|
8
|
+
_defineProperty(this, "filters", [{
|
|
9
|
+
name: 'not-visible',
|
|
10
|
+
filter: ({
|
|
11
|
+
type,
|
|
12
|
+
ignoreReason
|
|
13
|
+
}) => {
|
|
14
|
+
return !(ignoreReason !== null && ignoreReason !== void 0 && ignoreReason.includes('not-visible'));
|
|
15
|
+
}
|
|
16
|
+
}]);
|
|
17
|
+
_defineProperty(this, "removedFilters", []);
|
|
18
|
+
this.mergeConfig();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export const revFY25_01Classifier = new FY25_01Classifier();
|