Browse Source

UI work toward fixing #7, #36

pull/2/head
Raymond Hill 10 years ago
parent
commit
ce6305210c
  1. BIN
      src/css/fonts/fontawesome-webfont.ttf
  2. 43
      src/css/popup.css
  3. 6
      src/js/contentscript-start.js
  4. 10
      src/js/httpsb.js
  5. 63
      src/js/matrix.js
  6. 43
      src/js/messaging-handlers.js
  7. 28
      src/js/popup.js
  8. 6
      src/js/traffic.js
  9. 15
      src/popup.html

BIN
src/css/fonts/fontawesome-webfont.ttf

43
src/css/popup.css

@ -66,9 +66,6 @@ body .toolbar button:hover {
body .toolbar button.disabled { body .toolbar button.disabled {
color: #ccc; color: #ccc;
} }
body .toolbar button.switch.disabled {
color: #a00;
}
body .toolbar button.fa { body .toolbar button.fa {
font: 1.75em 'FontAwesome'; font: 1.75em 'FontAwesome';
min-width: 1.1em; min-width: 1.1em;
@ -82,18 +79,38 @@ body.tScopeDomain .scopeRel:not(.disabled) {
body.tScopeSite .scopeRel:not(.disabled) { body.tScopeSite .scopeRel:not(.disabled) {
color: #48c; color: #48c;
} }
#mtxSwitch_matrix-off.switchTrue {
color: #a00;
}
#mtxSwitches > li {
color: #888;
}
#mtxSwitches > li.switchTrue {
color: #000;
}
#mtxSwitches > li > span:before {
content: '\f204';
font: 120% FontAwesome;
padding-right: 0.5em;
}
#mtxSwitches > li.switchTrue > span:before {
color: #000;
content: '\f205';
font: 120% FontAwesome;
padding-right: 0.5em;
}
.dropdown-menu { .dropdown-menu {
margin: 0; margin: 0;
border: 0; border: 0;
display: none;
font-size: 110%;
padding: 3px 0 0 0; padding: 3px 0 0 0;
position: absolute; position: absolute;
z-index: 50;
font-size: 110%;
display: none;
white-space: normal; white-space: normal;
z-index: 50;
} }
.dropdown-menu > ul { .dropdown-menu > ul {
margin: 0; margin: 0;
@ -105,26 +122,24 @@ body.tScopeSite .scopeRel:not(.disabled) {
list-style-type: none; list-style-type: none;
} }
.dropdown-menu > ul > li.dropdown-menu-entry { .dropdown-menu > ul > li.dropdown-menu-entry {
margin: 0;
border: 0; border: 0;
padding: 4px 0.5em;
color: black; color: black;
cursor: pointer; cursor: pointer;
margin: 0;
padding: 4px 0.5em;
white-space: nowrap;
} }
.dropdown-menu > ul > li.dropdown-menu-entry:hover { .dropdown-menu > ul > li.dropdown-menu-entry:hover {
background: #eee; background: #eee;
} }
.dropdown-menu > ul > li.dropdown-menu-entry-divider { .dropdown-menu > ul > li.dropdown-menu-entry-divider {
margin: 0.5em 0;
border-top: 1px solid #ccc; border-top: 1px solid #ccc;
margin: 0.5em 0;
} }
.dropdown-menu > ul > li.dropdown-menu-entry > .fa { .dropdown-menu > ul > li.dropdown-menu-entry > .fa {
margin-right: 0.5em;
font-size: 110%;
color: #aaa; color: #aaa;
}
.dropdown-menu {
display: none;
font-size: 110%;
margin-right: 0.5em;
} }
.dropdown-menu.show { .dropdown-menu.show {
display: block; display: block;

6
src/js/contentscript-start.js

@ -205,7 +205,11 @@ var injectNavigatorSpoofer = function(spoofedUserAgent) {
} }
}; };
messaging.ask({ what: 'getUserAgentReplaceStr' }, injectNavigatorSpoofer);
var requestDetails = {
what: 'getUserAgentReplaceStr',
hostname: window.location.hostname
};
messaging.ask(requestDetails, injectNavigatorSpoofer);
/******************************************************************************/ /******************************************************************************/
/******************************************************************************/ /******************************************************************************/

