diff --git a/src/css/devtool-log.css b/src/css/devtool-log.css index 36557925b..913c46ed1 100644 --- a/src/css/devtool-log.css +++ b/src/css/devtool-log.css @@ -10,32 +10,35 @@ body { width: 100%; } #toolbar { - padding: 8px 0; + background-color: white; + border: 0; + box-sizing: border-box; + height: 36px; + margin: 0; + padding: 0; position: fixed; text-align: center; top: 0; - width: 4em; + width: 100%; } #toolbar .button { background-color: white; border: none; + box-sizing: border-box; cursor: pointer; - display: block; - font-size: large; + display: inline-block; + font-size: 20px; margin: 0; - padding: 0.5em 0; + padding: 8px; } #toolbar .button:hover { background-color: #eee; } +#toolbar #filterButton.off { + opacity: 0.25; + } #content { - width: calc(100% - 4em); - } -body[dir="ltr"] #content { - margin-left: 4em; - } -body[dir="rtl"] #content { - margin-right: 4em; + margin-top: 36px; } #content table { border: 0; @@ -55,6 +58,9 @@ body[dir="rtl"] #content { #content table tr.maindoc { background-color: #eee; } +#content table tr.hidden { + display: none; + } #content table tr td { border: 1px solid #ccc; padding: 3px; @@ -63,6 +69,7 @@ body[dir="rtl"] #content { #content table tr td:nth-of-type(1) { padding: 3px 0; text-align: center; + white-space: pre; } #content table tr td:nth-of-type(2) { white-space: normal; diff --git a/src/devtool-log.html b/src/devtool-log.html index 3b6ecd885..e97ac1e9a 100644 --- a/src/devtool-log.html +++ b/src/devtool-log.html @@ -10,7 +10,9 @@
-
+ +
+
diff --git a/src/js/devtool-log.js b/src/js/devtool-log.js index 29a8ae0df..31ba1f974 100644 --- a/src/js/devtool-log.js +++ b/src/js/devtool-log.js @@ -36,6 +36,7 @@ var doc = document; var body = doc.body; var tbody = doc.querySelector('#content tbody'); var rowJunkyard = []; +var reFilter = null; /******************************************************************************/ @@ -101,15 +102,15 @@ var renderLogEntry = function(entry) { var tr = createRow(); if ( entry.result.charAt(1) === 'b' ) { tr.classList.add('blocked'); - tr.cells[0].textContent = '\u2009\u2212\u2009'; + tr.cells[0].textContent = ' \u2212\u00A0'; } else if ( entry.result.charAt(1) === 'a' ) { tr.classList.add('allowed'); if ( entry.result.charAt(0) === 'm' ) { tr.classList.add('mirrored'); } - tr.cells[0].textContent = '\u2009+\u2009'; + tr.cells[0].textContent = ' +\u00A0'; } else { - tr.cells[0].textContent = '\u2009\u00A0\u2009'; + tr.cells[0].textContent = ' '; } if ( entry.type === 'main_frame' ) { tr.classList.add('maindoc'); @@ -118,9 +119,10 @@ var renderLogEntry = function(entry) { if ( entry.result.lastIndexOf('sa', 0) === 0 ) { filterText = '@@' + filterText; } - tr.cells[1].textContent = filterText; - tr.cells[2].textContent = entry.type; + tr.cells[1].textContent = filterText + ' '; + tr.cells[2].textContent = entry.type + ' '; vAPI.insertHTML(tr.cells[3], renderURL(entry.url, entry.result)); + applyFilterToRow(tr); tbody.insertBefore(tr, tbody.firstChild); }; @@ -196,6 +198,105 @@ var reloadTab = function() { /******************************************************************************/ +var applyFilterToRow = function(row) { + var re = reFilter; + if ( re === null || re.test(row.textContent) ) { + row.classList.remove('hidden'); + } else { + row.classList.add('hidden'); + } +}; + +/******************************************************************************/ + +var applyFilter = function() { + if ( reFilter === null ) { + unapplyFilter(); + return; + } + var row = document.querySelector('#content tr'); + if ( row === null ) { + return; + } + var re = reFilter; + while ( row !== null ) { + if ( re.test(row.textContent) ) { + row.classList.remove('hidden'); + } else { + row.classList.add('hidden'); + } + row = row.nextSibling; + } +}; + +/******************************************************************************/ + +var unapplyFilter = function() { + var row = document.querySelector('#content tr'); + if ( row === null ) { + return; + } + while ( row !== null ) { + row.classList.remove('hidden'); + row = row.nextSibling; + } +}; + +/******************************************************************************/ + +var onFilterButton = function() { + uDom('#filterButton').toggleClass('off'); + onFilterChanged(); +}; + +/******************************************************************************/ + +var onFilterChanged = function() { + var filterRaw = uDom('#filterButton').hasClass('off') ? + '' : + uDom('#filterExpression').val().trim(); + + if ( filterRaw === '') { + reFilter = null; + unapplyFilter(); + return; + } + + var filterParts = filterRaw + .replace(/^\s*-(\s+|$)/, '−\xA0') + .replace(/^\s*\\+(\s+|$)/, '\\+\xA0') + .split(/\s+/); + var n = filterParts.length; + for ( var i = 0; i < n; i++ ) { + filterParts[i] = filterParts[i].replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + } + reFilter = new RegExp(filterParts.join('.*\\s+.*')); + + applyFilter(); +}; + +/******************************************************************************/ + +var onFilterChangedAsync = (function() { + var timer = null; + + var commit = function() { + timer = null; + onFilterChanged(); + }; + + var changed = function() { + if ( timer !== null ) { + clearTimeout(timer); + } + timer = setTimeout(commit, 750); + }; + + return changed; +})(); + +/******************************************************************************/ + uDom.onLoad(function() { // Extract the tab id of the page we need to pull the log var matches = window.location.search.match(/[\?&]tabId=([^&]+)/); @@ -207,6 +308,8 @@ uDom.onLoad(function() { uDom('#reload').on('click', reloadTab); uDom('#clear').on('click', clearBuffer); + uDom('#filterButton').on('click', onFilterButton); + uDom('#filterExpression').on('input', onFilterChangedAsync); }); /******************************************************************************/