1
0
Fork 0
mirror of https://github.com/gorhill/uMatrix.git synced 2024-06-29 03:21:09 +12:00

work toward resolving #853

This commit is contained in:
gorhill 2017-11-28 12:33:22 -05:00
parent 07eb60abc6
commit 537f8ef79a
No known key found for this signature in database
GPG key ID: 25E1490B761470C2
3 changed files with 147 additions and 217 deletions

View file

@ -31,7 +31,7 @@
/******************************************************************************/ /******************************************************************************/
var µm = µMatrix; var µm = µMatrix;
var magicId = 'tckuvvpyvswo'; var magicId = 'axyorpwxtmnf';
/******************************************************************************/ /******************************************************************************/
@ -58,24 +58,24 @@ Matrix.GrayIndirect = Matrix.Gray | Matrix.Indirect;
/******************************************************************************/ /******************************************************************************/
var typeBitOffsets = { var typeBitOffsets = new Map([
'*': 0, [ '*', 0 ],
'doc': 2, [ 'doc', 2 ],
'cookie': 4, [ 'cookie', 4 ],
'css': 6, [ 'css', 6 ],
'image': 8, [ 'image', 8 ],
'media': 10, [ 'media', 10 ],
'script': 12, [ 'script', 12 ],
'xhr': 14, [ 'xhr', 14 ],
'frame': 16, [ 'frame', 16 ],
'other': 18 [ 'other', 18 ]
}; ]);
var stateToNameMap = { var stateToNameMap = new Map([
'1': 'block', [ 1, 'block' ],
'2': 'allow', [ 2, 'allow' ],
'3': 'inherit' [ 3, 'inherit' ]
}; ]);
var nameToStateMap = { var nameToStateMap = {
'block': 1, 'block': 1,
@ -84,63 +84,36 @@ var nameToStateMap = {
'inherit': 3 'inherit': 3
}; };
var switchBitOffsets = { var switchBitOffsets = new Map([
'matrix-off': 0, [ 'matrix-off', 0 ],
'https-strict': 2, [ 'https-strict', 2 ],
'ua-spoof': 4, [ 'ua-spoof', 4 ],
'referrer-spoof': 6 [ 'referrer-spoof', 6 ]
}; ]);
var switchStateToNameMap = { var switchStateToNameMap = new Map([
'1': 'true', [ 1, 'true' ],
'2': 'false' [ 2, 'false' ]
}; ]);
var nameToSwitchStateMap = { var nameToSwitchStateMap = {
'true': 1, 'true': 1,
'false': 2, 'false': 2
'on': 2, // backward compatibility
'off': 1 // backward compatibility
}; };
/******************************************************************************/ /******************************************************************************/
var columnHeaders = (function() { Matrix.columnHeaderIndices = (function() {
var out = {}; var out = new Map(),
var i = 0; i = 0;
for ( var type in typeBitOffsets ) { for ( var type of typeBitOffsets.keys() ) {
if ( typeBitOffsets.hasOwnProperty(type) === false ) { out.set(type, i++);
continue;
}
out[type] = i++;
} }
return out; return out;
})(); })();
/******************************************************************************/
Matrix.getColumnHeaders = function() { Matrix.switchNames = new Set(switchBitOffsets.keys());
return columnHeaders;
};
/******************************************************************************/
var switchNames = (function() {
var out = {};
for ( var switchName in switchBitOffsets ) {
if ( switchBitOffsets.hasOwnProperty(switchName) === false ) {
continue;
}
out[switchName] = true;
}
return out;
})();
/******************************************************************************/
Matrix.getSwitchNames = function() {
return switchNames;
};
/******************************************************************************/ /******************************************************************************/
@ -208,8 +181,8 @@ var extractFirstPartyDesDomain = function(srcHostname, desHostname) {
/******************************************************************************/ /******************************************************************************/
Matrix.prototype.reset = function() { Matrix.prototype.reset = function() {
this.switches = {}; this.switches = new Map();
this.rules = {}; this.rules = new Map();
this.rootValue = Matrix.RedIndirect; this.rootValue = Matrix.RedIndirect;
this.modifiedTime = 0; this.modifiedTime = 0;
}; };
@ -220,38 +193,26 @@ Matrix.prototype.reset = function() {
// a live matrix. // a live matrix.
Matrix.prototype.assign = function(other) { Matrix.prototype.assign = function(other) {
var k; var k, entry;
// Remove rules not in other // Remove rules not in other
for ( k in this.rules ) { for ( k of this.rules.keys() ) {
if ( this.rules.hasOwnProperty(k) === false ) { if ( other.rules.has(k) === false ) {
continue; this.rules.delete(k);
}
if ( other.rules.hasOwnProperty(k) === false ) {
delete this.rules[k];
} }
} }
// Remove switches not in other // Remove switches not in other
for ( k in this.switches ) { for ( k of this.switches.keys() ) {
if ( this.switches.hasOwnProperty(k) === false ) { if ( other.switches.has(k) === false ) {
continue; this.switches.delete(k);
}
if ( other.switches.hasOwnProperty(k) === false ) {
delete this.switches[k];
} }
} }
// Add/change rules in other // Add/change rules in other
for ( k in other.rules ) { for ( entry of other.rules ) {
if ( other.rules.hasOwnProperty(k) === false ) { this.rules.set(entry[0], entry[1]);
continue;
}
this.rules[k] = other.rules[k];
} }
// Add/change switches in other // Add/change switches in other
for ( k in other.switches ) { for ( entry of other.switches ) {
if ( other.switches.hasOwnProperty(k) === false ) { this.switches.set(entry[0], entry[1]);
continue;
}
this.switches[k] = other.switches[k];
} }
this.modifiedTime = other.modifiedTime; this.modifiedTime = other.modifiedTime;
return this; return this;
@ -264,20 +225,20 @@ Matrix.prototype.assign = function(other) {
// If value is undefined, the switch is removed // If value is undefined, the switch is removed
Matrix.prototype.setSwitch = function(switchName, srcHostname, newVal) { Matrix.prototype.setSwitch = function(switchName, srcHostname, newVal) {
var bitOffset = switchBitOffsets[switchName]; var bitOffset = switchBitOffsets.get(switchName);
if ( bitOffset === undefined ) { if ( bitOffset === undefined ) {
return false; return false;
} }
if ( newVal === this.evaluateSwitch(switchName, srcHostname) ) { if ( newVal === this.evaluateSwitch(switchName, srcHostname) ) {
return false; return false;
} }
var bits = this.switches[srcHostname] || 0; var bits = this.switches.get(srcHostname) || 0;
bits &= ~(3 << bitOffset); bits &= ~(3 << bitOffset);
bits |= newVal << bitOffset; bits |= newVal << bitOffset;
if ( bits === 0 ) { if ( bits === 0 ) {
delete this.switches[srcHostname]; this.switches.delete(srcHostname);
} else { } else {
this.switches[srcHostname] = bits; this.switches.set(srcHostname, bits);
} }
this.modifiedTime = Date.now(); this.modifiedTime = Date.now();
return true; return true;
@ -286,9 +247,9 @@ Matrix.prototype.setSwitch = function(switchName, srcHostname, newVal) {
/******************************************************************************/ /******************************************************************************/
Matrix.prototype.setCell = function(srcHostname, desHostname, type, state) { Matrix.prototype.setCell = function(srcHostname, desHostname, type, state) {
var bitOffset = typeBitOffsets[type]; var bitOffset = typeBitOffsets.get(type),
var k = srcHostname + ' ' + desHostname; k = srcHostname + ' ' + desHostname,
var oldBitmap = this.rules[k]; oldBitmap = this.rules.get(k);
if ( oldBitmap === undefined ) { if ( oldBitmap === undefined ) {
oldBitmap = 0; oldBitmap = 0;
} }
@ -297,9 +258,9 @@ Matrix.prototype.setCell = function(srcHostname, desHostname, type, state) {
return false; return false;
} }
if ( newBitmap === 0 ) { if ( newBitmap === 0 ) {
delete this.rules[k]; this.rules.delete(k);
} else { } else {
this.rules[k] = newBitmap; this.rules.set(k, newBitmap);
} }
this.modifiedTime = Date.now(); this.modifiedTime = Date.now();
return true; return true;
@ -357,21 +318,21 @@ Matrix.prototype.graylistCell = function(srcHostname, desHostname, type) {
Matrix.prototype.evaluateCell = function(srcHostname, desHostname, type) { Matrix.prototype.evaluateCell = function(srcHostname, desHostname, type) {
var key = srcHostname + ' ' + desHostname; var key = srcHostname + ' ' + desHostname;
var bitmap = this.rules[key]; var bitmap = this.rules.get(key);
if ( bitmap === undefined ) { if ( bitmap === undefined ) {
return 0; return 0;
} }
return bitmap >> typeBitOffsets[type] & 3; return bitmap >> typeBitOffsets.get(type) & 3;
}; };
/******************************************************************************/ /******************************************************************************/
Matrix.prototype.evaluateCellZ = function(srcHostname, desHostname, type) { Matrix.prototype.evaluateCellZ = function(srcHostname, desHostname, type) {
var bitOffset = typeBitOffsets[type]; var bitOffset = typeBitOffsets.get(type);
var s = srcHostname; var s = srcHostname;
var v; var v;
for (;;) { for (;;) {
v = this.rules[s + ' ' + desHostname]; v = this.rules.get(s + ' ' + desHostname);
if ( v !== undefined ) { if ( v !== undefined ) {
v = v >> bitOffset & 3; v = v >> bitOffset & 3;
if ( v !== 0 ) { if ( v !== 0 ) {
@ -380,9 +341,7 @@ Matrix.prototype.evaluateCellZ = function(srcHostname, desHostname, type) {
} }
// TODO: external rules? (for presets) // TODO: external rules? (for presets)
s = toBroaderHostname(s); s = toBroaderHostname(s);
if ( s === '' ) { if ( s === '' ) { break; }
break;
}
} }
// srcHostname is '*' at this point // srcHostname is '*' at this point
@ -396,6 +355,7 @@ Matrix.prototype.evaluateCellZ = function(srcHostname, desHostname, type) {
if ( type === 'doc' && desHostname === '*' ) { if ( type === 'doc' && desHostname === '*' ) {
return 2; return 2;
} }
return 0; return 0;
}; };
@ -495,10 +455,7 @@ Matrix.prototype.evaluateCellZXY = function(srcHostname, desHostname, type) {
Matrix.prototype.evaluateRowZXY = function(srcHostname, desHostname) { Matrix.prototype.evaluateRowZXY = function(srcHostname, desHostname) {
var out = []; var out = [];
for ( var type in typeBitOffsets ) { for ( var type of typeBitOffsets.keys() ) {
if ( typeBitOffsets.hasOwnProperty(type) === false ) {
continue;
}
out.push(this.evaluateCellZXY(srcHostname, desHostname, type)); out.push(this.evaluateCellZXY(srcHostname, desHostname, type));
} }
return out; return out;
@ -525,7 +482,7 @@ Matrix.prototype.desHostnameFromRule = function(rule) {
/******************************************************************************/ /******************************************************************************/
Matrix.prototype.setSwitchZ = function(switchName, srcHostname, newState) { Matrix.prototype.setSwitchZ = function(switchName, srcHostname, newState) {
var bitOffset = switchBitOffsets[switchName]; var bitOffset = switchBitOffsets.get(switchName);
if ( bitOffset === undefined ) { if ( bitOffset === undefined ) {
return false; return false;
} }
@ -536,19 +493,19 @@ Matrix.prototype.setSwitchZ = function(switchName, srcHostname, newState) {
if ( newState === undefined ) { if ( newState === undefined ) {
newState = !state; newState = !state;
} }
var bits = this.switches[srcHostname] || 0; var bits = this.switches.get(srcHostname) || 0;
bits &= ~(3 << bitOffset); bits &= ~(3 << bitOffset);
if ( bits === 0 ) { if ( bits === 0 ) {
delete this.switches[srcHostname]; this.switches.delete(srcHostname);
} else { } else {
this.switches[srcHostname] = bits; this.switches.set(srcHostname, bits);
} }
this.modifiedTime = Date.now(); this.modifiedTime = Date.now();
state = this.evaluateSwitchZ(switchName, srcHostname); state = this.evaluateSwitchZ(switchName, srcHostname);
if ( state === newState ) { if ( state === newState ) {
return true; return true;
} }
this.switches[srcHostname] = bits | ((newState ? 1 : 2) << bitOffset); this.switches.set(srcHostname, bits | ((newState ? 1 : 2) << bitOffset));
return true; return true;
}; };
@ -559,11 +516,11 @@ Matrix.prototype.setSwitchZ = function(switchName, srcHostname, newState) {
// 2 = forced default state (to override a broader non-default state) // 2 = forced default state (to override a broader non-default state)
Matrix.prototype.evaluateSwitch = function(switchName, srcHostname) { Matrix.prototype.evaluateSwitch = function(switchName, srcHostname) {
var bits = this.switches[srcHostname] || 0; var bits = this.switches.get(srcHostname) || 0;
if ( bits === 0 ) { if ( bits === 0 ) {
return 0; return 0;
} }
var bitOffset = switchBitOffsets[switchName]; var bitOffset = switchBitOffsets.get(switchName);
if ( bitOffset === undefined ) { if ( bitOffset === undefined ) {
return 0; return 0;
} }
@ -573,14 +530,14 @@ Matrix.prototype.evaluateSwitch = function(switchName, srcHostname) {
/******************************************************************************/ /******************************************************************************/
Matrix.prototype.evaluateSwitchZ = function(switchName, srcHostname) { Matrix.prototype.evaluateSwitchZ = function(switchName, srcHostname) {
var bitOffset = switchBitOffsets[switchName]; var bitOffset = switchBitOffsets.get(switchName);
if ( bitOffset === undefined ) { if ( bitOffset === undefined ) {
return false; return false;
} }
var bits; var bits;
var s = srcHostname; var s = srcHostname;
for (;;) { for (;;) {
bits = this.switches[s] || 0; bits = this.switches.get(s) || 0;
if ( bits !== 0 ) { if ( bits !== 0 ) {
bits = bits >> bitOffset & 3; bits = bits >> bitOffset & 3;
if ( bits !== 0 ) { if ( bits !== 0 ) {
@ -602,11 +559,7 @@ Matrix.prototype.evaluateSwitchZ = function(switchName, srcHostname) {
Matrix.prototype.extractAllSourceHostnames = function() { Matrix.prototype.extractAllSourceHostnames = function() {
var srcHostnames = {}; var srcHostnames = {};
var rules = this.rules; for ( var rule of this.rules.keys() ) {
for ( var rule in rules ) {
if ( rules.hasOwnProperty(rule) === false ) {
continue;
}
srcHostnames[rule.slice(0, rule.indexOf(' '))] = true; srcHostnames[rule.slice(0, rule.indexOf(' '))] = true;
} }
return srcHostnames; return srcHostnames;
@ -619,11 +572,7 @@ Matrix.prototype.extractAllSourceHostnames = function() {
Matrix.prototype.extractAllDestinationHostnames = function() { Matrix.prototype.extractAllDestinationHostnames = function() {
var desHostnames = {}; var desHostnames = {};
var rules = this.rules; for ( var rule of this.rules.keys() ) {
for ( var rule in rules ) {
if ( rules.hasOwnProperty(rule) === false ) {
continue;
}
desHostnames[this.desHostnameFromRule(rule)] = true; desHostnames[this.desHostnameFromRule(rule)] = true;
} }
return desHostnames; return desHostnames;
@ -635,41 +584,25 @@ Matrix.prototype.toString = function() {
var out = []; var out = [];
var rule, type, switchName, val; var rule, type, switchName, val;
var srcHostname, desHostname; var srcHostname, desHostname;
for ( rule in this.rules ) { for ( rule of this.rules.keys() ) {
if ( this.rules.hasOwnProperty(rule) === false ) {
continue;
}
srcHostname = this.srcHostnameFromRule(rule); srcHostname = this.srcHostnameFromRule(rule);
desHostname = this.desHostnameFromRule(rule); desHostname = this.desHostnameFromRule(rule);
for ( type in typeBitOffsets ) { for ( type of typeBitOffsets.keys() ) {
if ( typeBitOffsets.hasOwnProperty(type) === false ) {
continue;
}
val = this.evaluateCell(srcHostname, desHostname, type); val = this.evaluateCell(srcHostname, desHostname, type);
if ( val === 0 ) { if ( val === 0 ) { continue; }
continue;
}
out.push( out.push(
punycode.toUnicode(srcHostname) + ' ' + punycode.toUnicode(srcHostname) + ' ' +
punycode.toUnicode(desHostname) + ' ' + punycode.toUnicode(desHostname) + ' ' +
type + ' ' + type + ' ' +
stateToNameMap[val] stateToNameMap.get(val)
); );
} }
} }
for ( srcHostname in this.switches ) { for ( srcHostname of this.switches.keys() ) {
if ( this.switches.hasOwnProperty(srcHostname) === false ) { for ( switchName of switchBitOffsets.keys() ) {
continue;
}
for ( switchName in switchBitOffsets ) {
if ( switchBitOffsets.hasOwnProperty(switchName) === false ) {
continue;
}
val = this.evaluateSwitch(switchName, srcHostname); val = this.evaluateSwitch(switchName, srcHostname);
if ( val === 0 ) { if ( val === 0 ) { continue; }
continue; out.push(switchName + ': ' + srcHostname + ' ' + switchStateToNameMap.get(val));
}
out.push(switchName + ': ' + srcHostname + ' ' + switchStateToNameMap[val]);
} }
} }
return out.sort().join('\n'); return out.sort().join('\n');
@ -744,7 +677,7 @@ Matrix.prototype.fromString = function(text, append) {
if ( pos !== -1 ) { if ( pos !== -1 ) {
switchName = fieldVal.slice(0, pos); switchName = fieldVal.slice(0, pos);
} }
if ( switchBitOffsets.hasOwnProperty(switchName) ) { if ( switchBitOffsets.has(switchName) ) {
srcHostname = punycode.toASCII(fields[1]); srcHostname = punycode.toASCII(fields[1]);
// No state field: reject // No state field: reject
@ -801,7 +734,7 @@ Matrix.prototype.fromString = function(text, append) {
type = 'media'; type = 'media';
} }
// Unknown type: reject // Unknown type: reject
if ( typeBitOffsets.hasOwnProperty(type) === false ) { if ( typeBitOffsets.has(type) === false ) {
continue; continue;
} }
} else { } else {
@ -835,17 +768,19 @@ Matrix.prototype.fromString = function(text, append) {
Matrix.prototype.toSelfie = function() { Matrix.prototype.toSelfie = function() {
return { return {
magicId: magicId, magicId: magicId,
switches: this.switches, switches: Array.from(this.switches),
rules: this.rules rules: Array.from(this.rules)
}; };
}; };
/******************************************************************************/ /******************************************************************************/
Matrix.prototype.fromSelfie = function(selfie) { Matrix.prototype.fromSelfie = function(selfie) {
this.switches = selfie.switches; if ( selfie.magicId !== magicId ) { return false; }
this.rules = selfie.rules; this.switches = new Map(selfie.switches);
this.rules = new Map(selfie.rules);
this.modifiedTime = Date.now(); this.modifiedTime = Date.now();
return true;
}; };
/******************************************************************************/ /******************************************************************************/
@ -855,10 +790,7 @@ Matrix.prototype.diff = function(other, srcHostname, desHostnames) {
var desHostname, type; var desHostname, type;
var switchName, i, thisVal, otherVal; var switchName, i, thisVal, otherVal;
for (;;) { for (;;) {
for ( switchName in switchBitOffsets ) { for ( switchName of switchBitOffsets.keys() ) {
if ( switchBitOffsets.hasOwnProperty(switchName) === false ) {
continue;
}
thisVal = this.evaluateSwitch(switchName, srcHostname); thisVal = this.evaluateSwitch(switchName, srcHostname);
otherVal = other.evaluateSwitch(switchName, srcHostname); otherVal = other.evaluateSwitch(switchName, srcHostname);
if ( thisVal !== otherVal ) { if ( thisVal !== otherVal ) {
@ -871,15 +803,10 @@ Matrix.prototype.diff = function(other, srcHostname, desHostnames) {
i = desHostnames.length; i = desHostnames.length;
while ( i-- ) { while ( i-- ) {
desHostname = desHostnames[i]; desHostname = desHostnames[i];
for ( type in typeBitOffsets ) { for ( type of typeBitOffsets.keys() ) {
if ( typeBitOffsets.hasOwnProperty(type) === false ) {
continue;
}
thisVal = this.evaluateCell(srcHostname, desHostname, type); thisVal = this.evaluateCell(srcHostname, desHostname, type);
otherVal = other.evaluateCell(srcHostname, desHostname, type); otherVal = other.evaluateCell(srcHostname, desHostname, type);
if ( thisVal === otherVal ) { if ( thisVal === otherVal ) { continue; }
continue;
}
out.push({ out.push({
'what': 'rule', 'what': 'rule',
'src': srcHostname, 'src': srcHostname,
@ -909,7 +836,7 @@ Matrix.prototype.applyDiff = function(diff, from) {
changed = this.setCell(action.src, action.des, action.type, val) || changed; changed = this.setCell(action.src, action.des, action.type, val) || changed;
continue; continue;
} }
if ( switchBitOffsets.hasOwnProperty(action.what) ) { if ( switchBitOffsets.has(action.what) ) {
val = from.evaluateSwitch(action.what, action.src); val = from.evaluateSwitch(action.what, action.src);
changed = this.setSwitch(action.what, action.src, val) || changed; changed = this.setSwitch(action.what, action.src, val) || changed;
continue; continue;

View file

@ -130,9 +130,8 @@ var RowSnapshot = function(srcHostname, desHostname, desDomain) {
}; };
RowSnapshot.counts = (function() { RowSnapshot.counts = (function() {
var i = Object.keys(µm.Matrix.getColumnHeaders()).length; var aa = [];
var aa = new Array(i); for ( var i = 0, n = µm.Matrix.columnHeaderIndices.size; i < n; i++ ) {
while ( i-- ) {
aa[i] = 0; aa[i] = 0;
} }
return aa; return aa;
@ -142,12 +141,14 @@ RowSnapshot.counts = (function() {
var matrixSnapshot = function(pageStore, details) { var matrixSnapshot = function(pageStore, details) {
var µmuser = µm.userSettings; var µmuser = µm.userSettings;
var headerIndices = µm.Matrix.columnHeaderIndices;
var r = { var r = {
appVersion: vAPI.app.version, appVersion: vAPI.app.version,
blockedCount: pageStore.requestStats.blocked.all, blockedCount: pageStore.requestStats.blocked.all,
diff: [], diff: [],
domain: pageStore.pageDomain, domain: pageStore.pageDomain,
headers: µm.Matrix.getColumnHeaders(), headerIndices: Array.from(headerIndices),
hostname: pageStore.pageHostname, hostname: pageStore.pageHostname,
mtxContentModified: pageStore.mtxContentModifiedTime !== details.mtxContentModifiedTime, mtxContentModified: pageStore.mtxContentModifiedTime !== details.mtxContentModifiedTime,
mtxCountModified: pageStore.mtxCountModifiedTime !== details.mtxCountModifiedTime, mtxCountModified: pageStore.mtxCountModifiedTime !== details.mtxCountModifiedTime,
@ -171,8 +172,6 @@ var matrixSnapshot = function(pageStore, details) {
} }
}; };
var headers = r.headers;
if ( typeof details.scope === 'string' ) { if ( typeof details.scope === 'string' ) {
r.scope = details.scope; r.scope = details.scope;
} else if ( µmuser.popupScopeLevel === 'site' ) { } else if ( µmuser.popupScopeLevel === 'site' ) {
@ -181,11 +180,7 @@ var matrixSnapshot = function(pageStore, details) {
r.scope = r.domain; r.scope = r.domain;
} }
var switchNames = µm.Matrix.getSwitchNames(); for ( var switchName of µm.Matrix.switchNames ) {
for ( var switchName in switchNames ) {
if ( switchNames.hasOwnProperty(switchName) === false ) {
continue;
}
r.tSwitches[switchName] = µm.tMatrix.evaluateSwitchZ(switchName, r.scope); r.tSwitches[switchName] = µm.tMatrix.evaluateSwitchZ(switchName, r.scope);
r.pSwitches[switchName] = µm.pMatrix.evaluateSwitchZ(switchName, r.scope); r.pSwitches[switchName] = µm.pMatrix.evaluateSwitchZ(switchName, r.scope);
} }
@ -199,7 +194,7 @@ var matrixSnapshot = function(pageStore, details) {
var reqKey, reqType, reqHostname, reqDomain; var reqKey, reqType, reqHostname, reqDomain;
var desHostname; var desHostname;
var row, typeIndex; var row, typeIndex;
var anyIndex = headers['*']; var anyIndex = headerIndices.get('*');
var pageRequests = pageStore.requests; var pageRequests = pageStore.requests;
var reqKeys = pageRequests.getRequestKeys(); var reqKeys = pageRequests.getRequestKeys();
@ -236,7 +231,7 @@ var matrixSnapshot = function(pageStore, details) {
desHostname = desHostname.slice(pos + 1); desHostname = desHostname.slice(pos + 1);
} }
typeIndex = headers[reqType]; typeIndex = headerIndices.get(reqType);
row = r.rows[reqHostname]; row = r.rows[reqHostname];
row.counts[typeIndex] += 1; row.counts[typeIndex] += 1;

View file

@ -224,8 +224,7 @@ function getGroupStats() {
// hierarchy is white or blacklisted // hierarchy is white or blacklisted
var pageDomain = matrixSnapshot.domain; var pageDomain = matrixSnapshot.domain;
var rows = matrixSnapshot.rows; var rows = matrixSnapshot.rows;
var columnOffsets = matrixSnapshot.headers; var anyTypeOffset = matrixSnapshot.headerIndices.get('*');
var anyTypeOffset = columnOffsets['*'];
var hostname, domain; var hostname, domain;
var row, color, count, groupIndex; var row, color, count, groupIndex;
var domainToGroupMap = {}; var domainToGroupMap = {};
@ -349,11 +348,11 @@ function getGroupStats() {
// helpers // helpers
function getTemporaryColor(hostname, type) { function getTemporaryColor(hostname, type) {
return matrixSnapshot.rows[hostname].temporary[matrixSnapshot.headers[type]]; return matrixSnapshot.rows[hostname].temporary[matrixSnapshot.headerIndices.get(type)];
} }
function getPermanentColor(hostname, type) { function getPermanentColor(hostname, type) {
return matrixSnapshot.rows[hostname].permanent[matrixSnapshot.headers[type]]; return matrixSnapshot.rows[hostname].permanent[matrixSnapshot.headerIndices.get(type)];
} }
function addCellClass(cell, hostname, type) { function addCellClass(cell, hostname, type) {
@ -429,7 +428,7 @@ function updateMatrixCounts() {
var matCells = uDom('.matrix .matRow.rw > .matCell'), var matCells = uDom('.matrix .matRow.rw > .matCell'),
i = matCells.length, i = matCells.length,
matRow, matCell, count, counts, matRow, matCell, count, counts,
headers = matrixSnapshot.headers, headerIndices = matrixSnapshot.headerIndices,
rows = matrixSnapshot.rows, rows = matrixSnapshot.rows,
expandos; expandos;
while ( i-- ) { while ( i-- ) {
@ -440,7 +439,7 @@ function updateMatrixCounts() {
} }
matRow = matCell.parentNode; matRow = matCell.parentNode;
counts = matRow.classList.contains('meta') ? 'totals' : 'counts'; counts = matRow.classList.contains('meta') ? 'totals' : 'counts';
count = rows[expandos.hostname][counts][headers[expandos.reqType]]; count = rows[expandos.hostname][counts][headerIndices.get(expandos.reqType)];
if ( count === expandos.count ) { continue; } if ( count === expandos.count ) { continue; }
expandos.count = count; expandos.count = count;
matCell.textContent = count ? count : '\u00A0'; matCell.textContent = count ? count : '\u00A0';
@ -705,15 +704,15 @@ function renderMatrixCellType(cell, hostname, type, count) {
function renderMatrixCellTypes(cells, hostname, countName) { function renderMatrixCellTypes(cells, hostname, countName) {
var counts = matrixSnapshot.rows[hostname][countName]; var counts = matrixSnapshot.rows[hostname][countName];
var countIndices = matrixSnapshot.headers; var headerIndices = matrixSnapshot.headerIndices;
renderMatrixCellType(cells.at(1), hostname, 'cookie', counts[countIndices.cookie]); renderMatrixCellType(cells.at(1), hostname, 'cookie', counts[headerIndices.get('cookie')]);
renderMatrixCellType(cells.at(2), hostname, 'css', counts[countIndices.css]); renderMatrixCellType(cells.at(2), hostname, 'css', counts[headerIndices.get('css')]);
renderMatrixCellType(cells.at(3), hostname, 'image', counts[countIndices.image]); renderMatrixCellType(cells.at(3), hostname, 'image', counts[headerIndices.get('image')]);
renderMatrixCellType(cells.at(4), hostname, 'media', counts[countIndices.media]); renderMatrixCellType(cells.at(4), hostname, 'media', counts[headerIndices.get('media')]);
renderMatrixCellType(cells.at(5), hostname, 'script', counts[countIndices.script]); renderMatrixCellType(cells.at(5), hostname, 'script', counts[headerIndices.get('script')]);
renderMatrixCellType(cells.at(6), hostname, 'xhr', counts[countIndices.xhr]); renderMatrixCellType(cells.at(6), hostname, 'xhr', counts[headerIndices.get('xhr')]);
renderMatrixCellType(cells.at(7), hostname, 'frame', counts[countIndices.frame]); renderMatrixCellType(cells.at(7), hostname, 'frame', counts[headerIndices.get('frame')]);
renderMatrixCellType(cells.at(8), hostname, 'other', counts[countIndices.other]); renderMatrixCellType(cells.at(8), hostname, 'other', counts[headerIndices.get('other')]);
} }
/******************************************************************************/ /******************************************************************************/
@ -760,36 +759,37 @@ function renderMatrixMetaCellType(cell, count) {
} }
function makeMatrixMetaRow(totals) { function makeMatrixMetaRow(totals) {
var typeOffsets = matrixSnapshot.headers; var headerIndices = matrixSnapshot.headerIndices,
var matrixRow = createMatrixRow().at(0).addClass('ro'); matrixRow = createMatrixRow().at(0).addClass('ro'),
var cells = matrixRow.descendants('.matCell'); cells = matrixRow.descendants('.matCell'),
var contents = cells.at(0).addClass('t81').contents(); contents = cells.at(0).addClass('t81').contents(),
var expandos = expandosFromNode(cells.nodeAt(0)); expandos = expandosFromNode(cells.nodeAt(0));
expandos.hostname = ''; expandos.hostname = '';
expandos.reqType = '*'; expandos.reqType = '*';
contents.nodeAt(0).textContent = ' '; contents.nodeAt(0).textContent = ' ';
contents.nodeAt(1).textContent = blacklistedHostnamesLabel.replace( contents.nodeAt(1).textContent = blacklistedHostnamesLabel.replace(
'{{count}}', '{{count}}',
totals[typeOffsets['*']].toLocaleString() totals[headerIndices.get('*')].toLocaleString()
); );
renderMatrixMetaCellType(cells.at(1), totals[typeOffsets.cookie]); renderMatrixMetaCellType(cells.at(1), totals[headerIndices.get('cookie')]);
renderMatrixMetaCellType(cells.at(2), totals[typeOffsets.css]); renderMatrixMetaCellType(cells.at(2), totals[headerIndices.get('css')]);
renderMatrixMetaCellType(cells.at(3), totals[typeOffsets.image]); renderMatrixMetaCellType(cells.at(3), totals[headerIndices.get('image')]);
renderMatrixMetaCellType(cells.at(4), totals[typeOffsets.media]); renderMatrixMetaCellType(cells.at(4), totals[headerIndices.get('media')]);
renderMatrixMetaCellType(cells.at(5), totals[typeOffsets.script]); renderMatrixMetaCellType(cells.at(5), totals[headerIndices.get('script')]);
renderMatrixMetaCellType(cells.at(6), totals[typeOffsets.xhr]); renderMatrixMetaCellType(cells.at(6), totals[headerIndices.get('xhr')]);
renderMatrixMetaCellType(cells.at(7), totals[typeOffsets.frame]); renderMatrixMetaCellType(cells.at(7), totals[headerIndices.get('frame')]);
renderMatrixMetaCellType(cells.at(8), totals[typeOffsets.other]); renderMatrixMetaCellType(cells.at(8), totals[headerIndices.get('other')]);
return matrixRow; return matrixRow;
} }
/******************************************************************************/ /******************************************************************************/
function computeMatrixGroupMetaStats(group) { function computeMatrixGroupMetaStats(group) {
var headers = matrixSnapshot.headers; var headerIndices = matrixSnapshot.headerIndices,
var n = Object.keys(headers).length; anyTypeIndex = headerIndices.get('*'),
var totals = new Array(n); n = headerIndices.size,
var i = n; totals = new Array(n),
i = n;
while ( i-- ) { while ( i-- ) {
totals[i] = 0; totals[i] = 0;
} }
@ -802,7 +802,7 @@ function computeMatrixGroupMetaStats(group) {
if ( group.hasOwnProperty(row.domain) === false ) { if ( group.hasOwnProperty(row.domain) === false ) {
continue; continue;
} }
if ( row.counts[headers['*']] === 0 ) { if ( row.counts[anyTypeIndex] === 0 ) {
continue; continue;
} }
totals[0] += 1; totals[0] += 1;
@ -1367,6 +1367,13 @@ var onMatrixSnapshotReady = function(response) {
var matrixSnapshotPoller = (function() { var matrixSnapshotPoller = (function() {
var timer = null; var timer = null;
var preprocessMatrixSnapshot = function(snapshot) {
if ( Array.isArray(snapshot.headerIndices) ) {
snapshot.headerIndices = new Map(snapshot.headerIndices);
}
return snapshot;
};
var processPollResult = function(response) { var processPollResult = function(response) {
if ( typeof response !== 'object' ) { if ( typeof response !== 'object' ) {
return; return;
@ -1379,7 +1386,8 @@ var matrixSnapshotPoller = (function() {
) { ) {
return; return;
} }
matrixSnapshot = response; matrixSnapshot = preprocessMatrixSnapshot(response);
if ( response.mtxContentModified ) { if ( response.mtxContentModified ) {
makeMenu(); makeMenu();
return; return;
@ -1454,7 +1462,7 @@ var matrixSnapshotPoller = (function() {
var snapshotFetched = function(response) { var snapshotFetched = function(response) {
if ( typeof response === 'object' ) { if ( typeof response === 'object' ) {
matrixSnapshot = response; matrixSnapshot = preprocessMatrixSnapshot(response);
} }
onMatrixSnapshotReady(response); onMatrixSnapshotReady(response);
pollAsync(); pollAsync();