diff options
author | Jesús <heckyel@hyperbola.info> | 2019-12-30 15:55:13 -0500 |
---|---|---|
committer | Jesús <heckyel@hyperbola.info> | 2019-12-30 15:55:13 -0500 |
commit | 288df6a7bf8b933e2dc499e38f4915fcf974c14b (patch) | |
tree | 77bba994f260c064d3ee7f76c427ddfaa4f91710 /js/popup.js | |
parent | a2c9deaa145b780722e93b3899600f287c8094a4 (diff) | |
download | ematrix-288df6a7bf8b933e2dc499e38f4915fcf974c14b.tar.lz ematrix-288df6a7bf8b933e2dc499e38f4915fcf974c14b.tar.xz ematrix-288df6a7bf8b933e2dc499e38f4915fcf974c14b.zip |
backport
- Flush caches on upgrade
- Properly handle FrameModule's unloading
- Use the new module and remove the old implementation
Diffstat (limited to 'js/popup.js')
-rw-r--r-- | js/popup.js | 1134 |
1 files changed, 578 insertions, 556 deletions
diff --git a/js/popup.js b/js/popup.js index 2197c5c..a5a48d7 100644 --- a/js/popup.js +++ b/js/popup.js @@ -21,32 +21,28 @@ uMatrix Home: https://github.com/gorhill/uMatrix */ -/* global punycode, uDom */ -/* jshint esnext: true, bitwise: false */ - 'use strict'; -/******************************************************************************/ -/******************************************************************************/ - -(function() { +(function () { - /******************************************************************************/ - /******************************************************************************/ + Cu.import('chrome://ematrix/content/lib/Punycode.jsm'); // Stuff which is good to do very early so as to avoid visual glitches. - - (function() { - var paneContentPaddingTop = vAPI.localStorage.getItem('paneContentPaddingTop'), - touchDevice = vAPI.localStorage.getItem('touchDevice'); - - if ( typeof paneContentPaddingTop === 'string' ) { - document.querySelector('.paneContent').style.setProperty( - 'padding-top', - paneContentPaddingTop - ); + (function () { + let paneContentPaddingTop = + vAPI.localStorage.getItem('paneContentPaddingTop'); + let touchDevice = vAPI.localStorage.getItem('touchDevice'); + + if (typeof paneContentPaddingTop === 'string') { + document + .querySelector('.paneContent') + .style + .setProperty('padding-top', + paneContentPaddingTop); } - if ( touchDevice === 'true' ) { + + /* This is for CSS */ + if (touchDevice === 'true') { document.body.setAttribute('data-touch', 'true'); } else { document.addEventListener('touchstart', function onTouched(ev) { @@ -58,54 +54,58 @@ } })(); - var popupWasResized = function() { + let popupWasResized = function () { document.body.setAttribute('data-resize-popup', ''); }; - var resizePopup = (function() { - var timer; - var fix = function() { + let resizePopup = (function () { + let timer; + + let fix = function () { timer = undefined; - var doc = document; + let doc = document; // Manually adjust the position of the main matrix according to the // height of the toolbar/matrix header. - var paddingTop = (doc.querySelector('.paneHead').clientHeight + 2) + 'px', - paneContent = doc.querySelector('.paneContent'); - if ( paddingTop !== paneContent.style.paddingTop ) { + let paddingTop = + (doc.querySelector('.paneHead').clientHeight + 2) + 'px'; + let paneContent = doc.querySelector('.paneContent'); + + if (paddingTop !== paneContent.style.paddingTop) { paneContent.style.setProperty('padding-top', paddingTop); vAPI.localStorage.setItem('paneContentPaddingTop', paddingTop); } - document.body.classList.toggle( - 'hConstrained', - window.innerWidth < document.body.clientWidth - ); + + document + .body + .classList + .toggle('hConstrained', + window.innerWidth < document.body.clientWidth); + popupWasResized(); }; - return function() { - if ( timer !== undefined ) { + + return function () { + if (timer !== undefined) { clearTimeout(timer); } timer = vAPI.setTimeout(fix, 97); }; })(); - /******************************************************************************/ - /******************************************************************************/ - // Must be consistent with definitions in matrix.js - var Dark = 0x80; - var Red = 1; - var Green = 2; - var DarkRed = Dark | Red; - var DarkGreen = Dark | Green; + let Dark = 0x80; + let Red = 1; + let Green = 2; + let DarkRed = Dark | Red; + let DarkGreen = Dark | Green; - var matrixSnapshot = {}; - var groupsSnapshot = []; - var allHostnamesSnapshot = 'do not leave this initial string empty'; + let matrixSnapshot = {}; + let groupsSnapshot = []; + let allHostnamesSnapshot = 'do not leave this initial string empty'; - var matrixCellHotspots = null; + let matrixCellHotspots = null; - var matrixHeaderPrettyNames = { + let matrixHeaderPrettyNames = { 'all': '', 'cookie': '', 'css': '', @@ -117,41 +117,37 @@ 'other': '' }; - var firstPartyLabel = ''; - var blacklistedHostnamesLabel = ''; + let firstPartyLabel = ''; + let blacklistedHostnamesLabel = ''; - var expandosIdGenerator = 1; - var nodeToExpandosMap = (function() { - if ( typeof window.Map === 'function' ) { + let expandosIdGenerator = 1; + let nodeToExpandosMap = (function () { + if (typeof window.Map === 'function') { return new window.Map(); } })(); - var expandosFromNode = function(node) { - if ( - node instanceof HTMLElement === false && - typeof node.nodeAt === 'function' - ) { + let expandosFromNode = function (node) { + if (node instanceof HTMLElement === false + && typeof node.nodeAt === 'function') { node = node.nodeAt(0); } - if ( nodeToExpandosMap ) { - var expandosId = node.getAttribute('data-expandos'); - if ( !expandosId ) { + if (nodeToExpandosMap) { + let expandosId = node.getAttribute('data-expandos'); + if (!expandosId) { expandosId = '' + (expandosIdGenerator++); node.setAttribute('data-expandos', expandosId); } - var expandos = nodeToExpandosMap.get(expandosId); - if ( expandos === undefined ) { - nodeToExpandosMap.set(expandosId, (expandos = Object.create(null))); + let expandos = nodeToExpandosMap.get(expandosId); + if (expandos === undefined) { + expandos = Object.create(null); + nodeToExpandosMap.set(expandosId, expandos); } return expandos; } return node; }; - /******************************************************************************/ - /******************************************************************************/ - function getUserSetting(setting) { return matrixSnapshot.userSettings[setting]; } @@ -165,31 +161,22 @@ }); } - /******************************************************************************/ - function getUISetting(setting) { - var r = vAPI.localStorage.getItem(setting); - if ( typeof r !== 'string' ) { + let r = vAPI.localStorage.getItem(setting); + if (typeof r !== 'string') { return undefined; } return JSON.parse(r); } function setUISetting(setting, value) { - vAPI.localStorage.setItem( - setting, - JSON.stringify(value) - ); + vAPI.localStorage.setItem(setting, JSON.stringify(value)); } - /******************************************************************************/ - function updateMatrixSnapshot() { matrixSnapshotPoller.pollNow(); } - /******************************************************************************/ - // For display purpose, create four distinct groups of rows: // 0th: literal "1st-party" row // 1st: page domain's related @@ -201,76 +188,79 @@ // Try to not reshuffle groups around while popup is opened if // no new hostname added. - var latestDomainListSnapshot = Object.keys(matrixSnapshot.rows).sort().join(); - if ( latestDomainListSnapshot === allHostnamesSnapshot ) { + let latestDomainListSnapshot = + Object.keys(matrixSnapshot.rows).sort().join(); + if (latestDomainListSnapshot === allHostnamesSnapshot) { return groupsSnapshot; } allHostnamesSnapshot = latestDomainListSnapshot; // First, group according to whether at least one node in the domain // hierarchy is white or blacklisted - var pageDomain = matrixSnapshot.domain; - var rows = matrixSnapshot.rows; - var anyTypeOffset = matrixSnapshot.headerIndices.get('*'); - var hostname, domain; - var row, color, count, groupIndex; - var domainToGroupMap = {}; + let pageDomain = matrixSnapshot.domain; + let rows = matrixSnapshot.rows; + let anyTypeOffset = matrixSnapshot.headerIndices.get('*'); + let hostname, domain; + let row, color, count; + let domainToGroupMap = {}; // These have hard-coded position which cannot be overriden domainToGroupMap['1st-party'] = 0; domainToGroupMap[pageDomain] = 1; // 1st pass: domain wins if it has an explicit rule or a count - for ( hostname in rows ) { - if ( rows.hasOwnProperty(hostname) === false ) { + for (hostname in rows) { + if (rows.hasOwnProperty(hostname) === false) { continue; } - if ( hostname === '*' || hostname === '1st-party' ) { + if (hostname === '*' || hostname === '1st-party') { continue; } domain = rows[hostname].domain; - if ( domain === pageDomain || hostname !== domain ) { + if (domain === pageDomain || hostname !== domain) { continue; } row = rows[domain]; color = row.temporary[anyTypeOffset]; - if ( color === DarkGreen ) { + if (color === DarkGreen) { domainToGroupMap[domain] = 2; continue; } - if ( color === DarkRed ) { + if (color === DarkRed) { domainToGroupMap[domain] = 4; continue; } count = row.counts[anyTypeOffset]; - if ( count !== 0 ) { + if (count !== 0) { domainToGroupMap[domain] = 3; continue; } } + // 2nd pass: green wins - for ( hostname in rows ) { - if ( rows.hasOwnProperty(hostname) === false ) { + for (hostname in rows) { + if (rows.hasOwnProperty(hostname) === false) { continue; } row = rows[hostname]; domain = row.domain; - if ( domainToGroupMap.hasOwnProperty(domain) ) { + if (domainToGroupMap.hasOwnProperty(domain)) { continue; } color = row.temporary[anyTypeOffset]; - if ( color === DarkGreen ) { + if (color === DarkGreen) { domainToGroupMap[domain] = 2; } } + // 3rd pass: gray with count wins - for ( hostname in rows ) { - if ( rows.hasOwnProperty(hostname) === false ) { + for (hostname in rows) { + if (rows.hasOwnProperty(hostname) === false) { continue; } row = rows[hostname]; domain = row.domain; - if ( domainToGroupMap.hasOwnProperty(domain) ) { + if (domainToGroupMap.hasOwnProperty(domain)) { continue; } color = row.temporary[anyTypeOffset]; @@ -279,47 +269,51 @@ domainToGroupMap[domain] = 3; } } + // 4th pass: red wins whatever is left - for ( hostname in rows ) { - if ( rows.hasOwnProperty(hostname) === false ) { + for (hostname in rows) { + if (rows.hasOwnProperty(hostname) === false) { continue; } row = rows[hostname]; domain = row.domain; - if ( domainToGroupMap.hasOwnProperty(domain) ) { + if (domainToGroupMap.hasOwnProperty(domain)) { continue; } color = row.temporary[anyTypeOffset]; - if ( color === DarkRed ) { + if (color === DarkRed) { domainToGroupMap[domain] = 4; } } + // 5th pass: gray wins whatever is left - for ( hostname in rows ) { - if ( rows.hasOwnProperty(hostname) === false ) { + for (hostname in rows) { + if (rows.hasOwnProperty(hostname) === false) { continue; } domain = rows[hostname].domain; - if ( domainToGroupMap.hasOwnProperty(domain) ) { + if (domainToGroupMap.hasOwnProperty(domain)) { continue; } domainToGroupMap[domain] = 3; } // Last pass: put each domain in a group - var groups = [ {}, {}, {}, {}, {} ]; - var group; - for ( hostname in rows ) { - if ( rows.hasOwnProperty(hostname) === false ) { + let groups = [ + {}, {}, {}, {}, {} + ]; + + for (hostname in rows) { + if (rows.hasOwnProperty(hostname) === false) { continue; } if ( hostname === '*' ) { continue; } domain = rows[hostname].domain; - groupIndex = domainToGroupMap[domain]; - group = groups[groupIndex]; - if ( group.hasOwnProperty(domain) === false ) { + let groupIndex = domainToGroupMap[domain]; + let group = groups[groupIndex]; + if (group.hasOwnProperty(domain) === false) { group[domain] = {}; } group[domain][hostname] = true; @@ -330,41 +324,40 @@ return groups; } - /******************************************************************************/ - // helpers - function getTemporaryColor(hostname, type) { - return matrixSnapshot.rows[hostname].temporary[matrixSnapshot.headerIndices.get(type)]; + return matrixSnapshot + .rows[hostname] + .temporary[matrixSnapshot.headerIndices.get(type)]; } function getPermanentColor(hostname, type) { - return matrixSnapshot.rows[hostname].permanent[matrixSnapshot.headerIndices.get(type)]; + return matrixSnapshot + .rows[hostname] + .permanent[matrixSnapshot.headerIndices.get(type)]; } function addCellClass(cell, hostname, type) { - var cl = cell.classList; + let cl = cell.classList; cl.add('matCell'); cl.add('t' + getTemporaryColor(hostname, type).toString(16)); cl.add('p' + getPermanentColor(hostname, type).toString(16)); } - /******************************************************************************/ - // This is required for when we update the matrix while it is open: // the user might have collapsed/expanded one or more domains, and we don't // want to lose all his hardwork. function getCollapseState(domain) { - var states = getUISetting('popupCollapseSpecificDomains'); - if ( typeof states === 'object' && states[domain] !== undefined ) { + let states = getUISetting('popupCollapseSpecificDomains'); + if (typeof states === 'object' && states[domain] !== undefined) { return states[domain]; } return matrixSnapshot.collapseAllDomains === true; } function toggleCollapseState(elem) { - if ( elem.ancestors('#matHead.collapsible').length > 0 ) { + if (elem.ancestors('#matHead.collapsible').length > 0) { toggleMainCollapseState(elem); } else { toggleSpecificCollapseState(elem); @@ -373,18 +366,21 @@ } function toggleMainCollapseState(uelem) { - var matHead = uelem.ancestors('#matHead.collapsible').toggleClass('collapsed'); - var collapsed = matrixSnapshot.collapseAllDomains = matHead.hasClass('collapsed'); - uDom('#matList .matSection.collapsible').toggleClass('collapsed', collapsed); + let matHead = + uelem.ancestors('#matHead.collapsible').toggleClass('collapsed'); + let collapsed = + matrixSnapshot.collapseAllDomains = matHead.hasClass('collapsed'); + + uDom('#matList .matSection.collapsible') + .toggleClass('collapsed', collapsed); setUserSetting('popupCollapseAllDomains', collapsed); - var specificCollapseStates = getUISetting('popupCollapseSpecificDomains') || {}; - var domains = Object.keys(specificCollapseStates); - var i = domains.length; - var domain; - while ( i-- ) { - domain = domains[i]; - if ( specificCollapseStates[domain] === collapsed ) { + let specificCollapseStates = + getUISetting('popupCollapseSpecificDomains') || {}; + let domains = Object.keys(specificCollapseStates); + for (let i=domains.length-1; i>=0; --i) { + let domain = domains[i]; + if (specificCollapseStates[domain] === collapsed) { delete specificCollapseStates[domain]; } } @@ -394,71 +390,79 @@ function toggleSpecificCollapseState(uelem) { // Remember collapse state forever, but only if it is different // from main collapse switch. - var section = uelem.ancestors('.matSection.collapsible').toggleClass('collapsed'), - domain = expandosFromNode(section).domain, - collapsed = section.hasClass('collapsed'), - mainCollapseState = matrixSnapshot.collapseAllDomains === true, - specificCollapseStates = getUISetting('popupCollapseSpecificDomains') || {}; - if ( collapsed !== mainCollapseState ) { + let section = + uelem.ancestors('.matSection.collapsible').toggleClass('collapsed'); + let domain = expandosFromNode(section).domain; + let collapsed = section.hasClass('collapsed'); + let mainCollapseState = matrixSnapshot.collapseAllDomains === true; + let specificCollapseStates = + getUISetting('popupCollapseSpecificDomains') || {}; + + if (collapsed !== mainCollapseState) { specificCollapseStates[domain] = collapsed; - setUISetting('popupCollapseSpecificDomains', specificCollapseStates); - } else if ( specificCollapseStates[domain] !== undefined ) { + setUISetting('popupCollapseSpecificDomains', + specificCollapseStates); + } else if (specificCollapseStates[domain] !== undefined) { delete specificCollapseStates[domain]; - setUISetting('popupCollapseSpecificDomains', specificCollapseStates); + setUISetting('popupCollapseSpecificDomains', + specificCollapseStates); } } - /******************************************************************************/ - // Update count value of matrix cells(s) function updateMatrixCounts() { - var matCells = uDom('.matrix .matRow.rw > .matCell'), - i = matCells.length, - matRow, matCell, count, counts, - headerIndices = matrixSnapshot.headerIndices, - rows = matrixSnapshot.rows, - expandos; - while ( i-- ) { + let matCells = uDom('.matrix .matRow.rw > .matCell'); + let matRow, matCell, count, counts; + let headerIndices = matrixSnapshot.headerIndices; + let rows = matrixSnapshot.rows; + let expandos; + + for (let i=matCells.length-1; i>=0; --i) { matCell = matCells.nodeAt(i); expandos = expandosFromNode(matCell); - if ( expandos.hostname === '*' || expandos.reqType === '*' ) { + if (expandos.hostname === '*' || expandos.reqType === '*') { continue; } matRow = matCell.parentNode; counts = matRow.classList.contains('meta') ? 'totals' : 'counts'; - count = rows[expandos.hostname][counts][headerIndices.get(expandos.reqType)]; - if ( count === expandos.count ) { continue; } + count = rows[expandos.hostname][counts][headerIndices + .get(expandos.reqType)]; + if (count === expandos.count) { + continue; + } expandos.count = count; matCell.textContent = cellTextFromCount(count); } } function cellTextFromCount(count) { - if ( count === 0 ) { return '\u00A0'; } - if ( count < 100 ) { return count; } + if (count === 0) { + return '\u00A0'; + } + + if (count < 100) { + return count; + } + return '99+'; } - /******************************************************************************/ - // Update color of matrix cells(s) // Color changes when rules change function updateMatrixColors() { - var cells = uDom('.matrix .matRow.rw > .matCell').removeClass(), - i = cells.length, - cell, expandos; - while ( i-- ) { + let cells = uDom('.matrix .matRow.rw > .matCell').removeClass(); + let cell, expandos; + for (let i=cells.length-1; i>=0; --i) { cell = cells.nodeAt(i); expandos = expandosFromNode(cell); addCellClass(cell, expandos.hostname, expandos.reqType); } + popupWasResized(); } - /******************************************************************************/ - // Update behavior of matrix: // - Whether a section is collapsible or not. It is collapsible if: // - It has at least one subdomain AND @@ -467,57 +471,68 @@ function updateMatrixBehavior() { matrixList = matrixList || uDom('#matList'); - var sections = matrixList.descendants('.matSection'); - var i = sections.length; - var section, subdomainRows, j, subdomainRow; - while ( i-- ) { + let sections = matrixList.descendants('.matSection'); + let section, subdomainRows, subdomainRow; + for (let i=sections.length-1; i>=0; --i) { section = sections.at(i); subdomainRows = section.descendants('.l2:not(.g4)'); - j = subdomainRows.length; - while ( j-- ) { + for (let j=subdomainRows.length-1; j>=0; --j) { subdomainRow = subdomainRows.at(j); - subdomainRow.toggleClass('collapsible', subdomainRow.descendants('.t81,.t82').length === 0); + subdomainRow.toggleClass('collapsible', + subdomainRow + .descendants('.t81,.t82') + .length === 0); } - section.toggleClass('collapsible', subdomainRows.filter('.collapsible').length > 0); + + section.toggleClass('collapsible', + subdomainRows.filter('.collapsible').length > 0); } } - /******************************************************************************/ - // handle user interaction with filters function getCellAction(hostname, type, leaning) { - var temporaryColor = getTemporaryColor(hostname, type); - var hue = temporaryColor & 0x03; + let temporaryColor = getTemporaryColor(hostname, type); + let hue = temporaryColor & 0x03; + // Special case: root toggle only between two states - if ( type === '*' && hostname === '*' ) { - return hue === Green ? 'blacklistMatrixCell' : 'whitelistMatrixCell'; + if (type === '*' && hostname === '*') { + return hue === Green ? + 'blacklistMatrixCell' : + 'whitelistMatrixCell'; } + // When explicitly blocked/allowed, can only graylist - var saturation = temporaryColor & 0x80; - if ( saturation === Dark ) { + let saturation = temporaryColor & 0x80; + if (saturation === Dark) { return 'graylistMatrixCell'; } - return leaning === 'whitelisting' ? 'whitelistMatrixCell' : 'blacklistMatrixCell'; + + return leaning === 'whitelisting' ? + 'whitelistMatrixCell' : + 'blacklistMatrixCell'; } function handleFilter(button, leaning) { // our parent cell knows who we are - var cell = button.ancestors('div.matCell'), - expandos = expandosFromNode(cell), - type = expandos.reqType, - desHostname = expandos.hostname; + let cell = button.ancestors('div.matCell'); + let expandos = expandosFromNode(cell); + let type = expandos.reqType; + let desHostname = expandos.hostname; + // https://github.com/gorhill/uMatrix/issues/24 // No hostname can happen -- like with blacklist meta row - if ( desHostname === '' ) { + if (desHostname === '') { return; } - var request = { + + let request = { what: getCellAction(desHostname, type, leaning), srcHostname: matrixSnapshot.scope, desHostname: desHostname, type: type }; + vAPI.messaging.send('popup.js', request, updateMatrixSnapshot); } @@ -529,164 +544,180 @@ handleFilter(button, 'blacklisting'); } - /******************************************************************************/ - - var matrixRowPool = []; - var matrixSectionPool = []; - var matrixGroupPool = []; - var matrixRowTemplate = null; - var matrixList = null; + let matrixRowPool = []; + let matrixSectionPool = []; + let matrixGroupPool = []; + let matrixRowTemplate = null; + let matrixList = null; - var startMatrixUpdate = function() { + let startMatrixUpdate = function () { matrixList = matrixList || uDom('#matList'); matrixList.detach(); - var rows = matrixList.descendants('.matRow'); + let rows = matrixList.descendants('.matRow'); rows.detach(); matrixRowPool = matrixRowPool.concat(rows.toArray()); - var sections = matrixList.descendants('.matSection'); + let sections = matrixList.descendants('.matSection'); sections.detach(); matrixSectionPool = matrixSectionPool.concat(sections.toArray()); - var groups = matrixList.descendants('.matGroup'); + let groups = matrixList.descendants('.matGroup'); groups.detach(); matrixGroupPool = matrixGroupPool.concat(groups.toArray()); }; - var endMatrixUpdate = function() { - // https://github.com/gorhill/httpswitchboard/issues/246 - // If the matrix has no rows, we need to insert a dummy one, invisible, - // to ensure the extension pop-up is properly sized. This is needed because - // the header pane's `position` property is `fixed`, which means it doesn't - // affect layout size, hence the matrix header row will be truncated. - if ( matrixSnapshot.rowCount <= 1 ) { + let endMatrixUpdate = function () { + // https://github.com/gorhill/httpswitchboard/issues/246 If + // the matrix has no rows, we need to insert a dummy one, + // invisible, to ensure the extension pop-up is properly + // sized. This is needed because the header pane's `position` + // property is `fixed`, which means it doesn't affect layout + // size, hence the matrix header row will be truncated. + if (matrixSnapshot.rowCount <= 1) { matrixList.append(createMatrixRow().css('visibility', 'hidden')); } + updateMatrixBehavior(); matrixList.css('display', ''); matrixList.appendTo('.paneContent'); }; - var createMatrixGroup = function() { - var group = matrixGroupPool.pop(); - if ( group ) { + let createMatrixGroup = function () { + let group = matrixGroupPool.pop(); + if (group) { return uDom(group).removeClass().addClass('matGroup'); } return uDom(document.createElement('div')).addClass('matGroup'); }; - var createMatrixSection = function() { - var section = matrixSectionPool.pop(); - if ( section ) { + let createMatrixSection = function () { + let section = matrixSectionPool.pop(); + if (section) { return uDom(section).removeClass().addClass('matSection'); } return uDom(document.createElement('div')).addClass('matSection'); }; - var createMatrixRow = function() { - var row = matrixRowPool.pop(); - if ( row ) { + let createMatrixRow = function () { + let row = matrixRowPool.pop(); + if (row) { row.style.visibility = ''; row = uDom(row); row.descendants('.matCell').removeClass().addClass('matCell'); row.removeClass().addClass('matRow'); return row; } - if ( matrixRowTemplate === null ) { + + if (matrixRowTemplate === null) { matrixRowTemplate = uDom('#templates .matRow'); } + return matrixRowTemplate.clone(); }; - /******************************************************************************/ - function renderMatrixHeaderRow() { - var matHead = uDom('#matHead.collapsible'); - matHead.toggleClass('collapsed', matrixSnapshot.collapseAllDomains === true); - var cells = matHead.descendants('.matCell'), cell, expandos; - cell = cells.nodeAt(0); - expandos = expandosFromNode(cell); + let matHead = uDom('#matHead.collapsible'); + matHead.toggleClass('collapsed', + matrixSnapshot.collapseAllDomains === true); + + let cells = matHead.descendants('.matCell') + let cell = cells.nodeAt(0); + let expandos = expandosFromNode(cell); expandos.reqType = '*'; expandos.hostname = '*'; addCellClass(cell, '*', '*'); + cell = cells.nodeAt(1); expandos = expandosFromNode(cell); expandos.reqType = 'cookie'; expandos.hostname = '*'; addCellClass(cell, '*', 'cookie'); + cell = cells.nodeAt(2); expandos = expandosFromNode(cell); expandos.reqType = 'css'; expandos.hostname = '*'; addCellClass(cell, '*', 'css'); + cell = cells.nodeAt(3); expandos = expandosFromNode(cell); expandos.reqType = 'image'; expandos.hostname = '*'; addCellClass(cell, '*', 'image'); + cell = cells.nodeAt(4); expandos = expandosFromNode(cell); expandos.reqType = 'media'; expandos.hostname = '*'; addCellClass(cell, '*', 'media'); + cell = cells.nodeAt(5); expandos = expandosFromNode(cell); expandos.reqType = 'script'; expandos.hostname = '*'; addCellClass(cell, '*', 'script'); + cell = cells.nodeAt(6); expandos = expandosFromNode(cell); expandos.reqType = 'xhr'; expandos.hostname = '*'; addCellClass(cell, '*', 'xhr'); + cell = cells.nodeAt(7); expandos = expandosFromNode(cell); expandos.reqType = 'frame'; expandos.hostname = '*'; addCellClass(cell, '*', 'frame'); + cell = cells.nodeAt(8); expandos = expandosFromNode(cell); expandos.reqType = 'other'; expandos.hostname = '*'; addCellClass(cell, '*', 'other'); + uDom('#matHead .matRow').css('display', ''); } - /******************************************************************************/ - function renderMatrixCellDomain(cell, domain) { - var expandos = expandosFromNode(cell); + let expandos = expandosFromNode(cell); expandos.hostname = domain; expandos.reqType = '*'; addCellClass(cell.nodeAt(0), domain, '*'); - var contents = cell.contents(); + + let contents = cell.contents(); contents.nodeAt(0).textContent = domain === '1st-party' ? firstPartyLabel : - punycode.toUnicode(domain); + Punycode.toUnicode(domain); + contents.nodeAt(1).textContent = ' '; } function renderMatrixCellSubdomain(cell, domain, subomain) { - var expandos = expandosFromNode(cell); + let expandos = expandosFromNode(cell); expandos.hostname = subomain; expandos.reqType = '*'; addCellClass(cell.nodeAt(0), subomain, '*'); - var contents = cell.contents(); - contents.nodeAt(0).textContent = punycode.toUnicode(subomain.slice(0, subomain.lastIndexOf(domain)-1)) + '.'; - contents.nodeAt(1).textContent = punycode.toUnicode(domain); + + let contents = cell.contents(); + contents.nodeAt(0).textContent = + Punycode.toUnicode(subomain.slice(0, + subomain.lastIndexOf(domain)-1)) + + '.'; + contents.nodeAt(1).textContent = Punycode.toUnicode(domain); } function renderMatrixMetaCellDomain(cell, domain) { - var expandos = expandosFromNode(cell); + let expandos = expandosFromNode(cell); expandos.hostname = domain; expandos.reqType = '*'; addCellClass(cell.nodeAt(0), domain, '*'); - var contents = cell.contents(); - contents.nodeAt(0).textContent = '\u2217.' + punycode.toUnicode(domain); + + let contents = cell.contents(); + contents.nodeAt(0).textContent = '\u2217.' + Punycode.toUnicode(domain); contents.nodeAt(1).textContent = ' '; } function renderMatrixCellType(cell, hostname, type, count) { - var node = cell.nodeAt(0), - expandos = expandosFromNode(node); + let node = cell.nodeAt(0); + let expandos = expandosFromNode(node); expandos.hostname = hostname; expandos.reqType = type; expandos.count = count; @@ -695,51 +726,55 @@ } function renderMatrixCellTypes(cells, hostname, countName) { - var counts = matrixSnapshot.rows[hostname][countName]; - var headerIndices = matrixSnapshot.headerIndices; - renderMatrixCellType(cells.at(1), hostname, 'cookie', counts[headerIndices.get('cookie')]); - renderMatrixCellType(cells.at(2), hostname, 'css', counts[headerIndices.get('css')]); - renderMatrixCellType(cells.at(3), hostname, 'image', counts[headerIndices.get('image')]); - renderMatrixCellType(cells.at(4), hostname, 'media', counts[headerIndices.get('media')]); - renderMatrixCellType(cells.at(5), hostname, 'script', counts[headerIndices.get('script')]); - renderMatrixCellType(cells.at(6), hostname, 'xhr', counts[headerIndices.get('xhr')]); - renderMatrixCellType(cells.at(7), hostname, 'frame', counts[headerIndices.get('frame')]); - renderMatrixCellType(cells.at(8), hostname, 'other', counts[headerIndices.get('other')]); + let counts = matrixSnapshot.rows[hostname][countName]; + let headerIndices = matrixSnapshot.headerIndices; + renderMatrixCellType(cells.at(1), hostname, 'cookie', + counts[headerIndices.get('cookie')]); + renderMatrixCellType(cells.at(2), hostname, 'css', + counts[headerIndices.get('css')]); + renderMatrixCellType(cells.at(3), hostname, 'image', + counts[headerIndices.get('image')]); + renderMatrixCellType(cells.at(4), hostname, 'media', + counts[headerIndices.get('media')]); + renderMatrixCellType(cells.at(5), hostname, 'script', + counts[headerIndices.get('script')]); + renderMatrixCellType(cells.at(6), hostname, 'xhr', + counts[headerIndices.get('xhr')]); + renderMatrixCellType(cells.at(7), hostname, 'frame', + counts[headerIndices.get('frame')]); + renderMatrixCellType(cells.at(8), hostname, 'other', + counts[headerIndices.get('other')]); } - /******************************************************************************/ - function makeMatrixRowDomain(domain) { - var matrixRow = createMatrixRow().addClass('rw'); - var cells = matrixRow.descendants('.matCell'); + let matrixRow = createMatrixRow().addClass('rw'); + let cells = matrixRow.descendants('.matCell'); renderMatrixCellDomain(cells.at(0), domain); renderMatrixCellTypes(cells, domain, 'counts'); return matrixRow; } function makeMatrixRowSubdomain(domain, subdomain) { - var matrixRow = createMatrixRow().addClass('rw'); - var cells = matrixRow.descendants('.matCell'); + let matrixRow = createMatrixRow().addClass('rw'); + let cells = matrixRow.descendants('.matCell'); renderMatrixCellSubdomain(cells.at(0), domain, subdomain); renderMatrixCellTypes(cells, subdomain, 'counts'); return matrixRow; } function makeMatrixMetaRowDomain(domain) { - var matrixRow = createMatrixRow().addClass('rw'); - var cells = matrixRow.descendants('.matCell'); + let matrixRow = createMatrixRow().addClass('rw'); + let cells = matrixRow.descendants('.matCell'); renderMatrixMetaCellDomain(cells.at(0), domain); renderMatrixCellTypes(cells, domain, 'totals'); return matrixRow; } - /******************************************************************************/ - function renderMatrixMetaCellType(cell, count) { // https://github.com/gorhill/uMatrix/issues/24 // Don't forget to reset cell properties - var node = cell.nodeAt(0), - expandos = expandosFromNode(node); + let node = cell.nodeAt(0); + let expandos = expandosFromNode(node); expandos.hostname = ''; expandos.reqType = ''; expandos.count = count; @@ -748,87 +783,94 @@ } function makeMatrixMetaRow(totals) { - var headerIndices = matrixSnapshot.headerIndices, - matrixRow = createMatrixRow().at(0).addClass('ro'), - cells = matrixRow.descendants('.matCell'), - contents = cells.at(0).addClass('t81').contents(), - expandos = expandosFromNode(cells.nodeAt(0)); + let headerIndices = matrixSnapshot.headerIndices; + let matrixRow = createMatrixRow().at(0).addClass('ro'); + let cells = matrixRow.descendants('.matCell'); + let contents = cells.at(0).addClass('t81').contents(); + let expandos = expandosFromNode(cells.nodeAt(0)); expandos.hostname = ''; expandos.reqType = '*'; contents.nodeAt(0).textContent = ' '; - contents.nodeAt(1).textContent = blacklistedHostnamesLabel.replace( - '{{count}}', - totals[headerIndices.get('*')].toLocaleString() - ); - renderMatrixMetaCellType(cells.at(1), totals[headerIndices.get('cookie')]); - renderMatrixMetaCellType(cells.at(2), totals[headerIndices.get('css')]); - renderMatrixMetaCellType(cells.at(3), totals[headerIndices.get('image')]); - renderMatrixMetaCellType(cells.at(4), totals[headerIndices.get('media')]); - renderMatrixMetaCellType(cells.at(5), totals[headerIndices.get('script')]); - renderMatrixMetaCellType(cells.at(6), totals[headerIndices.get('xhr')]); - renderMatrixMetaCellType(cells.at(7), totals[headerIndices.get('frame')]); - renderMatrixMetaCellType(cells.at(8), totals[headerIndices.get('other')]); + contents.nodeAt(1).textContent = + blacklistedHostnamesLabel + .replace('{{count}}', + totals[headerIndices.get('*')].toLocaleString()); + + renderMatrixMetaCellType(cells.at(1), + totals[headerIndices.get('cookie')]); + renderMatrixMetaCellType(cells.at(2), + totals[headerIndices.get('css')]); + renderMatrixMetaCellType(cells.at(3), + totals[headerIndices.get('image')]); + renderMatrixMetaCellType(cells.at(4), + totals[headerIndices.get('media')]); + renderMatrixMetaCellType(cells.at(5), + totals[headerIndices.get('script')]); + renderMatrixMetaCellType(cells.at(6), + totals[headerIndices.get('xhr')]); + renderMatrixMetaCellType(cells.at(7), + totals[headerIndices.get('frame')]); + renderMatrixMetaCellType(cells.at(8), + totals[headerIndices.get('other')]); return matrixRow; } - /******************************************************************************/ - function computeMatrixGroupMetaStats(group) { - var headerIndices = matrixSnapshot.headerIndices, - anyTypeIndex = headerIndices.get('*'), - n = headerIndices.size, - totals = new Array(n), - i = n; - while ( i-- ) { + let headerIndices = matrixSnapshot.headerIndices; + let anyTypeIndex = headerIndices.get('*'); + let totals = new Array(headerIndices.size); + + for (let i=headerIndices.size-1; i>=0; --i) { totals[i] = 0; } - var rows = matrixSnapshot.rows, row; - for ( var hostname in rows ) { - if ( rows.hasOwnProperty(hostname) === false ) { + + let rows = matrixSnapshot.rows; + let row; + for (let hostname in rows) { + if (rows.hasOwnProperty(hostname) === false) { continue; } row = rows[hostname]; - if ( group.hasOwnProperty(row.domain) === false ) { + if (group.hasOwnProperty(row.domain) === false) { continue; } - if ( row.counts[anyTypeIndex] === 0 ) { + if (row.counts[anyTypeIndex] === 0) { continue; } totals[0] += 1; - for ( i = 1; i < n; i++ ) { + for (let i=1; i<headerIndices.size; ++i) { totals[i] += row.counts[i]; } } + return totals; } - /******************************************************************************/ - // Compare hostname helper, to order hostname in a logical manner: // top-most < bottom-most, take into account whether IP address or // named hostname - function hostnameCompare(a,b) { + function hostnameCompare(a, b) { // Normalize: most significant parts first - if ( !a.match(/^\d+(\.\d+){1,3}$/) ) { - var aa = a.split('.'); + if (!a.match(/^\d+(\.\d+){1,3}$/)) { + let aa = a.split('.'); a = aa.slice(-2).concat(aa.slice(0,-2).reverse()).join('.'); } - if ( !b.match(/^\d+(\.\d+){1,3}$/) ) { - var bb = b.split('.'); + + if (!b.match(/^\d+(\.\d+){1,3}$/)) { + let bb = b.split('.'); b = bb.slice(-2).concat(bb.slice(0,-2).reverse()).join('.'); } + return a.localeCompare(b); } - /******************************************************************************/ - function makeMatrixGroup0SectionDomain() { return makeMatrixRowDomain('1st-party').addClass('g0 l1'); } function makeMatrixGroup0Section() { - var domainDiv = createMatrixSection(); + let domainDiv = createMatrixSection(); expandosFromNode(domainDiv).domain = '1st-party'; makeMatrixGroup0SectionDomain().appendTo(domainDiv); return domainDiv; @@ -837,24 +879,20 @@ function makeMatrixGroup0() { // Show literal "1st-party" row only if there is // at least one 1st-party hostname - if ( Object.keys(groupsSnapshot[1]).length === 0 ) { + if (Object.keys(groupsSnapshot[1]).length === 0) { return; } - var groupDiv = createMatrixGroup().addClass('g0'); + let groupDiv = createMatrixGroup().addClass('g0'); makeMatrixGroup0Section().appendTo(groupDiv); groupDiv.appendTo(matrixList); } - /******************************************************************************/ - function makeMatrixGroup1SectionDomain(domain) { - return makeMatrixRowDomain(domain) - .addClass('g1 l1'); + return makeMatrixRowDomain(domain).addClass('g1 l1'); } function makeMatrixGroup1SectionSubomain(domain, subdomain) { - return makeMatrixRowSubdomain(domain, subdomain) - .addClass('g1 l2'); + return makeMatrixRowSubdomain(domain, subdomain).addClass('g1 l2'); } function makeMatrixGroup1SectionMetaDomain(domain) { @@ -862,17 +900,16 @@ } function makeMatrixGroup1Section(hostnames) { - var domain = hostnames[0]; - var domainDiv = createMatrixSection() - .toggleClass('collapsed', getCollapseState(domain)); + let domain = hostnames[0]; + let domainDiv = + createMatrixSection().toggleClass('collapsed', + getCollapseState(domain)); expandosFromNode(domainDiv).domain = domain; - if ( hostnames.length > 1 ) { - makeMatrixGroup1SectionMetaDomain(domain) - .appendTo(domainDiv); + if (hostnames.length > 1) { + makeMatrixGroup1SectionMetaDomain(domain).appendTo(domainDiv); } - makeMatrixGroup1SectionDomain(domain) - .appendTo(domainDiv); - for ( var i = 1; i < hostnames.length; i++ ) { + makeMatrixGroup1SectionDomain(domain).appendTo(domainDiv); + for (let i=1; i<hostnames.length; ++i) { makeMatrixGroup1SectionSubomain(domain, hostnames[i]) .appendTo(domainDiv); } @@ -880,29 +917,27 @@ } function makeMatrixGroup1(group) { - var domains = Object.keys(group).sort(hostnameCompare); - if ( domains.length ) { - var groupDiv = createMatrixGroup().addClass('g1'); - makeMatrixGroup1Section(Object.keys(group[domains[0]]).sort(hostnameCompare)) + let domains = Object.keys(group).sort(hostnameCompare); + if (domains.length) { + let groupDiv = createMatrixGroup().addClass('g1'); + makeMatrixGroup1Section(Object.keys(group[domains[0]]) + .sort(hostnameCompare)) .appendTo(groupDiv); - for ( var i = 1; i < domains.length; i++ ) { - makeMatrixGroup1Section(Object.keys(group[domains[i]]).sort(hostnameCompare)) + for (let i=1; i<domains.length; ++i) { + makeMatrixGroup1Section(Object.keys(group[domains[i]]) + .sort(hostnameCompare)) .appendTo(groupDiv); } groupDiv.appendTo(matrixList); } } - /******************************************************************************/ - function makeMatrixGroup2SectionDomain(domain) { - return makeMatrixRowDomain(domain) - .addClass('g2 l1'); + return makeMatrixRowDomain(domain).addClass('g2 l1'); } function makeMatrixGroup2SectionSubomain(domain, subdomain) { - return makeMatrixRowSubdomain(domain, subdomain) - .addClass('g2 l2'); + return makeMatrixRowSubdomain(domain, subdomain).addClass('g2 l2'); } function makeMatrixGroup2SectionMetaDomain(domain) { @@ -910,16 +945,16 @@ } function makeMatrixGroup2Section(hostnames) { - var domain = hostnames[0]; - var domainDiv = createMatrixSection() - .toggleClass('collapsed', getCollapseState(domain)); + let domain = hostnames[0]; + let domainDiv = + createMatrixSection().toggleClass('collapsed', + getCollapseState(domain)); expandosFromNode(domainDiv).domain = domain; - if ( hostnames.length > 1 ) { + if (hostnames.length > 1) { makeMatrixGroup2SectionMetaDomain(domain).appendTo(domainDiv); } - makeMatrixGroup2SectionDomain(domain) - .appendTo(domainDiv); - for ( var i = 1; i < hostnames.length; i++ ) { + makeMatrixGroup2SectionDomain(domain).appendTo(domainDiv); + for (let i=1; i<hostnames.length; ++i) { makeMatrixGroup2SectionSubomain(domain, hostnames[i]) .appendTo(domainDiv); } @@ -927,30 +962,27 @@ } function makeMatrixGroup2(group) { - var domains = Object.keys(group).sort(hostnameCompare); - if ( domains.length) { - var groupDiv = createMatrixGroup() - .addClass('g2'); - makeMatrixGroup2Section(Object.keys(group[domains[0]]).sort(hostnameCompare)) + let domains = Object.keys(group).sort(hostnameCompare); + if (domains.length) { + let groupDiv = createMatrixGroup().addClass('g2'); + makeMatrixGroup2Section(Object.keys(group[domains[0]]) + .sort(hostnameCompare)) .appendTo(groupDiv); - for ( var i = 1; i < domains.length; i++ ) { - makeMatrixGroup2Section(Object.keys(group[domains[i]]).sort(hostnameCompare)) + for (let i=1; i<domains.length; ++i) { + makeMatrixGroup2Section(Object.keys(group[domains[i]]) + .sort(hostnameCompare)) .appendTo(groupDiv); } groupDiv.appendTo(matrixList); } } - /******************************************************************************/ - function makeMatrixGroup3SectionDomain(domain) { - return makeMatrixRowDomain(domain) - .addClass('g3 l1'); + return makeMatrixRowDomain(domain).addClass('g3 l1'); } function makeMatrixGroup3SectionSubomain(domain, subdomain) { - return makeMatrixRowSubdomain(domain, subdomain) - .addClass('g3 l2'); + return makeMatrixRowSubdomain(domain, subdomain).addClass('g3 l2'); } function makeMatrixGroup3SectionMetaDomain(domain) { @@ -958,16 +990,15 @@ } function makeMatrixGroup3Section(hostnames) { - var domain = hostnames[0]; - var domainDiv = createMatrixSection() - .toggleClass('collapsed', getCollapseState(domain)); + let domain = hostnames[0]; + let domainDiv = createMatrixSection().toggleClass('collapsed', + getCollapseState(domain)); expandosFromNode(domainDiv).domain = domain; - if ( hostnames.length > 1 ) { + if (hostnames.length > 1) { makeMatrixGroup3SectionMetaDomain(domain).appendTo(domainDiv); } - makeMatrixGroup3SectionDomain(domain) - .appendTo(domainDiv); - for ( var i = 1; i < hostnames.length; i++ ) { + makeMatrixGroup3SectionDomain(domain).appendTo(domainDiv); + for (let i=1; i<hostnames.length; ++i) { makeMatrixGroup3SectionSubomain(domain, hostnames[i]) .appendTo(domainDiv); } @@ -975,39 +1006,35 @@ } function makeMatrixGroup3(group) { - var domains = Object.keys(group).sort(hostnameCompare); - if ( domains.length) { - var groupDiv = createMatrixGroup() - .addClass('g3'); - makeMatrixGroup3Section(Object.keys(group[domains[0]]).sort(hostnameCompare)) + let domains = Object.keys(group).sort(hostnameCompare); + if (domains.length) { + let groupDiv = createMatrixGroup().addClass('g3'); + makeMatrixGroup3Section(Object.keys(group[domains[0]]) + .sort(hostnameCompare)) .appendTo(groupDiv); - for ( var i = 1; i < domains.length; i++ ) { - makeMatrixGroup3Section(Object.keys(group[domains[i]]).sort(hostnameCompare)) + for (let i=1; i<domains.length; ++i) { + makeMatrixGroup3Section(Object.keys(group[domains[i]]) + .sort(hostnameCompare)) .appendTo(groupDiv); } groupDiv.appendTo(matrixList); } } - /******************************************************************************/ - function makeMatrixGroup4SectionDomain(domain) { - return makeMatrixRowDomain(domain) - .addClass('g4 l1'); + return makeMatrixRowDomain(domain).addClass('g4 l1'); } function makeMatrixGroup4SectionSubomain(domain, subdomain) { - return makeMatrixRowSubdomain(domain, subdomain) - .addClass('g4 l2'); + return makeMatrixRowSubdomain(domain, subdomain).addClass('g4 l2'); } function makeMatrixGroup4Section(hostnames) { - var domain = hostnames[0]; - var domainDiv = createMatrixSection(); + let domain = hostnames[0]; + let domainDiv = createMatrixSection(); expandosFromNode(domainDiv).domain = domain; - makeMatrixGroup4SectionDomain(domain) - .appendTo(domainDiv); - for ( var i = 1; i < hostnames.length; i++ ) { + makeMatrixGroup4SectionDomain(domain).appendTo(domainDiv); + for (let i=1; i<hostnames.length; ++i) { makeMatrixGroup4SectionSubomain(domain, hostnames[i]) .appendTo(domainDiv); } @@ -1015,35 +1042,38 @@ } function makeMatrixGroup4(group) { - var domains = Object.keys(group).sort(hostnameCompare); - if ( domains.length === 0 ) { + let domains = Object.keys(group).sort(hostnameCompare); + if (domains.length === 0) { return; } - var groupDiv = createMatrixGroup().addClass('g4'); + let groupDiv = createMatrixGroup().addClass('g4'); createMatrixSection() .addClass('g4Meta') - .toggleClass('g4Collapsed', !!matrixSnapshot.collapseBlacklistedDomains) + .toggleClass('g4Collapsed', + !!matrixSnapshot.collapseBlacklistedDomains) .appendTo(groupDiv); makeMatrixMetaRow(computeMatrixGroupMetaStats(group), 'g4') .appendTo(groupDiv); - makeMatrixGroup4Section(Object.keys(group[domains[0]]).sort(hostnameCompare)) + makeMatrixGroup4Section(Object.keys(group[domains[0]]) + .sort(hostnameCompare)) .appendTo(groupDiv); - for ( var i = 1; i < domains.length; i++ ) { - makeMatrixGroup4Section(Object.keys(group[domains[i]]).sort(hostnameCompare)) + for (let i=1; i<domains.length; ++i) { + makeMatrixGroup4Section(Object.keys(group[domains[i]]) + .sort(hostnameCompare)) .appendTo(groupDiv); } groupDiv.appendTo(matrixList); } - /******************************************************************************/ - - var makeMenu = function() { - var groupStats = getGroupStats(); + let makeMenu = function () { + let groupStats = getGroupStats(); - if ( Object.keys(groupStats).length === 0 ) { return; } + if (Object.keys(groupStats).length === 0) { + return; + } // https://github.com/gorhill/httpswitchboard/issues/31 - if ( matrixCellHotspots ) { + if (matrixCellHotspots) { matrixCellHotspots.detach(); } @@ -1062,43 +1092,37 @@ resizePopup(); }; - /******************************************************************************/ - // Do all the stuff that needs to be done before building menu et al. function initMenuEnvironment() { - document.body.style.setProperty( - 'font-size', - getUserSetting('displayTextSize') - ); - document.body.classList.toggle( - 'colorblind', - getUserSetting('colorBlindFriendly') - ); - uDom.nodeFromId('version').textContent = matrixSnapshot.appVersion || ''; - - var prettyNames = matrixHeaderPrettyNames; - var keys = Object.keys(prettyNames); - var i = keys.length; - var cell, key, text; - while ( i-- ) { - key = keys[i]; - cell = uDom('#matHead .matCell[data-req-type="'+ key +'"]'); - text = vAPI.i18n(key + 'PrettyName'); + document.body.style.setProperty('font-size', + getUserSetting('displayTextSize')); + document.body.classList.toggle('colorblind', + getUserSetting('colorBlindFriendly')); + uDom.nodeFromId('version').textContent = + matrixSnapshot.appVersion || ''; + + let prettyNames = matrixHeaderPrettyNames; + let keys = Object.keys(prettyNames); + for (let i=keys.length-1; i>=0; --i) { + let key = keys[i]; + let cell = uDom('#matHead .matCell[data-req-type="'+ key +'"]'); + let text = vAPI.i18n(key + 'PrettyName'); cell.text(text); prettyNames[key] = text; } firstPartyLabel = uDom('[data-i18n="matrix1stPartyLabel"]').text(); - blacklistedHostnamesLabel = uDom('[data-i18n="matrixBlacklistedHostnames"]').text(); + blacklistedHostnamesLabel = + uDom('[data-i18n="matrixBlacklistedHostnames"]').text(); } - /******************************************************************************/ - // Create page scopes for the web page function selectGlobalScope() { - if ( matrixSnapshot.scope === '*' ) { return; } + if (matrixSnapshot.scope === '*') { + return; + } matrixSnapshot.scope = '*'; document.body.classList.add('globalScope'); matrixSnapshot.tMatrixModifiedTime = undefined; @@ -1107,8 +1131,10 @@ } function selectSpecificScope(ev) { - var newScope = ev.target.getAttribute('data-scope'); - if ( !newScope || matrixSnapshot.scope === newScope ) { return; } + let newScope = ev.target.getAttribute('data-scope'); + if (!newScope || matrixSnapshot.scope === newScope) { + return; + } document.body.classList.remove('globalScope'); matrixSnapshot.scope = newScope; matrixSnapshot.tMatrixModifiedTime = undefined; @@ -1118,45 +1144,49 @@ function initScopeCell() { // It's possible there is no page URL at this point: some pages cannot - // be filtered by uMatrix. - if ( matrixSnapshot.url === '' ) { return; } - var specificScope = uDom.nodeFromId('specificScope'); + // be filtered by ηMatrix. + if (matrixSnapshot.url === '') { + return; + } + let specificScope = uDom.nodeFromId('specificScope'); - while ( specificScope.firstChild !== null ) { + while (specificScope.firstChild !== null) { specificScope.removeChild(specificScope.firstChild); } // Fill in the scope menu entries - var pos = matrixSnapshot.domain.indexOf('.'); - var tld, labels; - if ( pos === -1 ) { + let pos = matrixSnapshot.domain.indexOf('.'); + let tld, labels; + if (pos === -1) { tld = ''; labels = matrixSnapshot.hostname; } else { tld = matrixSnapshot.domain.slice(pos + 1); labels = matrixSnapshot.hostname.slice(0, -tld.length); } - var beg = 0, span, label; - while ( beg < labels.length ) { + let beg = 0; + let span, label; + while (beg < labels.length) { pos = labels.indexOf('.', beg); - if ( pos === -1 ) { + if (pos === -1) { pos = labels.length; } else { pos += 1; } label = document.createElement('span'); - label.appendChild( - document.createTextNode(punycode.toUnicode(labels.slice(beg, pos))) - ); + label.appendChild(document + .createTextNode(Punycode + .toUnicode(labels.slice(beg, + pos)))); span = document.createElement('span'); span.setAttribute('data-scope', labels.slice(beg) + tld); span.appendChild(label); specificScope.appendChild(span); beg = pos; } - if ( tld !== '' ) { + if (tld !== '') { label = document.createElement('span'); - label.appendChild(document.createTextNode(punycode.toUnicode(tld))); + label.appendChild(document.createTextNode(Punycode.toUnicode(tld))); span = document.createElement('span'); span.setAttribute('data-scope', tld); span.appendChild(label); @@ -1166,50 +1196,48 @@ } function updateScopeCell() { - var specificScope = uDom.nodeFromId('specificScope'), - isGlobal = matrixSnapshot.scope === '*'; + let specificScope = uDom.nodeFromId('specificScope'); + let isGlobal = matrixSnapshot.scope === '*'; + document.body.classList.toggle('globalScope', isGlobal); specificScope.classList.toggle('on', !isGlobal); uDom.nodeFromId('globalScope').classList.toggle('on', isGlobal); - for ( var node of specificScope.children ) { - node.classList.toggle( - 'on', - !isGlobal && - matrixSnapshot.scope.endsWith(node.getAttribute('data-scope')) - ); + + for (let node of specificScope.children) { + node.classList.toggle('on', + !isGlobal + && matrixSnapshot + .scope + .endsWith(node.getAttribute('data-scope'))); } } - /******************************************************************************/ - function updateMatrixSwitches() { - var count = 0, - enabled, - switches = matrixSnapshot.tSwitches; - for ( var switchName in switches ) { - if ( switches.hasOwnProperty(switchName) === false ) { continue; } + let count = 0; + let enabled; + let switches = matrixSnapshot.tSwitches; + + for (let switchName in switches) { + if (switches.hasOwnProperty(switchName) === false) { + continue; + } enabled = switches[switchName]; - if ( enabled && switchName !== 'matrix-off' ) { + if (enabled && switchName !== 'matrix-off') { count += 1; } uDom('#mtxSwitch_' + switchName).toggleClass('switchTrue', enabled); } - uDom.nodeFromId('mtxSwitch_https-strict').classList.toggle( - 'relevant', - matrixSnapshot.hasMixedContent - ); - uDom.nodeFromId('mtxSwitch_no-workers').classList.toggle( - 'relevant', - matrixSnapshot.hasWebWorkers - ); - uDom.nodeFromId('mtxSwitch_referrer-spoof').classList.toggle( - 'relevant', - matrixSnapshot.has3pReferrer - ); - uDom.nodeFromId('mtxSwitch_noscript-spoof').classList.toggle( - 'relevant', - matrixSnapshot.hasNoscriptTags - ); + uDom.nodeFromId('mtxSwitch_https-strict') + .classList + .toggle('relevant', matrixSnapshot.hasMixedContent); + uDom.nodeFromId('mtxSwitch_no-workers') + .classList + .toggle('relevant', matrixSnapshot.hasWebWorkers); + uDom.nodeFromId('mtxSwitch_referrer-spoof') + .classList.toggle('relevant', matrixSnapshot.has3pReferrer); + uDom.nodeFromId('mtxSwitch_noscript-spoof') + .classList + .toggle('relevant', matrixSnapshot.hasNoscriptTags); uDom.nodeFromSelector('#buttonMtxSwitches span.badge').textContent = count.toLocaleString(); uDom.nodeFromSelector('#mtxSwitch_matrix-off span.badge').textContent = @@ -1218,12 +1246,18 @@ } function toggleMatrixSwitch(ev) { - if ( ev.target.localName === 'a' ) { return; } - var elem = ev.currentTarget; - var pos = elem.id.indexOf('_'); - if ( pos === -1 ) { return; } - var switchName = elem.id.slice(pos + 1); - var request = { + if (ev.target.localName === 'a') { + return; + } + + let elem = ev.currentTarget; + let pos = elem.id.indexOf('_'); + if (pos === -1) { + return; + } + + let switchName = elem.id.slice(pos + 1); + let request = { what: 'toggleMatrixSwitch', switchName: switchName, srcHostname: matrixSnapshot.scope @@ -1231,46 +1265,44 @@ vAPI.messaging.send('popup.js', request, updateMatrixSnapshot); } - /******************************************************************************/ - function updatePersistButton() { - var diffCount = matrixSnapshot.diff.length; - var button = uDom('#buttonPersist'); + let diffCount = matrixSnapshot.diff.length; + let button = uDom('#buttonPersist'); + button.contents() - .filter(function(){return this.nodeType===3;}) + .filter(function () { + return this.nodeType===3; + }) .first() .text(diffCount > 0 ? '\uf13e' : '\uf023'); + button.descendants('span.badge').text(diffCount > 0 ? diffCount : ''); - var disabled = diffCount === 0; + + let disabled = diffCount === 0; + button.toggleClass('disabled', disabled); uDom('#buttonRevertScope').toggleClass('disabled', disabled); } - /******************************************************************************/ - function persistMatrix() { - var request = { + let request = { what: 'applyDiffToPermanentMatrix', diff: matrixSnapshot.diff }; vAPI.messaging.send('popup.js', request, updateMatrixSnapshot); } - /******************************************************************************/ - // rhill 2014-03-12: revert completely ALL changes related to the // current page, including scopes. function revertMatrix() { - var request = { + let request = { what: 'applyDiffToTemporaryMatrix', diff: matrixSnapshot.diff }; vAPI.messaging.send('popup.js', request, updateMatrixSnapshot); } - /******************************************************************************/ - // Buttons which are affected by any changes in the matrix function updateMatrixButtons() { @@ -1279,18 +1311,14 @@ updatePersistButton(); } - /******************************************************************************/ - function revertAll() { - var request = { + let request = { what: 'revertTemporaryMatrix' }; vAPI.messaging.send('popup.js', request, updateMatrixSnapshot); dropDownMenuHide(); } - /******************************************************************************/ - function buttonReloadHandler(ev) { vAPI.messaging.send('popup.js', { what: 'forceReloadTab', @@ -1299,8 +1327,6 @@ }); } - /******************************************************************************/ - function mouseenterMatrixCellHandler(ev) { matrixCellHotspots.appendTo(ev.target); } @@ -1309,11 +1335,9 @@ matrixCellHotspots.detach(); } - /******************************************************************************/ - function gotoExtensionURL(ev) { - var url = uDom(ev.currentTarget).attr('data-extension-url'); - if ( url ) { + let url = uDom(ev.currentTarget).attr('data-extension-url'); + if (url) { vAPI.messaging.send('popup.js', { what: 'gotoExtensionURL', url: url, @@ -1324,18 +1348,16 @@ vAPI.closePopup(); } - /******************************************************************************/ - function dropDownMenuShow(ev) { - var button = ev.target; - var menuOverlay = document.getElementById(button.getAttribute('data-dropdown-menu')); - var butnRect = button.getBoundingClientRect(); - var viewRect = document.body.getBoundingClientRect(); - var butnNormalLeft = butnRect.left / (viewRect.width - butnRect.width); + let button = ev.target; + let menuOverlay = document.getElementById(button.getAttribute('data-dropdown-menu')); + let butnRect = button.getBoundingClientRect(); + let viewRect = document.body.getBoundingClientRect(); + let butnNormalLeft = butnRect.left / (viewRect.width - butnRect.width); menuOverlay.classList.add('show'); - var menu = menuOverlay.querySelector('.dropdown-menu'); - var menuRect = menu.getBoundingClientRect(); - var menuLeft = butnNormalLeft * (viewRect.width - menuRect.width); + let menu = menuOverlay.querySelector('.dropdown-menu'); + let menuRect = menu.getBoundingClientRect(); + let menuLeft = butnNormalLeft * (viewRect.width - menuRect.width); menu.style.left = menuLeft.toFixed(0) + 'px'; menu.style.top = butnRect.bottom + 'px'; } @@ -1344,10 +1366,8 @@ uDom('.dropdown-menu-capture').removeClass('show'); } - /******************************************************************************/ - - var onMatrixSnapshotReady = function(response) { - if ( response === 'ENOTFOUND' ) { + let onMatrixSnapshotReady = function (response) { + if (response === 'ENOTFOUND') { uDom.nodeFromId('noTabFound').textContent = vAPI.i18n('matrixNoTabFound'); document.body.classList.add('noTabFound'); @@ -1359,7 +1379,7 @@ makeMenu(); // After popup menu is built, check whether there is a non-empty matrix - if ( matrixSnapshot.url === '' ) { + if (matrixSnapshot.url === '') { uDom('#matHead').remove(); uDom('#toolbarContainer').remove(); @@ -1371,58 +1391,58 @@ // Create a hash to find out whether the reload button needs to be // highlighted. // TODO: + // ηMatrix: not sure what the purpose of highlighting is... + // Maybe telling the user that the page needs refreshing? But + // that's hardly useful (and by now people have gotten used to + // the lack of such a feature.) + // Not really going to do it, but let's leave the comment. }; - /******************************************************************************/ + let matrixSnapshotPoller = (function () { + let timer = null; - var matrixSnapshotPoller = (function() { - var timer = null; - - var preprocessMatrixSnapshot = function(snapshot) { - if ( Array.isArray(snapshot.headerIndices) ) { + let preprocessMatrixSnapshot = function (snapshot) { + if (Array.isArray(snapshot.headerIndices)) { snapshot.headerIndices = new Map(snapshot.headerIndices); } return snapshot; }; - var processPollResult = function(response) { - if ( typeof response !== 'object' ) { + let processPollResult = function (response) { + if (typeof response !== 'object') { return; } - if ( - response.mtxContentModified === false && - response.mtxCountModified === false && - response.pMatrixModified === false && - response.tMatrixModified === false - ) { + + if (response.mtxContentModified === false + && response.mtxCountModified === false + && response.pMatrixModified === false + && response.tMatrixModified === false) { return; } matrixSnapshot = preprocessMatrixSnapshot(response); - if ( response.mtxContentModified ) { + if (response.mtxContentModified) { makeMenu(); return; } - if ( response.mtxCountModified ) { + if (response.mtxCountModified) { updateMatrixCounts(); } - if ( - response.pMatrixModified || - response.tMatrixModified || - response.scopeModified - ) { + if (response.pMatrixModified + || response.tMatrixModified + || response.scopeModified) { updateMatrixColors(); updateMatrixBehavior(); updateMatrixButtons(); } }; - var onPolled = function(response) { + let onPolled = function (response) { processPollResult(response); pollAsync(); }; - var pollNow = function() { + let pollNow = function () { unpollAsync(); vAPI.messaging.send('popup.js', { what: 'matrixSnapshot', @@ -1436,43 +1456,47 @@ }, onPolled); }; - var poll = function() { + let poll = function () { timer = null; pollNow(); }; - var pollAsync = function() { - if ( timer !== null ) { + let pollAsync = function () { + if (timer !== null) { return; } - if ( document.defaultView === null ) { + if (document.defaultView === null) { return; } timer = vAPI.setTimeout(poll, 1414); }; - var unpollAsync = function() { - if ( timer !== null ) { + let unpollAsync = function () { + if (timer !== null) { clearTimeout(timer); timer = null; } }; - (function() { - var tabId = matrixSnapshot.tabId; + (function () { + let tabId = matrixSnapshot.tabId; // If no tab id yet, see if there is one specified in our URL - if ( tabId === undefined ) { - var matches = window.location.search.match(/(?:\?|&)tabId=([^&]+)/); - if ( matches !== null ) { + if (tabId === undefined) { + let matches = window + .location + .search + .match(/(?:\?|&)tabId=([^&]+)/); + + if (matches !== null) { tabId = matches[1]; // No need for logger button when embedded in logger uDom('[data-extension-url="logger-ui.html"]').remove(); } } - var snapshotFetched = function(response) { - if ( typeof response === 'object' ) { + let snapshotFetched = function (response) { + if (typeof response === 'object') { matrixSnapshot = preprocessMatrixSnapshot(response); } onMatrixSnapshotReady(response); @@ -1490,28 +1514,31 @@ }; })(); - /******************************************************************************/ - // Below is UI stuff which is not key to make the menu, so this can // be done without having to wait for a tab to be bound to the menu. // We reuse for all cells the one and only cell hotspots. - uDom('#whitelist').on('click', function() { + uDom('#whitelist').on('click', function () { handleWhitelistFilter(uDom(this)); return false; }); - uDom('#blacklist').on('click', function() { + + uDom('#blacklist').on('click', function () { handleBlacklistFilter(uDom(this)); return false; }); - uDom('#domainOnly').on('click', function() { + + uDom('#domainOnly').on('click', function () { toggleCollapseState(uDom(this)); return false; }); + matrixCellHotspots = uDom('#cellHotspots').detach(); + uDom('body') .on('mouseenter', '.matCell', mouseenterMatrixCellHandler) .on('mouseleave', '.matCell', mouseleaveMatrixCellHandler); + uDom('#specificScope').on('click', selectSpecificScope); uDom('#globalScope').on('click', selectGlobalScope); uDom('[id^="mtxSwitch_"]').on('click', toggleMatrixSwitch); @@ -1525,15 +1552,10 @@ uDom('body').on('click', '[data-dropdown-menu]', dropDownMenuShow); uDom('body').on('click', '.dropdown-menu-capture', dropDownMenuHide); - uDom('#matList').on('click', '.g4Meta', function(ev) { + uDom('#matList').on('click', '.g4Meta', function (ev) { matrixSnapshot.collapseBlacklistedDomains = ev.target.classList.toggle('g4Collapsed'); - setUserSetting( - 'popupCollapseBlacklistedDomains', - matrixSnapshot.collapseBlacklistedDomains - ); + setUserSetting('popupCollapseBlacklistedDomains', + matrixSnapshot.collapseBlacklistedDomains); }); - - /******************************************************************************/ - })(); |