2014-10-18 08:01:09 +13:00
|
|
|
/*******************************************************************************
|
|
|
|
|
2018-04-14 02:24:50 +12:00
|
|
|
uMatrix - a browser extension to black/white list requests.
|
2018-09-29 22:31:59 +12:00
|
|
|
Copyright (C) 2014-present Raymond Hill
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
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://github.com/gorhill/uMatrix
|
|
|
|
*/
|
|
|
|
|
2018-09-29 22:31:59 +12:00
|
|
|
/* global punycode, uDom, uMatrixScopeWidget */
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2017-03-16 09:30:48 +13:00
|
|
|
'use strict';
|
|
|
|
|
2014-10-18 08:01:09 +13:00
|
|
|
/******************************************************************************/
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
{
|
|
|
|
// >>>>> start of local scope
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2017-11-24 06:14:29 +13:00
|
|
|
// Stuff which is good to do very early so as to avoid visual glitches.
|
2017-11-23 01:07:34 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
{
|
|
|
|
const url = new URL(self.location.href);
|
|
|
|
const params = url.searchParams;
|
|
|
|
if ( params.has('tabid') || params.has('rule') ) {
|
|
|
|
document.body.classList.add('embedded');
|
|
|
|
}
|
|
|
|
if ( params.has('rule') ) {
|
|
|
|
document.body.classList.add('tabless');
|
2017-11-24 06:14:29 +13:00
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
|
|
|
|
const touchDevice = vAPI.localStorage.getItem('touchDevice');
|
2017-11-24 06:14:29 +13:00
|
|
|
if ( touchDevice === 'true' ) {
|
|
|
|
document.body.setAttribute('data-touch', 'true');
|
|
|
|
} else {
|
|
|
|
document.addEventListener('touchstart', function onTouched(ev) {
|
|
|
|
document.removeEventListener(ev.type, onTouched);
|
|
|
|
document.body.setAttribute('data-touch', 'true');
|
2017-12-05 10:48:59 +13:00
|
|
|
vAPI.localStorage.setItem('touchDevice', 'true');
|
2017-11-24 06:14:29 +13:00
|
|
|
});
|
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
}
|
2017-11-24 06:14:29 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const popupWasResized = function() {
|
2017-12-03 02:48:23 +13:00
|
|
|
document.body.setAttribute('data-resize-popup', '');
|
|
|
|
};
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const resizePopup = (( ) => {
|
|
|
|
let timer;
|
|
|
|
|
|
|
|
// The purpose of `fix` is to make it so that the popup panel can still
|
|
|
|
// function properly in a horizontally-restricted viewport: in such case
|
|
|
|
// we need an horizontal scrollbar.
|
|
|
|
const fix = function() {
|
2017-11-24 06:14:29 +13:00
|
|
|
timer = undefined;
|
|
|
|
document.body.classList.toggle(
|
|
|
|
'hConstrained',
|
|
|
|
window.innerWidth < document.body.clientWidth
|
|
|
|
);
|
2017-12-03 02:48:23 +13:00
|
|
|
popupWasResized();
|
2017-11-24 06:14:29 +13:00
|
|
|
};
|
2019-12-21 06:24:18 +13:00
|
|
|
|
|
|
|
// The purpose of `xobserver` is to initiate the resize handler only
|
|
|
|
// when the popup panel is actually visible.
|
2020-03-09 04:12:47 +13:00
|
|
|
|
|
|
|
// https://github.com/uBlockOrigin/uMatrix-issues/issues/235
|
|
|
|
if ( self.IntersectionObserver instanceof Object === false ) {
|
|
|
|
return ( ) => { };
|
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
let xobserver = new IntersectionObserver(intersections => {
|
|
|
|
if ( intersections.length === 0 ) { return; }
|
|
|
|
if ( intersections[0].isIntersecting === false ) { return; }
|
|
|
|
xobserver.disconnect();
|
|
|
|
xobserver = null;
|
|
|
|
resizePopup();
|
|
|
|
});
|
|
|
|
xobserver.observe(document.body);
|
|
|
|
|
2017-11-24 06:14:29 +13:00
|
|
|
return function() {
|
|
|
|
if ( timer !== undefined ) {
|
|
|
|
clearTimeout(timer);
|
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
if ( xobserver !== null ) { return; }
|
2017-11-24 06:14:29 +13:00
|
|
|
timer = vAPI.setTimeout(fix, 97);
|
|
|
|
};
|
|
|
|
})();
|
2017-11-23 01:07:34 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2014-10-20 17:53:13 +13:00
|
|
|
// Must be consistent with definitions in matrix.js
|
2019-12-21 06:24:18 +13:00
|
|
|
const Dark = 0x80;
|
|
|
|
const Red = 1;
|
|
|
|
const Green = 2;
|
|
|
|
const DarkRed = Dark | Red;
|
|
|
|
const DarkGreen = Dark | Green;
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
let matrixSnapshot = {};
|
|
|
|
let groupsSnapshot = [];
|
|
|
|
let allHostnamesSnapshot = 'do not leave this initial string empty';
|
2014-10-21 09:40:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
let matrixCellHotspots = null;
|
2014-10-21 09:40:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const matrixHeaderPrettyNames = {
|
2014-10-21 09:40:09 +13:00
|
|
|
'all': '',
|
|
|
|
'cookie': '',
|
|
|
|
'css': '',
|
|
|
|
'image': '',
|
2017-04-28 00:10:54 +12:00
|
|
|
'media': '',
|
2014-10-21 09:40:09 +13:00
|
|
|
'script': '',
|
2019-12-21 06:24:18 +13:00
|
|
|
'fetch': '',
|
2014-10-21 09:40:09 +13:00
|
|
|
'frame': '',
|
|
|
|
'other': ''
|
|
|
|
};
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
let firstPartyLabel = '';
|
|
|
|
let blacklistedHostnamesLabel = '';
|
2014-10-29 07:33:16 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const nodeToExpandosMap = new Map();
|
|
|
|
let expandosIdGenerator = 1;
|
2017-03-16 09:30:48 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const expandosFromNode = function(node) {
|
2017-03-16 09:30:48 +13:00
|
|
|
if (
|
|
|
|
node instanceof HTMLElement === false &&
|
|
|
|
typeof node.nodeAt === 'function'
|
|
|
|
) {
|
|
|
|
node = node.nodeAt(0);
|
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
if ( node.hasAttribute('data-expandos') === false ) {
|
|
|
|
const expandosId = '' + (expandosIdGenerator++);
|
|
|
|
node.setAttribute('data-expandos', expandosId);
|
|
|
|
nodeToExpandosMap.set(expandosId, Object.create(null));
|
2017-03-16 09:30:48 +13:00
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
return nodeToExpandosMap.get(node.getAttribute('data-expandos'));
|
2017-03-16 09:30:48 +13:00
|
|
|
};
|
|
|
|
|
2014-10-18 08:01:09 +13:00
|
|
|
/******************************************************************************/
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const getUserSetting = function(setting) {
|
|
|
|
return matrixSnapshot.userSettings[setting];
|
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const setUserSetting = function(setting, value) {
|
2014-10-21 14:19:24 +13:00
|
|
|
matrixSnapshot.userSettings[setting] = value;
|
2017-12-07 03:47:20 +13:00
|
|
|
vAPI.messaging.send('popup.js', {
|
2014-10-18 08:01:09 +13:00
|
|
|
what: 'userSettings',
|
|
|
|
name: setting,
|
|
|
|
value: value
|
|
|
|
});
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const getUISetting = function(setting) {
|
2015-05-12 02:55:06 +12:00
|
|
|
var r = vAPI.localStorage.getItem(setting);
|
|
|
|
if ( typeof r !== 'string' ) {
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
return JSON.parse(r);
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2015-05-12 02:55:06 +12:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const setUISetting = function(setting, value) {
|
2015-05-12 02:55:06 +12:00
|
|
|
vAPI.localStorage.setItem(
|
|
|
|
setting,
|
|
|
|
JSON.stringify(value)
|
|
|
|
);
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2015-05-12 02:55:06 +12:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const updateMatrixSnapshot = function() {
|
2015-05-07 10:59:07 +12:00
|
|
|
matrixSnapshotPoller.pollNow();
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
// For display purpose, create four distinct groups of rows:
|
2014-10-23 12:46:30 +13:00
|
|
|
// 0th: literal "1st-party" row
|
2014-10-18 08:01:09 +13:00
|
|
|
// 1st: page domain's related
|
|
|
|
// 2nd: whitelisted
|
|
|
|
// 3rd: graylisted
|
|
|
|
// 4th: blacklisted
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const getGroupStats = function() {
|
2014-10-18 08:01:09 +13:00
|
|
|
// Try to not reshuffle groups around while popup is opened if
|
|
|
|
// no new hostname added.
|
2019-12-21 06:24:18 +13:00
|
|
|
const latestDomainListSnapshot = Object.keys(matrixSnapshot.rows).sort().join();
|
2014-10-21 09:40:09 +13:00
|
|
|
if ( latestDomainListSnapshot === allHostnamesSnapshot ) {
|
|
|
|
return groupsSnapshot;
|
2014-10-18 08:01:09 +13:00
|
|
|
}
|
2014-10-21 09:40:09 +13:00
|
|
|
allHostnamesSnapshot = latestDomainListSnapshot;
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
// First, group according to whether at least one node in the domain
|
|
|
|
// hierarchy is white or blacklisted
|
2019-12-21 06:24:18 +13:00
|
|
|
const pageDomain = matrixSnapshot.domain;
|
|
|
|
const rows = matrixSnapshot.rows;
|
|
|
|
const anyTypeOffset = matrixSnapshot.headerIndices.get('*');
|
|
|
|
const domainToGroupMap = {};
|
2014-10-20 17:53:13 +13:00
|
|
|
|
2014-10-26 13:03:22 +13:00
|
|
|
// 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
|
2019-12-21 06:24:18 +13:00
|
|
|
for ( const hostname in rows ) {
|
|
|
|
if ( rows.hasOwnProperty(hostname) === false ) { continue; }
|
|
|
|
if ( hostname === '*' || hostname === '1st-party' ) { continue; }
|
|
|
|
const domain = rows[hostname].domain;
|
|
|
|
if ( domain === pageDomain || hostname !== domain ) { continue; }
|
|
|
|
const row = rows[domain];
|
|
|
|
const color = row.temporary[anyTypeOffset];
|
2014-10-26 13:03:22 +13:00
|
|
|
if ( color === DarkGreen ) {
|
|
|
|
domainToGroupMap[domain] = 2;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ( color === DarkRed ) {
|
|
|
|
domainToGroupMap[domain] = 4;
|
|
|
|
continue;
|
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
const count = row.counts[anyTypeOffset];
|
2014-10-26 13:03:22 +13:00
|
|
|
if ( count !== 0 ) {
|
|
|
|
domainToGroupMap[domain] = 3;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 2nd pass: green wins
|
2019-12-21 06:24:18 +13:00
|
|
|
for ( const hostname in rows ) {
|
|
|
|
if ( rows.hasOwnProperty(hostname) === false ) { continue; }
|
|
|
|
const row = rows[hostname];
|
|
|
|
const domain = row.domain;
|
|
|
|
if ( domainToGroupMap.hasOwnProperty(domain) ) { continue; }
|
|
|
|
const color = row.temporary[anyTypeOffset];
|
2014-10-20 17:53:13 +13:00
|
|
|
if ( color === DarkGreen ) {
|
2014-10-23 12:46:30 +13:00
|
|
|
domainToGroupMap[domain] = 2;
|
2014-10-26 13:03:22 +13:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// 3rd pass: gray with count wins
|
2019-12-21 06:24:18 +13:00
|
|
|
for ( const hostname in rows ) {
|
|
|
|
if ( rows.hasOwnProperty(hostname) === false ) { continue; }
|
|
|
|
const row = rows[hostname];
|
|
|
|
const domain = row.domain;
|
|
|
|
if ( domainToGroupMap.hasOwnProperty(domain) ) { continue; }
|
|
|
|
const color = row.temporary[anyTypeOffset];
|
|
|
|
const count = row.counts[anyTypeOffset];
|
2014-10-26 13:03:22 +13:00
|
|
|
if ( color !== DarkRed && count !== 0 ) {
|
|
|
|
domainToGroupMap[domain] = 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 4th pass: red wins whatever is left
|
2019-12-21 06:24:18 +13:00
|
|
|
for ( const hostname in rows ) {
|
|
|
|
if ( rows.hasOwnProperty(hostname) === false ) { continue; }
|
|
|
|
const row = rows[hostname];
|
|
|
|
const domain = row.domain;
|
|
|
|
if ( domainToGroupMap.hasOwnProperty(domain) ) { continue; }
|
|
|
|
const color = row.temporary[anyTypeOffset];
|
2014-10-20 17:53:13 +13:00
|
|
|
if ( color === DarkRed ) {
|
2014-10-26 13:03:22 +13:00
|
|
|
domainToGroupMap[domain] = 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 5th pass: gray wins whatever is left
|
2019-12-21 06:24:18 +13:00
|
|
|
for ( const hostname in rows ) {
|
|
|
|
if ( rows.hasOwnProperty(hostname) === false ) { continue; }
|
|
|
|
const domain = rows[hostname].domain;
|
|
|
|
if ( domainToGroupMap.hasOwnProperty(domain) ) { continue; }
|
2014-10-23 12:46:30 +13:00
|
|
|
domainToGroupMap[domain] = 3;
|
2014-10-20 17:53:13 +13:00
|
|
|
}
|
|
|
|
|
2014-10-26 13:03:22 +13:00
|
|
|
// Last pass: put each domain in a group
|
2019-12-21 06:24:18 +13:00
|
|
|
const groups = [ {}, {}, {}, {}, {} ];
|
|
|
|
for ( const hostname in rows ) {
|
|
|
|
if ( rows.hasOwnProperty(hostname) === false ) { continue; }
|
|
|
|
if ( hostname === '*' ) { continue; }
|
|
|
|
const domain = rows[hostname].domain;
|
|
|
|
const groupIndex = domainToGroupMap[domain];
|
|
|
|
const group = groups[groupIndex];
|
2014-10-20 17:53:13 +13:00
|
|
|
if ( group.hasOwnProperty(domain) === false ) {
|
|
|
|
group[domain] = {};
|
2014-10-18 08:01:09 +13:00
|
|
|
}
|
2014-10-20 17:53:13 +13:00
|
|
|
group[domain][hostname] = true;
|
2014-10-18 08:01:09 +13:00
|
|
|
}
|
|
|
|
|
2014-10-21 09:40:09 +13:00
|
|
|
groupsSnapshot = groups;
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
return groups;
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
// helpers
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const getTemporaryColor = function(hostname, type) {
|
|
|
|
return matrixSnapshot.rows[hostname]
|
|
|
|
.temporary[matrixSnapshot.headerIndices.get(type)];
|
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const getPermanentColor = function(hostname, type) {
|
|
|
|
return matrixSnapshot.rows[hostname]
|
|
|
|
.permanent[matrixSnapshot.headerIndices.get(type)];
|
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const addCellClass = function(cell, hostname, type) {
|
|
|
|
const cl = cell.classList;
|
2017-12-04 08:56:08 +13:00
|
|
|
cl.add('matCell');
|
|
|
|
cl.add('t' + getTemporaryColor(hostname, type).toString(16));
|
|
|
|
cl.add('p' + getPermanentColor(hostname, type).toString(16));
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const getCollapseState = function(domain) {
|
|
|
|
const states = getUISetting('popupCollapseSpecificDomains');
|
2015-05-12 02:55:06 +12:00
|
|
|
if ( typeof states === 'object' && states[domain] !== undefined ) {
|
2014-10-18 08:01:09 +13:00
|
|
|
return states[domain];
|
|
|
|
}
|
2017-11-30 08:40:18 +13:00
|
|
|
return matrixSnapshot.collapseAllDomains === true;
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const toggleCollapseState = function(elem) {
|
2014-10-19 09:49:06 +13:00
|
|
|
if ( elem.ancestors('#matHead.collapsible').length > 0 ) {
|
|
|
|
toggleMainCollapseState(elem);
|
2014-10-18 08:01:09 +13:00
|
|
|
} else {
|
2014-10-19 09:49:06 +13:00
|
|
|
toggleSpecificCollapseState(elem);
|
2014-10-18 08:01:09 +13:00
|
|
|
}
|
2017-12-03 02:48:23 +13:00
|
|
|
popupWasResized();
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const toggleMainCollapseState = function(uelem) {
|
|
|
|
const matHead = uelem.ancestors('#matHead.collapsible').toggleClass('collapsed');
|
|
|
|
const collapsed = matrixSnapshot.collapseAllDomains = matHead.hasClass('collapsed');
|
2014-10-18 18:09:09 +13:00
|
|
|
uDom('#matList .matSection.collapsible').toggleClass('collapsed', collapsed);
|
2017-11-30 08:40:18 +13:00
|
|
|
setUserSetting('popupCollapseAllDomains', collapsed);
|
2019-12-21 06:24:18 +13:00
|
|
|
const specificCollapseStates = getUISetting('popupCollapseSpecificDomains') || {};
|
|
|
|
for ( const domain of Object.keys(specificCollapseStates) ) {
|
2014-10-18 08:01:09 +13:00
|
|
|
if ( specificCollapseStates[domain] === collapsed ) {
|
|
|
|
delete specificCollapseStates[domain];
|
|
|
|
}
|
|
|
|
}
|
2015-05-12 02:55:06 +12:00
|
|
|
setUISetting('popupCollapseSpecificDomains', specificCollapseStates);
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const toggleSpecificCollapseState = function(uelem) {
|
2014-10-18 08:01:09 +13:00
|
|
|
// Remember collapse state forever, but only if it is different
|
|
|
|
// from main collapse switch.
|
2019-12-21 06:24:18 +13:00
|
|
|
const section = uelem.ancestors('.matSection.collapsible').toggleClass('collapsed');
|
|
|
|
const domain = expandosFromNode(section).domain;
|
|
|
|
const collapsed = section.hasClass('collapsed');
|
|
|
|
const mainCollapseState = matrixSnapshot.collapseAllDomains === true;
|
|
|
|
const specificCollapseStates = getUISetting('popupCollapseSpecificDomains') || {};
|
2014-10-18 08:01:09 +13:00
|
|
|
if ( collapsed !== mainCollapseState ) {
|
|
|
|
specificCollapseStates[domain] = collapsed;
|
2015-05-12 02:55:06 +12:00
|
|
|
setUISetting('popupCollapseSpecificDomains', specificCollapseStates);
|
2014-10-18 08:01:09 +13:00
|
|
|
} else if ( specificCollapseStates[domain] !== undefined ) {
|
|
|
|
delete specificCollapseStates[domain];
|
2015-05-12 02:55:06 +12:00
|
|
|
setUISetting('popupCollapseSpecificDomains', specificCollapseStates);
|
2014-10-18 08:01:09 +13:00
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2015-05-07 08:32:41 +12:00
|
|
|
// Update count value of matrix cells(s)
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const updateMatrixCounts = function() {
|
|
|
|
const matCells = uDom('.matrix .matRow.rw > .matCell');
|
|
|
|
const headerIndices = matrixSnapshot.headerIndices;
|
|
|
|
const rows = matrixSnapshot.rows;
|
|
|
|
let i = matCells.length;
|
2015-05-07 08:32:41 +12:00
|
|
|
while ( i-- ) {
|
2019-12-21 06:24:18 +13:00
|
|
|
const matCell = matCells.nodeAt(i);
|
|
|
|
const expandos = expandosFromNode(matCell);
|
2017-03-16 09:30:48 +13:00
|
|
|
if ( expandos.hostname === '*' || expandos.reqType === '*' ) {
|
2015-05-07 08:32:41 +12:00
|
|
|
continue;
|
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
const matRow = matCell.parentNode;
|
|
|
|
const counts = matRow.classList.contains('meta') ? 'totals' : 'counts';
|
|
|
|
const count = rows[expandos.hostname][counts][headerIndices.get(expandos.reqType)];
|
2017-03-16 09:30:48 +13:00
|
|
|
if ( count === expandos.count ) { continue; }
|
|
|
|
expandos.count = count;
|
2017-12-04 05:40:27 +13:00
|
|
|
matCell.textContent = cellTextFromCount(count);
|
2015-05-07 08:32:41 +12:00
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2015-05-07 08:32:41 +12:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const cellTextFromCount = function(count) {
|
2017-12-04 05:40:27 +13:00
|
|
|
if ( count === 0 ) { return '\u00A0'; }
|
|
|
|
if ( count < 100 ) { return count; }
|
|
|
|
return '99+';
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2017-12-04 05:40:27 +13:00
|
|
|
|
2015-05-07 08:32:41 +12:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2014-10-18 08:01:09 +13:00
|
|
|
// Update color of matrix cells(s)
|
|
|
|
// Color changes when rules change
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const updateMatrixColors = function() {
|
|
|
|
const cells = uDom('.matrix .matRow.rw > .matCell').removeClass();
|
|
|
|
for ( let i = 0; i < cells.length; i++ ) {
|
|
|
|
const cell = cells.nodeAt(i);
|
|
|
|
const expandos = expandosFromNode(cell);
|
2017-03-16 09:30:48 +13:00
|
|
|
addCellClass(cell, expandos.hostname, expandos.reqType);
|
2014-10-18 08:01:09 +13:00
|
|
|
}
|
2017-12-03 02:48:23 +13:00
|
|
|
popupWasResized();
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
// Update behavior of matrix:
|
|
|
|
// - Whether a section is collapsible or not. It is collapsible if:
|
|
|
|
// - It has at least one subdomain AND
|
|
|
|
// - There is no explicit rule anywhere in the subdomain cells AND
|
|
|
|
// - It is not part of group 3 (blacklisted hostnames)
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const updateMatrixBehavior = function() {
|
2014-10-19 09:49:06 +13:00
|
|
|
matrixList = matrixList || uDom('#matList');
|
2019-12-21 06:24:18 +13:00
|
|
|
const sections = matrixList.descendants('.matSection');
|
|
|
|
let i = sections.length;
|
2014-10-18 08:01:09 +13:00
|
|
|
while ( i-- ) {
|
2019-12-21 06:24:18 +13:00
|
|
|
const section = sections.at(i);
|
|
|
|
const subdomainRows = section.descendants('.l2:not(.g4)');
|
|
|
|
let j = subdomainRows.length;
|
2014-10-18 08:01:09 +13:00
|
|
|
while ( j-- ) {
|
2019-12-21 06:24:18 +13:00
|
|
|
const subdomainRow = subdomainRows.at(j);
|
|
|
|
subdomainRow.toggleClass(
|
|
|
|
'collapsible',
|
|
|
|
subdomainRow.descendants('.t81,.t82').length === 0
|
|
|
|
);
|
2014-10-18 08:01:09 +13:00
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
section.toggleClass(
|
|
|
|
'collapsible',
|
|
|
|
subdomainRows.filter('.collapsible').length > 0
|
|
|
|
);
|
2014-10-18 08:01:09 +13:00
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
// handle user interaction with filters
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const getCellAction = function(hostname, type, leaning) {
|
|
|
|
const temporaryColor = getTemporaryColor(hostname, type);
|
|
|
|
const hue = temporaryColor & 0x03;
|
2014-10-21 14:19:24 +13:00
|
|
|
// Special case: root toggle only between two states
|
|
|
|
if ( type === '*' && hostname === '*' ) {
|
|
|
|
return hue === Green ? 'blacklistMatrixCell' : 'whitelistMatrixCell';
|
|
|
|
}
|
|
|
|
// When explicitly blocked/allowed, can only graylist
|
2019-12-21 06:24:18 +13:00
|
|
|
const saturation = temporaryColor & 0x80;
|
2014-10-21 14:19:24 +13:00
|
|
|
if ( saturation === Dark ) {
|
|
|
|
return 'graylistMatrixCell';
|
|
|
|
}
|
|
|
|
return leaning === 'whitelisting' ? 'whitelistMatrixCell' : 'blacklistMatrixCell';
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-21 14:19:24 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const handleFilter = function(button, leaning) {
|
2014-10-18 08:01:09 +13:00
|
|
|
// our parent cell knows who we are
|
2019-12-21 06:24:18 +13:00
|
|
|
const cell = button.ancestors('div.matCell');
|
|
|
|
const expandos = expandosFromNode(cell);
|
|
|
|
const type = expandos.reqType;
|
|
|
|
const desHostname = expandos.hostname;
|
2014-10-30 02:27:11 +13:00
|
|
|
// https://github.com/gorhill/uMatrix/issues/24
|
|
|
|
// No hostname can happen -- like with blacklist meta row
|
2018-09-29 22:31:59 +12:00
|
|
|
if ( desHostname === '' ) { return; }
|
2019-12-21 06:24:18 +13:00
|
|
|
vAPI.messaging.send('default', {
|
2014-10-23 12:46:30 +13:00
|
|
|
what: getCellAction(desHostname, type, leaning),
|
2014-10-24 00:47:53 +13:00
|
|
|
srcHostname: matrixSnapshot.scope,
|
2014-10-23 12:46:30 +13:00
|
|
|
desHostname: desHostname,
|
2014-10-21 14:19:24 +13:00
|
|
|
type: type
|
2019-12-21 06:24:18 +13:00
|
|
|
}).then(( ) => {
|
|
|
|
updateMatrixSnapshot();
|
|
|
|
});
|
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const handleWhitelistFilter = function(button) {
|
2014-10-18 08:01:09 +13:00
|
|
|
handleFilter(button, 'whitelisting');
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const handleBlacklistFilter = function(button) {
|
2014-10-18 08:01:09 +13:00
|
|
|
handleFilter(button, 'blacklisting');
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
let matrixRowPool = [];
|
|
|
|
let matrixSectionPool = [];
|
|
|
|
let matrixGroupPool = [];
|
|
|
|
let matrixRowTemplate = null;
|
|
|
|
let matrixList = null;
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const startMatrixUpdate = function() {
|
2014-10-19 09:49:06 +13:00
|
|
|
matrixList = matrixList || uDom('#matList');
|
2014-10-18 08:01:09 +13:00
|
|
|
matrixList.detach();
|
2019-12-21 06:24:18 +13:00
|
|
|
const rows = matrixList.descendants('.matRow');
|
2014-10-18 08:01:09 +13:00
|
|
|
rows.detach();
|
|
|
|
matrixRowPool = matrixRowPool.concat(rows.toArray());
|
2019-12-21 06:24:18 +13:00
|
|
|
const sections = matrixList.descendants('.matSection');
|
2014-10-18 08:01:09 +13:00
|
|
|
sections.detach();
|
|
|
|
matrixSectionPool = matrixSectionPool.concat(sections.toArray());
|
2019-12-21 06:24:18 +13:00
|
|
|
const groups = matrixList.descendants('.matGroup');
|
2014-10-18 08:01:09 +13:00
|
|
|
groups.detach();
|
|
|
|
matrixGroupPool = matrixGroupPool.concat(groups.toArray());
|
|
|
|
};
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const endMatrixUpdate = function() {
|
2014-10-18 08:01:09 +13:00
|
|
|
// 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.
|
2014-10-20 17:53:13 +13:00
|
|
|
if ( matrixSnapshot.rowCount <= 1 ) {
|
2014-10-18 08:01:09 +13:00
|
|
|
matrixList.append(createMatrixRow().css('visibility', 'hidden'));
|
|
|
|
}
|
|
|
|
updateMatrixBehavior();
|
|
|
|
matrixList.css('display', '');
|
2014-10-19 09:49:06 +13:00
|
|
|
matrixList.appendTo('.paneContent');
|
2014-10-18 08:01:09 +13:00
|
|
|
};
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const createMatrixGroup = function() {
|
|
|
|
const group = matrixGroupPool.pop();
|
2014-10-18 08:01:09 +13:00
|
|
|
if ( group ) {
|
2014-10-19 09:49:06 +13:00
|
|
|
return uDom(group).removeClass().addClass('matGroup');
|
2014-10-18 08:01:09 +13:00
|
|
|
}
|
2015-07-22 00:29:15 +12:00
|
|
|
return uDom(document.createElement('div')).addClass('matGroup');
|
2014-10-18 08:01:09 +13:00
|
|
|
};
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const createMatrixSection = function() {
|
|
|
|
const section = matrixSectionPool.pop();
|
2014-10-18 08:01:09 +13:00
|
|
|
if ( section ) {
|
2014-10-19 09:49:06 +13:00
|
|
|
return uDom(section).removeClass().addClass('matSection');
|
2014-10-18 08:01:09 +13:00
|
|
|
}
|
2015-07-22 00:29:15 +12:00
|
|
|
return uDom(document.createElement('div')).addClass('matSection');
|
2014-10-18 08:01:09 +13:00
|
|
|
};
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const createMatrixRow = function() {
|
|
|
|
let row = matrixRowPool.pop();
|
2014-10-18 08:01:09 +13:00
|
|
|
if ( row ) {
|
|
|
|
row.style.visibility = '';
|
2014-10-19 09:49:06 +13:00
|
|
|
row = uDom(row);
|
|
|
|
row.descendants('.matCell').removeClass().addClass('matCell');
|
2014-10-18 08:01:09 +13:00
|
|
|
row.removeClass().addClass('matRow');
|
|
|
|
return row;
|
|
|
|
}
|
|
|
|
if ( matrixRowTemplate === null ) {
|
2014-10-19 09:49:06 +13:00
|
|
|
matrixRowTemplate = uDom('#templates .matRow');
|
2014-10-18 08:01:09 +13:00
|
|
|
}
|
|
|
|
return matrixRowTemplate.clone();
|
|
|
|
};
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const renderMatrixHeaderRow = function() {
|
|
|
|
const matHead = uDom('#matHead.collapsible');
|
2017-11-30 08:40:18 +13:00
|
|
|
matHead.toggleClass('collapsed', matrixSnapshot.collapseAllDomains === true);
|
2019-12-21 06:24:18 +13:00
|
|
|
const cells = matHead.descendants('.matCell');
|
|
|
|
cells.removeClass();
|
|
|
|
let cell = cells.nodeAt(0);
|
|
|
|
let expandos = expandosFromNode(cell);
|
2017-03-16 09:30:48 +13:00
|
|
|
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);
|
2017-04-28 00:10:54 +12:00
|
|
|
expandos.reqType = 'media';
|
2017-03-16 09:30:48 +13:00
|
|
|
expandos.hostname = '*';
|
2017-04-28 00:10:54 +12:00
|
|
|
addCellClass(cell, '*', 'media');
|
2017-03-16 09:30:48 +13:00
|
|
|
cell = cells.nodeAt(5);
|
|
|
|
expandos = expandosFromNode(cell);
|
|
|
|
expandos.reqType = 'script';
|
|
|
|
expandos.hostname = '*';
|
|
|
|
addCellClass(cell, '*', 'script');
|
|
|
|
cell = cells.nodeAt(6);
|
|
|
|
expandos = expandosFromNode(cell);
|
2019-12-21 06:24:18 +13:00
|
|
|
expandos.reqType = 'fetch';
|
2017-03-16 09:30:48 +13:00
|
|
|
expandos.hostname = '*';
|
2019-12-21 06:24:18 +13:00
|
|
|
addCellClass(cell, '*', 'fetch');
|
2017-03-16 09:30:48 +13:00
|
|
|
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');
|
2014-10-18 18:09:09 +13:00
|
|
|
uDom('#matHead .matRow').css('display', '');
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const renderMatrixCellDomain = function(cell, domain) {
|
|
|
|
const expandos = expandosFromNode(cell);
|
2017-03-16 09:30:48 +13:00
|
|
|
expandos.hostname = domain;
|
|
|
|
expandos.reqType = '*';
|
|
|
|
addCellClass(cell.nodeAt(0), domain, '*');
|
2019-12-21 06:24:18 +13:00
|
|
|
const contents = cell.contents();
|
2014-11-04 14:15:14 +13:00
|
|
|
contents.nodeAt(0).textContent = domain === '1st-party' ?
|
|
|
|
firstPartyLabel :
|
|
|
|
punycode.toUnicode(domain);
|
2014-10-19 10:11:10 +13:00
|
|
|
contents.nodeAt(1).textContent = ' ';
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const renderMatrixCellSubdomain = function(cell, domain, subomain) {
|
|
|
|
const expandos = expandosFromNode(cell);
|
2017-03-16 09:30:48 +13:00
|
|
|
expandos.hostname = subomain;
|
|
|
|
expandos.reqType = '*';
|
|
|
|
addCellClass(cell.nodeAt(0), subomain, '*');
|
2019-12-21 06:24:18 +13:00
|
|
|
const contents = cell.contents();
|
2014-11-04 08:27:59 +13:00
|
|
|
contents.nodeAt(0).textContent = punycode.toUnicode(subomain.slice(0, subomain.lastIndexOf(domain)-1)) + '.';
|
2014-10-19 10:11:10 +13:00
|
|
|
contents.nodeAt(1).textContent = punycode.toUnicode(domain);
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const renderMatrixMetaCellDomain = function(cell, domain) {
|
|
|
|
const expandos = expandosFromNode(cell);
|
2017-03-16 09:30:48 +13:00
|
|
|
expandos.hostname = domain;
|
|
|
|
expandos.reqType = '*';
|
|
|
|
addCellClass(cell.nodeAt(0), domain, '*');
|
2019-12-21 06:24:18 +13:00
|
|
|
const contents = cell.contents();
|
2014-11-04 08:27:59 +13:00
|
|
|
contents.nodeAt(0).textContent = '\u2217.' + punycode.toUnicode(domain);
|
2014-10-19 10:11:10 +13:00
|
|
|
contents.nodeAt(1).textContent = ' ';
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const renderMatrixCellType = function(cell, hostname, type, count) {
|
|
|
|
const node = cell.nodeAt(0);
|
|
|
|
const expandos = expandosFromNode(node);
|
2017-03-16 09:30:48 +13:00
|
|
|
expandos.hostname = hostname;
|
|
|
|
expandos.reqType = type;
|
|
|
|
expandos.count = count;
|
2017-12-04 05:40:27 +13:00
|
|
|
addCellClass(node, hostname, type);
|
|
|
|
node.textContent = cellTextFromCount(count);
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const renderMatrixCellTypes = function(cells, hostname, countName) {
|
|
|
|
const counts = matrixSnapshot.rows[hostname][countName];
|
|
|
|
const headerIndices = matrixSnapshot.headerIndices;
|
2017-11-29 06:33:22 +13:00
|
|
|
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')]);
|
2019-12-21 06:24:18 +13:00
|
|
|
renderMatrixCellType(cells.at(6), hostname, 'fetch', counts[headerIndices.get('fetch')]);
|
2017-11-29 06:33:22 +13:00
|
|
|
renderMatrixCellType(cells.at(7), hostname, 'frame', counts[headerIndices.get('frame')]);
|
|
|
|
renderMatrixCellType(cells.at(8), hostname, 'other', counts[headerIndices.get('other')]);
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixRowDomain = function(domain) {
|
|
|
|
const matrixRow = createMatrixRow().addClass('rw');
|
|
|
|
const cells = matrixRow.descendants('.matCell');
|
2014-10-19 10:11:10 +13:00
|
|
|
renderMatrixCellDomain(cells.at(0), domain);
|
2014-10-20 17:53:13 +13:00
|
|
|
renderMatrixCellTypes(cells, domain, 'counts');
|
2014-10-18 08:01:09 +13:00
|
|
|
return matrixRow;
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixRowSubdomain = function(domain, subdomain) {
|
|
|
|
const matrixRow = createMatrixRow().addClass('rw');
|
|
|
|
const cells = matrixRow.descendants('.matCell');
|
2014-10-19 10:11:10 +13:00
|
|
|
renderMatrixCellSubdomain(cells.at(0), domain, subdomain);
|
2014-10-20 17:53:13 +13:00
|
|
|
renderMatrixCellTypes(cells, subdomain, 'counts');
|
2014-10-18 08:01:09 +13:00
|
|
|
return matrixRow;
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixMetaRowDomain = function(domain) {
|
|
|
|
const matrixRow = createMatrixRow().addClass('rw');
|
|
|
|
const cells = matrixRow.descendants('.matCell');
|
2014-10-19 10:11:10 +13:00
|
|
|
renderMatrixMetaCellDomain(cells.at(0), domain);
|
2014-10-20 17:53:13 +13:00
|
|
|
renderMatrixCellTypes(cells, domain, 'totals');
|
2014-10-18 08:01:09 +13:00
|
|
|
return matrixRow;
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const renderMatrixMetaCellType = function(cell, count) {
|
2014-10-30 02:27:11 +13:00
|
|
|
// https://github.com/gorhill/uMatrix/issues/24
|
|
|
|
// Don't forget to reset cell properties
|
2019-12-21 06:24:18 +13:00
|
|
|
const node = cell.nodeAt(0);
|
|
|
|
const expandos = expandosFromNode(node);
|
2017-03-16 09:30:48 +13:00
|
|
|
expandos.hostname = '';
|
|
|
|
expandos.reqType = '';
|
|
|
|
expandos.count = count;
|
|
|
|
cell.addClass('t1');
|
2017-12-04 05:40:27 +13:00
|
|
|
node.textContent = cellTextFromCount(count);
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixMetaRow = function(totals) {
|
|
|
|
const headerIndices = matrixSnapshot.headerIndices;
|
|
|
|
const matrixRow = createMatrixRow().at(0).addClass('ro');
|
|
|
|
const cells = matrixRow.descendants('.matCell');
|
|
|
|
const contents = cells.at(0).addClass('t81').contents();
|
|
|
|
const expandos = expandosFromNode(cells.nodeAt(0));
|
2017-03-16 09:30:48 +13:00
|
|
|
expandos.hostname = '';
|
|
|
|
expandos.reqType = '*';
|
2014-10-19 10:11:10 +13:00
|
|
|
contents.nodeAt(0).textContent = ' ';
|
2015-05-18 06:56:53 +12:00
|
|
|
contents.nodeAt(1).textContent = blacklistedHostnamesLabel.replace(
|
|
|
|
'{{count}}',
|
2017-11-29 06:33:22 +13:00
|
|
|
totals[headerIndices.get('*')].toLocaleString()
|
2015-05-18 06:56:53 +12:00
|
|
|
);
|
2017-11-29 06:33:22 +13:00
|
|
|
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')]);
|
2019-12-21 06:24:18 +13:00
|
|
|
renderMatrixMetaCellType(cells.at(6), totals[headerIndices.get('fetch')]);
|
2017-11-29 06:33:22 +13:00
|
|
|
renderMatrixMetaCellType(cells.at(7), totals[headerIndices.get('frame')]);
|
|
|
|
renderMatrixMetaCellType(cells.at(8), totals[headerIndices.get('other')]);
|
2014-10-19 09:49:06 +13:00
|
|
|
return matrixRow;
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const computeMatrixGroupMetaStats = function(group) {
|
|
|
|
const headerIndices = matrixSnapshot.headerIndices;
|
|
|
|
const anyTypeIndex = headerIndices.get('*');
|
|
|
|
const n = headerIndices.size;
|
|
|
|
const totals = new Array(n);
|
|
|
|
totals.fill(0);
|
|
|
|
const rows = matrixSnapshot.rows;
|
|
|
|
for ( const hostname in rows ) {
|
|
|
|
if ( rows.hasOwnProperty(hostname) === false ) { continue; }
|
|
|
|
const row = rows[hostname];
|
|
|
|
if ( group.hasOwnProperty(row.domain) === false ) { continue; }
|
|
|
|
if ( row.counts[anyTypeIndex] === 0 ) { continue; }
|
2014-10-29 07:33:16 +13:00
|
|
|
totals[0] += 1;
|
2019-12-21 06:24:18 +13:00
|
|
|
for ( let i = 1; i < n; i++ ) {
|
2014-10-29 16:21:06 +13:00
|
|
|
totals[i] += row.counts[i];
|
|
|
|
}
|
2014-10-18 08:01:09 +13:00
|
|
|
}
|
2014-10-20 17:53:13 +13:00
|
|
|
return totals;
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
// Compare hostname helper, to order hostname in a logical manner:
|
|
|
|
// top-most < bottom-most, take into account whether IP address or
|
|
|
|
// named hostname
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const hostnameCompare = function(a,b) {
|
2014-10-18 08:01:09 +13:00
|
|
|
// Normalize: most significant parts first
|
|
|
|
if ( !a.match(/^\d+(\.\d+){1,3}$/) ) {
|
2019-12-21 06:24:18 +13:00
|
|
|
const aa = a.split('.');
|
2014-10-18 08:01:09 +13:00
|
|
|
a = aa.slice(-2).concat(aa.slice(0,-2).reverse()).join('.');
|
|
|
|
}
|
|
|
|
if ( !b.match(/^\d+(\.\d+){1,3}$/) ) {
|
2019-12-21 06:24:18 +13:00
|
|
|
const bb = b.split('.');
|
2014-10-18 08:01:09 +13:00
|
|
|
b = bb.slice(-2).concat(bb.slice(0,-2).reverse()).join('.');
|
|
|
|
}
|
|
|
|
return a.localeCompare(b);
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup0SectionDomain = function() {
|
2014-11-04 14:15:14 +13:00
|
|
|
return makeMatrixRowDomain('1st-party').addClass('g0 l1');
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup0Section = function() {
|
|
|
|
const domainDiv = createMatrixSection();
|
2017-03-16 09:30:48 +13:00
|
|
|
expandosFromNode(domainDiv).domain = '1st-party';
|
2014-10-23 12:46:30 +13:00
|
|
|
makeMatrixGroup0SectionDomain().appendTo(domainDiv);
|
2014-10-18 08:01:09 +13:00
|
|
|
return domainDiv;
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup0 = function() {
|
2014-10-23 14:26:37 +13:00
|
|
|
// Show literal "1st-party" row only if there is
|
|
|
|
// at least one 1st-party hostname
|
|
|
|
if ( Object.keys(groupsSnapshot[1]).length === 0 ) {
|
|
|
|
return;
|
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
const groupDiv = createMatrixGroup().addClass('g0');
|
2014-10-23 12:46:30 +13:00
|
|
|
makeMatrixGroup0Section().appendTo(groupDiv);
|
|
|
|
groupDiv.appendTo(matrixList);
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup1SectionDomain = function(domain) {
|
2014-10-18 08:01:09 +13:00
|
|
|
return makeMatrixRowDomain(domain)
|
|
|
|
.addClass('g1 l1');
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup1SectionSubomain = function(domain, subdomain) {
|
2014-10-18 08:01:09 +13:00
|
|
|
return makeMatrixRowSubdomain(domain, subdomain)
|
|
|
|
.addClass('g1 l2');
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup1SectionMetaDomain = function(domain) {
|
|
|
|
return makeMatrixMetaRowDomain(domain)
|
|
|
|
.addClass('g1 l1 meta');
|
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup1Section = function(hostnames) {
|
|
|
|
const domain = hostnames[0];
|
|
|
|
const domainDiv = createMatrixSection().toggleClass(
|
|
|
|
'collapsed',
|
|
|
|
getCollapseState(domain)
|
|
|
|
);
|
2017-03-16 09:30:48 +13:00
|
|
|
expandosFromNode(domainDiv).domain = domain;
|
2014-10-18 08:01:09 +13:00
|
|
|
if ( hostnames.length > 1 ) {
|
2019-12-21 06:24:18 +13:00
|
|
|
makeMatrixGroup1SectionMetaDomain(domain).appendTo(domainDiv);
|
2014-10-18 08:01:09 +13:00
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
makeMatrixGroup1SectionDomain(domain).appendTo(domainDiv);
|
|
|
|
for ( let i = 1; i < hostnames.length; i++ ) {
|
2014-10-18 08:01:09 +13:00
|
|
|
makeMatrixGroup1SectionSubomain(domain, hostnames[i])
|
|
|
|
.appendTo(domainDiv);
|
|
|
|
}
|
|
|
|
return domainDiv;
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup1 = function(group) {
|
|
|
|
const domains = Object.keys(group).sort(hostnameCompare);
|
2014-10-23 12:46:30 +13:00
|
|
|
if ( domains.length ) {
|
2019-12-21 06:24:18 +13:00
|
|
|
const groupDiv = createMatrixGroup().addClass('g1');
|
2014-10-20 17:53:13 +13:00
|
|
|
makeMatrixGroup1Section(Object.keys(group[domains[0]]).sort(hostnameCompare))
|
2014-10-18 08:01:09 +13:00
|
|
|
.appendTo(groupDiv);
|
2019-12-21 06:24:18 +13:00
|
|
|
for ( let i = 1; i < domains.length; i++ ) {
|
2014-10-20 17:53:13 +13:00
|
|
|
makeMatrixGroup1Section(Object.keys(group[domains[i]]).sort(hostnameCompare))
|
2014-10-18 08:01:09 +13:00
|
|
|
.appendTo(groupDiv);
|
|
|
|
}
|
|
|
|
groupDiv.appendTo(matrixList);
|
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup2SectionDomain = function(domain) {
|
2014-10-18 08:01:09 +13:00
|
|
|
return makeMatrixRowDomain(domain)
|
|
|
|
.addClass('g2 l1');
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup2SectionSubomain = function(domain, subdomain) {
|
2014-10-18 08:01:09 +13:00
|
|
|
return makeMatrixRowSubdomain(domain, subdomain)
|
|
|
|
.addClass('g2 l2');
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup2SectionMetaDomain = function(domain) {
|
2014-10-20 17:53:13 +13:00
|
|
|
return makeMatrixMetaRowDomain(domain).addClass('g2 l1 meta');
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup2Section = function(hostnames) {
|
|
|
|
const domain = hostnames[0];
|
|
|
|
const domainDiv = createMatrixSection()
|
2017-03-16 09:30:48 +13:00
|
|
|
.toggleClass('collapsed', getCollapseState(domain));
|
|
|
|
expandosFromNode(domainDiv).domain = domain;
|
2014-10-18 08:01:09 +13:00
|
|
|
if ( hostnames.length > 1 ) {
|
2014-10-20 17:53:13 +13:00
|
|
|
makeMatrixGroup2SectionMetaDomain(domain).appendTo(domainDiv);
|
2014-10-18 08:01:09 +13:00
|
|
|
}
|
|
|
|
makeMatrixGroup2SectionDomain(domain)
|
|
|
|
.appendTo(domainDiv);
|
2019-12-21 06:24:18 +13:00
|
|
|
for ( let i = 1; i < hostnames.length; i++ ) {
|
2014-10-18 08:01:09 +13:00
|
|
|
makeMatrixGroup2SectionSubomain(domain, hostnames[i])
|
|
|
|
.appendTo(domainDiv);
|
|
|
|
}
|
|
|
|
return domainDiv;
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup2 = function(group) {
|
|
|
|
const domains = Object.keys(group).sort(hostnameCompare);
|
2014-10-18 08:01:09 +13:00
|
|
|
if ( domains.length) {
|
2019-12-21 06:24:18 +13:00
|
|
|
const groupDiv = createMatrixGroup()
|
2014-10-18 08:01:09 +13:00
|
|
|
.addClass('g2');
|
2014-10-20 17:53:13 +13:00
|
|
|
makeMatrixGroup2Section(Object.keys(group[domains[0]]).sort(hostnameCompare))
|
2014-10-18 08:01:09 +13:00
|
|
|
.appendTo(groupDiv);
|
2019-12-21 06:24:18 +13:00
|
|
|
for ( let i = 1; i < domains.length; i++ ) {
|
2014-10-20 17:53:13 +13:00
|
|
|
makeMatrixGroup2Section(Object.keys(group[domains[i]]).sort(hostnameCompare))
|
2014-10-18 08:01:09 +13:00
|
|
|
.appendTo(groupDiv);
|
|
|
|
}
|
|
|
|
groupDiv.appendTo(matrixList);
|
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup3SectionDomain = function(domain) {
|
2014-10-18 08:01:09 +13:00
|
|
|
return makeMatrixRowDomain(domain)
|
|
|
|
.addClass('g3 l1');
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup3SectionSubomain = function(domain, subdomain) {
|
2014-10-18 08:01:09 +13:00
|
|
|
return makeMatrixRowSubdomain(domain, subdomain)
|
|
|
|
.addClass('g3 l2');
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup3SectionMetaDomain = function(domain) {
|
2014-10-23 12:46:30 +13:00
|
|
|
return makeMatrixMetaRowDomain(domain).addClass('g3 l1 meta');
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-23 12:46:30 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup3Section = function(hostnames) {
|
|
|
|
const domain = hostnames[0];
|
|
|
|
const domainDiv = createMatrixSection()
|
2017-03-16 09:30:48 +13:00
|
|
|
.toggleClass('collapsed', getCollapseState(domain));
|
|
|
|
expandosFromNode(domainDiv).domain = domain;
|
2014-10-23 12:46:30 +13:00
|
|
|
if ( hostnames.length > 1 ) {
|
|
|
|
makeMatrixGroup3SectionMetaDomain(domain).appendTo(domainDiv);
|
|
|
|
}
|
2014-10-18 08:01:09 +13:00
|
|
|
makeMatrixGroup3SectionDomain(domain)
|
|
|
|
.appendTo(domainDiv);
|
2019-12-21 06:24:18 +13:00
|
|
|
for ( let i = 1; i < hostnames.length; i++ ) {
|
2014-10-18 08:01:09 +13:00
|
|
|
makeMatrixGroup3SectionSubomain(domain, hostnames[i])
|
|
|
|
.appendTo(domainDiv);
|
|
|
|
}
|
|
|
|
return domainDiv;
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup3 = function(group) {
|
|
|
|
const domains = Object.keys(group).sort(hostnameCompare);
|
2014-10-23 12:46:30 +13:00
|
|
|
if ( domains.length) {
|
2019-12-21 06:24:18 +13:00
|
|
|
const groupDiv = createMatrixGroup()
|
2014-10-23 12:46:30 +13:00
|
|
|
.addClass('g3');
|
|
|
|
makeMatrixGroup3Section(Object.keys(group[domains[0]]).sort(hostnameCompare))
|
|
|
|
.appendTo(groupDiv);
|
2019-12-21 06:24:18 +13:00
|
|
|
for ( let i = 1; i < domains.length; i++ ) {
|
2014-10-23 12:46:30 +13:00
|
|
|
makeMatrixGroup3Section(Object.keys(group[domains[i]]).sort(hostnameCompare))
|
|
|
|
.appendTo(groupDiv);
|
|
|
|
}
|
|
|
|
groupDiv.appendTo(matrixList);
|
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-23 12:46:30 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup4SectionDomain = function(domain) {
|
2014-10-23 12:46:30 +13:00
|
|
|
return makeMatrixRowDomain(domain)
|
|
|
|
.addClass('g4 l1');
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-23 12:46:30 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup4SectionSubomain = function(domain, subdomain) {
|
2014-10-23 12:46:30 +13:00
|
|
|
return makeMatrixRowSubdomain(domain, subdomain)
|
|
|
|
.addClass('g4 l2');
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-23 12:46:30 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup4Section = function(hostnames) {
|
|
|
|
const domain = hostnames[0];
|
|
|
|
const domainDiv = createMatrixSection();
|
2017-03-16 09:30:48 +13:00
|
|
|
expandosFromNode(domainDiv).domain = domain;
|
2014-10-23 12:46:30 +13:00
|
|
|
makeMatrixGroup4SectionDomain(domain)
|
|
|
|
.appendTo(domainDiv);
|
2019-12-21 06:24:18 +13:00
|
|
|
for ( let i = 1; i < hostnames.length; i++ ) {
|
2014-10-23 12:46:30 +13:00
|
|
|
makeMatrixGroup4SectionSubomain(domain, hostnames[i])
|
|
|
|
.appendTo(domainDiv);
|
|
|
|
}
|
|
|
|
return domainDiv;
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-23 12:46:30 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMatrixGroup4 = function(group) {
|
|
|
|
const domains = Object.keys(group).sort(hostnameCompare);
|
|
|
|
if ( domains.length === 0 ) { return; }
|
|
|
|
const groupDiv = createMatrixGroup().addClass('g4');
|
2014-10-18 08:01:09 +13:00
|
|
|
createMatrixSection()
|
2014-10-23 12:46:30 +13:00
|
|
|
.addClass('g4Meta')
|
2017-11-30 08:40:18 +13:00
|
|
|
.toggleClass('g4Collapsed', !!matrixSnapshot.collapseBlacklistedDomains)
|
2014-10-18 08:01:09 +13:00
|
|
|
.appendTo(groupDiv);
|
2014-10-23 12:46:30 +13:00
|
|
|
makeMatrixMetaRow(computeMatrixGroupMetaStats(group), 'g4')
|
2014-10-18 08:01:09 +13:00
|
|
|
.appendTo(groupDiv);
|
2014-10-23 12:46:30 +13:00
|
|
|
makeMatrixGroup4Section(Object.keys(group[domains[0]]).sort(hostnameCompare))
|
2014-10-18 08:01:09 +13:00
|
|
|
.appendTo(groupDiv);
|
2019-12-21 06:24:18 +13:00
|
|
|
for ( let i = 1; i < domains.length; i++ ) {
|
2014-10-23 12:46:30 +13:00
|
|
|
makeMatrixGroup4Section(Object.keys(group[domains[i]]).sort(hostnameCompare))
|
2014-10-18 08:01:09 +13:00
|
|
|
.appendTo(groupDiv);
|
|
|
|
}
|
|
|
|
groupDiv.appendTo(matrixList);
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const makeMenu = function() {
|
|
|
|
const groupStats = getGroupStats();
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2017-11-23 01:07:34 +13:00
|
|
|
if ( Object.keys(groupStats).length === 0 ) { return; }
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/31
|
|
|
|
if ( matrixCellHotspots ) {
|
|
|
|
matrixCellHotspots.detach();
|
|
|
|
}
|
|
|
|
|
|
|
|
renderMatrixHeaderRow();
|
|
|
|
|
|
|
|
startMatrixUpdate();
|
|
|
|
makeMatrixGroup0(groupStats[0]);
|
|
|
|
makeMatrixGroup1(groupStats[1]);
|
|
|
|
makeMatrixGroup2(groupStats[2]);
|
|
|
|
makeMatrixGroup3(groupStats[3]);
|
2014-10-23 12:46:30 +13:00
|
|
|
makeMatrixGroup4(groupStats[4]);
|
2014-10-18 08:01:09 +13:00
|
|
|
endMatrixUpdate();
|
|
|
|
|
2018-09-29 22:31:59 +12:00
|
|
|
uMatrixScopeWidget.init(
|
|
|
|
matrixSnapshot.domain,
|
|
|
|
matrixSnapshot.hostname,
|
|
|
|
matrixSnapshot.scope
|
|
|
|
);
|
2014-10-18 08:01:09 +13:00
|
|
|
updateMatrixButtons();
|
2015-07-29 07:00:31 +12:00
|
|
|
resizePopup();
|
2018-01-30 11:19:42 +13:00
|
|
|
recipeManager.fetch();
|
2014-10-20 17:53:13 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
// Do all the stuff that needs to be done before building menu et al.
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const initMenuEnvironment = function() {
|
2017-11-25 11:22:42 +13:00
|
|
|
document.body.style.setProperty(
|
|
|
|
'font-size',
|
|
|
|
getUserSetting('displayTextSize')
|
|
|
|
);
|
2018-02-01 04:00:33 +13:00
|
|
|
uDom.nodeFromId('version').textContent = matrixSnapshot.appVersion || '';
|
2017-11-25 11:22:42 +13:00
|
|
|
document.body.classList.toggle(
|
2017-11-25 13:55:48 +13:00
|
|
|
'colorblind',
|
2017-11-25 11:22:42 +13:00
|
|
|
getUserSetting('colorBlindFriendly')
|
|
|
|
);
|
2018-02-01 04:00:33 +13:00
|
|
|
document.body.classList.toggle(
|
|
|
|
'noTooltips',
|
|
|
|
getUserSetting('noTooltips')
|
|
|
|
);
|
2014-10-21 14:19:24 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const prettyNames = matrixHeaderPrettyNames;
|
|
|
|
const keys = Object.keys(prettyNames);
|
|
|
|
let i = keys.length;
|
2014-10-18 08:01:09 +13:00
|
|
|
while ( i-- ) {
|
2019-12-21 06:24:18 +13:00
|
|
|
const key = keys[i];
|
|
|
|
const cell = uDom('#matHead .matCell[data-req-type="'+ key +'"]');
|
|
|
|
const text = vAPI.i18n(key + 'PrettyName');
|
2014-10-18 08:01:09 +13:00
|
|
|
cell.text(text);
|
|
|
|
prettyNames[key] = text;
|
|
|
|
}
|
2014-10-29 07:33:16 +13:00
|
|
|
|
2014-11-04 08:27:59 +13:00
|
|
|
firstPartyLabel = uDom('[data-i18n="matrix1stPartyLabel"]').text();
|
|
|
|
blacklistedHostnamesLabel = uDom('[data-i18n="matrixBlacklistedHostnames"]').text();
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const scopeChangeHandler = function(ev) {
|
|
|
|
const newScope = ev.detail.scope;
|
2017-11-22 05:57:41 +13:00
|
|
|
if ( !newScope || matrixSnapshot.scope === newScope ) { return; }
|
2017-11-22 04:36:08 +13:00
|
|
|
matrixSnapshot.scope = newScope;
|
2015-05-07 16:39:17 +12:00
|
|
|
matrixSnapshot.tMatrixModifiedTime = undefined;
|
2014-10-20 17:53:13 +13:00
|
|
|
updateMatrixSnapshot();
|
2014-10-18 08:01:09 +13:00
|
|
|
dropDownMenuHide();
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const updateMatrixSwitches = function() {
|
|
|
|
const switches = matrixSnapshot.tSwitches;
|
|
|
|
let count = 0;
|
|
|
|
for ( const switchName in switches ) {
|
2017-12-22 02:30:05 +13:00
|
|
|
if ( switches.hasOwnProperty(switchName) === false ) { continue; }
|
2019-12-21 06:24:18 +13:00
|
|
|
const enabled = switches[switchName];
|
2016-08-12 11:21:51 +12:00
|
|
|
if ( enabled && switchName !== 'matrix-off' ) {
|
|
|
|
count += 1;
|
|
|
|
}
|
2016-08-12 01:18:15 +12:00
|
|
|
uDom('#mtxSwitch_' + switchName).toggleClass('switchTrue', enabled);
|
2014-11-19 15:18:57 +13:00
|
|
|
}
|
2017-12-22 02:30:05 +13:00
|
|
|
uDom.nodeFromId('mtxSwitch_https-strict').classList.toggle(
|
|
|
|
'relevant',
|
2019-12-21 06:24:18 +13:00
|
|
|
matrixSnapshot.hasMixedContent === true
|
2017-12-22 02:30:05 +13:00
|
|
|
);
|
2018-01-01 12:18:10 +13:00
|
|
|
uDom.nodeFromId('mtxSwitch_no-workers').classList.toggle(
|
|
|
|
'relevant',
|
2019-12-21 06:24:18 +13:00
|
|
|
matrixSnapshot.hasWebWorkers === true
|
2018-01-01 12:18:10 +13:00
|
|
|
);
|
2017-12-22 02:30:05 +13:00
|
|
|
uDom.nodeFromId('mtxSwitch_referrer-spoof').classList.toggle(
|
|
|
|
'relevant',
|
2019-12-21 06:24:18 +13:00
|
|
|
matrixSnapshot.has3pReferrer === true
|
2017-12-22 02:30:05 +13:00
|
|
|
);
|
|
|
|
uDom.nodeFromId('mtxSwitch_noscript-spoof').classList.toggle(
|
|
|
|
'relevant',
|
2019-12-21 06:24:18 +13:00
|
|
|
matrixSnapshot.hasNoscriptTags === true
|
|
|
|
);
|
|
|
|
uDom.nodeFromId('mtxSwitch_cname-reveal').classList.toggle(
|
|
|
|
'relevant',
|
|
|
|
matrixSnapshot.hasHostnameAliases === true
|
2017-12-22 02:30:05 +13:00
|
|
|
);
|
2018-10-04 03:01:41 +13:00
|
|
|
uDom.nodeFromSelector('#buttonMtxSwitches .fa-icon-badge').textContent =
|
2017-12-22 02:30:05 +13:00
|
|
|
count.toLocaleString();
|
2018-10-04 03:01:41 +13:00
|
|
|
uDom.nodeFromSelector('#mtxSwitch_matrix-off .fa-icon-badge').textContent =
|
2017-12-22 02:30:05 +13:00
|
|
|
matrixSnapshot.blockedCount.toLocaleString();
|
|
|
|
document.body.classList.toggle('powerOff', switches['matrix-off']);
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const toggleMatrixSwitch = function(ev) {
|
2017-12-17 04:45:50 +13:00
|
|
|
if ( ev.target.localName === 'a' ) { return; }
|
2019-12-21 06:24:18 +13:00
|
|
|
const elem = ev.currentTarget;
|
|
|
|
const pos = elem.id.indexOf('_');
|
2017-12-17 03:28:57 +13:00
|
|
|
if ( pos === -1 ) { return; }
|
2019-12-21 06:24:18 +13:00
|
|
|
const switchName = elem.id.slice(pos + 1);
|
|
|
|
vAPI.messaging.send('popup.js', {
|
2014-10-21 14:19:24 +13:00
|
|
|
what: 'toggleMatrixSwitch',
|
2014-11-19 15:18:57 +13:00
|
|
|
switchName: switchName,
|
2019-12-21 06:24:18 +13:00
|
|
|
srcHostname: matrixSnapshot.scope,
|
|
|
|
}).then(( ) => {
|
|
|
|
updateMatrixSnapshot();
|
|
|
|
});
|
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const updatePersistButton = function() {
|
|
|
|
const diffCount = matrixSnapshot.diff.length;
|
|
|
|
const button = uDom('#buttonPersist');
|
2014-10-18 08:01:09 +13:00
|
|
|
button.contents()
|
|
|
|
.filter(function(){return this.nodeType===3;})
|
2014-10-19 09:49:06 +13:00
|
|
|
.first()
|
2014-10-21 09:40:09 +13:00
|
|
|
.text(diffCount > 0 ? '\uf13e' : '\uf023');
|
2018-10-04 03:01:41 +13:00
|
|
|
button.descendants('.fa-icon-badge').text(diffCount > 0 ? diffCount : '');
|
2019-12-21 06:24:18 +13:00
|
|
|
const disabled = diffCount === 0;
|
2014-10-18 08:01:09 +13:00
|
|
|
button.toggleClass('disabled', disabled);
|
2014-10-18 18:09:09 +13:00
|
|
|
uDom('#buttonRevertScope').toggleClass('disabled', disabled);
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2014-10-21 09:40:09 +13:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const persistMatrix = function() {
|
|
|
|
vAPI.messaging.send('popup.js', {
|
2014-10-21 09:40:09 +13:00
|
|
|
what: 'applyDiffToPermanentMatrix',
|
2019-12-21 06:24:18 +13:00
|
|
|
diff: matrixSnapshot.diff,
|
|
|
|
}).then(( ) => {
|
|
|
|
updateMatrixSnapshot();
|
|
|
|
});
|
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
// rhill 2014-03-12: revert completely ALL changes related to the
|
|
|
|
// current page, including scopes.
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const revertMatrix = function() {
|
|
|
|
vAPI.messaging.send('popup.js', {
|
2014-10-21 09:40:09 +13:00
|
|
|
what: 'applyDiffToTemporaryMatrix',
|
2019-12-21 06:24:18 +13:00
|
|
|
diff: matrixSnapshot.diff,
|
|
|
|
}).then(( ) => {
|
|
|
|
updateMatrixSnapshot();
|
|
|
|
});
|
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
// Buttons which are affected by any changes in the matrix
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const updateMatrixButtons = function() {
|
2018-09-29 22:31:59 +12:00
|
|
|
uMatrixScopeWidget.update(matrixSnapshot.scope);
|
2014-11-19 15:18:57 +13:00
|
|
|
updateMatrixSwitches();
|
2014-10-18 08:01:09 +13:00
|
|
|
updatePersistButton();
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
uDom('#buttonReload').on('click', ev => {
|
2018-09-29 22:31:59 +12:00
|
|
|
vAPI.messaging.send('default', {
|
2014-10-18 08:01:09 +13:00
|
|
|
what: 'forceReloadTab',
|
2017-11-20 12:18:02 +13:00
|
|
|
tabId: matrixSnapshot.tabId,
|
2018-01-09 01:34:09 +13:00
|
|
|
bypassCache: ev.ctrlKey || ev.metaKey || ev.shiftKey
|
2014-10-18 08:01:09 +13:00
|
|
|
});
|
2019-12-21 06:24:18 +13:00
|
|
|
});
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const recipeManager = (( ) => {
|
|
|
|
const reScopeAlias = /(^|\s+)_(\s+|$)/g;
|
2018-01-30 11:19:42 +13:00
|
|
|
let recipes = [];
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const createEntry = function(name, ruleset, parent) {
|
|
|
|
const li = document.querySelector('#templates li.recipe')
|
2018-01-30 11:19:42 +13:00
|
|
|
.cloneNode(true);
|
|
|
|
li.querySelector('.name').textContent = name;
|
|
|
|
li.querySelector('.ruleset').textContent = ruleset;
|
|
|
|
if ( parent ) {
|
|
|
|
parent.appendChild(li);
|
|
|
|
}
|
|
|
|
return li;
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2018-01-30 11:19:42 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const apply = function(ev) {
|
2018-03-25 01:01:25 +13:00
|
|
|
if (
|
|
|
|
ev.target.classList.contains('expander') ||
|
|
|
|
ev.target.classList.contains('name')
|
|
|
|
) {
|
2018-01-30 11:19:42 +13:00
|
|
|
ev.currentTarget.classList.toggle('expanded');
|
|
|
|
return;
|
|
|
|
}
|
2018-03-25 01:01:25 +13:00
|
|
|
if (
|
|
|
|
ev.target.classList.contains('importer') === false &&
|
|
|
|
ev.target.classList.contains('committer') === false
|
|
|
|
) {
|
|
|
|
return;
|
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
const root = ev.currentTarget;
|
|
|
|
const ruleset = root.querySelector('.ruleset');
|
|
|
|
const commit = ev.target.classList.contains('committer');
|
|
|
|
vAPI.messaging.send('popup.js', {
|
|
|
|
what: 'applyRecipe',
|
|
|
|
ruleset: ruleset.textContent,
|
|
|
|
commit,
|
|
|
|
}).then(( ) => {
|
|
|
|
updateMatrixSnapshot();
|
|
|
|
});
|
2018-03-25 01:01:25 +13:00
|
|
|
root.classList.remove('mustImport');
|
2018-01-30 11:19:42 +13:00
|
|
|
if ( commit ) {
|
|
|
|
root.classList.remove('mustCommit');
|
|
|
|
}
|
|
|
|
//dropDownMenuHide();
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2018-01-30 11:19:42 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const show = function(details) {
|
|
|
|
const root = document.querySelector('#dropDownMenuRecipes .dropdown-menu');
|
|
|
|
const ul = document.createElement('ul');
|
|
|
|
for ( const recipe of details.recipes ) {
|
2018-01-30 11:19:42 +13:00
|
|
|
let li = createEntry(
|
|
|
|
recipe.name,
|
|
|
|
recipe.ruleset.replace(reScopeAlias, '$1' + details.scope + '$2'),
|
|
|
|
ul
|
|
|
|
);
|
2018-03-25 01:01:25 +13:00
|
|
|
li.classList.toggle('mustImport', recipe.mustImport === true);
|
2018-01-30 11:19:42 +13:00
|
|
|
li.classList.toggle('mustCommit', recipe.mustCommit === true);
|
|
|
|
li.addEventListener('click', apply);
|
|
|
|
}
|
|
|
|
root.replaceChild(ul, root.querySelector('ul'));
|
|
|
|
dropDownMenuShow(uDom.nodeFromId('buttonRecipes'));
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2018-01-30 11:19:42 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const beforeShow = async function() {
|
2018-01-30 11:19:42 +13:00
|
|
|
if ( recipes.length === 0 ) { return; }
|
2019-12-21 06:24:18 +13:00
|
|
|
const details = await vAPI.messaging.send('popup.js', {
|
|
|
|
what: 'fetchRecipeCommitStatuses',
|
|
|
|
scope: matrixSnapshot.scope,
|
|
|
|
recipes: recipes,
|
|
|
|
});
|
|
|
|
show(details);
|
|
|
|
};
|
2018-01-30 11:19:42 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const fetch = async function() {
|
|
|
|
const desHostnames = [];
|
|
|
|
for ( const hostname in matrixSnapshot.rows ) {
|
2018-01-30 11:19:42 +13:00
|
|
|
if ( matrixSnapshot.rows.hasOwnProperty(hostname) === false ) {
|
|
|
|
continue;
|
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
const row = matrixSnapshot.rows[hostname];
|
2018-01-30 11:19:42 +13:00
|
|
|
if ( row.domain === matrixSnapshot.domain ) { continue; }
|
|
|
|
if ( row.counts[0] !== 0 || row.domain === hostname ) {
|
|
|
|
desHostnames.push(hostname);
|
|
|
|
}
|
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
const response = await vAPI.messaging.send('popup.js', {
|
|
|
|
what: 'fetchRecipes',
|
|
|
|
srcHostname: matrixSnapshot.hostname,
|
|
|
|
desHostnames: desHostnames
|
|
|
|
});
|
|
|
|
recipes = Array.isArray(response) ? response : [];
|
|
|
|
const button = uDom.nodeFromId('buttonRecipes');
|
|
|
|
if ( recipes.length === 0 ) {
|
|
|
|
button.classList.add('disabled');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
button.classList.remove('disabled');
|
|
|
|
button.querySelector('.fa-icon-badge').textContent = recipes.length;
|
2018-01-30 11:19:42 +13:00
|
|
|
};
|
2019-12-21 06:24:18 +13:00
|
|
|
|
|
|
|
return { fetch, show: beforeShow, apply };
|
2018-01-30 11:19:42 +13:00
|
|
|
})();
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const revertAll = function() {
|
|
|
|
vAPI.messaging.send('popup.js', {
|
|
|
|
what: 'revertTemporaryMatrix'
|
|
|
|
}).then(( ) => {
|
|
|
|
updateMatrixSnapshot();
|
|
|
|
});
|
|
|
|
};
|
2018-01-30 11:19:42 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const mouseenterMatrixCellHandler = function(ev) {
|
2015-05-04 12:55:27 +12:00
|
|
|
matrixCellHotspots.appendTo(ev.target);
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const mouseleaveMatrixCellHandler = function() {
|
2014-10-18 08:01:09 +13:00
|
|
|
matrixCellHotspots.detach();
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const gotoExtensionURL = function(ev) {
|
|
|
|
const target = ev.currentTarget;
|
|
|
|
if ( target.hasAttribute('data-extension-url') === false ) { return; }
|
|
|
|
let url = target.getAttribute('data-extension-url');
|
|
|
|
if ( url === '' ) { return; }
|
|
|
|
if (
|
|
|
|
url === 'logger-ui.html#_' &&
|
|
|
|
typeof matrixSnapshot.tabId === 'number'
|
|
|
|
) {
|
|
|
|
url += '+' + matrixSnapshot.tabId;
|
2014-10-18 08:01:09 +13:00
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
vAPI.messaging.send('popup.js', {
|
|
|
|
what: 'gotoExtensionURL',
|
|
|
|
url,
|
|
|
|
select: true,
|
|
|
|
shiftKey: ev.shiftKey,
|
|
|
|
});
|
2015-05-07 02:04:49 +12:00
|
|
|
dropDownMenuHide();
|
2015-05-03 05:43:50 +12:00
|
|
|
vAPI.closePopup();
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const dropDownMenuShow = function(button) {
|
|
|
|
const menuOverlay = document.getElementById(
|
|
|
|
button.getAttribute('data-dropdown-menu')
|
|
|
|
);
|
|
|
|
const butnRect = button.getBoundingClientRect();
|
|
|
|
const viewRect = document.body.getBoundingClientRect();
|
|
|
|
const butnNormalLeft = butnRect.left / (viewRect.width - butnRect.width);
|
2017-12-17 03:28:57 +13:00
|
|
|
menuOverlay.classList.add('show');
|
2019-12-21 06:24:18 +13:00
|
|
|
const menu = menuOverlay.querySelector('.dropdown-menu');
|
|
|
|
const menuRect = menu.getBoundingClientRect();
|
|
|
|
const menuLeft = butnNormalLeft * (viewRect.width - menuRect.width);
|
2017-12-17 03:28:57 +13:00
|
|
|
menu.style.top = butnRect.bottom + 'px';
|
2018-03-25 01:01:25 +13:00
|
|
|
if ( menuOverlay.classList.contains('dropdown-menu-centered') === false ) {
|
|
|
|
menu.style.left = menuLeft.toFixed(0) + 'px';
|
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const dropDownMenuHide = function() {
|
2017-12-17 03:28:57 +13:00
|
|
|
uDom('.dropdown-menu-capture').removeClass('show');
|
2019-12-21 06:24:18 +13:00
|
|
|
};
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const onMatrixSnapshotReady = function(response) {
|
2017-11-25 11:22:42 +13:00
|
|
|
if ( response === 'ENOTFOUND' ) {
|
|
|
|
uDom.nodeFromId('noTabFound').textContent =
|
|
|
|
vAPI.i18n('matrixNoTabFound');
|
|
|
|
document.body.classList.add('noTabFound');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-10-18 08:01:09 +13:00
|
|
|
// Now that tabId and pageURL are set, we can build our menu
|
|
|
|
initMenuEnvironment();
|
|
|
|
makeMenu();
|
|
|
|
|
|
|
|
// After popup menu is built, check whether there is a non-empty matrix
|
2014-10-21 14:19:24 +13:00
|
|
|
if ( matrixSnapshot.url === '' ) {
|
2014-10-19 09:49:06 +13:00
|
|
|
uDom('#matHead').remove();
|
2017-11-22 04:36:08 +13:00
|
|
|
uDom('#toolbarContainer').remove();
|
2014-10-18 08:01:09 +13:00
|
|
|
|
|
|
|
// https://github.com/gorhill/httpswitchboard/issues/191
|
2015-04-12 09:15:57 +12:00
|
|
|
uDom('#noNetTrafficPrompt').text(vAPI.i18n('matrixNoNetTrafficPrompt'));
|
2014-10-18 18:09:09 +13:00
|
|
|
uDom('#noNetTrafficPrompt').css('display', '');
|
2014-10-18 08:01:09 +13:00
|
|
|
}
|
2015-05-03 10:33:55 +12:00
|
|
|
|
|
|
|
// Create a hash to find out whether the reload button needs to be
|
|
|
|
// highlighted.
|
|
|
|
// TODO:
|
2014-10-18 08:01:09 +13:00
|
|
|
};
|
|
|
|
|
2015-07-25 00:22:54 +12:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
const matrixSnapshotPoller = (( ) => {
|
2019-02-03 04:13:25 +13:00
|
|
|
let timer;
|
2015-05-06 16:30:45 +12:00
|
|
|
|
2019-02-03 04:13:25 +13:00
|
|
|
const preprocessMatrixSnapshot = function(snapshot) {
|
2017-11-29 06:33:22 +13:00
|
|
|
if ( Array.isArray(snapshot.headerIndices) ) {
|
|
|
|
snapshot.headerIndices = new Map(snapshot.headerIndices);
|
|
|
|
}
|
|
|
|
return snapshot;
|
|
|
|
};
|
|
|
|
|
2019-02-03 04:13:25 +13:00
|
|
|
const processPollResult = function(response) {
|
2019-12-21 06:24:18 +13:00
|
|
|
if ( typeof response !== 'object' ) { return; }
|
2015-05-07 10:59:07 +12:00
|
|
|
if (
|
|
|
|
response.mtxContentModified === false &&
|
|
|
|
response.mtxCountModified === false &&
|
2015-05-07 16:39:17 +12:00
|
|
|
response.pMatrixModified === false &&
|
|
|
|
response.tMatrixModified === false
|
2015-05-07 10:59:07 +12:00
|
|
|
) {
|
|
|
|
return;
|
|
|
|
}
|
2019-02-03 04:13:25 +13:00
|
|
|
if ( response instanceof Object ) {
|
|
|
|
matrixSnapshot = preprocessMatrixSnapshot(response);
|
|
|
|
}
|
2015-05-07 10:59:07 +12:00
|
|
|
if ( response.mtxContentModified ) {
|
|
|
|
makeMenu();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ( response.mtxCountModified ) {
|
|
|
|
updateMatrixCounts();
|
|
|
|
}
|
2015-05-07 16:39:17 +12:00
|
|
|
if (
|
|
|
|
response.pMatrixModified ||
|
|
|
|
response.tMatrixModified ||
|
|
|
|
response.scopeModified
|
|
|
|
) {
|
2015-05-07 10:59:07 +12:00
|
|
|
updateMatrixColors();
|
|
|
|
updateMatrixBehavior();
|
|
|
|
updateMatrixButtons();
|
2015-05-06 16:30:45 +12:00
|
|
|
}
|
2015-05-07 05:01:02 +12:00
|
|
|
};
|
2015-05-06 16:30:45 +12:00
|
|
|
|
2019-02-03 04:13:25 +13:00
|
|
|
const onPolled = function(response) {
|
2015-05-07 10:59:07 +12:00
|
|
|
processPollResult(response);
|
|
|
|
pollAsync();
|
|
|
|
};
|
|
|
|
|
2019-02-03 04:13:25 +13:00
|
|
|
const pollNow = function() {
|
2015-05-07 08:32:41 +12:00
|
|
|
unpollAsync();
|
2017-12-07 03:47:20 +13:00
|
|
|
vAPI.messaging.send('popup.js', {
|
2015-05-07 05:01:02 +12:00
|
|
|
what: 'matrixSnapshot',
|
|
|
|
tabId: matrixSnapshot.tabId,
|
2017-11-22 04:36:08 +13:00
|
|
|
scope: matrixSnapshot.scope,
|
2015-05-07 05:01:02 +12:00
|
|
|
mtxContentModifiedTime: matrixSnapshot.mtxContentModifiedTime,
|
2015-05-07 16:39:17 +12:00
|
|
|
mtxCountModifiedTime: matrixSnapshot.mtxCountModifiedTime,
|
|
|
|
mtxDiffCount: matrixSnapshot.diff.length,
|
|
|
|
pMatrixModifiedTime: matrixSnapshot.pMatrixModifiedTime,
|
|
|
|
tMatrixModifiedTime: matrixSnapshot.tMatrixModifiedTime,
|
2019-12-21 06:24:18 +13:00
|
|
|
}).then(response => {
|
|
|
|
onPolled(response);
|
|
|
|
});
|
2014-10-21 09:40:09 +13:00
|
|
|
};
|
2015-05-07 05:01:02 +12:00
|
|
|
|
2019-02-03 04:13:25 +13:00
|
|
|
const pollAsync = function() {
|
|
|
|
if ( timer !== undefined ) { return; }
|
|
|
|
if ( document.defaultView === null ) { return; }
|
2019-12-21 06:24:18 +13:00
|
|
|
//if ( typeof matrixSnapshot.tabId !== 'number' ) { return; }
|
2019-02-03 04:13:25 +13:00
|
|
|
timer = vAPI.setTimeout(
|
|
|
|
( ) => {
|
|
|
|
timer = undefined;
|
|
|
|
pollNow();
|
|
|
|
},
|
|
|
|
1414
|
|
|
|
);
|
2014-10-28 17:38:02 +13:00
|
|
|
};
|
2015-05-07 05:01:02 +12:00
|
|
|
|
2019-02-03 04:13:25 +13:00
|
|
|
const unpollAsync = function() {
|
|
|
|
if ( timer !== undefined ) {
|
2015-05-07 05:01:02 +12:00
|
|
|
clearTimeout(timer);
|
2019-02-03 04:13:25 +13:00
|
|
|
timer = undefined;
|
2015-05-07 05:01:02 +12:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
vAPI.messaging.send('popup.js', {
|
|
|
|
what: 'matrixSnapshot',
|
|
|
|
tabId: matrixSnapshot.tabId,
|
|
|
|
}).then(response => {
|
|
|
|
if ( response instanceof Object ) {
|
|
|
|
matrixSnapshot = preprocessMatrixSnapshot(response);
|
2015-05-07 05:01:02 +12:00
|
|
|
}
|
2019-12-21 06:24:18 +13:00
|
|
|
onMatrixSnapshotReady(response);
|
|
|
|
pollAsync();
|
|
|
|
});
|
2015-05-07 05:01:02 +12:00
|
|
|
|
2015-05-07 10:59:07 +12:00
|
|
|
return {
|
|
|
|
pollNow: pollNow
|
|
|
|
};
|
2015-05-07 05:01:02 +12:00
|
|
|
})();
|
2014-10-20 17:53:13 +13:00
|
|
|
|
2014-10-18 08:01:09 +13:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2015-05-07 08:32:41 +12:00
|
|
|
// 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() {
|
|
|
|
handleWhitelistFilter(uDom(this));
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
uDom('#blacklist').on('click', function() {
|
|
|
|
handleBlacklistFilter(uDom(this));
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
uDom('#domainOnly').on('click', function() {
|
|
|
|
toggleCollapseState(uDom(this));
|
|
|
|
return false;
|
2014-10-18 08:01:09 +13:00
|
|
|
});
|
2015-05-07 08:32:41 +12:00
|
|
|
matrixCellHotspots = uDom('#cellHotspots').detach();
|
|
|
|
uDom('body')
|
|
|
|
.on('mouseenter', '.matCell', mouseenterMatrixCellHandler)
|
|
|
|
.on('mouseleave', '.matCell', mouseleaveMatrixCellHandler);
|
2018-09-29 22:31:59 +12:00
|
|
|
window.addEventListener('uMatrixScopeWidgetChange', scopeChangeHandler);
|
2018-01-30 11:19:42 +13:00
|
|
|
uDom('#buttonMtxSwitches').on('click', function(ev) {
|
|
|
|
dropDownMenuShow(ev.target);
|
|
|
|
});
|
2015-05-07 08:32:41 +12:00
|
|
|
uDom('[id^="mtxSwitch_"]').on('click', toggleMatrixSwitch);
|
|
|
|
uDom('#buttonPersist').on('click', persistMatrix);
|
|
|
|
uDom('#buttonRevertScope').on('click', revertMatrix);
|
|
|
|
|
2018-01-30 11:19:42 +13:00
|
|
|
uDom('#buttonRecipes').on('click', function() {
|
|
|
|
recipeManager.show();
|
|
|
|
});
|
|
|
|
|
2015-05-07 08:32:41 +12:00
|
|
|
uDom('#buttonRevertAll').on('click', revertAll);
|
2019-12-21 06:24:18 +13:00
|
|
|
uDom('[data-extension-url]').on('click', gotoExtensionURL);
|
2015-05-07 08:32:41 +12:00
|
|
|
uDom('body').on('click', '.dropdown-menu-capture', dropDownMenuHide);
|
|
|
|
|
2017-12-01 03:31:14 +13:00
|
|
|
uDom('#matList').on('click', '.g4Meta', function(ev) {
|
|
|
|
matrixSnapshot.collapseBlacklistedDomains =
|
|
|
|
ev.target.classList.toggle('g4Collapsed');
|
|
|
|
setUserSetting(
|
|
|
|
'popupCollapseBlacklistedDomains',
|
|
|
|
matrixSnapshot.collapseBlacklistedDomains
|
|
|
|
);
|
2014-10-18 08:01:09 +13:00
|
|
|
});
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-12-21 06:24:18 +13:00
|
|
|
// <<<<< end of local scope
|
|
|
|
}
|