Skip to content

Commit a8693d2

Browse files
committed
make extension opera--compatible + other odds and ends
1 parent 3c0ceb8 commit a8693d2

File tree

14 files changed

+213
-155
lines changed

14 files changed

+213
-155
lines changed

background.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
<script src="js/httpsb.js"></script>
1818
<script src="js/reqstats.js"></script>
1919
<script src="js/cookies.js"></script>
20-
<script src="js/inject.js"></script>
2120
<script src="js/profiler.js"></script>
2221
<script src="js/storage.js"></script>
2322
<script src="js/tab.js"></script>
2423
<script src="js/traffic.js"></script>
2524
<script src="js/contextmenu.js"></script>
25+
<script src="js/contentscripthandlers.js"></script>
2626
<script src="js/start.js"></script>
2727
</body>
2828
</html>

icon_64.png

5.96 KB
Loading

js/async.js

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ function updateBadgeCallback(pageUrl) {
113113
}
114114

115115
function updateBadge(pageUrl) {
116-
asyncJobQueue.add('updateBadge ' + pageUrl, pageUrl, updateBadgeCallback, 250);
116+
asyncJobQueue.add('updateBadge ' + pageUrl, pageUrl, updateBadgeCallback, 500);
117117
}
118118

119119
/******************************************************************************/
@@ -192,23 +192,21 @@ function onMessageHandler(request, sender, callback) {
192192
}
193193
break;
194194

195-
case 'contentHasLocalStorage':
196-
// `blocked` aka `response`
197-
response = HTTPSB.blacklisted(request.url, 'cookie', uriTools.hostnameFromURI(request.url));
198-
recordFromPageUrl(request.url, 'cookie', uriTools.rootURLFromURI(request.url) + '/{localStorage}', response);
199-
response = response && HTTPSB.userSettings.deleteLocalStorage;
200-
if ( response ) {
201-
HTTPSB.localStorageRemovedCounter++;
202-
}
195+
case 'contentScriptHasLocalStorage':
196+
response = contentScriptLocalStorageHandler(request.url)
197+
break;
198+
199+
case 'contentScriptSummary':
200+
contentScriptSummaryHandler(request.details);
203201
break;
204202

205-
default:
203+
default:
206204
// console.error('HTTP Switchboard > onMessage > unknown request: %o', request);
207205
break;
208206
}
209207
}
210208

211-
if ( response && callback ) {
209+
if ( response !== undefined && callback ) {
212210
callback(response);
213211
}
214212
}

js/inject.js renamed to js/contentscript.js

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,24 @@
22