10
src/js/httpsb.js

@ -26,11 +26,11 @@
(function() { (function() {
var µm = µMatrix; var µm = µMatrix;
µm.pMatrix = new µm.Matrix(); µm.pMatrix = new µm.Matrix();
µm.pMatrix.setSwitch('matrix-off', 'localhost', true);
µm.pMatrix.setSwitch('matrix-off', 'chrome-extension-scheme', true);
µm.pMatrix.setSwitch('matrix-off', 'chrome-scheme', true);
µm.pMatrix.setSwitch('matrix-off', µm.behindTheSceneScope, true);
µm.pMatrix.setSwitch('matrix-off', 'opera-scheme', true);
µm.pMatrix.setSwitch('matrix-off', 'localhost', 1);
µm.pMatrix.setSwitch('matrix-off', 'chrome-extension-scheme', 1);
µm.pMatrix.setSwitch('matrix-off', 'chrome-scheme', 1);
µm.pMatrix.setSwitch('matrix-off', µm.behindTheSceneScope, 1);
µm.pMatrix.setSwitch('matrix-off', 'opera-scheme', 1);
µm.pMatrix.setCell('*', '*', '*', µm.Matrix.Red); µm.pMatrix.setCell('*', '*', '*', µm.Matrix.Red);
µm.pMatrix.setCell('*', '*', 'doc', µm.Matrix.Green); µm.pMatrix.setCell('*', '*', 'doc', µm.Matrix.Green);
µm.pMatrix.setCell('*', '*', 'css', µm.Matrix.Green); µm.pMatrix.setCell('*', '*', 'css', µm.Matrix.Green);

63
src/js/matrix.js

@ -81,17 +81,22 @@ var nameToStateMap = {
'inherit': 3 'inherit': 3
}; };
var nameToSwitchStateMap = {
'true': true,
'false': false,
'on': false, // backward compatibility
'off': true // backward compatibility
};
var switchBitOffsets = { var switchBitOffsets = {
'matrix-off': 0, 'matrix-off': 0,
'https-strict': 2, 'https-strict': 2,
'ua-spoof-off': 4
'ua-spoof': 4
};
var switchStateToNameMap = {
'1': 'true',
'2': 'false'
};
var nameToSwitchStateMap = {
'true': 1,
'false': 2,
'on': 2, // backward compatibility
'off': 1 // backward compatibility
}; };
/******************************************************************************/ /******************************************************************************/
@ -116,6 +121,25 @@ Matrix.getColumnHeaders = function() {
/******************************************************************************/ /******************************************************************************/
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;
};
/******************************************************************************/
// For performance purpose, as simple tests as possible // For performance purpose, as simple tests as possible
var reHostnameVeryCoarse = /[g-z_-]/; var reHostnameVeryCoarse = /[g-z_-]/;
var reIPv4VeryCoarse = /\.\d+$/; var reIPv4VeryCoarse = /\.\d+$/;
@ -232,17 +256,22 @@ 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, newState) {
Matrix.prototype.setSwitch = function(switchName, srcHostname, newVal) {
var bitOffset = switchBitOffsets[switchName]; var bitOffset = switchBitOffsets[switchName];
if ( bitOffset === undefined ) { if ( bitOffset === undefined ) {
return false; return false;
} }
var state = this.evaluateSwitch(switchName, srcHostname);
if ( newState === state ) {
if ( newVal === this.evaluateSwitch(switchName, srcHostname) ) {
return false; return false;
} }
var bits = this.switches[srcHostname] || 0; var bits = this.switches[srcHostname] || 0;
this.switches[srcHostname] = (bits & ~(3 << bitOffset)) | ((newState ? 1 : 2) << bitOffset);
bits &= ~(3 << bitOffset);
bits |= newVal << bitOffset;
if ( bits === 0 ) {
delete this.switches[srcHostname];
} else {
this.switches[srcHostname] = bits;
}
return true; return true;
}; };
@ -508,13 +537,13 @@ Matrix.prototype.setSwitchZ = function(switchName, srcHostname, newState) {
Matrix.prototype.evaluateSwitch = function(switchName, srcHostname) { Matrix.prototype.evaluateSwitch = function(switchName, srcHostname) {
var bits = this.switches[srcHostname] || 0; var bits = this.switches[srcHostname] || 0;
if ( bits === 0 ) { if ( bits === 0 ) {
return false;
return 0;
} }
var bitOffset = switchBitOffsets[switchName]; var bitOffset = switchBitOffsets[switchName];
if ( bitOffset === undefined ) { if ( bitOffset === undefined ) {
return false;
return 0;
} }
return ((bits >> bitOffset) & 3) === 1;
return (bits >> bitOffset) & 3;
}; };
/******************************************************************************/ /******************************************************************************/
@ -613,10 +642,10 @@ Matrix.prototype.toString = function() {
continue; continue;
} }
val = this.evaluateSwitch(switchName, srcHostname); val = this.evaluateSwitch(switchName, srcHostname);
if ( val === false ) {
if ( val === 0 ) {
continue; continue;
} }
out.push(switchName + ': ' + srcHostname + ' ' + val);
out.push(switchName + ': ' + srcHostname + ' ' + switchStateToNameMap[val]);
} }
} }
return out.join('\n'); return out.join('\n');

