@@ -52,17 +52,72 @@ browser.storage.local.get('favorites', function (result) {
52
52
} ) ;
53
53
54
54
// Update sidebar when a tab changes
55
- browser . tabs . onUpdated . addListener ( ( changeInfo ) => {
56
- if ( changeInfo . status === "complete" ) {
57
- initTabSidebarControl ( ) ;
58
- }
55
+ browser . tabs . onUpdated . addListener ( ( ) => {
56
+ initTabSidebarControl ( ) ;
57
+ } ) ;
58
+
59
+ // Update sidebar when tabs are created, activated, closed
60
+ browser . tabs . onCreated . addListener ( ( ) => {
61
+ initTabSidebarControl ( ) ;
59
62
} ) ;
60
63
61
- // Update sidebar when a tab is created
62
- browser . tabs . onCreated . addListener ( function ( ) {
64
+ browser . tabs . onActivated . addListener ( ( ) => {
63
65
initTabSidebarControl ( ) ;
64
66
} ) ;
65
67
68
+ browser . tabs . onRemoved . addListener ( ( tabId ) => {
69
+ const index = base . findIndex ( ( tab ) => tab . id === tabId ) ;
70
+ if ( index !== - 1 ) {
71
+ base . splice ( index , 1 ) ;
72
+ }
73
+ initTabSidebarControl ( ) ;
74
+ } )
75
+
76
+ // Sidebar clear button
77
+ function clearTabs ( tabs ) {
78
+ let newTabs = tabs
79
+ tabs . forEach ( ( tab ) => {
80
+ if ( ! tab . active && ! tab . audible && ! openedFavorites . includes ( tab . id ) ) {
81
+ browser . tabs . remove ( tab . id )
82
+ newTabs = tabs . filter ( ( tab ) => {
83
+ if ( false ) return
84
+ } )
85
+ }
86
+ } )
87
+ if ( newTabs . length == tabs . length ) {
88
+ tabs . forEach ( ( tab ) => {
89
+ if ( ! tab . active && ! openedFavorites . includes ( tab . id ) ) {
90
+ browser . tabs . remove ( tab . id )
91
+ newTabs = tabs . filter ( ( tab ) => {
92
+ if ( false ) return
93
+ } )
94
+ }
95
+ } )
96
+ }
97
+ if ( newTabs . length == tabs . length ) {
98
+ tabs . forEach ( ( tab ) => {
99
+ if ( ! openedFavorites . includes ( tab . id ) ) {
100
+ browser . tabs . remove ( tab . id )
101
+ newTabs = tabs . filter ( ( tab ) => {
102
+ if ( false ) return
103
+ } )
104
+ }
105
+ } )
106
+ }
107
+ }
108
+
109
+ function canClearTabs ( tabs ) {
110
+ let newTabs = tabs . filter ( ( tab ) => {
111
+ return ! openedFavorites . includes ( tab . id ) ;
112
+ } ) ;
113
+ return ( newTabs . length > 0 )
114
+ }
115
+ document . querySelector ( '#separator span' ) . addEventListener ( 'click' , ( ) => {
116
+ browser . tabs . query ( { currentWindow : true } ) . then ( ( tabs ) => {
117
+ clearTabs ( tabs )
118
+ } )
119
+ } )
120
+
66
121
// Browser-control
67
122
function handleBrowserControl ( id ) {
68
123
browser . tabs . query ( { active : true , currentWindow : true } ) . then ( ( tabs ) => {
@@ -205,73 +260,76 @@ document.querySelector('button#b2').addEventListener("click", function () {
205
260
206
261
function newTab ( ) {
207
262
browser . tabs . create ( { } ) ;
208
- document . querySelectorAll ( '[aria-label="favopen"]' ) ?. forEach ( ( elemento ) => {
209
- elemento . ariaLabel = "" ;
210
- } )
211
263
}
212
264
213
265
// Sidebar Code
214
266
let base , draggedOver , dragging , activeTabId ;
215
267
216
268
const init = ( array ) => {
217
- base = array . map ( ( tab ) => ( {
218
- id : tab . id ,
219
- title : tab . title ,
220
- favIconUrl : tab . favIconUrl ,
221
- } ) ) ;
269
+ base = array ;
222
270
renderItems ( base ) ;
223
271
} ;
224
272
225
273
const renderItems = ( data ) => {
226
274
tabList . innerHTML = '' ;
227
275
data . forEach ( ( tab ) => {
228
- const node = document . createElement ( 'li' ) ;
229
- node . draggable = true ;
230
- node . dataset . tabId = tab . id ;
231
-
232
- const titleNode = document . createElement ( 'div' ) ;
233
- titleNode . classList . add ( 'tab-title' ) ;
234
- titleNode . textContent = tab . title ;
235
-
236
- let iconNode ;
237
- if ( tab . favIconUrl ) {
238
- iconNode = document . createElement ( 'img' ) ;
239
- iconNode . src = tab . favIconUrl ;
240
- iconNode . alt = tab . title ;
241
- } else {
242
- iconNode = document . createElement ( 'i' ) ;
243
- iconNode . classList . add ( 'fa' , 'fa-solid' , 'fa-globe' ) ;
244
- iconNode . setAttribute ( 'aria-hidden' , 'true' ) ;
245
- }
276
+ if ( ! openedFavorites . includes ( tab . id ) ) {
277
+ const node = document . createElement ( 'li' ) ;
278
+ node . draggable = true ;
279
+ node . dataset . tabId = tab . id ;
280
+
281
+ const titleNode = document . createElement ( 'div' ) ;
282
+ titleNode . classList . add ( 'tab-title' ) ;
283
+ titleNode . textContent = tab . title ;
284
+
285
+ let iconNode ;
286
+ if ( tab . favIconUrl ) {
287
+ iconNode = document . createElement ( 'img' ) ;
288
+ iconNode . src = tab . favIconUrl ;
289
+ iconNode . alt = tab . title ;
290
+ } else {
291
+ iconNode = document . createElement ( 'i' ) ;
292
+ iconNode . classList . add ( 'fa' , 'fa-solid' , 'fa-globe' ) ;
293
+ iconNode . setAttribute ( 'aria-hidden' , 'true' ) ;
294
+ }
295
+
296
+ const closeButton = document . createElement ( 'button' ) ;
297
+ closeButton . classList . add ( 'close' ) ;
298
+ closeButton . innerHTML = '×' ;
299
+ closeButton . addEventListener ( 'click' , closeTab ) ;
300
+
301
+ node . appendChild ( iconNode ) ;
246
302
247
- const closeButton = document . createElement ( 'button' ) ;
248
- closeButton . classList . add ( 'close' ) ;
249
- closeButton . title = 'Close Tab' ;
250
- closeButton . innerHTML = '×' ;
251
- closeButton . addEventListener ( 'click' , closeTab ) ;
252
-
253
- node . appendChild ( iconNode ) ;
254
- node . appendChild ( titleNode ) ;
255
- node . appendChild ( closeButton ) ;
256
-
257
- node . addEventListener ( 'drag' , setDragging ) ;
258
- node . addEventListener ( 'dragover' , setDraggedOver ) ;
259
- node . addEventListener ( 'drop' , compare ) ;
260
- node . addEventListener ( 'click' , navigateToTab ) ;
261
- node . addEventListener ( 'auxclick' , ( event ) => {
262
- if ( event . button === 1 ) {
263
- closeTab ( event ) ;
303
+ if ( tab . audible ) {
304
+ const soundIcon = document . createElement ( 'i' ) ;
305
+ soundIcon . classList . add ( 'fa' , 'fa-light' , 'fa-volume-high' ) ;
306
+ soundIcon . setAttribute ( 'aria-hidden' , 'true' ) ;
307
+ node . appendChild ( soundIcon )
264
308
}
265
- } ) ;
266
309
267
- if ( tab . id === activeTabId ) {
268
- node . classList . add ( 'active' ) ;
269
- }
310
+ node . appendChild ( titleNode ) ;
311
+ node . appendChild ( closeButton ) ;
270
312
271
- if ( ! openedFavorites . includes ( tab . id ) ) {
313
+ node . addEventListener ( 'drag' , setDragging ) ;
314
+ node . addEventListener ( 'dragover' , setDraggedOver ) ;
315
+ node . addEventListener ( 'drop' , compare ) ;
316
+ node . addEventListener ( 'click' , navigateToTab ) ;
317
+ node . addEventListener ( 'auxclick' , ( event ) => {
318
+ if ( event . button === 1 ) {
319
+ closeTab ( event ) ;
320
+ }
321
+ } ) ;
272
322
tabList . appendChild ( node ) ;
273
323
}
324
+
325
+ document . querySelector ( '.active' ) ?. classList . remove ( 'active' ) ;
326
+ document . querySelector ( `[data-tab-id="${ activeTabId } "]` ) ?. classList . add ( 'active' ) ;
274
327
} ) ;
328
+ if ( canClearTabs ( data ) ) {
329
+ document . querySelector ( '#separator span' ) . style . display = 'block'
330
+ } else {
331
+ document . querySelector ( '#separator span' ) . style . display = 'none'
332
+ }
275
333
} ;
276
334
277
335
const compare = ( ) => {
@@ -306,26 +364,12 @@ const closeTab = (e, middleclick = false) => {
306
364
browser . tabs . remove ( tabId ) ;
307
365
} ;
308
366
309
- browser . tabs . onRemoved . addListener ( ( tabId ) => {
310
- const index = base . findIndex ( ( tab ) => tab . id === tabId ) ;
311
- if ( index !== - 1 ) {
312
- base . splice ( index , 1 ) ;
313
- renderItems ( base ) ;
314
- }
315
- initTabSidebarControl ( ) ;
316
- updateSearchBar ( ) ;
317
- } )
318
-
319
367
const navigateToTab = ( e ) => {
320
368
const tabId = parseInt ( e . currentTarget . dataset . tabId ) ;
321
369
browser . tabs . update ( tabId , { active : true , highlighted : false } ) ;
322
370
updateSearchBar ( ) ;
323
371
324
- tabList . querySelector ( '.active' ) ?. classList . remove ( 'active' ) ;
325
- document . querySelector ( '[aria-label="favopen"]' ) ?. setAttribute ( 'aria-label' , '' ) ;
326
-
327
372
activeTabId = tabId ;
328
- tabList . querySelector ( `[data-tab-id="${ activeTabId } "]` ) ?. classList . add ( 'active' ) ;
329
373
330
374
e . currentTarget . classList . add ( 'current-tab' ) ;
331
375
} ;
@@ -359,10 +403,10 @@ function favoriteDrop() {
359
403
if ( ! tabtoPin . url . startsWith ( 'about:' ) ) {
360
404
favoritesg [ i ] = { url : tabtoPin . url , favicon : tabtoPin . favIconUrl , id : i }
361
405
openedFavorites [ i ] = tabtoPin . id
362
- renderItems ( base ) ;
363
406
browser . storage . local . set ( {
364
407
favorites : favoritesg
365
408
} ) ;
409
+ initTabSidebarControl ( ) ;
366
410
}
367
411
} )
368
412
}
@@ -374,51 +418,44 @@ favoriteDiv.addEventListener('dragover', favoriteDragOver);
374
418
favoriteDiv . addEventListener ( 'drop' , favoriteDrop ) ;
375
419
376
420
function loadFavorites ( ) {
421
+ favoriteDiv . innerHTML = "" ;
377
422
// Render
378
423
favorites . forEach ( async ( favorite ) => {
379
424
if ( favorite !== undefined ) {
380
425
const element = document . createElement ( 'button' )
381
- element . className = "favorite"
382
- element . dataset . url = favorite . url ;
383
426
if ( openedFavorites [ favorite . id ] && ( await browser . tabs . get ( openedFavorites [ favorite . id ] ) ) ?. active ) {
384
- element . ariaLabel = 'favopen' ;
427
+ element . dataset . tabId = openedFavorites [ favorite . id ] ;
428
+ element . classList . add ( 'active' )
385
429
}
386
430
element . onclick = async ( ) => {
387
431
if ( ! openedFavorites [ favorite . id ] ) {
388
- const tabCreated = await browser . tabs . create ( { url : element . dataset . url } ) ;
432
+ const tabCreated = await browser . tabs . create ( { url : favorite . url } ) ;
389
433
openedFavorites [ favorite . id ] = tabCreated . id ;
390
434
} else {
391
- tabList . querySelector ( '.active' ) ?. classList . remove ( 'active' ) ;
392
435
browser . tabs . update ( openedFavorites [ favorite . id ] , { active : true } ) ;
393
436
}
394
- document . querySelectorAll ( '[aria-label="favopen"]' ) ?. forEach ( ( elemento ) => {
395
- elemento . ariaLabel = "" ;
396
- } )
397
- element . ariaLabel = "favopen" ;
398
- updateSearchBar ( ) ;
437
+ element . dataset . tabId = openedFavorites [ favorite . id ] ;
438
+ element . classList . add ( 'active' )
399
439
}
400
- element . onauxclick = async ( event ) => {
440
+ element . onauxclick = ( event ) => {
401
441
if ( event . button == 1 && openedFavorites [ favorite . id ] ) {
402
442
// Unload favorite
403
443
browser . tabs . remove ( openedFavorites [ favorite . id ] )
404
444
openedFavorites [ favorite . id ] = undefined
405
445
element . ariaLabel = ""
406
446
} else if ( event . button == 2 ) {
407
447
// Remove favorite
408
- initTabSidebarControl ( ) ;
409
- if ( openedFavorites [ favorite . id ] ) {
410
- delete openedFavorites [ favorite . id ] ;
411
- }
448
+ delete openedFavorites [ favorite . id ] ;
412
449
browser . storage . local . get ( 'favorites' , function ( result ) {
413
450
var favoritesg = result . favorites ;
414
451
delete favoritesg [ favorite . id ]
415
- favoriteDiv . innerHTML = "" ;
416
452
favorites = favoritesg
417
453
loadFavorites ( ) ;
418
454
browser . storage . local . set ( {
419
455
favorites : favoritesg
420
456
} ) ;
421
457
} )
458
+ initTabSidebarControl ( ) ;
422
459
}
423
460
}
424
461
@@ -429,8 +466,8 @@ function loadFavorites() {
429
466
430
467
favoriteDiv . appendChild ( element ) ;
431
468
}
432
- updateSearchBar ( ) ;
433
469
} ) ;
470
+ updateSearchBar ( ) ;
434
471
}
435
472
436
473
// Look for updates
@@ -440,7 +477,6 @@ browser.storage.onChanged.addListener(() => {
440
477
if ( JSON . stringify ( favoritesg ) !== JSON . stringify ( favorites ) ) {
441
478
favoritesg . forEach ( fav => {
442
479
if ( fav ?. url !== favorites [ fav . id ] ?. url ) {
443
- favoriteDiv . innerHTML = "" ;
444
480
favorites = favoritesg
445
481
loadFavorites ( ) ;
446
482
}
@@ -460,16 +496,7 @@ function initTabSidebarControl() {
460
496
init ( tabs ) ;
461
497
activeTabId = tabs . find ( ( tab ) => tab . active ) . id ;
462
498
renderItems ( base ) ;
463
- } ) ;
464
-
465
- browser . tabs . onUpdated . addListener ( ( tabId , changeInfo , tab ) => {
466
- const index = base . findIndex ( ( t ) => t . id === tabId ) ;
467
- if ( index !== - 1 ) {
468
- base [ index ] . title = tab . title ;
469
- base [ index ] . favIconUrl = tab . favIconUrl ;
470
- renderItems ( base ) ;
471
- updateSearchBar ( ) ;
472
- }
499
+ updateSearchBar ( ) ;
473
500
} ) ;
474
501
}
475
502
0 commit comments