@atlaskit/react-ufo 4.15.4 → 4.15.6
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 +16 -0
- package/dist/cjs/create-payload/index.js +6 -4
- package/dist/cjs/vc/vc-observer/observers/ssr-placeholders/index.js +7 -0
- package/dist/cjs/vc/vc-observer-new/metric-calculator/vcnext/index.js +4 -1
- package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +290 -191
- package/dist/cjs/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +45 -2
- package/dist/cjs/vc/vc-observer-new/viewport-observer/utils/get-mutated-elements.js +15 -4
- package/dist/cjs/vc/vc-observer-new/viewport-observer/utils/is-zero-dimension-rectangle.js +9 -0
- package/dist/es2019/create-payload/index.js +4 -2
- package/dist/es2019/vc/vc-observer/observers/ssr-placeholders/index.js +5 -0
- package/dist/es2019/vc/vc-observer-new/metric-calculator/vcnext/index.js +4 -1
- package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +158 -81
- package/dist/es2019/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +33 -2
- package/dist/es2019/vc/vc-observer-new/viewport-observer/utils/get-mutated-elements.js +15 -4
- package/dist/es2019/vc/vc-observer-new/viewport-observer/utils/is-zero-dimension-rectangle.js +3 -0
- package/dist/esm/create-payload/index.js +6 -4
- package/dist/esm/vc/vc-observer/observers/ssr-placeholders/index.js +7 -0
- package/dist/esm/vc/vc-observer-new/metric-calculator/vcnext/index.js +4 -1
- package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +288 -189
- package/dist/esm/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +45 -2
- package/dist/esm/vc/vc-observer-new/viewport-observer/utils/get-mutated-elements.js +15 -4
- package/dist/esm/vc/vc-observer-new/viewport-observer/utils/is-zero-dimension-rectangle.js +3 -0
- package/dist/types/vc/vc-observer/observers/ssr-placeholders/index.d.ts +1 -0
- package/dist/types/vc/vc-observer-new/types.d.ts +1 -1
- package/dist/types/vc/vc-observer-new/viewport-observer/utils/is-zero-dimension-rectangle.d.ts +1 -0
- package/dist/types-ts4.5/vc/vc-observer/observers/ssr-placeholders/index.d.ts +1 -0
- package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +1 -1
- package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/utils/is-zero-dimension-rectangle.d.ts +1 -0
- package/package.json +10 -1
|
@@ -10,9 +10,21 @@ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
|
10
10
|
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; } } }; }
|
|
11
11
|
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; } }
|
|
12
12
|
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; }
|
|
13
|
+
function isElementStyledWithDisplayContents(element) {
|
|
14
|
+
var _window2;
|
|
15
|
+
// To minimise calling `getComputedStyle`, we are making an assumption that if an element is from the Entrypoints framework, then it will have `display: contents` styling
|
|
16
|
+
// as per https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/e4ccf437262ef4c0fd3c651ffb7ad4770b15aed4/jira/src/packages/platform/entry-points/entry-point-placeholder/src/index.tsx#lines-136
|
|
17
|
+
if ((0, _platformFeatureFlags.fg)('platform_ufo_detect_entrypoint_parent')) {
|
|
18
|
+
var _window;
|
|
19
|
+
if (element.hasAttribute('data-ep-placeholder-id')) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
return ((_window = window) === null || _window === void 0 || (_window = _window.getComputedStyle(element)) === null || _window === void 0 ? void 0 : _window.display) === 'contents';
|
|
23
|
+
}
|
|
24
|
+
return ((_window2 = window) === null || _window2 === void 0 || (_window2 = _window2.getComputedStyle(element)) === null || _window2 === void 0 ? void 0 : _window2.display) === 'contents';
|
|
25
|
+
}
|
|
13
26
|
var MAX_NESTED_LEVELS_OF_DISPLAY_CONTENT_ELEMENTS_HANDLED = 3;
|
|
14
27
|
function getMutatedElements(element) {
|
|
15
|
-
var _window;
|
|
16
28
|
var depthLevel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
17
29
|
if ((0, _platformFeatureFlags.fg)('platform_ufo_disable_vcnext_observations')) {
|
|
18
30
|
return [{
|
|
@@ -20,16 +32,15 @@ function getMutatedElements(element) {
|
|
|
20
32
|
isDisplayContentsElementChildren: false
|
|
21
33
|
}];
|
|
22
34
|
}
|
|
23
|
-
if ((
|
|
35
|
+
if (isElementStyledWithDisplayContents(element)) {
|
|
24
36
|
var mutatedElements = [];
|
|
25
37
|
var nestedDisplayContentsElementChildren = [];
|
|
26
38
|
var _iterator = _createForOfIteratorHelper(element.children),
|
|
27
39
|
_step;
|
|
28
40
|
try {
|
|
29
41
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
30
|
-
var _window2;
|
|
31
42
|
var child = _step.value;
|
|
32
|
-
if ((
|
|
43
|
+
if (isElementStyledWithDisplayContents(child)) {
|
|
33
44
|
nestedDisplayContentsElementChildren.push(child);
|
|
34
45
|
}
|
|
35
46
|
mutatedElements.push({
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isZeroDimensionRectangle = isZeroDimensionRectangle;
|
|
7
|
+
function isZeroDimensionRectangle(rect) {
|
|
8
|
+
return rect.bottom === 0 && rect.top === 0 && rect.left === 0 && rect.right === 0 && rect.x === 0 && rect.y === 0 && rect.width === 0 && rect.height === 0;
|
|
9
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import{getDocument}from'@atlaskit/browser-apis';import{fg}from'@atlaskit/platform-feature-flags';// Import common utilities
|
|
2
|
-
import{getLighthouseMetrics}from'../additional-payload';import{CHRReporter}from'../assets';import*as bundleEvalTiming from'../bundle-eval-timing';import coinflip from'../coinflip';import{getConfig,getExperimentalInteractionRate,getUfoNameOverrides}from'../config';import{getExperimentalVCMetrics}from'../create-experimental-interaction-metrics-payload';import{getBm3Timings}from'../custom-timings';import{getGlobalErrorCount}from'../global-error-handler';import{getPageVisibilityState}from'../hidden-timing';import*as initialPageLoadExtraTiming from'../initial-page-load-extra-timing';import{interactionSpans as atlaskitInteractionSpans}from'../interaction-metrics';import{createMemoryStateReport,createPressureStateReport}from'../machine-utilisation';import*as resourceTiming from'../resource-timing';import{filterResourceTimings}from'../resource-timing/common/utils/resource-timing-buffer';import{roundEpsilon}from'../round-number';import*as ssr from'../ssr';import{buildSegmentTree,getOldSegmentsLabelStack,labelStackStartWith,optimizeLabelStack,sanitizeUfoName,stringifyLabelStackFully}from'./common/utils';import{createCriticalMetricsPayloads}from'./critical-metrics-payload';import{addPerformanceMeasures}from'./utils/add-performance-measures';import{getBatteryInfoToLegacyFormat}from'./utils/get-battery-info';import{getBrowserMetadataToLegacyFormat}from'./utils/get-browser-metadata';import getInteractionStatus from'./utils/get-interaction-status';import{getMoreAccuratePageVisibilityUpToTTAI}from'./utils/get-more-accurate-page-visibility-up-to-ttai';import{getNavigationMetricsToLegacyFormat}from'./utils/get-navigation-metrics';import getPageVisibilityUpToTTAI from'./utils/get-page-visibility-up-to-ttai';import{getPaintMetricsToLegacyFormat}from'./utils/get-paint-metrics';import getPayloadSize from'./utils/get-payload-size';import{getReactUFOPayloadVersion}from'./utils/get-react-ufo-payload-version';import getSSRDoneTimeValue from'./utils/get-ssr-done-time-value';import getSSRSuccessUtil from'./utils/get-ssr-success';import getTTAI from'./utils/get-ttai';import getVCMetrics from'./utils/get-vc-metrics';import{getVisibilityStateFromPerformance}from'./utils/get-visibility-state-from-performance';import{optimizeApdex}from'./utils/optimize-apdex';import{optimizeCustomTimings}from'./utils/optimize-custom-timings';import{optimizeHoldInfo}from'./utils/optimize-hold-info';import{optimizeMarks}from'./utils/optimize-marks';import{optimizeReactProfilerTimings}from'./utils/optimize-react-profiler-timings';import{optimizeRequestInfo}from'./utils/optimize-request-info';import{optimizeSpans}from'./utils/optimize-spans';const MAX_PAYLOAD_SIZE=
|
|
2
|
+
import{getLighthouseMetrics}from'../additional-payload';import{CHRReporter}from'../assets';import*as bundleEvalTiming from'../bundle-eval-timing';import coinflip from'../coinflip';import{getConfig,getExperimentalInteractionRate,getUfoNameOverrides}from'../config';import{getExperimentalVCMetrics}from'../create-experimental-interaction-metrics-payload';import{getBm3Timings}from'../custom-timings';import{getGlobalErrorCount}from'../global-error-handler';import{getPageVisibilityState}from'../hidden-timing';import*as initialPageLoadExtraTiming from'../initial-page-load-extra-timing';import{interactionSpans as atlaskitInteractionSpans}from'../interaction-metrics';import{createMemoryStateReport,createPressureStateReport}from'../machine-utilisation';import*as resourceTiming from'../resource-timing';import{filterResourceTimings}from'../resource-timing/common/utils/resource-timing-buffer';import{roundEpsilon}from'../round-number';import*as ssr from'../ssr';import{buildSegmentTree,getOldSegmentsLabelStack,labelStackStartWith,optimizeLabelStack,sanitizeUfoName,stringifyLabelStackFully}from'./common/utils';import{createCriticalMetricsPayloads}from'./critical-metrics-payload';import{addPerformanceMeasures}from'./utils/add-performance-measures';import{getBatteryInfoToLegacyFormat}from'./utils/get-battery-info';import{getBrowserMetadataToLegacyFormat}from'./utils/get-browser-metadata';import getInteractionStatus from'./utils/get-interaction-status';import{getMoreAccuratePageVisibilityUpToTTAI}from'./utils/get-more-accurate-page-visibility-up-to-ttai';import{getNavigationMetricsToLegacyFormat}from'./utils/get-navigation-metrics';import getPageVisibilityUpToTTAI from'./utils/get-page-visibility-up-to-ttai';import{getPaintMetricsToLegacyFormat}from'./utils/get-paint-metrics';import getPayloadSize from'./utils/get-payload-size';import{getReactUFOPayloadVersion}from'./utils/get-react-ufo-payload-version';import getSSRDoneTimeValue from'./utils/get-ssr-done-time-value';import getSSRSuccessUtil from'./utils/get-ssr-success';import getTTAI from'./utils/get-ttai';import getVCMetrics from'./utils/get-vc-metrics';import{getVisibilityStateFromPerformance}from'./utils/get-visibility-state-from-performance';import{optimizeApdex}from'./utils/optimize-apdex';import{optimizeCustomTimings}from'./utils/optimize-custom-timings';import{optimizeHoldInfo}from'./utils/optimize-hold-info';import{optimizeMarks}from'./utils/optimize-marks';import{optimizeReactProfilerTimings}from'./utils/optimize-react-profiler-timings';import{optimizeRequestInfo}from'./utils/optimize-request-info';import{optimizeSpans}from'./utils/optimize-spans';const MAX_PAYLOAD_SIZE=230;function getUfoNameOverride(interaction){const{ufoName,apdex}=interaction;try{const ufoNameOverrides=getUfoNameOverrides();if(ufoNameOverrides!=null){const metricKey=apdex.length>0?apdex[0].key:'';if(ufoNameOverrides[ufoName][metricKey]){return ufoNameOverrides[ufoName][metricKey];}}return ufoName;}catch(e){return ufoName;}}function getEarliestLegacyStopTime(interaction,labelStack){let earliestLegacyStopTime=null;interaction.apdex.forEach(a=>{var _a$labelStack,_earliestLegacyStopTi;if(!(a!==null&&a!==void 0&&a.stopTime)){return;}if(!labelStackStartWith((_a$labelStack=a.labelStack)!==null&&_a$labelStack!==void 0?_a$labelStack:[],labelStack)){return;}if(a.stopTime>interaction.start&&((_earliestLegacyStopTi=earliestLegacyStopTime)!==null&&_earliestLegacyStopTi!==void 0?_earliestLegacyStopTi:a.stopTime)>=a.stopTime){earliestLegacyStopTime=a.stopTime;}});return earliestLegacyStopTime;}function getBm3EndTimeOrFallbackValue(interaction,labelStack=[],fallbackValue=interaction.end){var _getEarliestLegacySto;if(interaction.type==='press'){return fallbackValue;}return(_getEarliestLegacySto=getEarliestLegacyStopTime(interaction,labelStack))!==null&&_getEarliestLegacySto!==void 0?_getEarliestLegacySto:fallbackValue;}function getPageVisibilityUpToTTI(interaction){const{start}=interaction;const bm3EndTimeOrInteractionEndTime=getBm3EndTimeOrFallbackValue(interaction);return getPageVisibilityState(start,bm3EndTimeOrInteractionEndTime);}function getMoreAccuratePageVisibilityUpToTTI(interaction){const old=getPageVisibilityUpToTTI(interaction);const tti=getEarliestLegacyStopTime(interaction,[]);if(!tti){return old;}const buffered=getVisibilityStateFromPerformance(tti);if(!buffered){return old;}if(buffered!==old){return'mixed';}return old;}function getResourceTimings(start,end){var _resourceTiming$getRe;return(_resourceTiming$getRe=resourceTiming.getResourceTimings(start,end))!==null&&_resourceTiming$getRe!==void 0?_resourceTiming$getRe:undefined;}function getBundleEvalTimings(start){return bundleEvalTiming.getBundleEvalTimings(start);}function getSSRPhaseSuccess(type){return type==='page_load'?ssr.getSSRPhaseSuccess():undefined;}function getSSRFeatureFlags(type){return type==='page_load'?ssr.getSSRFeatureFlags():undefined;}function getPPSMetrics(interaction){var _interaction$apdex,_interaction$apdex$;const{start,end}=interaction;const config=getConfig();const interactionStatus=getInteractionStatus(interaction);const pageVisibilityUpToTTAI=getPageVisibilityUpToTTAI(interaction);const tti=(_interaction$apdex=interaction.apdex)===null||_interaction$apdex===void 0?void 0:(_interaction$apdex$=_interaction$apdex[0])===null||_interaction$apdex$===void 0?void 0:_interaction$apdex$.stopTime;const ttai=interactionStatus.originalInteractionStatus==='SUCCEEDED'&&pageVisibilityUpToTTAI==='visible'?Math.round(end-start):undefined;const PPSMetricsAtTTI=tti!==undefined?getLighthouseMetrics({start,stop:tti}):null;const PPSMetricsAtTTAI=ttai!==undefined?getLighthouseMetrics({start,stop:interaction.end}):null;if(fg('platform_ufo_remove_deprecated_config_fields')){if(PPSMetricsAtTTAI!==null){return PPSMetricsAtTTAI;}}else{if(config!==null&&config!==void 0&&config.shouldCalculateLighthouseMetricsFromTTAI&&PPSMetricsAtTTAI!==null){return PPSMetricsAtTTAI;}if(PPSMetricsAtTTI!==null){return{...PPSMetricsAtTTI,'metrics@ttai':PPSMetricsAtTTAI};}}return{};}function getSSRProperties(type){const ssrPhases=getSSRPhaseSuccess(type);return{'ssr:success':(ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.done)!=null?ssrPhases.done:getSSRSuccessUtil(type),'ssr:featureFlags':getSSRFeatureFlags(type),...((ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.earlyFlush)!=null?{'ssr:earlyflush:success':ssrPhases.earlyFlush}:null),...((ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.prefetch)!=null?{'ssr:prefetch:success':ssrPhases.prefetch}:null)};}function getAssetsMetrics(interaction,SSRDoneTime){try{const config=getConfig();const{type}=interaction;const allowedTypes=['page_load'];const assetsConfig=config===null||config===void 0?void 0:config.assetsConfig;if(!allowedTypes.includes(type)||!assetsConfig){// Skip if: type not allowed or assetsClassification isn't configured
|
|
3
3
|
return{};}const reporter=new CHRReporter();const resourceTimings=filterResourceTimings(interaction.start,interaction.end);const assets=reporter.get(resourceTimings,assetsConfig,SSRDoneTime);if(assets){// Only add assets in case it exists
|
|
4
4
|
return{'event:assets':assets};}return{};}catch(error){// Skip CHR in case of error
|
|
5
5
|
return{};}}function getTracingContextData(interaction){const{trace,start}=interaction;let tracingContextData={};if(trace){tracingContextData={'ufo:tracingContext':{'X-B3-TraceId':trace.traceId,'X-B3-SpanId':trace.spanId,// eslint-disable-next-line compat/compat
|
|
@@ -13,7 +13,9 @@ const getPageLoadDetailedInteractionMetrics=()=>{var _config$ssr3;if(!isPageLoad
|
|
|
13
13
|
'event:cpu:usage':createPressureStateReport(interaction.start,interaction.end),'event:memory:usage':createMemoryStateReport(interaction.start,interaction.end),...(criticalPayloadCount!==undefined?{'ufo:multipayload':true,'ufo:criticalPayloadCount':criticalPayloadCount}:{}),// root
|
|
14
14
|
...getBrowserMetadataToLegacyFormat(),...batteryInfo,...getSSRProperties(type),...getAssetsMetrics(interaction,pageLoadInteractionMetrics===null||pageLoadInteractionMetrics===void 0?void 0:pageLoadInteractionMetrics.SSRDoneTime),...getPPSMetrics(interaction),...paintMetrics,...getNavigationMetricsToLegacyFormat(type),...finalVCMetrics,...experimentalMetrics,...((_config$additionalPay=config.additionalPayloadData)===null||_config$additionalPay===void 0?void 0:_config$additionalPay.call(config,interaction)),...getTracingContextData(interaction),...getStylesheetMetrics(),...getErrorCounts(interaction),...getReactHydrationStats(),interactionMetrics:{namePrefix:config.namePrefix||'',segmentPrefix:config.segmentPrefix||'',interactionId,pageVisibilityAtTTI,pageVisibilityAtTTAI,experimental__pageVisibilityAtTTI:moreAccuratePageVisibilityAtTTI,experimental__pageVisibilityAtTTAI:moreAccuratePageVisibilityAtTTAI,// raw interaction metrics
|
|
15
15
|
rate,routeName,type,abortReason,featureFlags,previousInteractionName,isPreviousInteractionAborted,abortedByInteractionName,// performance
|
|
16
|
-
apdex:optimizeApdex(interaction.apdex,getReactUFOPayloadVersion(interaction.type)),end:Math.round(end),start:Math.round(start),segments:getReactUFOPayloadVersion(interaction.type)==='2.0.0'?segmentTree:getOldSegmentsLabelStack(segments,interaction.type),marks:optimizeMarks(interaction.marks,getReactUFOPayloadVersion(interaction.type)),customData:optimizeCustomData(interaction),reactProfilerTimings:optimizeReactProfilerTimings(interaction.reactProfilerTimings,start,getReactUFOPayloadVersion(interaction.type)),minorInteractions:interaction.minorInteractions,...(responsiveness?{responsiveness}:{}),...labelStack,...pageLoadInteractionMetrics,...getDetailedInteractionMetrics(resourceTimings),...getPageLoadDetailedInteractionMetrics(),...getBm3TrackerTimings(interaction),'metric:ttai':experimental?regularTTAI||expTTAI:undefined,'metric:experimental:ttai':expTTAI,...(unknownElementName?{unknownElementName}:{}),...(unknownElementHierarchy?{unknownElementHierarchy}:{})},'ufo:payloadTime':roundEpsilon(performance.now()-interactionPayloadStart)}}};if(experimental){regularTTAI=undefined;expTTAI=undefined;}if(fg('platform_ufo_enable_vc_raw_data')){const size=getPayloadSize(payload.attributes.properties);const vcRev=payload.attributes.properties['ufo:vc:rev'];const rawData=vcRev.find(item=>item.revision==='raw-handler');if(rawData){const rawDataSize=getPayloadSize(rawData);payload.attributes.properties['ufo:vc:raw:size']=rawDataSize;if(size>MAX_PAYLOAD_SIZE&&Array.isArray(vcRev)&&vcRev.length>0){payload.attributes.properties['ufo:vc:rev']=vcRev.filter(item=>item.revision!=='raw-handler');payload.attributes.properties['ufo:vc:raw:removed']=true;}}payload.attributes.properties['event:sizeInKb']=getPayloadSize(payload.attributes.properties);}else{payload.attributes.properties['event:sizeInKb']=getPayloadSize(payload.attributes.properties);}
|
|
16
|
+
apdex:optimizeApdex(interaction.apdex,getReactUFOPayloadVersion(interaction.type)),end:Math.round(end),start:Math.round(start),segments:getReactUFOPayloadVersion(interaction.type)==='2.0.0'?segmentTree:getOldSegmentsLabelStack(segments,interaction.type),marks:optimizeMarks(interaction.marks,getReactUFOPayloadVersion(interaction.type)),customData:optimizeCustomData(interaction),reactProfilerTimings:optimizeReactProfilerTimings(interaction.reactProfilerTimings,start,getReactUFOPayloadVersion(interaction.type)),minorInteractions:interaction.minorInteractions,...(responsiveness?{responsiveness}:{}),...labelStack,...pageLoadInteractionMetrics,...getDetailedInteractionMetrics(resourceTimings),...getPageLoadDetailedInteractionMetrics(),...getBm3TrackerTimings(interaction),'metric:ttai':experimental?regularTTAI||expTTAI:undefined,'metric:experimental:ttai':expTTAI,...(unknownElementName?{unknownElementName}:{}),...(unknownElementHierarchy?{unknownElementHierarchy}:{})},'ufo:payloadTime':roundEpsilon(performance.now()-interactionPayloadStart)}}};if(experimental){regularTTAI=undefined;expTTAI=undefined;}if(fg('platform_ufo_enable_vc_raw_data')){const size=getPayloadSize(payload.attributes.properties);const vcRev=payload.attributes.properties['ufo:vc:rev'];const rawData=vcRev.find(item=>item.revision==='raw-handler');if(rawData){const rawDataSize=getPayloadSize(rawData);payload.attributes.properties['ufo:vc:raw:size']=rawDataSize;if(size>MAX_PAYLOAD_SIZE&&Array.isArray(vcRev)&&vcRev.length>0){payload.attributes.properties['ufo:vc:rev']=vcRev.filter(item=>item.revision!=='raw-handler');payload.attributes.properties['ufo:vc:raw:removed']=true;}}payload.attributes.properties['event:sizeInKb']=getPayloadSize(payload.attributes.properties);}else{payload.attributes.properties['event:sizeInKb']=getPayloadSize(payload.attributes.properties);}if(fg('platform_ufo_enable_trimmed_payload')){// in order of importance, first one being least important
|
|
17
|
+
// we can add more fields as necessary
|
|
18
|
+
const interactionMetricsFieldsToTrim=['requestInfo','featureFlags','resourceTimings'];const properties=payload.attributes.properties;const interactionMetrics=properties.interactionMetrics;if(interactionMetrics){for(const field of interactionMetricsFieldsToTrim){if(getPayloadSize(properties)<=MAX_PAYLOAD_SIZE){continue;}interactionMetrics[field]=undefined;properties['event:isTrimmed']=true;let trimmedFields=properties['event:trimmedFields'];if(!Array.isArray(trimmedFields)){trimmedFields=[];}trimmedFields.push(`interactionMetrics.${field}`);properties['event:trimmedFields']=trimmedFields;}}}return payload;}export async function createPayloads(interactionId,interaction){const ufoNameOverride=getUfoNameOverride(interaction);const modifiedInteraction={...interaction,ufoName:ufoNameOverride};const payloads=[];const isCriticalMetricsEnabled=fg('platform_ufo_critical_metrics_payload');// Calculate VC metrics once to avoid duplicate expensive calculations
|
|
17
19
|
const vcMetrics=await getVCMetrics(interaction);// typeof Promise<CriticalMetricsPayload[]>
|
|
18
20
|
const criticalMetricsPayloads=isCriticalMetricsEnabled?await createCriticalMetricsPayloads(interactionId,interaction,vcMetrics):[];payloads.push(...criticalMetricsPayloads);const criticalPayloadCount=isCriticalMetricsEnabled?criticalMetricsPayloads.length:undefined;const interactionMetricsPayload=await createInteractionMetricsPayload(modifiedInteraction,interactionId,undefined,criticalPayloadCount,vcMetrics);payloads.push(interactionMetricsPayload);return payloads.filter(Boolean);}export async function createExperimentalMetricsPayload(interactionId,interaction){const config=getConfig();if(!config){throw Error('UFO Configuration not provided');}const ufoName=sanitizeUfoName(interaction.ufoName);const rate=getExperimentalInteractionRate(ufoName,interaction.type);if(!coinflip(rate)){return null;}const pageVisibilityState=getPageVisibilityState(interaction.start,interaction.end);if(pageVisibilityState!=='visible'){return null;}const result=await createInteractionMetricsPayload(interaction,interactionId,true);return result;}export async function createExtraSearchPageInteractionPayload(interactionId,interaction){var _newEnd;const SAIN_HOLD_NAMES=['search-ai-dialog-visible-text-loading','search-ai-dialog-all-text-loading'];const NAME_OVERRIDE='search-page-ignoring-smart-answers';const SEARCH_PAGE_SMART_ANSWERS_SEGMENT_LABEL='search-page-smart-answers';const newInteractionId=`${interactionId}-ignoring-smart-answers`;// Calculate a new end time which excludes SAIN holds
|
|
19
21
|
let newEnd;const{holdInfo,reactProfilerTimings}=interaction;const lastHold=holdInfo.at(-1);const isLastHoldSAIN=Boolean(lastHold&&SAIN_HOLD_NAMES.includes(lastHold.name));// A new end time is only calculated if the last hold is a SAIN hold
|
|
@@ -233,6 +233,11 @@ export class SSRPlaceholderHandlers {
|
|
|
233
233
|
}
|
|
234
234
|
});
|
|
235
235
|
}
|
|
236
|
+
validateReactComponentMatchToPlaceholderV4(el) {
|
|
237
|
+
el = this.findNearestPlaceholderContainerIfIgnored(el);
|
|
238
|
+
const id = this.getPlaceholderReplacementId(el);
|
|
239
|
+
return this.staticPlaceholders.has(id);
|
|
240
|
+
}
|
|
236
241
|
hasSameSizePosition(rect, boundingClientRect) {
|
|
237
242
|
if (!rect) {
|
|
238
243
|
return false;
|
|
@@ -8,7 +8,10 @@ const getConsideredEntryTypes = () => {
|
|
|
8
8
|
if (fg('platform_ufo_remove_ssr_placeholder_in_ttvc_v4')) {
|
|
9
9
|
consideredEntryTypes.push('mutation:ssr-placeholder');
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
if (fg('platform_ufo_detect_zero_dimension_rectangles')) {
|
|
12
|
+
consideredEntryTypes.push('mutation:display-contents-children-attribute');
|
|
13
|
+
}
|
|
14
|
+
return consideredEntryTypes;
|
|
12
15
|
};
|
|
13
16
|
const getExcludedEntryTypes = () => {
|
|
14
17
|
const excludedEntryTypes = ['layout-shift:same-rect'];
|
|
@@ -31,6 +31,67 @@ const createElementMutationsWatcher = removedNodeRects => ({
|
|
|
31
31
|
}
|
|
32
32
|
return 'mutation:element';
|
|
33
33
|
};
|
|
34
|
+
const createElementMutationsWatcherV4 = (removedNodeRects, isWithinThirdPartySegment, hasSameDeletedNode, timestamp, isTargetReactRoot, getSSRState, getSSRPlaceholderHandler) => ({
|
|
35
|
+
target,
|
|
36
|
+
rect
|
|
37
|
+
}) => {
|
|
38
|
+
if (getSSRState) {
|
|
39
|
+
const ssrState = getSSRState();
|
|
40
|
+
const SSRStateEnum = {
|
|
41
|
+
normal: 1,
|
|
42
|
+
waitingForFirstRender: 2,
|
|
43
|
+
ignoring: 3
|
|
44
|
+
};
|
|
45
|
+
if (ssrState.state === SSRStateEnum.waitingForFirstRender && timestamp > ssrState.renderStart && isTargetReactRoot) {
|
|
46
|
+
ssrState.state = SSRStateEnum.ignoring;
|
|
47
|
+
if (ssrState.renderStop === -1) {
|
|
48
|
+
// arbitrary 500ms DOM update window
|
|
49
|
+
ssrState.renderStop = timestamp + 500;
|
|
50
|
+
}
|
|
51
|
+
return 'ssr-hydration';
|
|
52
|
+
}
|
|
53
|
+
if (ssrState.state === SSRStateEnum.ignoring && timestamp > ssrState.renderStart && isTargetReactRoot) {
|
|
54
|
+
if (timestamp <= ssrState.renderStop) {
|
|
55
|
+
return 'ssr-hydration';
|
|
56
|
+
} else {
|
|
57
|
+
ssrState.state = SSRStateEnum.normal;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (getSSRPlaceholderHandler) {
|
|
62
|
+
const ssrPlaceholderHandler = getSSRPlaceholderHandler();
|
|
63
|
+
if (ssrPlaceholderHandler) {
|
|
64
|
+
if ((ssrPlaceholderHandler.isPlaceholder(target) || ssrPlaceholderHandler.isPlaceholderIgnored(target)) && ssrPlaceholderHandler.checkIfExistedAndSizeMatchingV3(target)) {
|
|
65
|
+
return 'mutation:ssr-placeholder';
|
|
66
|
+
}
|
|
67
|
+
if ((ssrPlaceholderHandler.isPlaceholderReplacement(target) || ssrPlaceholderHandler.isPlaceholderIgnored(target)) && ssrPlaceholderHandler.validateReactComponentMatchToPlaceholderV4(target)) {
|
|
68
|
+
return 'mutation:ssr-placeholder';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (hasSameDeletedNode && isInVCIgnoreIfNoLayoutShiftMarker(target)) {
|
|
73
|
+
return 'mutation:remount';
|
|
74
|
+
}
|
|
75
|
+
if (isContainedWithinMediaWrapper(target)) {
|
|
76
|
+
return 'mutation:media';
|
|
77
|
+
}
|
|
78
|
+
if (isWithinThirdPartySegment) {
|
|
79
|
+
return 'mutation:third-party-element';
|
|
80
|
+
}
|
|
81
|
+
const isInIgnoreLsMarker = isInVCIgnoreIfNoLayoutShiftMarker(target);
|
|
82
|
+
if (!isInIgnoreLsMarker) {
|
|
83
|
+
return 'mutation:element';
|
|
84
|
+
}
|
|
85
|
+
const isRLLPlaceholder = RLLPlaceholderHandlers.getInstance().isRLLPlaceholderHydration(rect);
|
|
86
|
+
if (isRLLPlaceholder && isInIgnoreLsMarker) {
|
|
87
|
+
return 'mutation:rll-placeholder';
|
|
88
|
+
}
|
|
89
|
+
const wasDeleted = removedNodeRects.some(nr => isSameRectDimensions(nr, rect));
|
|
90
|
+
if (wasDeleted && isInIgnoreLsMarker) {
|
|
91
|
+
return 'mutation:element-replacement';
|
|
92
|
+
}
|
|
93
|
+
return 'mutation:element';
|
|
94
|
+
};
|
|
34
95
|
export default class ViewportObserver {
|
|
35
96
|
// SSR context functions
|
|
36
97
|
|
|
@@ -81,96 +142,112 @@ export default class ViewportObserver {
|
|
|
81
142
|
if (!addedNode) {
|
|
82
143
|
continue;
|
|
83
144
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const ssrState = this.getSSRState();
|
|
91
|
-
const SSRStateEnum = {
|
|
92
|
-
normal: 1,
|
|
93
|
-
waitingForFirstRender: 2,
|
|
94
|
-
ignoring: 3
|
|
95
|
-
};
|
|
96
|
-
if (ssrState.state === SSRStateEnum.waitingForFirstRender && timestamp > ssrState.renderStart && targetNode === ssrState.reactRootElement) {
|
|
97
|
-
var _this$intersectionObs;
|
|
98
|
-
ssrState.state = SSRStateEnum.ignoring;
|
|
99
|
-
if (ssrState.renderStop === -1) {
|
|
100
|
-
// arbitrary 500ms DOM update window
|
|
101
|
-
ssrState.renderStop = timestamp + 500;
|
|
102
|
-
}
|
|
103
|
-
(_this$intersectionObs = this.intersectionObserver) === null || _this$intersectionObs === void 0 ? void 0 : _this$intersectionObs.watchAndTag(element, 'ssr-hydration');
|
|
104
|
-
continue;
|
|
145
|
+
if (fg('platform_ufo_detect_zero_dimension_rectangles')) {
|
|
146
|
+
var _this$getSSRState, _this$getSSRState$cal, _this$intersectionObs;
|
|
147
|
+
const hasSameDeletedNode = removedNodes.find(ref => {
|
|
148
|
+
const n = ref.deref();
|
|
149
|
+
if (!n || !addedNode) {
|
|
150
|
+
return false;
|
|
105
151
|
}
|
|
106
|
-
|
|
107
|
-
|
|
152
|
+
return n.isEqualNode(addedNode);
|
|
153
|
+
});
|
|
154
|
+
const {
|
|
155
|
+
isWithin: isWithinThirdPartySegment
|
|
156
|
+
} = checkWithinComponent(addedNode, 'UFOThirdPartySegment', this.mapIs3pResult);
|
|
157
|
+
const isTargetReactRoot = targetNode === ((_this$getSSRState = this.getSSRState) === null || _this$getSSRState === void 0 ? void 0 : (_this$getSSRState$cal = _this$getSSRState.call(this)) === null || _this$getSSRState$cal === void 0 ? void 0 : _this$getSSRState$cal.reactRootElement);
|
|
158
|
+
(_this$intersectionObs = this.intersectionObserver) === null || _this$intersectionObs === void 0 ? void 0 : _this$intersectionObs.watchAndTag(addedNode, createElementMutationsWatcherV4(removedNodeRects, isWithinThirdPartySegment, !!hasSameDeletedNode, timestamp, isTargetReactRoot, this.getSSRState, this.getSSRPlaceholderHandler));
|
|
159
|
+
} else {
|
|
160
|
+
for (const {
|
|
161
|
+
isDisplayContentsElementChildren,
|
|
162
|
+
element
|
|
163
|
+
} of getMutatedElements(addedNode)) {
|
|
164
|
+
// SSR hydration logic
|
|
165
|
+
if (this.getSSRState) {
|
|
166
|
+
const ssrState = this.getSSRState();
|
|
167
|
+
const SSRStateEnum = {
|
|
168
|
+
normal: 1,
|
|
169
|
+
waitingForFirstRender: 2,
|
|
170
|
+
ignoring: 3
|
|
171
|
+
};
|
|
172
|
+
if (ssrState.state === SSRStateEnum.waitingForFirstRender && timestamp > ssrState.renderStart && targetNode === ssrState.reactRootElement) {
|
|
108
173
|
var _this$intersectionObs2;
|
|
174
|
+
ssrState.state = SSRStateEnum.ignoring;
|
|
175
|
+
if (ssrState.renderStop === -1) {
|
|
176
|
+
// arbitrary 500ms DOM update window
|
|
177
|
+
ssrState.renderStop = timestamp + 500;
|
|
178
|
+
}
|
|
109
179
|
(_this$intersectionObs2 = this.intersectionObserver) === null || _this$intersectionObs2 === void 0 ? void 0 : _this$intersectionObs2.watchAndTag(element, 'ssr-hydration');
|
|
110
180
|
continue;
|
|
111
|
-
} else {
|
|
112
|
-
ssrState.state = SSRStateEnum.normal;
|
|
113
181
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
// SSR placeholder logic - check and handle with await
|
|
118
|
-
if (this.getSSRPlaceholderHandler) {
|
|
119
|
-
const ssrPlaceholderHandler = this.getSSRPlaceholderHandler();
|
|
120
|
-
if (ssrPlaceholderHandler) {
|
|
121
|
-
if (ssrPlaceholderHandler.isPlaceholder(element) || ssrPlaceholderHandler.isPlaceholderIgnored(element)) {
|
|
122
|
-
if (ssrPlaceholderHandler.checkIfExistedAndSizeMatchingV3(element)) {
|
|
182
|
+
if (ssrState.state === SSRStateEnum.ignoring && timestamp > ssrState.renderStart && targetNode === ssrState.reactRootElement) {
|
|
183
|
+
if (timestamp <= ssrState.renderStop) {
|
|
123
184
|
var _this$intersectionObs3;
|
|
124
|
-
(_this$intersectionObs3 = this.intersectionObserver) === null || _this$intersectionObs3 === void 0 ? void 0 : _this$intersectionObs3.watchAndTag(element, '
|
|
185
|
+
(_this$intersectionObs3 = this.intersectionObserver) === null || _this$intersectionObs3 === void 0 ? void 0 : _this$intersectionObs3.watchAndTag(element, 'ssr-hydration');
|
|
125
186
|
continue;
|
|
187
|
+
} else {
|
|
188
|
+
ssrState.state = SSRStateEnum.normal;
|
|
126
189
|
}
|
|
127
|
-
// If result is false, continue to normal mutation logic below
|
|
128
190
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// SSR placeholder logic - check and handle with await
|
|
194
|
+
if (this.getSSRPlaceholderHandler) {
|
|
195
|
+
const ssrPlaceholderHandler = this.getSSRPlaceholderHandler();
|
|
196
|
+
if (ssrPlaceholderHandler) {
|
|
197
|
+
if (ssrPlaceholderHandler.isPlaceholder(element) || ssrPlaceholderHandler.isPlaceholderIgnored(element)) {
|
|
198
|
+
if (ssrPlaceholderHandler.checkIfExistedAndSizeMatchingV3(element)) {
|
|
199
|
+
var _this$intersectionObs4;
|
|
200
|
+
(_this$intersectionObs4 = this.intersectionObserver) === null || _this$intersectionObs4 === void 0 ? void 0 : _this$intersectionObs4.watchAndTag(element, 'mutation:ssr-placeholder');
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
// If result is false, continue to normal mutation logic below
|
|
204
|
+
}
|
|
205
|
+
if (ssrPlaceholderHandler.isPlaceholderReplacement(element) || ssrPlaceholderHandler.isPlaceholderIgnored(element)) {
|
|
206
|
+
const result = await ssrPlaceholderHandler.validateReactComponentMatchToPlaceholder(element);
|
|
207
|
+
if (result !== false) {
|
|
208
|
+
var _this$intersectionObs5;
|
|
209
|
+
(_this$intersectionObs5 = this.intersectionObserver) === null || _this$intersectionObs5 === void 0 ? void 0 : _this$intersectionObs5.watchAndTag(element, 'mutation:ssr-placeholder');
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
// If result is false, continue to normal mutation logic below
|
|
135
213
|
}
|
|
136
|
-
// If result is false, continue to normal mutation logic below
|
|
137
214
|
}
|
|
138
215
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
216
|
+
const sameDeletedNode = removedNodes.find(ref => {
|
|
217
|
+
const n = ref.deref();
|
|
218
|
+
if (!n || !element) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
return n.isEqualNode(element);
|
|
222
|
+
});
|
|
223
|
+
const isInIgnoreLsMarker = element instanceof HTMLElement ? isInVCIgnoreIfNoLayoutShiftMarker(element) : false;
|
|
224
|
+
if (sameDeletedNode && isInIgnoreLsMarker) {
|
|
225
|
+
var _this$intersectionObs6;
|
|
226
|
+
(_this$intersectionObs6 = this.intersectionObserver) === null || _this$intersectionObs6 === void 0 ? void 0 : _this$intersectionObs6.watchAndTag(element, 'mutation:remount');
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (isContainedWithinMediaWrapper(element)) {
|
|
230
|
+
var _this$intersectionObs7;
|
|
231
|
+
(_this$intersectionObs7 = this.intersectionObserver) === null || _this$intersectionObs7 === void 0 ? void 0 : _this$intersectionObs7.watchAndTag(element, 'mutation:media');
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
const {
|
|
235
|
+
isWithin: isWithinThirdPartySegment
|
|
236
|
+
} = element instanceof HTMLElement ? checkWithinComponent(element, 'UFOThirdPartySegment', this.mapIs3pResult) : {
|
|
237
|
+
isWithin: false
|
|
238
|
+
};
|
|
239
|
+
if (isWithinThirdPartySegment) {
|
|
240
|
+
var _this$intersectionObs8;
|
|
241
|
+
(_this$intersectionObs8 = this.intersectionObserver) === null || _this$intersectionObs8 === void 0 ? void 0 : _this$intersectionObs8.watchAndTag(element, 'mutation:third-party-element');
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (isDisplayContentsElementChildren) {
|
|
245
|
+
var _this$intersectionObs9;
|
|
246
|
+
(_this$intersectionObs9 = this.intersectionObserver) === null || _this$intersectionObs9 === void 0 ? void 0 : _this$intersectionObs9.watchAndTag(element, 'mutation:display-contents-children-element');
|
|
247
|
+
} else {
|
|
248
|
+
var _this$intersectionObs0;
|
|
249
|
+
(_this$intersectionObs0 = this.intersectionObserver) === null || _this$intersectionObs0 === void 0 ? void 0 : _this$intersectionObs0.watchAndTag(element, createElementMutationsWatcher(removedNodeRects));
|
|
144
250
|
}
|
|
145
|
-
return n.isEqualNode(element);
|
|
146
|
-
});
|
|
147
|
-
const isInIgnoreLsMarker = element instanceof HTMLElement ? isInVCIgnoreIfNoLayoutShiftMarker(element) : false;
|
|
148
|
-
if (sameDeletedNode && isInIgnoreLsMarker) {
|
|
149
|
-
var _this$intersectionObs5;
|
|
150
|
-
(_this$intersectionObs5 = this.intersectionObserver) === null || _this$intersectionObs5 === void 0 ? void 0 : _this$intersectionObs5.watchAndTag(element, 'mutation:remount');
|
|
151
|
-
continue;
|
|
152
|
-
}
|
|
153
|
-
if (isContainedWithinMediaWrapper(element)) {
|
|
154
|
-
var _this$intersectionObs6;
|
|
155
|
-
(_this$intersectionObs6 = this.intersectionObserver) === null || _this$intersectionObs6 === void 0 ? void 0 : _this$intersectionObs6.watchAndTag(element, 'mutation:media');
|
|
156
|
-
continue;
|
|
157
|
-
}
|
|
158
|
-
const {
|
|
159
|
-
isWithin: isWithinThirdPartySegment
|
|
160
|
-
} = element instanceof HTMLElement ? checkWithinComponent(element, 'UFOThirdPartySegment', this.mapIs3pResult) : {
|
|
161
|
-
isWithin: false
|
|
162
|
-
};
|
|
163
|
-
if (isWithinThirdPartySegment) {
|
|
164
|
-
var _this$intersectionObs7;
|
|
165
|
-
(_this$intersectionObs7 = this.intersectionObserver) === null || _this$intersectionObs7 === void 0 ? void 0 : _this$intersectionObs7.watchAndTag(element, 'mutation:third-party-element');
|
|
166
|
-
continue;
|
|
167
|
-
}
|
|
168
|
-
if (isDisplayContentsElementChildren) {
|
|
169
|
-
var _this$intersectionObs8;
|
|
170
|
-
(_this$intersectionObs8 = this.intersectionObserver) === null || _this$intersectionObs8 === void 0 ? void 0 : _this$intersectionObs8.watchAndTag(element, 'mutation:display-contents-children-element');
|
|
171
|
-
} else {
|
|
172
|
-
var _this$intersectionObs9;
|
|
173
|
-
(_this$intersectionObs9 = this.intersectionObserver) === null || _this$intersectionObs9 === void 0 ? void 0 : _this$intersectionObs9.watchAndTag(element, createElementMutationsWatcher(removedNodeRects));
|
|
174
251
|
}
|
|
175
252
|
}
|
|
176
253
|
}
|
|
@@ -181,8 +258,8 @@ export default class ViewportObserver {
|
|
|
181
258
|
oldValue,
|
|
182
259
|
newValue
|
|
183
260
|
}) => {
|
|
184
|
-
var _this$
|
|
185
|
-
(_this$
|
|
261
|
+
var _this$intersectionObs1;
|
|
262
|
+
(_this$intersectionObs1 = this.intersectionObserver) === null || _this$intersectionObs1 === void 0 ? void 0 : _this$intersectionObs1.watchAndTag(target, ({
|
|
186
263
|
target,
|
|
187
264
|
rect
|
|
188
265
|
}) => {
|
|
@@ -339,12 +416,12 @@ export default class ViewportObserver {
|
|
|
339
416
|
this.isStarted = true;
|
|
340
417
|
}
|
|
341
418
|
stop() {
|
|
342
|
-
var _this$mutationObserve2, _this$
|
|
419
|
+
var _this$mutationObserve2, _this$intersectionObs10, _this$performanceObse2;
|
|
343
420
|
if (!this.isStarted) {
|
|
344
421
|
return;
|
|
345
422
|
}
|
|
346
423
|
(_this$mutationObserve2 = this.mutationObserver) === null || _this$mutationObserve2 === void 0 ? void 0 : _this$mutationObserve2.disconnect();
|
|
347
|
-
(_this$
|
|
424
|
+
(_this$intersectionObs10 = this.intersectionObserver) === null || _this$intersectionObs10 === void 0 ? void 0 : _this$intersectionObs10.disconnect();
|
|
348
425
|
(_this$performanceObse2 = this.performanceObserver) === null || _this$performanceObse2 === void 0 ? void 0 : _this$performanceObse2.disconnect();
|
|
349
426
|
this.isStarted = false;
|
|
350
427
|
// Clean up caches when stopping
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
|
+
import { isZeroDimensionRectangle } from '../utils/is-zero-dimension-rectangle';
|
|
1
3
|
function isValidEntry(entry) {
|
|
2
4
|
return entry.isIntersecting && entry.intersectionRect.width > 0 && entry.intersectionRect.height > 0;
|
|
3
5
|
}
|
|
@@ -14,12 +16,41 @@ export function createIntersectionObserver({
|
|
|
14
16
|
const startTime = performance.now();
|
|
15
17
|
entries.forEach(entry => {
|
|
16
18
|
var _mutationTag;
|
|
17
|
-
if (!(entry.target instanceof HTMLElement)
|
|
19
|
+
if (!(entry.target instanceof HTMLElement)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const tagOrCallback = callbacksPerElement.get(entry.target);
|
|
23
|
+
if (fg('platform_ufo_detect_zero_dimension_rectangles')) {
|
|
24
|
+
if (isZeroDimensionRectangle(entry.intersectionRect)) {
|
|
25
|
+
const zeroDimensionRectangleTagCallback = props => {
|
|
26
|
+
const tagOrCallbackResult = typeof tagOrCallback === 'function' ? tagOrCallback(props) : tagOrCallback;
|
|
27
|
+
|
|
28
|
+
// override as display-contents mutation
|
|
29
|
+
if (tagOrCallbackResult === 'mutation:element') {
|
|
30
|
+
return 'mutation:display-contents-children-element';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// override as display-contents mutation
|
|
34
|
+
if (tagOrCallbackResult && typeof tagOrCallbackResult !== 'string' && tagOrCallbackResult.type === 'mutation:attribute') {
|
|
35
|
+
return {
|
|
36
|
+
type: 'mutation:display-contents-children-attribute',
|
|
37
|
+
mutationData: tagOrCallbackResult.mutationData
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
return tagOrCallbackResult;
|
|
41
|
+
};
|
|
42
|
+
for (const child of entry.target.children) {
|
|
43
|
+
observer.observe(child);
|
|
44
|
+
callbacksPerElement.set(child, zeroDimensionRectangleTagCallback);
|
|
45
|
+
}
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (!isValidEntry(entry)) {
|
|
18
50
|
return;
|
|
19
51
|
}
|
|
20
52
|
let mutationTag = null;
|
|
21
53
|
let mutationData = null;
|
|
22
|
-
const tagOrCallback = callbacksPerElement.get(entry.target);
|
|
23
54
|
if (typeof tagOrCallback === 'function') {
|
|
24
55
|
const tagOrCallbackResult = tagOrCallback({
|
|
25
56
|
target: entry.target,
|
|
@@ -1,19 +1,30 @@
|
|
|
1
1
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
|
+
function isElementStyledWithDisplayContents(element) {
|
|
3
|
+
var _window2, _window2$getComputedS;
|
|
4
|
+
// To minimise calling `getComputedStyle`, we are making an assumption that if an element is from the Entrypoints framework, then it will have `display: contents` styling
|
|
5
|
+
// as per https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/e4ccf437262ef4c0fd3c651ffb7ad4770b15aed4/jira/src/packages/platform/entry-points/entry-point-placeholder/src/index.tsx#lines-136
|
|
6
|
+
if (fg('platform_ufo_detect_entrypoint_parent')) {
|
|
7
|
+
var _window, _window$getComputedSt;
|
|
8
|
+
if (element.hasAttribute('data-ep-placeholder-id')) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
return ((_window = window) === null || _window === void 0 ? void 0 : (_window$getComputedSt = _window.getComputedStyle(element)) === null || _window$getComputedSt === void 0 ? void 0 : _window$getComputedSt.display) === 'contents';
|
|
12
|
+
}
|
|
13
|
+
return ((_window2 = window) === null || _window2 === void 0 ? void 0 : (_window2$getComputedS = _window2.getComputedStyle(element)) === null || _window2$getComputedS === void 0 ? void 0 : _window2$getComputedS.display) === 'contents';
|
|
14
|
+
}
|
|
2
15
|
const MAX_NESTED_LEVELS_OF_DISPLAY_CONTENT_ELEMENTS_HANDLED = 3;
|
|
3
16
|
export function getMutatedElements(element, depthLevel = 0) {
|
|
4
|
-
var _window, _window$getComputedSt;
|
|
5
17
|
if (fg('platform_ufo_disable_vcnext_observations')) {
|
|
6
18
|
return [{
|
|
7
19
|
element,
|
|
8
20
|
isDisplayContentsElementChildren: false
|
|
9
21
|
}];
|
|
10
22
|
}
|
|
11
|
-
if ((
|
|
23
|
+
if (isElementStyledWithDisplayContents(element)) {
|
|
12
24
|
const mutatedElements = [];
|
|
13
25
|
const nestedDisplayContentsElementChildren = [];
|
|
14
26
|
for (const child of element.children) {
|
|
15
|
-
|
|
16
|
-
if (((_window2 = window) === null || _window2 === void 0 ? void 0 : (_window2$getComputedS = _window2.getComputedStyle(child)) === null || _window2$getComputedS === void 0 ? void 0 : _window2$getComputedS.display) === 'contents') {
|
|
27
|
+
if (isElementStyledWithDisplayContents(child)) {
|
|
17
28
|
nestedDisplayContentsElementChildren.push(child);
|
|
18
29
|
}
|
|
19
30
|
mutatedElements.push({
|