@@ -1404,6 +1404,24 @@ export function viewProfileFromPostMessage(
14041404 } ;
14051405}
14061406
1407+ // Given a profile view URL, extract the raw URL needed to fetch the profile
1408+ // data. This mirrors the manual pathname splitting done in retrieveProfileForRawUrl,
1409+ // so we can fetch the profile before calling stateFromLocation.
1410+ function getProfileFetchUrl ( urlString : string ) : string {
1411+ const pathParts = new URL ( urlString ) . pathname . split ( '/' ) . filter ( ( d ) => d ) ;
1412+ const dataSource = ensureIsValidDataSource ( pathParts [ 0 ] ) ;
1413+ switch ( dataSource ) {
1414+ case 'public' :
1415+ return getProfileUrlForHash ( pathParts [ 1 ] ) ;
1416+ case 'from-url' :
1417+ return decodeURIComponent ( pathParts [ 1 ] ) ;
1418+ default :
1419+ throw new Error (
1420+ 'Only public uploaded profiles are supported by the comparison function.'
1421+ ) ;
1422+ }
1423+ }
1424+
14071425/**
14081426 * This action retrieves several profiles and push them into 1 profile using the
14091427 * information contained in the query.
@@ -1416,9 +1434,7 @@ export function retrieveProfilesToCompare(
14161434 dispatch ( waitingForProfileFromUrl ( ) ) ;
14171435
14181436 try {
1419- // First we get a state from each URL. From these states we'll get all the
1420- // data we need to fetch and process the profiles.
1421- const profileStates = await Promise . all (
1437+ const profilesAndStates = await Promise . all (
14221438 profileViewUrls . map ( async ( url ) => {
14231439 if (
14241440 url . startsWith ( 'https://perfht.ml/' ) ||
@@ -1427,28 +1443,9 @@ export function retrieveProfilesToCompare(
14271443 ) {
14281444 url = await expandUrl ( url ) ;
14291445 }
1430- // TODO: Pass the profileUpgradeInfo here. See #5871.
1431- return stateFromLocation ( new URL ( url ) ) ;
1432- } )
1433- ) ;
14341446
1435- // Then we retrieve the profiles from the online store, and unserialize
1436- // and process them if needed.
1437- const promises = profileStates . map (
1438- async ( { dataSource, hash, profileUrl } ) => {
1439- switch ( dataSource ) {
1440- case 'public' :
1441- // Use a URL from the public store.
1442- profileUrl = getProfileUrlForHash ( hash ) ;
1443- break ;
1444- case 'from-url' :
1445- // Use the profile URL in the decoded state, decoded from the input URL.
1446- break ;
1447- default :
1448- throw new Error (
1449- 'Only public uploaded profiles are supported by the comparison function.'
1450- ) ;
1451- }
1447+ const profileUrl = getProfileFetchUrl ( url ) ;
1448+
14521449 const response : ProfileOrZip = await _fetchProfile ( {
14531450 url : profileUrl ,
14541451 onTemporaryError : ( e : TemporaryError ) => {
@@ -1458,18 +1455,27 @@ export function retrieveProfilesToCompare(
14581455 if ( response . responseType !== 'PROFILE' ) {
14591456 throw new Error ( 'Expected to receive a profile from _fetchProfile' ) ;
14601457 }
1461- const serializedProfile = response . profile ;
14621458
1463- const profile =
1464- unserializeProfileOfArbitraryFormat ( serializedProfile ) ;
1465- return profile ;
1466- }
1459+ const upgradeInfo : ProfileUpgradeInfo = { } ;
1460+ const profile = await unserializeProfileOfArbitraryFormat (
1461+ response . profile ,
1462+ profileUrl ,
1463+ upgradeInfo
1464+ ) ;
1465+
1466+ const profileState = stateFromLocation ( new URL ( url ) , {
1467+ profile,
1468+ upgradeInfo,
1469+ } ) ;
1470+
1471+ return { profile, profileState } ;
1472+ } )
14671473 ) ;
14681474
1469- // Once all profiles have been fetched and unserialized, we can start
1470- // pushing them to a brand new profile. This resulting profile will keep
1471- // only the 2 selected threads from the 2 profiles.
1472- const profiles = await Promise . all ( promises ) ;
1475+ const profiles = profilesAndStates . map ( ( { profile } ) => profile ) ;
1476+ const profileStates = profilesAndStates . map (
1477+ ( { profileState } ) => profileState
1478+ ) ;
14731479
14741480 const {
14751481 profile : resultProfile ,
0 commit comments