33
// rhill 2013-11-09: Weird... This code is executed from HTTP Switchboard
44
// context first time extension is launched. Avoid this.
5-
if ( window.location.href.match(/^https?:\/\//) ) {
5+
if ( /^https?:\/\/./.test(window.location.href) ) {
66

77
/******************************************************************************/
88

9+
function localStorageHandler(mustRemove) {
10+
if ( mustRemove ) {
11+
window.localStorage.clear();
12+
// console.debug('HTTP Switchboard > found and removed non-empty localStorage');
13+
}
14+
}
15+
16+
/*----------------------------------------------------------------------------*/
17+
918
// This is to take care of
1019
// https://code.google.com/p/chromium/issues/detail?id=232410
1120
// We look up noscript tags and force the DOM parser to parse
1221
// them.
13-
(function() {
22+
function fixNoscriptTags() {
1423
var a = document.querySelectorAll('noscript');
1524
var i = a.length;
1625
var html;
@@ -20,17 +29,13 @@ if ( window.location.href.match(/^https?:\/\//) ) {
2029
html = html.replace(/&gt;/g, '>');
2130
a[i].innerHTML = html;
2231
}
23-
})();
32+
}
2433

25-
// Can extension remove localStorage of pages (like when cookies for
26-
// page are blacklisted)? Need to investigate. (Well at least when
27-
// scripts are blocked, localStorage won't happen..)
34+
/*----------------------------------------------------------------------------*/
2835

29-
// This must be last, so that result is returned to extension.
30-
// This is used so that inline script tags and preemptively blocked scripts
31-
// (which won't generate web requests) are logged in the stats.
32-
(function() {
36+
function collectExternalResources() {
3337
var r = {
38+
refCounter: 0,
3439
pageUrl: window.location.href,
3540
scriptSources: {}, // to avoid duplicates
3641
pluginSources: {}, // to avoid duplicates
@@ -50,6 +55,7 @@ if ( window.location.href.match(/^https?:\/\//) ) {
5055
r.scriptSources[elem.src.trim()] = true;
5156
}
5257
}
58+
5359
// https://github.com/gorhill/httpswitchboard/issues/25
5460
elems = document.querySelectorAll('object');
5561
i = elems.length;
@@ -59,6 +65,7 @@ if ( window.location.href.match(/^https?:\/\//) ) {
5965
r.pluginSources[elem.data.trim()] = true;
6066
}
6167
}
68+
6269
// https://github.com/gorhill/httpswitchboard/issues/25
6370
elems = document.querySelectorAll('embed');
6471
i = elems.length;
@@ -68,25 +75,23 @@ if ( window.location.href.match(/^https?:\/\//) ) {
6875
r.pluginSources[elem.src.trim()] = true;
6976
}
7077
}
78+
7179
// Check for non-empty localStorage
7280
if ( window.localStorage && window.localStorage.length ) {
7381
r.localStorage = true;
7482
chrome.runtime.sendMessage({
75-
what: 'contentHasLocalStorage',
83+
what: 'contentScriptHasLocalStorage',
7684
url: r.pageUrl
77-
}, function(mustRemove) {
78-
if ( mustRemove ) {
79-
window.localStorage.clear();
80-
// console.debug('HTTP Switchboard > found and removed non-empty localStorage');
81-
}
82-
});
85+
}, localStorageHandler);
8386
}
87+
8488
// TODO: indexedDB
8589
if ( window.indexedDB && !!window.indexedDB.webkitGetDatabaseNames ) {
8690
// var db = window.indexedDB.webkitGetDatabaseNames().onsuccess = function(sender) {
8791
// console.debug('webkitGetDatabaseNames(): result=%o', sender.target.result);
8892
// };
8993
}
94+
9095
// TODO: Web SQL
9196
if ( window.openDatabase ) {
9297
// Sad:
@@ -95,8 +100,20 @@ if ( window.location.href.match(/^https?:\/\//) ) {
95100
}
96101

97102
// Important!!
98-
return r;
99-
})();
103+
chrome.runtime.sendMessage({
104+
what: 'contentScriptSummary',
105+
details: r
106+
});
107+
}
108+
109+
/*----------------------------------------------------------------------------*/
110+
111+
function loadHandler() {
112+
fixNoscriptTags();
113+
collectExternalResources();
114+
}
115+
116+
window.addEventListener('load', loadHandler);
100117

101118
/******************************************************************************/
102119

js/contentscripthandlers.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*******************************************************************************
2+
3+
httpswitchboard - a Chromium browser extension to black/white list requests.
4+
Copyright (C) 2013 Raymond Hill
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see {http://www.gnu.org/licenses/}.
18+
19+
Home: https://github.com/gorhill/httpswitchboard
20+
*/
21+
22+
/******************************************************************************/
23+
24+
function contentScriptSummaryHandler(details) {
25+
// TODO: Investigate "Error in response to tabs.executeScript: TypeError:
26+
// Cannot read property 'pageUrl' of null" (2013-11-12). When can this
27+
// happens?
28+
if ( !details || !details.pageUrl ) {
29+
return;
30+
}
31+
var ut = uriTools;
32+
var httpsb = HTTPSB;
33+
var pageUrl = ut.normalizeURI(details.pageUrl);
34+
var pageHostname = ut.hostnameFromURI(pageUrl);
35+
var sources, i;
36+
var url, domain, block;
37+
38+
// scripts
39+
// https://github.com/gorhill/httpswitchboard/issues/25
40+
sources = Object.keys(details.scriptSources);
41+
i = sources.length;
42+
while ( i-- ) {
43+
url = sources[i];
44+
if ( url === '{inline_script}' ) {
45+
domain = pageHostname;
46+
url = pageUrl + '{inline_script}';
47+
} else {
48+
url = ut.normalizeURI(url);
49+
domain = ut.hostnameFromURI(url);
50+
}
51+
block = httpsb.blacklisted(pageUrl, 'script', domain);
52+
recordFromPageUrl(pageUrl, 'script', url, block);
53+
}
54+
55+
// plugins
56+
// https://github.com/gorhill/httpswitchboard/issues/25
57+
sources = Object.keys(details.pluginSources);
58+
i = sources.length;
59+
while ( i-- ) {
60+
url = ut.normalizeURI(sources[i]);
61+
domain = ut.hostnameFromURI(url);
62+
block = httpsb.blacklisted(pageUrl, 'object', domain);
63+
recordFromPageUrl(pageUrl, 'object', url, block);
64+
}
65+
}
66+
67+
/******************************************************************************/
68+
69+
function contentScriptLocalStorageHandler(pageURL) {
70+
var httpsb = HTTPSB;
71+
var response = httpsb.blacklisted(pageURL, 'cookie', uriTools.hostnameFromURI(pageURL));
72+
recordFromPageUrl(pageURL, 'cookie', uriTools.rootURLFromURI(pageURL) + '/{localStorage}', response);
73+
response = response && httpsb.userSettings.deleteLocalStorage;
74+
if ( response ) {
75+
httpsb.localStorageRemovedCounter++;
76+
}
77+
return response;
78+
}
79+

js/contextmenu.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ function updateContextMenuHandler(tabs) {
8282
var pageDomain = uriTools.domainFromURI(pageUrl);
8383
var color = HTTPSB.evaluate(pageUrl, '*', pageDomain);
8484
chrome.contextMenus.update('gdt-group0', {
85-
title: 'Temporarily whitelist *.' + pageDomain,
85+
title: 'Temporarily whitelist *.' + punycode.toUnicode(pageDomain),
8686
enabled: color.charAt(0) !== 'g' && !HTTPSB.off
8787
});
8888
chrome.contextMenus.update('revertPermissions', {

js/httpsb.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ HTTPSB.evaluate = function(src, type, hostname) {
136136
if ( this.off ) {
137137
return 'gpt';
138138
}
139+
// rhill 2013-12-07:
140+
// stylesheets are evaluated as `main_frame`.
141+
if ( type === 'stylesheet' ) {
142+
type = 'main_frame';
143+
}
139144
return this.temporaryScopes.evaluate(src, type, hostname);
140145
};
141146

@@ -278,3 +283,29 @@ HTTPSB.savePermissions = function() {
278283

279284
/******************************************************************************/
280285

286+
HTTPSB.turnOff = function() {
287+
this.off = true;
288+
// rhill 2013-12-07:
289+
// Relinquish control over javascript execution to the user.
290+
// https://github.com/gorhill/httpswitchboard/issues/74
291+
chrome.contentSettings.javascript.clear({});
292+
}
293+
294+
HTTPSB.turnOn = function() {
295+
chrome.contentSettings.javascript.clear({});
296+
297+
// rhill 2013-12-07:
298+
// Tell Chromium to all javascript: HTTPSB will control whether
299+
// javascript execute through `Content-Policy-Directive` and webRequest.
300+
// https://github.com/gorhill/httpswitchboard/issues/74
301+
chrome.contentSettings.javascript.set({
302+
primaryPattern: 'https://*/*',
303+
setting: 'allow'
304+
});
305+
chrome.contentSettings.javascript.set({
306+
primaryPattern: 'http://*/*',
307+
setting: 'allow'
308+
});
309+
310+
this.off = false;
311+
}

js/lists.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ PermissionScope.prototype.assign = function(other) {
221221
// otherwise.
222222

223223
PermissionScope.prototype.evaluate = function(type, hostname) {
224-
var blacklistReadonly = this.httpsb.blacklistReadonly;
224+
var blacklistReadonly = HTTPSB.blacklistReadonly;
225225
var blacklist = this.black.list;
226226
var whitelist = this.white.list;
227227
var graylist = this.gray.list;
@@ -245,6 +245,8 @@ PermissionScope.prototype.evaluate = function(type, hostname) {
245245
// indirect: any type, specific hostname
246246
cellKey = '*|' + hostname;
247247

248+
var strictBlocking = HTTPSB.userSettings.strictBlocking;
249+
248250
// rhill 2013-10-26: Whitelist MUST be checked before blacklist,
249251
// because read-only blacklists are, hum... read-only? (which means
250252
// they can only be overriden through occultation, which means
@@ -253,7 +255,7 @@ PermissionScope.prototype.evaluate = function(type, hostname) {
253255
// https://github.com/gorhill/httpswitchboard/issues/29
254256
// The cell is indirectly whitelisted because of hostname, type
255257
// must NOT be blacklisted.
256-
if ( this.httpsb.userSettings.strictBlocking && blacklist[typeKey] ) {
258+
if ( strictBlocking && blacklist[typeKey] ) {
257259
return 'rpt';
258260
}
259261
return 'gpt';
@@ -286,7 +288,7 @@ PermissionScope.prototype.evaluate = function(type, hostname) {
286288
// https://github.com/gorhill/httpswitchboard/issues/29
287289
// The cell is indirectly whitelisted because of hostname, type
288290
// must NOT be blacklisted.
289-
if ( this.httpsb.userSettings.strictBlocking && blacklist[typeKey] ) {
291+
if ( strictBlocking && blacklist[typeKey] ) {
290292
return 'rpt';
291293
}
292294
return 'gpt';
@@ -383,7 +385,7 @@ PermissionScope.prototype.blacklist = function(type, hostname) {
383385
// which is already in read-only blacklist (after graylisting or
384386
// whitelisting it), user expects entry to still be blacklisted if ever
385387
// same entry is removed from read-only blacklist.
386-
if ( type !== '*' || !this.httpsb.blacklistReadonly[hostname] ) {
388+
if ( type !== '*' || !HTTPSB.blacklistReadonly[hostname] ) {
387389
changed = this.black.addOne(key) || changed;
388390
}
389391
return changed;
@@ -402,7 +404,7 @@ PermissionScope.prototype.graylist = function(type, hostname) {
402404
// rhill 2013-10-25: special case, we expressly graylist only if the
403405
// key is '*' and hostname is found in read-only blacklist, so that the
404406
// express graylisting occults the read-only blacklist status.
405-
if ( type === '*' && this.httpsb.blacklistReadonly[hostname] ) {
407+
if ( type === '*' && HTTPSB.blacklistReadonly[hostname] ) {
406408
changed = this.gray.addOne(key) || changed;
407409
}
408410
return changed;
@@ -441,7 +443,7 @@ PermissionScopes.prototype.fromString = function(s) {
441443
var i = bin.scopes.length;
442444
var scope, scopeBin;
443445
while ( i-- ) {
444-
scope = new PermissionScope(this.httpsb);
446+
scope = new PermissionScope();
445447
scopeBin = bin.scopes[i];
446448
scope.fromString(scopeBin.scopeStr);
447449
this.scopes[scopeBin.scopeKey] = scope;
@@ -472,7 +474,7 @@ PermissionScopes.prototype.assign = function(other) {
472474
while ( i-- ) {
473475
scopeKey = scopeKeys[i];
474476
if ( !this.scopes[scopeKey] ) {
475-
this.scopes[scopeKey] = new PermissionScope(this.httpsb);
477+
this.scopes[scopeKey] = new PermissionScope();
476478
this.scopes[scopeKey].assign(other.scopes[scopeKey]);
477479
}
478480
}

0 commit comments

Comments
 (0)