@@ -20,7 +20,6 @@ import { Interceptor } from '.';
20
20
const FIREFOX_PREF_REGEX = / \w + _ p r e f \( " ( [ ^ " ] + ) " , ( .* ) \) ; /
21
21
22
22
let profileSetupBrowser : BrowserInstance | undefined ;
23
- let browsers : _ . Dictionary < BrowserInstance > = { } ;
24
23
25
24
export const NSS_DIR = path . join ( APP_ROOT , 'nss' ) ;
26
25
@@ -69,18 +68,26 @@ const getCertutilCommand = _.memoize(async () => {
69
68
}
70
69
} ) ;
71
70
72
- export class FreshFirefox implements Interceptor {
73
- id = 'fresh-firefox' ;
74
- version = '1.1.0' ;
71
+ abstract class Firefox implements Interceptor {
72
+ readonly abstract id : string ;
73
+ readonly abstract version : string ;
74
+
75
+ protected constructor (
76
+ private config : HtkConfig ,
77
+ private variantName : string ,
78
+ private pathName : string = variantName + '-profile' ,
79
+ ) { }
80
+
81
+ private readonly activeBrowsers : _ . Dictionary < BrowserInstance > = { } ;
75
82
76
- constructor ( private config : HtkConfig ) { }
77
83
78
84
isActive ( proxyPort : number | string ) {
79
- return browsers [ proxyPort ] != null && ! ! browsers [ proxyPort ] . pid ;
85
+ const browser = this . activeBrowsers [ proxyPort ] ;
86
+ return ! ! browser && ! ! browser . pid ;
80
87
}
81
88
82
89
async isActivable ( ) {
83
- const firefoxBrowser = await getBrowserDetails ( this . config . configPath , 'firefox' ) ;
90
+ const firefoxBrowser = await getBrowserDetails ( this . config . configPath , this . variantName ) ;
84
91
85
92
return ! ! firefoxBrowser && // Must have Firefox installed
86
93
parseInt ( firefoxBrowser . version . split ( '.' ) [ 0 ] , 0 ) >= 58 && // Must use cert9.db
@@ -96,7 +103,7 @@ export class FreshFirefox implements Interceptor {
96
103
const initialUrl = initialServer . url ;
97
104
98
105
const browser = await launchBrowser ( initialUrl , {
99
- browser : 'firefox' ,
106
+ browser : this . variantName ,
100
107
profile : profilePath ,
101
108
proxy : proxyPort ? `127.0.0.1:${ proxyPort } ` : undefined ,
102
109
prefs : _ . assign (
@@ -239,18 +246,18 @@ export class FreshFirefox implements Interceptor {
239
246
async activate ( proxyPort : number ) {
240
247
if ( this . isActive ( proxyPort ) || ! ! profileSetupBrowser ) return ;
241
248
242
- const browserDetails = await getBrowserDetails ( this . config . configPath , 'firefox' ) ;
249
+ const browserDetails = await getBrowserDetails ( this . config . configPath , this . variantName ) ;
243
250
if ( ! browserDetails ) throw new Error ( 'Firefox could not be detected' ) ;
244
251
245
252
const profilePath = await isSnap ( browserDetails . command )
246
- ? path . join ( await getSnapConfigPath ( 'firefox' ) , 'profile' )
247
- : path . join ( this . config . configPath , 'firefox-profile' ) ;
253
+ ? path . join ( await getSnapConfigPath ( this . variantName ) , 'profile' )
254
+ : path . join ( this . config . configPath , this . pathName ) ;
248
255
249
256
const firefoxPrefsFile = path . join ( profilePath , 'prefs.js' ) ;
250
257
251
258
let existingPrefs : _ . Dictionary < any > = { } ;
252
259
253
- if ( await canAccess ( firefoxPrefsFile ) === false ) {
260
+ if ( ! await canAccess ( firefoxPrefsFile ) ) {
254
261
/*
255
262
First time, we do a separate pre-usage startup & stop, without the proxy, for certificate setup.
256
263
This helps avoid initial Firefox profile setup request noise, and tidies up some awkward UX where
@@ -288,10 +295,10 @@ export class FreshFirefox implements Interceptor {
288
295
logError ( e ) ;
289
296
} ) ;
290
297
291
- browsers [ proxyPort ] = browser ;
298
+ this . activeBrowsers [ proxyPort ] = browser ;
292
299
browser . process . once ( 'close' , async ( exitCode ) => {
293
300
console . log ( 'Firefox closed' ) ;
294
- delete browsers [ proxyPort ] ;
301
+ delete this . activeBrowsers [ proxyPort ] ;
295
302
296
303
// It seems maybe this can happen when firefox is just updated - it starts and
297
304
// closes immediately, but loses some settings along the way. In that case, the 2nd
@@ -316,7 +323,7 @@ export class FreshFirefox implements Interceptor {
316
323
317
324
async deactivate ( proxyPort : number | string ) {
318
325
if ( this . isActive ( proxyPort ) ) {
319
- const browser = browsers [ proxyPort ] ;
326
+ const browser = this . activeBrowsers [ proxyPort ] ;
320
327
const closePromise = new Promise ( ( resolve ) => browser . process . once ( 'close' , resolve ) ) ;
321
328
browser . stop ( ) ;
322
329
await closePromise ;
@@ -325,11 +332,41 @@ export class FreshFirefox implements Interceptor {
325
332
326
333
async deactivateAll ( ) : Promise < void > {
327
334
await Promise . all (
328
- Object . keys ( browsers ) . map ( ( proxyPort ) => this . deactivate ( proxyPort ) )
335
+ Object . keys ( this . activeBrowsers ) . map ( ( proxyPort ) => this . deactivate ( proxyPort ) )
329
336
) ;
330
337
if ( profileSetupBrowser ) {
331
338
profileSetupBrowser . stop ( ) ;
332
339
return new Promise ( ( resolve ) => profileSetupBrowser ! . process . once ( 'close' , resolve ) ) ;
333
340
}
334
341
}
342
+ } ;
343
+
344
+ export class FreshFirefox extends Firefox {
345
+
346
+ id = 'fresh-firefox' ;
347
+ version = '1.2.0' ;
348
+
349
+ constructor ( config : HtkConfig ) {
350
+ super ( config , 'firefox' ) ;
351
+ }
352
+ } ;
353
+
354
+ export class FreshFirefoxDeveloper extends Firefox {
355
+
356
+ id = 'fresh-firefox-dev' ;
357
+ version = '1.2.0' ;
358
+
359
+ constructor ( config : HtkConfig ) {
360
+ super ( config , 'firefox-developer' ) ;
361
+ }
362
+ } ;
363
+
364
+ export class FreshFirefoxNightly extends Firefox {
365
+
366
+ id = 'fresh-firefox-nightly' ;
367
+ version = '1.2.0' ;
368
+
369
+ constructor ( config : HtkConfig ) {
370
+ super ( config , 'firefox-nightly' ) ;
371
+ }
335
372
} ;
0 commit comments