@@ -8,7 +8,7 @@ export const BACKGROUND_COLOR_START = 'rgba(85, 127, 243, 0.10)';
88export  const  BACKGROUND_COLOR_END  =  'rgba(85, 127, 243, 0.25)' ; 
99export  const  OVERLAY_ID  =  'ddg-password-import-overlay' ; 
1010export  const  DELAY_BEFORE_ANIMATION  =  300 ; 
11- const  TAKEOUT_DOWNLOAD_URL_BASE  =  '/takeout/download ' ; 
11+ const  MANAGE_ARCHIVE_DEFAULT_BASE  =  '/manage/archive ' ; 
1212
1313/** 
1414 * @typedef  ButtonAnimationStyle 
@@ -55,8 +55,6 @@ export default class AutofillImport extends ActionExecutorBase {
5555
5656    #domLoaded; 
5757
58-     #exportId; 
59- 
6058    #processingBookmark; 
6159
6260    #isBookmarkModalVisible =  false ; 
@@ -589,22 +587,23 @@ export default class AutofillImport extends ActionExecutorBase {
589587    } 
590588
591589    /** Bookmark import code */ 
590+     get  defaultRetrySettings ( )  { 
591+         return  { 
592+             maxAttempts : this . getFeatureSetting ( 'downloadRetryLimit' )  ??  Infinity , 
593+             interval : this . getFeatureSetting ( 'downloadRetryInterval' )  ??  1000 , 
594+         } ; 
595+     } 
596+ 
592597    async  downloadData ( )  { 
593598        // Run with retry forever until the download link is available, 
594599        // Android is the one that timesout anyway and closes the whole tab if this doesn't complete 
595-         const  downloadRetryLimit  =  this . getFeatureSetting ( 'downloadRetryLimit' )  ??  Infinity ; 
596-         const  downloadRetryInterval  =  this . getFeatureSetting ( 'downloadRetryInterval' )  ??  1000 ; 
597- 
598-         const  userIdElement  =  await  this . runWithRetry ( 
599-             ( )  =>  document . querySelector ( this . bookmarkImportSelectorSettings . userIdLink ) , 
600-             downloadRetryLimit , 
601-             downloadRetryInterval , 
602-             'linear' , 
603-         ) ; 
604-         const  userIdLink  =  userIdElement ?. getAttribute ( 'href' ) ; 
605-         const  userId  =  userIdLink  ? new  URL ( userIdLink ,  window . location . origin ) . searchParams . get ( 'user' )  : null ; 
606600
607-         if  ( ! userId  ||  ! this . #exportId)  { 
601+         const  exportId  =  window . location . pathname 
602+             . split ( '/' ) 
603+             . filter ( ( segment )  =>  segment ) 
604+             . pop ( ) ; 
605+ 
606+         if  ( ! exportId )  { 
608607            this . postBookmarkImportMessage ( 'actionCompleted' ,  { 
609608                result : new  ErrorResponse ( { 
610609                    actionID : 'download-data' , 
@@ -614,30 +613,28 @@ export default class AutofillImport extends ActionExecutorBase {
614613            return ; 
615614        } 
616615
617-         await  this . runWithRetry ( 
618-             ( )  =>  document . querySelector ( `a[href="./manage/archive/${ this . #exportId}  "]` ) , 
619-             downloadRetryLimit , 
620-             downloadRetryInterval , 
621-             'linear' , 
616+         const  downloadLinkSelector  =  this . bookmarkImportSelectorSettings . downloadLink  ??  `a[href*="&i=0&user="]` ; 
617+         const  downloadButton  =  /** @type  {HTMLAnchorElement|null } */  ( 
618+             await  this . runWithRetry ( ( )  =>  document . querySelector ( downloadLinkSelector ) ,  5 ,  1000 ,  'linear' ) 
622619        ) ; 
620+         if  ( downloadButton  ==  null )  { 
621+             // If there was no download link, it was likely a 404 
622+             // so we reload the page to try again 
623+             window . location . reload ( ) ; 
624+         } 
623625
624-         const  downloadURL  =  `${ TAKEOUT_DOWNLOAD_URL_BASE }  ?j=${ this . #exportId}  &i=0&user=${ userId }  ` ; 
625- 
626-         // Sleep before downloading to ensure the download link is available 
627-         const  downloadNavigationDelayMs  =  this . getFeatureSetting ( 'downloadNavigationDelayMs' )  ??  2000 ; 
628-         await  new  Promise ( ( resolve )  =>  setTimeout ( resolve ,  downloadNavigationDelayMs ) ) ; 
629- 
630-         window . location . href  =  downloadURL ; 
626+         downloadButton ?. click ( ) ; 
631627    } 
632628
633629    /** 
634630     * Here we ignore the action and return a default retry config 
635631     * as for now the retry doesn't need to be per action. 
636632     */ 
637633    retryConfigFor ( _ )  { 
634+         const  {  interval,  maxAttempts }  =  this . defaultRetrySettings ; 
638635        return  { 
639-             interval : {  ms : 1000  } , 
640-             maxAttempts :  30 , 
636+             interval : {  ms : interval  } , 
637+             maxAttempts, 
641638        } ; 
642639    } 
643640
@@ -660,14 +657,17 @@ export default class AutofillImport extends ActionExecutorBase {
660657    async  handleBookmarkImportPath ( pathname )  { 
661658        if  ( pathname  ===  '/'  &&  ! this . #isBookmarkModalVisible)  { 
662659            for  ( const  action  of  this . bookmarkImportActionSettings )  { 
663-                 // Before clicking on the manage button, we need to store the export id 
664-                 if  ( action . id  ===  'manage-button-click' )  { 
665-                     await  this . storeExportId ( ) ; 
666-                 } 
667- 
668660                await  this . patchMessagingAndProcessAction ( action ) ; 
669661            } 
662+ 
663+             // Parse the export id from the page and then navigate to the 'manage' page 
664+             const  exportId  =  await  this . getExportId ( ) ; 
665+             window . location . href  =  `${ MANAGE_ARCHIVE_DEFAULT_BASE }  /${ exportId }  ` ; 
666+         }  else  if  ( pathname . startsWith ( MANAGE_ARCHIVE_DEFAULT_BASE ) )  { 
667+             // If we're on the 'manage' page, we can download the data 
670668            await  this . downloadData ( ) ; 
669+         }  else  { 
670+             // Unhandled path, we bail out 
671671        } 
672672    } 
673673
@@ -681,11 +681,13 @@ export default class AutofillImport extends ActionExecutorBase {
681681    findExportId ( )  { 
682682        const  panels  =  document . querySelectorAll ( this . bookmarkImportSelectorSettings . tabPanel ) ; 
683683        const  exportPanel  =  panels [ panels . length  -  1 ] ; 
684-         return  exportPanel . querySelector ( 'div[data-archive-id]' ) ?. getAttribute ( 'data-archive-id' ) ; 
684+         const  dataArchiveIdSelector  =  this . bookmarkImportSelectorSettings . dataArchiveId  ??  `div[data-archive-id]` ; 
685+         return  exportPanel . querySelector ( dataArchiveIdSelector ) ?. getAttribute ( 'data-archive-id' ) ; 
685686    } 
686687
687-     async  storeExportId ( )  { 
688-         this . #exportId =  await  this . runWithRetry ( ( )  =>  this . findExportId ( ) ,  30 ,  1000 ,  'linear' ) ; 
688+     async  getExportId ( )  { 
689+         const  {  maxAttempts,  interval }  =  this . defaultRetrySettings ; 
690+         return  await  this . runWithRetry ( ( )  =>  this . findExportId ( ) ,  maxAttempts ,  interval ,  'linear' ) ; 
689691    } 
690692
691693    urlChanged ( )  { 
0 commit comments