3030
3131/******************************************************************************/
3232
33+ // Adjust top padding of content table, to match that of toolbar height.
34+
35+ document . getElementById ( 'content' ) . style . setProperty (
36+ 'margin-top' ,
37+ document . getElementById ( 'toolbar' ) . offsetHeight + 'px'
38+ ) ;
39+
40+ /******************************************************************************/
41+
3342var messager = vAPI . messaging . channel ( 'logger-ui.js' ) ;
3443var tbody = document . querySelector ( '#content tbody' ) ;
3544var trJunkyard = [ ] ;
@@ -40,6 +49,8 @@ var maxEntries = 5000;
4049var noTabId = '' ;
4150var allTabIds = { } ;
4251
52+ var hiddenTemplate = document . querySelector ( '#hiddenTemplate > span' ) ;
53+
4354var prettyRequestTypes = {
4455 'main_frame' : 'doc' ,
4556 'stylesheet' : 'css' ,
@@ -61,6 +72,18 @@ var dateOptions = {
6172
6273/******************************************************************************/
6374
75+ var classNameFromTabId = function ( tabId ) {
76+ if ( tabId === noTabId ) {
77+ return 'tab_bts' ;
78+ }
79+ if ( tabId !== '' ) {
80+ return 'tab_' + tabId ;
81+ }
82+ return '' ;
83+ } ;
84+
85+ /******************************************************************************/
86+
6487// Emphasize hostname in URL, as this is what matters in uMatrix's rules.
6588
6689var nodeFromURL = function ( url , filter ) {
@@ -165,6 +188,14 @@ var createRow = function(layout) {
165188
166189/******************************************************************************/
167190
191+ var createHiddenTextNode = function ( text ) {
192+ var node = hiddenTemplate . cloneNode ( true ) ;
193+ node . textContent = text ;
194+ return node ;
195+ } ;
196+
197+ /******************************************************************************/
198+
168199var createGap = function ( tabId , url ) {
169200 var tr = createRow ( '1' ) ;
170201 tr . classList . add ( 'tab' ) ;
@@ -246,11 +277,9 @@ var renderLogEntry = function(entry) {
246277 tr . cells [ 0 ] . title = time . toLocaleDateString ( 'fullwide' , dateOptions ) ;
247278
248279 if ( entry . tab ) {
249- tr . classList . add ( 'tab' ) ;
280+ tr . classList . add ( 'tab' , classNameFromTabId ( entry . tab ) ) ;
250281 if ( entry . tab === noTabId ) {
251- tr . classList . add ( 'tab_bts' ) ;
252- } else if ( entry . tab !== '' ) {
253- tr . classList . add ( 'tab_' + entry . tab ) ;
282+ tr . cells [ 1 ] . appendChild ( createHiddenTextNode ( 'bts' ) ) ;
254283 }
255284 }
256285 if ( entry . cat !== '' ) {
@@ -316,6 +345,78 @@ var renderLogEntries = function(response) {
316345
317346/******************************************************************************/
318347
348+ var synchronizeTabIds = function ( newTabIds ) {
349+ var oldTabIds = allTabIds ;
350+
351+ // Neuter rows for which a tab does not exist anymore
352+ // TODO: sort to avoid using indexOf
353+
354+ var autoDeleteVoidRows = ! ! vAPI . localStorage . getItem ( 'loggerAutoDeleteVoidRows' ) ;
355+ var rowVoided = false ;
356+ var trs ;
357+ for ( var tabId in oldTabIds ) {
358+ if ( oldTabIds . hasOwnProperty ( tabId ) === false ) {
359+ continue ;
360+ }
361+ if ( newTabIds . hasOwnProperty ( tabId ) ) {
362+ continue ;
363+ }
364+ // Mark or remove voided rows
365+ trs = uDom ( '.tab_' + tabId ) ;
366+ if ( autoDeleteVoidRows ) {
367+ toJunkyard ( trs ) ;
368+ } else {
369+ trs . removeClass ( 'canMtx' ) ;
370+ rowVoided = true ;
371+ }
372+ // Remove popup if it is currently bound to a removed tab.
373+ if ( tabId === popupManager . tabId ) {
374+ popupManager . toggleOff ( ) ;
375+ }
376+ }
377+
378+ var select = document . getElementById ( 'pageSelector' ) ;
379+ var selectValue = select . value ;
380+ var tabIds = Object . keys ( newTabIds ) . sort ( function ( a , b ) {
381+ return newTabIds [ a ] . localeCompare ( newTabIds [ b ] ) ;
382+ } ) ;
383+ var option ;
384+ for ( var i = 0 , j = 2 ; i < tabIds . length ; i ++ ) {
385+ tabId = tabIds [ i ] ;
386+ if ( tabId === noTabId ) {
387+ continue ;
388+ }
389+ option = select . options [ j ] ;
390+ j += 1 ;
391+ if ( ! option ) {
392+ option = document . createElement ( 'option' ) ;
393+ select . appendChild ( option ) ;
394+ }
395+ option . textContent = newTabIds [ tabId ] ;
396+ option . value = classNameFromTabId ( tabId ) ;
397+ if ( option . value === selectValue ) {
398+ option . setAttribute ( 'selected' , '' ) ;
399+ } else {
400+ option . removeAttribute ( 'selected' ) ;
401+ }
402+ }
403+ while ( j < select . options . length ) {
404+ select . removeChild ( select . options [ j ] ) ;
405+ }
406+ if ( select . value !== selectValue ) {
407+ select . selectedIndex = 0 ;
408+ select . value = '' ;
409+ select . options [ 0 ] . setAttribute ( 'selected' , '' ) ;
410+ pageSelectorChanged ( ) ;
411+ }
412+
413+ allTabIds = newTabIds ;
414+
415+ return rowVoided ;
416+ } ;
417+
418+ /******************************************************************************/
419+
319420var truncateLog = function ( size ) {
320421 if ( size === 0 ) {
321422 size = 5000 ;
@@ -343,28 +444,7 @@ var onLogBufferRead = function(response) {
343444
344445 // Neuter rows for which a tab does not exist anymore
345446 // TODO: sort to avoid using indexOf
346- var autoDeleteVoidRows = vAPI . localStorage . getItem ( 'loggerAutoDeleteVoidRows' ) ;
347- var rowVoided = false , trs ;
348- for ( var tabId in allTabIds ) {
349- if ( allTabIds . hasOwnProperty ( tabId ) === false ) {
350- continue ;
351- }
352- if ( response . tabIds . hasOwnProperty ( tabId ) ) {
353- continue ;
354- }
355- trs = uDom ( '.tab_' + tabId ) ;
356- if ( autoDeleteVoidRows ) {
357- toJunkyard ( trs ) ;
358- } else {
359- trs . removeClass ( 'canMtx' ) ;
360- rowVoided = true ;
361- }
362- if ( tabId === popupManager . tabId ) {
363- popupManager . toggleOff ( ) ;
364- }
365- }
366- allTabIds = response . tabIds ;
367-
447+ var rowVoided = synchronizeTabIds ( response . tabIds ) ;
368448 renderLogEntries ( response ) ;
369449
370450 if ( rowVoided ) {
@@ -395,6 +475,41 @@ var readLogBuffer = function() {
395475
396476/******************************************************************************/
397477
478+ var pageSelectorChanged = function ( ) {
479+ var style = document . getElementById ( 'tabFilterer' ) ;
480+ var tabClass = document . getElementById ( 'pageSelector' ) . value ;
481+ var sheet = style . sheet ;
482+ while ( sheet . cssRules . length !== 0 ) {
483+ sheet . deleteRule ( 0 ) ;
484+ }
485+ if ( tabClass !== '' ) {
486+ sheet . insertRule (
487+ '#content table tr:not(.' + tabClass + ') { display: none; }' ,
488+ 0
489+ ) ;
490+ }
491+ uDom ( '#refresh' ) . toggleClass (
492+ 'disabled' ,
493+ tabClass === '' || tabClass === 'tab_bts'
494+ ) ;
495+ } ;
496+
497+ /******************************************************************************/
498+
499+ var reloadTab = function ( ) {
500+ var tabClass = document . getElementById ( 'pageSelector' ) . value ;
501+ var matches = tabClass . match ( / ^ t a b _ ( .+ ) $ / ) ;
502+ if ( matches === null ) {
503+ return ;
504+ }
505+ if ( matches [ 1 ] === 'bts' ) {
506+ return ;
507+ }
508+ messager . send ( { what : 'reloadTab' , tabId : matches [ 1 ] } ) ;
509+ } ;
510+
511+ /******************************************************************************/
512+
398513var onMaxEntriesChanged = function ( ) {
399514 var raw = uDom ( this ) . val ( ) ;
400515 try {
@@ -649,7 +764,7 @@ var popupManager = (function() {
649764 popupObserver = new MutationObserver ( resizePopup ) ;
650765 container . appendChild ( popup ) ;
651766
652- style = document . querySelector ( '#content > style ') ;
767+ style = document . getElementById ( 'popupFilterer ') ;
653768 style . textContent = styleTemplate . replace ( '{{tabId}}' , localTabId ) ;
654769
655770 document . body . classList . add ( 'popupOn' ) ;
@@ -701,6 +816,8 @@ var popupManager = (function() {
701816uDom . onLoad ( function ( ) {
702817 readLogBuffer ( ) ;
703818
819+ uDom ( '#pageSelector' ) . on ( 'change' , pageSelectorChanged ) ;
820+ uDom ( '#refresh' ) . on ( 'click' , reloadTab ) ;
704821 uDom ( '#compactViewToggler' ) . on ( 'click' , toggleCompactView ) ;
705822 uDom ( '#clean' ) . on ( 'click' , cleanBuffer ) ;
706823 uDom ( '#clear' ) . on ( 'click' , clearBuffer ) ;
0 commit comments