43
src/js/messaging-handlers.js

@ -72,8 +72,8 @@ var matrixSnapshot = function(details) {
blockedCount: 0, blockedCount: 0,
scope: '*', scope: '*',
headers: µm.Matrix.getColumnHeaders(), headers: µm.Matrix.getColumnHeaders(),
tSwitch: false,
pSwitch: false,
tSwitches: {},
pSwitches: {},
rows: {}, rows: {},
rowCount: 0, rowCount: 0,
diff: [], diff: [],
@ -115,8 +115,14 @@ var matrixSnapshot = function(details) {
r.scope = r.domain; r.scope = r.domain;
} }
r.tSwitch = µm.tMatrix.evaluateSwitchZ('matrix-off', r.scope);
r.pSwitch = µm.pMatrix.evaluateSwitchZ('matrix-off', r.scope);
var switchNames = µm.Matrix.getSwitchNames();
for ( var switchName in switchNames ) {
if ( switchNames.hasOwnProperty(switchName) === false ) {
continue;
}
r.tSwitches[switchName] = µm.tMatrix.evaluateSwitchZ(switchName, r.scope);
r.pSwitches[switchName] = µm.pMatrix.evaluateSwitchZ(switchName, r.scope);
}
// These rows always exist // These rows always exist
r.rows['*'] = new RowSnapshot(r.scope, '*', '*'); r.rows['*'] = new RowSnapshot(r.scope, '*', '*');
@ -210,9 +216,9 @@ var onMessage = function(request, sender, callback) {
case 'toggleMatrixSwitch': case 'toggleMatrixSwitch':
µm.tMatrix.setSwitchZ( µm.tMatrix.setSwitchZ(
'matrix-off',
request.switchName,
request.srcHostname, request.srcHostname,
!µm.tMatrix.evaluateSwitchZ('matrix-off', request.srcHostname)
µm.tMatrix.evaluateSwitchZ(request.switchName, request.srcHostname) === false
); );
break; break;
@ -272,6 +278,10 @@ var onMessage = function(request, sender, callback) {
(function() { (function() {
var µm = µMatrix;
/******************************************************************************/
var contentScriptSummaryHandler = function(details, sender) { var contentScriptSummaryHandler = function(details, sender) {
// TODO: Investigate "Error in response to tabs.executeScript: TypeError: // TODO: Investigate "Error in response to tabs.executeScript: TypeError:
// Cannot read property 'locationURL' of null" (2013-11-12). When can this // Cannot read property 'locationURL' of null" (2013-11-12). When can this
@ -279,7 +289,6 @@ var contentScriptSummaryHandler = function(details, sender) {
if ( !details || !details.locationURL ) { if ( !details || !details.locationURL ) {
return; return;
} }
var µm = µMatrix;
var pageURL = µm.pageUrlFromTabId(sender.tab.id); var pageURL = µm.pageUrlFromTabId(sender.tab.id);
var pageStats = µm.pageStatsFromPageUrl(pageURL); var pageStats = µm.pageStatsFromPageUrl(pageURL);
var µmuri = µm.URI.set(details.locationURL); var µmuri = µm.URI.set(details.locationURL);
@ -327,8 +336,9 @@ var contentScriptSummaryHandler = function(details, sender) {
µm.onPageLoadCompleted(pageURL); µm.onPageLoadCompleted(pageURL);
}; };
/******************************************************************************/
var contentScriptLocalStorageHandler = function(pageURL) { var contentScriptLocalStorageHandler = function(pageURL) {
var µm = µMatrix;
var µmuri = µm.URI.set(pageURL); var µmuri = µm.URI.set(pageURL);
var response = µm.mustBlock(µm.scopeFromURL(pageURL), µmuri.hostname, 'cookie'); var response = µm.mustBlock(µm.scopeFromURL(pageURL), µmuri.hostname, 'cookie');
µm.recordFromPageUrl( µm.recordFromPageUrl(
@ -344,6 +354,8 @@ var contentScriptLocalStorageHandler = function(pageURL) {
return response; return response;
}; };
/******************************************************************************/
var onMessage = function(request, sender, callback) { var onMessage = function(request, sender, callback) {
// Async // Async
switch ( request.what ) { switch ( request.what ) {
@ -365,21 +377,22 @@ var onMessage = function(request, sender, callback) {
case 'checkScriptBlacklisted': case 'checkScriptBlacklisted':
response = { response = {
scriptBlacklisted: µMatrix.mustBlock(
µMatrix.scopeFromURL(request.url),
µMatrix.hostnameFromURL(request.url),
scriptBlacklisted: µm.mustBlock(
µm.scopeFromURL(request.url),
µm.hostnameFromURL(request.url),
'script' 'script'
) )
}; };
break; break;
case 'getUserAgentReplaceStr': case 'getUserAgentReplaceStr':
response = µMatrix.userSettings.spoofUserAgent ? µMatrix.userAgentReplaceStr : undefined;
response = µm.tMatrix.evaluateSwitchZ('ua-spoof', request.hostname) ?
µm.userAgentReplaceStr :
undefined;
break; break;
default: default:
return µMatrix.messaging.defaultHandler(request, sender, callback);
return µm.messaging.defaultHandler(request, sender, callback);
} }
callback(response); callback(response);
@ -388,6 +401,8 @@ var onMessage = function(request, sender, callback) {
µMatrix.messaging.listen('contentscript-start.js', onMessage); µMatrix.messaging.listen('contentscript-start.js', onMessage);
µMatrix.messaging.listen('contentscript-end.js', onMessage); µMatrix.messaging.listen('contentscript-end.js', onMessage);
/******************************************************************************/
})(); })();
/******************************************************************************/ /******************************************************************************/

28
src/js/popup.js

@ -1016,19 +1016,31 @@ function updateScopeCell() {
/******************************************************************************/ /******************************************************************************/
function updateMtxbutton() {
var masterSwitch = matrixSnapshot.tSwitch;
function updateMatrixSwitches() {
var switches = matrixSnapshot.tSwitches;
for ( var switchName in switches ) {
if ( switches.hasOwnProperty(switchName) === false ) {
continue;
}
uDom('#mtxSwitch_' + switchName).toggleClass('switchTrue', switches[switchName]);
}
var count = matrixSnapshot.blockedCount; var count = matrixSnapshot.blockedCount;
var button = uDom('#buttonMtxFiltering');
button.toggleClass('disabled', masterSwitch);
var button = uDom('#mtxSwitch_matrix-off');
button.descendants('span.badge').text(count.toLocaleString()); button.descendants('span.badge').text(count.toLocaleString());
button.attr('data-tip', button.attr('data-tip').replace('{{count}}', count)); button.attr('data-tip', button.attr('data-tip').replace('{{count}}', count));
uDom('body').toggleClass('powerOff', masterSwitch);
uDom('body').toggleClass('powerOff', switches['matrix-off']);
} }
function toggleMtxFiltering() {
function toggleMatrixSwitch() {
var pos = this.id.indexOf('_');
if ( pos === -1 ) {
return;
}
var switchName = this.id.slice(pos + 1);
var request = { var request = {
what: 'toggleMatrixSwitch', what: 'toggleMatrixSwitch',
switchName: switchName,
srcHostname: matrixSnapshot.scope srcHostname: matrixSnapshot.scope
}; };
messaging.ask(request, updateMatrixSnapshot); messaging.ask(request, updateMatrixSnapshot);
@ -1078,7 +1090,7 @@ function revertMatrix() {
function updateMatrixButtons() { function updateMatrixButtons() {
updateScopeCell(); updateScopeCell();
updateMtxbutton();
updateMatrixSwitches();
updatePersistButton(); updatePersistButton();
} }
@ -1217,7 +1229,7 @@ uDom.onLoad(function() {
uDom('#scopeKeyGlobal').on('click', selectGlobalScope); uDom('#scopeKeyGlobal').on('click', selectGlobalScope);
uDom('#scopeKeyDomain').on('click', selectDomainScope); uDom('#scopeKeyDomain').on('click', selectDomainScope);
uDom('#scopeKeySite').on('click', selectSiteScope); uDom('#scopeKeySite').on('click', selectSiteScope);
uDom('#buttonMtxFiltering').on('click', toggleMtxFiltering);
uDom('[id^="mtxSwitch_"]').on('click', toggleMatrixSwitch);
uDom('#buttonPersist').on('click', persistMatrix); uDom('#buttonPersist').on('click', persistMatrix);
uDom('#buttonRevertScope').on('click', revertMatrix); uDom('#buttonRevertScope').on('click', revertMatrix);

6
src/js/traffic.js

@ -474,9 +474,7 @@ var onBeforeSendHeadersHandler = function(details) {
} }
// TODO: move the master ua-spoofing switch into the matrix. // TODO: move the master ua-spoofing switch into the matrix.
var mustSpoof = µm.userSettings.spoofUserAgent &&
µm.tMatrix.evaluateSwitchZ('ua-spoof-off', pageStore.pageHostname) === false;
if ( mustSpoof ) {
if ( µm.tMatrix.evaluateSwitchZ('ua-spoof', pageStore.pageHostname) ) {
changed = foilUserAgent(µm, details) || changed; changed = foilUserAgent(µm, details) || changed;
// https://github.com/gorhill/httpswitchboard/issues/252 // https://github.com/gorhill/httpswitchboard/issues/252
// To avoid potential mismatch between the user agent from HTTP headers // To avoid potential mismatch between the user agent from HTTP headers
@ -715,7 +713,7 @@ var onMainDocHeadersReceived = function(details) {
// Enforce strict HTTPS? // Enforce strict HTTPS?
if ( requestScheme === 'https' && µm.tMatrix.evaluateSwitchZ('https-strict', pageStats.pageHostname) ) { if ( requestScheme === 'https' && µm.tMatrix.evaluateSwitchZ('https-strict', pageStats.pageHostname) ) {
csp += "default-src https: 'unsafe-inline' 'unsafe-eval'";
csp += "default-src https: data: 'unsafe-inline' 'unsafe-eval'";
} }
// https://github.com/gorhill/httpswitchboard/issues/181 // https://github.com/gorhill/httpswitchboard/issues/181

15
src/popup.html

@ -28,7 +28,18 @@
</ul> </ul>
</div> </div>
<div class="dropdown-menu-capture"></div> <div class="dropdown-menu-capture"></div>
<button id="buttonMtxFiltering" type="button" class="dropdown-menu-entry fa scopeRel switch tip-anchor-left" data-i18n-tip="matrixMtxButtonTip">&#xf011;<span class="badge"></span></button>
<button id="mtxSwitch_matrix-off" type="button" class="fa scopeRel tip-anchor-left" data-i18n-tip="matrixMtxButtonTip">&#xf011;<span class="badge"></span></button>
<div style="display: inline-block;">
<button id="buttonMtxSwitches" type="button" class="dropdown-menu-button fa scopeRel" tabindex="-1">&#xf141;</button>
<div class="dropdown-menu">
<ul id="mtxSwitches">
<li id="mtxSwitch_https-strict" class="dropdown-menu-entry"><span>Strict HTTPS</span>
<li id="mtxSwitch_ua-spoof" class="dropdown-menu-entry"><span>User agent spoofing</span>
</ul>
</div>
<div class="dropdown-menu-capture"></div>
</div>
<button id="buttonPersist" type="button" class="fa scopeRel tip-anchor-left" data-i18n-tip="matrixPersistButtonTip">&#xf023;<span class="badge"></span></button> <button id="buttonPersist" type="button" class="fa scopeRel tip-anchor-left" data-i18n-tip="matrixPersistButtonTip">&#xf023;<span class="badge"></span></button>
<button id="buttonRevertScope" type="button" class="fa scopeRel tip-anchor-left" tabindex="-1" data-i18n-tip="matrixRevertButtonTip">&#xf12d;</button> <button id="buttonRevertScope" type="button" class="fa scopeRel tip-anchor-left" tabindex="-1" data-i18n-tip="matrixRevertButtonTip">&#xf12d;</button>
</div> </div>
@ -37,7 +48,7 @@
<div class="toolbar alignRight"> <div class="toolbar alignRight">
<button id="buttonRevertAll" type="button" class="fa tip-anchor-right" tabindex="-1" data-i18n-tip="matrixRevertButtonAllTip">&#xf12d;<span class="fa">&#xf12d;</span><span class="fa">&#xf12d;</span><span class="fa">&#xf12d;</span><span class="fa">&#xf12d;</span></button> <button id="buttonRevertAll" type="button" class="fa tip-anchor-right" tabindex="-1" data-i18n-tip="matrixRevertButtonAllTip">&#xf12d;<span class="fa">&#xf12d;</span><span class="fa">&#xf12d;</span><span class="fa">&#xf12d;</span><span class="fa">&#xf12d;</span></button>
<button id="buttonReload" type="button" class="fa tip-anchor-right" data-i18n-tip="matrixReloadButton">&#xf021;</button> <button id="buttonReload" type="button" class="fa tip-anchor-right" data-i18n-tip="matrixReloadButton">&#xf021;</button>
<button id="buttonDashboard" type="button" class="dropdown-menu-entry extensionURL fa tip-anchor-right" data-extension-url="dashboard.html">&#xf085;</button>
<button id="buttonDashboard" type="button" class="extensionURL fa tip-anchor-right" data-extension-url="dashboard.html">&#xf085;</button>
</div> </div>
<div id="matHead" class="matrix collapsible"> <div id="matHead" class="matrix collapsible">

Loading…
Cancel
Save