123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910 |
- /*******************************************************************************
- ηMatrix - a browser extension to black/white list requests.
- Copyright (C) 2015-2019 Raymond Hill
- Copyright (C) 2019 Alessio Vanni
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see {http://www.gnu.org/licenses/}.
- Home: https://libregit.org/heckyel/ematrix
- uMatrix Home: https://github.com/gorhill/sessbench
- */
- /* global uDom */
- 'use strict';
- /******************************************************************************/
- (function() {
- /******************************************************************************/
- var tbody = document.querySelector('#content tbody');
- var trJunkyard = [];
- var tdJunkyard = [];
- var firstVarDataCol = 2; // currently, column 2 (0-based index)
- var lastVarDataIndex = 3; // currently, d0-d3
- var maxEntries = 0;
- var noTabId = '';
- var allTabIds = {};
- var allTabIdsToken;
- var ownerId = Date.now();
- var emphasizeTemplate = document.querySelector('#emphasizeTemplate > span');
- var hiddenTemplate = document.querySelector('#hiddenTemplate > span');
- var prettyRequestTypes = {
- 'main_frame': 'doc',
- 'stylesheet': 'css',
- 'sub_frame': 'frame',
- 'xmlhttprequest': 'xhr'
- };
- var dontEmphasizeSet = new Set([
- 'COOKIE',
- 'CSP',
- 'REFERER'
- ]);
- /******************************************************************************/
- // Adjust top padding of content table, to match that of toolbar height.
- document.getElementById('content').style.setProperty(
- 'margin-top',
- document.getElementById('toolbar').clientHeight + 'px'
- );
- /******************************************************************************/
- var classNameFromTabId = function(tabId) {
- if ( tabId === noTabId ) {
- return 'tab_bts';
- }
- if ( tabId !== '' ) {
- return 'tab_' + tabId;
- }
- return '';
- };
- /******************************************************************************/
- // Emphasize hostname and cookie name.
- var emphasizeCookie = function(s) {
- var pnode = emphasizeHostname(s);
- if ( pnode.childNodes.length !== 3 ) {
- return pnode;
- }
- var prefix = '-cookie:';
- var text = pnode.childNodes[2].textContent;
- var beg = text.indexOf(prefix);
- if ( beg === -1 ) {
- return pnode;
- }
- beg += prefix.length;
- var end = text.indexOf('}', beg);
- if ( end === -1 ) {
- return pnode;
- }
- var cnode = emphasizeTemplate.cloneNode(true);
- cnode.childNodes[0].textContent = text.slice(0, beg);
- cnode.childNodes[1].textContent = text.slice(beg, end);
- cnode.childNodes[2].textContent = text.slice(end);
- pnode.replaceChild(cnode.childNodes[0], pnode.childNodes[2]);
- pnode.appendChild(cnode.childNodes[0]);
- pnode.appendChild(cnode.childNodes[0]);
- return pnode;
- };
- /******************************************************************************/
- // Emphasize hostname in URL.
- var emphasizeHostname = function(url) {
- var hnbeg = url.indexOf('://');
- if ( hnbeg === -1 ) {
- return document.createTextNode(url);
- }
- hnbeg += 3;
- var hnend = url.indexOf('/', hnbeg);
- if ( hnend === -1 ) {
- hnend = url.slice(hnbeg).search(/\?#/);
- if ( hnend !== -1 ) {
- hnend += hnbeg;
- } else {
- hnend = url.length;
- }
- }
- var node = emphasizeTemplate.cloneNode(true);
- node.childNodes[0].textContent = url.slice(0, hnbeg);
- node.childNodes[1].textContent = url.slice(hnbeg, hnend);
- node.childNodes[2].textContent = url.slice(hnend);
- return node;
- };
- /******************************************************************************/
- var createCellAt = function(tr, index) {
- var td = tr.cells[index];
- var mustAppend = !td;
- if ( mustAppend ) {
- td = tdJunkyard.pop();
- }
- if ( td ) {
- td.removeAttribute('colspan');
- td.textContent = '';
- } else {
- td = document.createElement('td');
- }
- if ( mustAppend ) {
- tr.appendChild(td);
- }
- return td;
- };
- /******************************************************************************/
- var createRow = function(layout) {
- var tr = trJunkyard.pop();
- if ( tr ) {
- tr.className = '';
- } else {
- tr = document.createElement('tr');
- }
- for ( var index = 0; index < firstVarDataCol; index++ ) {
- createCellAt(tr, index);
- }
- var i = 1, span = 1, td;
- for (;;) {
- td = createCellAt(tr, index);
- if ( i === lastVarDataIndex ) {
- break;
- }
- if ( layout.charAt(i) !== '1' ) {
- span += 1;
- } else {
- if ( span !== 1 ) {
- td.setAttribute('colspan', span);
- }
- index += 1;
- span = 1;
- }
- i += 1;
- }
- if ( span !== 1 ) {
- td.setAttribute('colspan', span);
- }
- index += 1;
- while ( (td = tr.cells[index]) ) {
- tdJunkyard.push(tr.removeChild(td));
- }
- return tr;
- };
- /******************************************************************************/
- var createHiddenTextNode = function(text) {
- var node = hiddenTemplate.cloneNode(true);
- node.textContent = text;
- return node;
- };
- /******************************************************************************/
- var padTo2 = function(v) {
- return v < 10 ? '0' + v : v;
- };
- /******************************************************************************/
- var createGap = function(tabId, url) {
- var tr = createRow('1');
- tr.classList.add('doc');
- tr.classList.add('tab');
- tr.classList.add('canMtx');
- tr.classList.add('tab_' + tabId);
- tr.cells[firstVarDataCol].textContent = url;
- tbody.insertBefore(tr, tbody.firstChild);
- };
- /******************************************************************************/
- var renderLogEntry = function(entry) {
- var tr;
- var fvdc = firstVarDataCol;
- switch ( entry.cat ) {
- case 'error':
- case 'info':
- tr = createRow('1');
- if ( entry.d0 === 'cookie' ) {
- tr.cells[fvdc].appendChild(emphasizeCookie(entry.d1));
- } else {
- tr.cells[fvdc].textContent = entry.d0;
- }
- break;
- case 'net':
- tr = createRow('111');
- tr.classList.add('canMtx');
- // If the request is that of a root frame, insert a gap in the table
- // in order to visually separate entries for different documents.
- if ( entry.d2 === 'doc' && entry.tab !== noTabId ) {
- createGap(entry.tab, entry.d1);
- }
- if ( entry.d3 ) {
- tr.classList.add('blocked');
- tr.cells[fvdc].textContent = '--';
- } else {
- tr.cells[fvdc].textContent = '';
- }
- tr.cells[fvdc+1].textContent = (prettyRequestTypes[entry.d2] || entry.d2);
- if ( dontEmphasizeSet.has(entry.d2) ) {
- tr.cells[fvdc+2].textContent = entry.d1;
- } else if ( entry.d2 === 'cookie' ) {
- tr.cells[fvdc+2].appendChild(emphasizeCookie(entry.d1));
- } else {
- tr.cells[fvdc+2].appendChild(emphasizeHostname(entry.d1));
- }
- break;
- default:
- tr = createRow('1');
- tr.cells[fvdc].textContent = entry.d0;
- break;
- }
- // Fields common to all rows.
- var time = logDate;
- time.setTime(entry.tstamp - logDateTimezoneOffset);
- tr.cells[0].textContent = padTo2(time.getUTCHours()) + ':' +
- padTo2(time.getUTCMinutes()) + ':' +
- padTo2(time.getSeconds());
- if ( entry.tab ) {
- tr.classList.add('tab');
- tr.classList.add(classNameFromTabId(entry.tab));
- if ( entry.tab === noTabId ) {
- tr.cells[1].appendChild(createHiddenTextNode('bts'));
- }
- }
- if ( entry.cat !== '' ) {
- tr.classList.add('cat_' + entry.cat);
- }
- rowFilterer.filterOne(tr, true);
- tbody.insertBefore(tr, tbody.firstChild);
- };
- // Reuse date objects.
- var logDate = new Date(),
- logDateTimezoneOffset = logDate.getTimezoneOffset() * 60000;
- /******************************************************************************/
- var renderLogEntries = function(response) {
- var entries = response.entries;
- if ( entries.length === 0 ) {
- return;
- }
- // Preserve scroll position
- var height = tbody.offsetHeight;
- var tabIds = response.tabIds;
- var n = entries.length;
- var entry;
- for ( var i = 0; i < n; i++ ) {
- entry = entries[i];
- // Unlikely, but it may happen
- if ( entry.tab && tabIds.hasOwnProperty(entry.tab) === false ) {
- continue;
- }
- renderLogEntry(entries[i]);
- }
- // Prevent logger from growing infinitely and eating all memory. For
- // instance someone could forget that it is left opened for some
- // dynamically refreshed pages.
- truncateLog(maxEntries);
- var yDelta = tbody.offsetHeight - height;
- if ( yDelta === 0 ) {
- return;
- }
- // Chromium:
- // body.scrollTop = good value
- // body.parentNode.scrollTop = 0
- if ( document.body.scrollTop !== 0 ) {
- document.body.scrollTop += yDelta;
- return;
- }
- // Firefox:
- // body.scrollTop = 0
- // body.parentNode.scrollTop = good value
- var parentNode = document.body.parentNode;
- if ( parentNode && parentNode.scrollTop !== 0 ) {
- parentNode.scrollTop += yDelta;
- }
- };
- /******************************************************************************/
- var synchronizeTabIds = function(newTabIds) {
- var oldTabIds = allTabIds;
- var autoDeleteVoidRows = !!vAPI.localStorage.getItem('loggerAutoDeleteVoidRows');
- var rowVoided = false;
- var trs;
- for ( var tabId in oldTabIds ) {
- if ( oldTabIds.hasOwnProperty(tabId) === false ) {
- continue;
- }
- if ( newTabIds.hasOwnProperty(tabId) ) {
- continue;
- }
- // Mark or remove voided rows
- trs = uDom('.tab_' + tabId);
- if ( autoDeleteVoidRows ) {
- toJunkyard(trs);
- } else {
- trs.removeClass('canMtx');
- rowVoided = true;
- }
- // Remove popup if it is currently bound to a removed tab.
- if ( tabId === popupManager.tabId ) {
- popupManager.toggleOff();
- }
- }
- var select = document.getElementById('pageSelector');
- var selectValue = select.value;
- var tabIds = Object.keys(newTabIds).sort(function(a, b) {
- return newTabIds[a].localeCompare(newTabIds[b]);
- });
- var option;
- for ( var i = 0, j = 2; i < tabIds.length; i++ ) {
- tabId = tabIds[i];
- if ( tabId === noTabId ) {
- continue;
- }
- option = select.options[j];
- j += 1;
- if ( !option ) {
- option = document.createElement('option');
- select.appendChild(option);
- }
- option.textContent = newTabIds[tabId];
- option.value = classNameFromTabId(tabId);
- if ( option.value === selectValue ) {
- option.setAttribute('selected', '');
- } else {
- option.removeAttribute('selected');
- }
- }
- while ( j < select.options.length ) {
- select.removeChild(select.options[j]);
- }
- if ( select.value !== selectValue ) {
- select.selectedIndex = 0;
- select.value = '';
- select.options[0].setAttribute('selected', '');
- pageSelectorChanged();
- }
- allTabIds = newTabIds;
- return rowVoided;
- };
- /******************************************************************************/
- var truncateLog = function(size) {
- if ( size === 0 ) {
- size = 5000;
- }
- var tbody = document.querySelector('#content tbody');
- size = Math.min(size, 10000);
- var tr;
- while ( tbody.childElementCount > size ) {
- tr = tbody.lastElementChild;
- trJunkyard.push(tbody.removeChild(tr));
- }
- };
- /******************************************************************************/
- var onLogBufferRead = function(response) {
- if ( !response || response.unavailable ) {
- readLogBufferAsync();
- return;
- }
- // This tells us the behind-the-scene tab id
- noTabId = response.noTabId;
- // This may have changed meanwhile
- if ( response.maxLoggedRequests !== maxEntries ) {
- maxEntries = response.maxLoggedRequests;
- uDom('#maxEntries').val(maxEntries || '');
- }
- // Neuter rows for which a tab does not exist anymore
- var rowVoided = false;
- if ( response.tabIdsToken !== allTabIdsToken ) {
- rowVoided = synchronizeTabIds(response.tabIds);
- allTabIdsToken = response.tabIdsToken;
- }
- renderLogEntries(response);
- if ( rowVoided ) {
- uDom('#clean').toggleClass(
- 'disabled',
- tbody.querySelector('tr.tab:not(.canMtx)') === null
- );
- }
- // Synchronize toolbar with content of log
- uDom('#clear').toggleClass(
- 'disabled',
- tbody.querySelector('tr') === null
- );
- readLogBufferAsync();
- };
- /******************************************************************************/
- // This can be called only once, at init time. After that, this will be called
- // automatically. If called after init time, this will be messy, and this would
- // require a bit more code to ensure no multi time out events.
- var readLogBuffer = function() {
- if ( ownerId === undefined ) { return; }
- vAPI.messaging.send(
- 'logger-ui.js',
- { what: 'readMany', ownerId: ownerId },
- onLogBufferRead
- );
- };
- var readLogBufferAsync = function() {
- if ( ownerId === undefined ) { return; }
- vAPI.setTimeout(readLogBuffer, 1200);
- };
- /******************************************************************************/
- var pageSelectorChanged = function() {
- var style = document.getElementById('tabFilterer');
- var tabClass = document.getElementById('pageSelector').value;
- var sheet = style.sheet;
- while ( sheet.cssRules.length !== 0 ) {
- sheet.deleteRule(0);
- }
- if ( tabClass !== '' ) {
- sheet.insertRule(
- '#content table tr:not(.' + tabClass + ') { display: none; }',
- 0
- );
- }
- uDom('#refresh').toggleClass(
- 'disabled',
- tabClass === '' || tabClass === 'tab_bts'
- );
- };
- /******************************************************************************/
- var refreshTab = function() {
- var tabClass = document.getElementById('pageSelector').value;
- var matches = tabClass.match(/^tab_(.+)$/);
- if ( matches === null ) {
- return;
- }
- if ( matches[1] === 'bts' ) {
- return;
- }
- vAPI.messaging.send(
- 'logger-ui.js',
- { what: 'forceReloadTab', tabId: matches[1] }
- );
- };
- /******************************************************************************/
- var onMaxEntriesChanged = function() {
- var raw = uDom(this).val();
- try {
- maxEntries = parseInt(raw, 10);
- if ( isNaN(maxEntries) ) {
- maxEntries = 0;
- }
- } catch (e) {
- maxEntries = 0;
- }
- vAPI.messaging.send('logger-ui.js', {
- what: 'userSettings',
- name: 'maxLoggedRequests',
- value: maxEntries
- });
- truncateLog(maxEntries);
- };
- /******************************************************************************/
- var rowFilterer = (function() {
- var filters = [];
- var parseInput = function() {
- filters = [];
- var rawPart, hardBeg, hardEnd;
- var raw = uDom('#filterInput').val().trim();
- var rawParts = raw.split(/\s+/);
- var reStr, reStrs = [], not = false;
- var n = rawParts.length;
- for ( var i = 0; i < n; i++ ) {
- rawPart = rawParts[i];
- if ( rawPart.charAt(0) === '!' ) {
- if ( reStrs.length === 0 ) {
- not = true;
- }
- rawPart = rawPart.slice(1);
- }
- hardBeg = rawPart.charAt(0) === '|';
- if ( hardBeg ) {
- rawPart = rawPart.slice(1);
- }
- hardEnd = rawPart.slice(-1) === '|';
- if ( hardEnd ) {
- rawPart = rawPart.slice(0, -1);
- }
- if ( rawPart === '' ) {
- continue;
- }
- // https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions
- reStr = rawPart.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
- if ( hardBeg ) {
- reStr = '(?:^|\\s)' + reStr;
- }
- if ( hardEnd ) {
- reStr += '(?:\\s|$)';
- }
- reStrs.push(reStr);
- if ( i < (n - 1) && rawParts[i + 1] === '||' ) {
- i += 1;
- continue;
- }
- reStr = reStrs.length === 1 ? reStrs[0] : reStrs.join('|');
- filters.push({
- re: new RegExp(reStr, 'i'),
- r: !not
- });
- reStrs = [];
- not = false;
- }
- };
- var filterOne = function(tr, clean) {
- var ff = filters;
- var fcount = ff.length;
- if ( fcount === 0 && clean === true ) {
- return;
- }
- // do not filter out doc boundaries, they help separate important
- // section of log.
- var cl = tr.classList;
- if ( cl.contains('doc') ) {
- return;
- }
- if ( fcount === 0 ) {
- cl.remove('f');
- return;
- }
- var cc = tr.cells;
- var ccount = cc.length;
- var hit, j, f;
- // each filter expression must hit (implicit and-op)
- // if...
- // positive filter expression = there must one hit on any field
- // negative filter expression = there must be no hit on all fields
- for ( var i = 0; i < fcount; i++ ) {
- f = ff[i];
- hit = !f.r;
- for ( j = 0; j < ccount; j++ ) {
- if ( f.re.test(cc[j].textContent) ) {
- hit = f.r;
- break;
- }
- }
- if ( !hit ) {
- cl.add('f');
- return;
- }
- }
- cl.remove('f');
- };
- var filterAll = function() {
- // Special case: no filter
- if ( filters.length === 0 ) {
- uDom('#content tr').removeClass('f');
- return;
- }
- var tbody = document.querySelector('#content tbody');
- var rows = tbody.rows;
- var i = rows.length;
- while ( i-- ) {
- filterOne(rows[i]);
- }
- };
- var onFilterChangedAsync = (function() {
- var timer = null;
- var commit = function() {
- timer = null;
- parseInput();
- filterAll();
- };
- return function() {
- if ( timer !== null ) {
- clearTimeout(timer);
- }
- timer = vAPI.setTimeout(commit, 750);
- };
- })();
- var onFilterButton = function() {
- var cl = document.body.classList;
- cl.toggle('f', cl.contains('f') === false);
- };
- uDom('#filterButton').on('click', onFilterButton);
- uDom('#filterInput').on('input', onFilterChangedAsync);
- return {
- filterOne: filterOne,
- filterAll: filterAll
- };
- })();
- /******************************************************************************/
- var toJunkyard = function(trs) {
- trs.remove();
- var i = trs.length;
- while ( i-- ) {
- trJunkyard.push(trs.nodeAt(i));
- }
- };
- /******************************************************************************/
- var clearBuffer = function() {
- var tbody = document.querySelector('#content tbody');
- var tr;
- while ( tbody.firstChild !== null ) {
- tr = tbody.lastElementChild;
- trJunkyard.push(tbody.removeChild(tr));
- }
- uDom('#clear').addClass('disabled');
- uDom('#clean').addClass('disabled');
- };
- /******************************************************************************/
- var cleanBuffer = function() {
- var rows = uDom('#content tr.tab:not(.canMtx)').remove();
- var i = rows.length;
- while ( i-- ) {
- trJunkyard.push(rows.nodeAt(i));
- }
- uDom('#clean').addClass('disabled');
- };
- /******************************************************************************/
- var toggleCompactView = function() {
- document.body.classList.toggle('compactView');
- uDom('#content table .vExpanded').removeClass('vExpanded');
- };
- var toggleCompactRow = function(ev) {
- ev.target.parentElement.classList.toggle('vExpanded');
- };
- /******************************************************************************/
- var popupManager = (function() {
- var realTabId = null;
- var localTabId = null;
- var container = null;
- var popup = null;
- var popupObserver = null;
- var style = null;
- var styleTemplate = [
- 'tr:not(.tab_{{tabId}}) {',
- 'cursor: not-allowed;',
- 'opacity: 0.2;',
- '}'
- ].join('\n');
- var resizePopup = function() {
- if ( popup === null ) {
- return;
- }
- var popupBody = popup.contentWindow.document.body;
- if ( popupBody.clientWidth !== 0 && container.clientWidth !== popupBody.clientWidth ) {
- container.style.setProperty('width', popupBody.clientWidth + 'px');
- }
- popup.style.removeProperty('height');
- if ( popupBody.clientHeight !== 0 && popup.clientHeight !== popupBody.clientHeight ) {
- popup.style.setProperty('height', popupBody.clientHeight + 'px');
- }
- var ph = document.documentElement.clientHeight;
- var crect = container.getBoundingClientRect();
- if ( crect.height > ph ) {
- popup.style.setProperty('height', 'calc(' + ph + 'px - 1.8em)');
- }
- // Adjust width for presence/absence of vertical scroll bar which may
- // have appeared as a result of last operation.
- var cw = container.clientWidth;
- var dw = popup.contentWindow.document.documentElement.clientWidth;
- if ( cw !== dw ) {
- container.style.setProperty('width', (2 * cw - dw) + 'px');
- }
- };
- var toggleSize = function() {
- container.classList.toggle('hide');
- };
- var onResizeRequested = function() {
- var popupBody = popup.contentWindow.document.body;
- if ( popupBody.hasAttribute('data-resize-popup') === false ) {
- return;
- }
- popupBody.removeAttribute('data-resize-popup');
- resizePopup();
- };
- var onLoad = function() {
- resizePopup();
- var popupBody = popup.contentDocument.body;
- popupBody.removeAttribute('data-resize-popup');
- popupObserver.observe(popupBody, {
- attributes: true,
- attributesFilter: [ 'data-resize-popup' ]
- });
- };
- var toggleOn = function(td) {
- var tr = td.parentNode;
- var matches = tr.className.match(/(?:^| )tab_([^ ]+)/);
- if ( matches === null ) {
- return;
- }
- realTabId = localTabId = matches[1];
- if ( localTabId === 'bts' ) {
- realTabId = noTabId;
- }
- container = document.getElementById('popupContainer');
- container.querySelector('div > span:nth-of-type(1)').addEventListener('click', toggleSize);
- container.querySelector('div > span:nth-of-type(2)').addEventListener('click', toggleOff);
- popup = document.createElement('iframe');
- popup.addEventListener('load', onLoad);
- popup.setAttribute('src', 'popup.html?tabId=' + realTabId);
- popupObserver = new MutationObserver(onResizeRequested);
- container.appendChild(popup);
- style = document.getElementById('popupFilterer');
- style.textContent = styleTemplate.replace('{{tabId}}', localTabId);
- document.body.classList.add('popupOn');
- };
- var toggleOff = function() {
- document.body.classList.remove('popupOn');
- container.querySelector('div > span:nth-of-type(1)').removeEventListener('click', toggleSize);
- container.querySelector('div > span:nth-of-type(2)').removeEventListener('click', toggleOff);
- container.classList.remove('hide');
- popup.removeEventListener('load', onLoad);
- popupObserver.disconnect();
- popupObserver = null;
- popup.setAttribute('src', '');
- container.removeChild(popup);
- popup = null;
- style.textContent = '';
- style = null;
- container = null;
- realTabId = null;
- };
- var exports = {
- toggleOn: function(ev) {
- if ( realTabId === null ) {
- toggleOn(ev.target);
- }
- },
- toggleOff: function() {
- if ( realTabId !== null ) {
- toggleOff();
- }
- }
- };
- Object.defineProperty(exports, 'tabId', {
- get: function() { return realTabId || 0; }
- });
- return exports;
- })();
- /******************************************************************************/
- var grabView = function() {
- if ( ownerId === undefined ) {
- ownerId = Date.now();
- }
- readLogBufferAsync();
- };
- var releaseView = function() {
- if ( ownerId === undefined ) { return; }
- vAPI.messaging.send(
- 'logger-ui.js',
- { what: 'releaseView', ownerId: ownerId }
- );
- ownerId = undefined;
- };
- window.addEventListener('pagehide', releaseView);
- window.addEventListener('pageshow', grabView);
- // https://bugzilla.mozilla.org/show_bug.cgi?id=1398625
- window.addEventListener('beforeunload', releaseView);
- /******************************************************************************/
- readLogBuffer();
- uDom('#pageSelector').on('change', pageSelectorChanged);
- uDom('#refresh').on('click', refreshTab);
- uDom('#compactViewToggler').on('click', toggleCompactView);
- uDom('#clean').on('click', cleanBuffer);
- uDom('#clear').on('click', clearBuffer);
- uDom('#maxEntries').on('change', onMaxEntriesChanged);
- uDom('#content table').on('click', 'tr > td:nth-of-type(1)', toggleCompactRow);
- uDom('#content table').on('click', 'tr.canMtx > td:nth-of-type(2)', popupManager.toggleOn);
- /******************************************************************************/
- })();
|