From 6bc728f8b81b43681a991eb793956b2f1e8aad89 Mon Sep 17 00:00:00 2001 From: gorhill Date: Sat, 9 May 2015 19:18:16 -0400 Subject: [PATCH] refactoring of inline script blocking + improving AMO validation --- platform/chromium/vapi-client.js | 6 + platform/chromium/vapi-common.js | 4 + platform/firefox/vapi-background.js | 13 +- platform/firefox/vapi-client.js | 6 + platform/firefox/vapi-common.js | 6 + src/css/info.css | 61 ---- src/info.html | 119 -------- src/js/assets.js | 2 +- src/js/async.js | 4 +- src/js/browsercache.js | 4 +- src/js/contentscript-end.js | 46 ++- src/js/info.js | 417 ---------------------------- src/js/logger-ui.js | 4 +- src/js/logger.js | 4 +- src/js/messaging.js | 108 +------ src/js/pagestats.js | 7 - src/js/popup.js | 2 +- src/js/tab.js | 28 +- src/js/traffic.js | 96 +------ 19 files changed, 89 insertions(+), 848 deletions(-) delete mode 100644 src/css/info.css delete mode 100644 src/info.html delete mode 100644 src/js/info.js diff --git a/platform/chromium/vapi-client.js b/platform/chromium/vapi-client.js index 2d03803..f6e5db2 100644 --- a/platform/chromium/vapi-client.js +++ b/platform/chromium/vapi-client.js @@ -180,6 +180,12 @@ if ( window !== window.top ) { /******************************************************************************/ +vAPI.setTimeout = vAPI.setTimeout || function(callback, delay) { + setTimeout(function() { callback(); }, delay); +}; + +/******************************************************************************/ + })(this); /******************************************************************************/ diff --git a/platform/chromium/vapi-common.js b/platform/chromium/vapi-common.js index 1bf121a..56b192e 100644 --- a/platform/chromium/vapi-common.js +++ b/platform/chromium/vapi-common.js @@ -92,6 +92,10 @@ vAPI.localStorage = window.localStorage; /******************************************************************************/ +vAPI.setTimeout = vAPI.setTimeout || window.setTimeout.bind(window); + +/******************************************************************************/ + })(); /******************************************************************************/ diff --git a/platform/firefox/vapi-background.js b/platform/firefox/vapi-background.js index e0472b1..debed66 100644 --- a/platform/firefox/vapi-background.js +++ b/platform/firefox/vapi-background.js @@ -743,7 +743,7 @@ vAPI.tabs.injectScript = function(tabId, details, callback) { ); if ( typeof callback === 'function' ) { - setTimeout(callback, 13); + vAPI.setTimeout(callback, 13); } }; @@ -1434,7 +1434,7 @@ vAPI.toolbarButton.init = function() { } // Anonymous elements need some time to be reachable - setTimeout(this.updateBadgeStyle, 250); + vAPI.setTimeout(this.updateBadgeStyle, 250); }.bind(this.CUIEvents); this.CUIEvents.onCustomizeEnd = updateBadge; this.CUIEvents.onWidgetUnderflow = updateBadge; @@ -1465,7 +1465,7 @@ vAPI.toolbarButton.init = function() { this.onCreated = function(button) { button.setAttribute('badge', ''); - setTimeout(updateBadge, 250); + vAPI.setTimeout(updateBadge, 250); }; CustomizableUI.addListener(this.CUIEvents); @@ -1531,7 +1531,7 @@ vAPI.toolbarButton.onBeforeCreated = function(doc) { if ( updateTimer ) { return; } - updateTimer = setTimeout(resizePopup, 10); + updateTimer = vAPI.setTimeout(resizePopup, 10); }; var resizePopup = function() { updateTimer = null; @@ -1870,8 +1870,7 @@ vAPI.browserData = {}; /******************************************************************************/ -// https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsICacheService -// https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsICache +// https://developer.mozilla.org/en-US/docs/HTTP_Cache vAPI.browserData.clearCache = function(callback) { // PURGE_DISK_DATA_ONLY:1 @@ -1957,7 +1956,7 @@ vAPI.cookies.getAll = function(callback) { } callback(out); }; - setTimeout(onAsync.bind(this), 0); + vAPI.setTimeout(onAsync.bind(this), 0); }; /******************************************************************************/ diff --git a/platform/firefox/vapi-client.js b/platform/firefox/vapi-client.js index 712bb41..883f7b6 100644 --- a/platform/firefox/vapi-client.js +++ b/platform/firefox/vapi-client.js @@ -200,6 +200,12 @@ if ( window !== window.top ) { /******************************************************************************/ +vAPI.setTimeout = vAPI.setTimeout || function(callback, delay) { + setTimeout(function() { callback(); }, delay); +}; + +/******************************************************************************/ + })(this); /******************************************************************************/ diff --git a/platform/firefox/vapi-common.js b/platform/firefox/vapi-common.js index 07465dc..6d03e72 100644 --- a/platform/firefox/vapi-common.js +++ b/platform/firefox/vapi-common.js @@ -153,6 +153,12 @@ vAPI.localStorage = { /******************************************************************************/ +vAPI.setTimeout = vAPI.setTimeout || function(callback, delay) { + setTimeout(function() { callback(); }, delay); +}; + +/******************************************************************************/ + })(); /******************************************************************************/ diff --git a/src/css/info.css b/src/css/info.css deleted file mode 100644 index cbaf7d2..0000000 --- a/src/css/info.css +++ /dev/null @@ -1,61 +0,0 @@ -select { - max-width: 20em; - } -#stats div div,#lists div div { - padding: 0 1em 0 0; - display: inline-block; - text-align: right; - } -#requestsFilters button { - font-size: 15px; - } -#requestsFilters label { - font-size: 13px; - padding-right: 0.5em; - white-space: nowrap; - } -#requests-log { - background-color: white; - border: 1px inset #eee; - direction: ltr; - font: 11px monospace; - margin: 0; - overflow: scroll; - padding: 0; - width: calc(100% - 1.5em); - } -#requestsTable { - border-collapse: collapse; - } -#requests-log tr { - margin: 0; - border: 0; - padding: 0; - color: #070; - } -#requests-log tr.ro { - color: gray; - } -#requests-log tr:hover { - background-color: #eee; - } -#requests-log tr.blocked-true { - color: #c00; - } -#requests-log tr:first-child { - font-weight: bold; - background-color: #eee; - } -#requests-log tr > td { - padding: 1px 0.75em 1px 0; - white-space: nowrap; - } -#requests-log tr > td:nth-of-type(2) { - text-align: right; - } -.type-main_frame { - font-weight: bold; - } -tr.unused { - display: none; - } diff --git a/src/info.html b/src/info.html deleted file mode 100644 index 311ebf6..0000000 --- a/src/info.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - -µMatrix — Info - - - - - - - -

-
- -
- -

-
- - - -

-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - -

-
-
- -

-

- - - - - - - - - - - - - -

-
-
- - - -
whenwhatwhere
<a>
-
-
- -
- - - - - - - - - diff --git a/src/js/assets.js b/src/js/assets.js index 40eb45d..60f518c 100644 --- a/src/js/assets.js +++ b/src/js/assets.js @@ -1353,7 +1353,7 @@ var scheduleUpdateDaemon = function() { if ( updateDaemonTimer !== null ) { clearTimeout(updateDaemonTimer); } - updateDaemonTimer = setTimeout( + updateDaemonTimer = vAPI.setTimeout( updateDaemon, exports.manualUpdate ? manualUpdateDaemonTimerPeriod : autoUpdateDaemonTimerPeriod ); diff --git a/src/js/async.js b/src/js/async.js index e22ff5b..c6b89bc 100644 --- a/src/js/async.js +++ b/src/js/async.js @@ -71,7 +71,7 @@ AsyncJobManager.prototype.restartTimer = function() { if ( when < this.timerWhen ) { clearTimeout(this.timerId); this.timerWhen = when; - this.timerId = setTimeout(processJobs, Math.max(when - Date.now(), 10)); + this.timerId = vAPI.setTimeout(processJobs, Math.max(when - Date.now(), 10)); } }; @@ -169,6 +169,6 @@ return asyncJobManager; if ( vAPI.isBehindTheSceneTabId(tabId) ) { return; } - tabIdToTimer[tabId] = setTimeout(updateBadge.bind(this, tabId), 500); + tabIdToTimer[tabId] = vAPI.setTimeout(updateBadge.bind(this, tabId), 500); }; })(); diff --git a/src/js/browsercache.js b/src/js/browsercache.js index defb155..33500e3 100644 --- a/src/js/browsercache.js +++ b/src/js/browsercache.js @@ -32,7 +32,7 @@ // Browser data jobs var clearCache = function() { - setTimeout(clearCache, 15 * 60 * 1000); + vAPI.setTimeout(clearCache, 15 * 60 * 1000); var µm = µMatrix; if ( !µm.userSettings.clearBrowserCache ) { @@ -55,7 +55,7 @@ var clearCache = function() { //console.debug('clearBrowserCacheCallback()> vAPI.browserData.clearCache() called'); }; -setTimeout(clearCache, 15 * 60 * 1000); +vAPI.setTimeout(clearCache, 15 * 60 * 1000); /******************************************************************************/ diff --git a/src/js/contentscript-end.js b/src/js/contentscript-end.js index 6d5812d..3fd6a63 100644 --- a/src/js/contentscript-end.js +++ b/src/js/contentscript-end.js @@ -242,7 +242,7 @@ var collapser = (function() { clearTimeout(timer); send(); } else if ( timer === null ) { - timer = setTimeout(send, delay || 50); + timer = vAPI.setTimeout(send, delay || 50); } }; @@ -360,9 +360,9 @@ var collapser = (function() { /******************************************************************************/ /******************************************************************************/ -var nodesAddedHandler = function(nodeList, summary) { +var hasInlineScript = function(nodeList, summary) { var i = 0; - var node, src, text; + var node, text; while ( node = nodeList.item(i++) ) { if ( node.nodeType !== 1 ) { continue; @@ -371,35 +371,29 @@ var nodesAddedHandler = function(nodeList, summary) { continue; } - switch ( node.localName ) { - - case 'script': + if ( node.localName === 'script' ) { // https://github.com/gorhill/httpswitchboard/issues/252 // Do not count uMatrix's own script tags, they are not required // to "unbreak" a web page if ( typeof node.id === 'string' && node.id.lastIndexOf('uMatrix-', 0) === 0 ) { - break; + continue; } text = node.textContent.trim(); - if ( text !== '' ) { - summary.scriptSources['{inline_script}'] = true; - summary.mustReport = true; - } - src = (node.src || '').trim(); - if ( src !== '' ) { - summary.scriptSources[src] = true; - summary.mustReport = true; + if ( text === '' ) { + continue; } + summary.inlineScript = true; break; + } - case 'a': - if ( node.href.lastIndexOf('javascript', 0) === 0 ) { - summary.scriptSources['{inline_script}'] = true; - summary.mustReport = true; - } + if ( node.localName === 'a' && node.href.lastIndexOf('javascript', 0) === 0 ) { + summary.inlineScript = true; break; } } + if ( summary.inlineScript ) { + summary.mustReport = true; + } }; /******************************************************************************/ @@ -412,11 +406,13 @@ var nodeListsAddedHandler = function(nodeLists) { var summary = { what: 'contentScriptSummary', locationURL: window.location.href, - scriptSources: {}, // to avoid duplicates + inlineScript: false, mustReport: false }; while ( i-- ) { - nodesAddedHandler(nodeLists[i], summary); + if ( summary.inlineScript === false ) { + hasInlineScript(nodeLists[i], summary); + } collapser.addBranches(nodeLists[i]); } if ( summary.mustReport ) { @@ -434,14 +430,14 @@ var nodeListsAddedHandler = function(nodeLists) { var summary = { what: 'contentScriptSummary', locationURL: window.location.href, - scriptSources: {}, // to avoid duplicates + inlineScript: false, mustReport: true }; // https://github.com/gorhill/httpswitchboard/issues/25 // & // Looks for inline javascript also in at least one a[href] element. // https://github.com/gorhill/httpswitchboard/issues/131 - nodesAddedHandler(document.querySelectorAll('a[href^="javascript:"],script'), summary); + hasInlineScript(document.querySelectorAll('a[href^="javascript:"],script'), summary); //console.debug('contentscript-end.js > firstObservationHandler(): found %d script tags in "%s"', Object.keys(summary.scriptSources).length, window.location.href); @@ -484,7 +480,7 @@ var nodeListsAddedHandler = function(nodeLists) { // nodes too often and the delay of many nodes less often. There is nothing // time critical here. if ( addedNodeListsTimer === null ) { - addedNodeListsTimer = setTimeout(treeMutationObservedHandler, 250); + addedNodeListsTimer = vAPI.setTimeout(treeMutationObservedHandler, 250); } }; diff --git a/src/js/info.js b/src/js/info.js deleted file mode 100644 index b6a5859..0000000 --- a/src/js/info.js +++ /dev/null @@ -1,417 +0,0 @@ -/******************************************************************************* - - µMatrix - a Chromium browser extension to black/white list requests. - Copyright (C) 2014 Raymond Hill - - 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 -*/ - -/* global vAPI, uDom */ - -/******************************************************************************/ - -(function() { - -'use strict'; - -/******************************************************************************/ - -var messager = vAPI.messaging.channel('info.js'); - -var targetTabId = null; -var maxRequests = 500; -var cachedUserSettings = {}; - -/******************************************************************************/ - -// Get a list of latest net requests - -function updateRequestData(callback) { - var onResponseReceived = function(r) { - var requests = []; - for ( var pageURL in r ) { - if ( r.hasOwnProperty(pageURL) === false ) { - continue; - } - requests = requests.concat(r[pageURL]); - } - requests = requests - .sort(function(a,b){return b.when-a.when;}) - .slice(0, maxRequests); - callback(requests); - }; - var request = { - what: 'getRequestLogs', - tabId: targetTabId - }; - messager.send(request, onResponseReceived); -} - -/******************************************************************************/ - -function clearRequestData() { - var request = { - what: 'clearRequestLogs', - tabId: targetTabId - }; - messager.send(request); -} - -/******************************************************************************/ - -function renderNumber(value) { - if ( isNaN(value) ) { - return '0'; - } - return value.toLocaleString(); -} - -/******************************************************************************/ - -function renderNumbers(set) { - var keys = Object.keys(set); - var i = keys.length; - var key; - while ( i-- ) { - key = keys[i]; - uDom(key).text(renderNumber(set[key])); - } -} - -/******************************************************************************/ - -var renderLocalized = function(id, map) { - var uElem = uDom('#' + id); - var msg = vAPI.i18n(id); - for ( var k in map ) { - if ( map.hasOwnProperty(k) === false ) { - continue; - } - msg = msg.replace('{{' + k + '}}', map[k]); - } - uElem.html(msg); -}; - -/******************************************************************************/ - -function renderPageUrls() { - var onResponseReceived = function(result) { - var i, n; - var select = uDom('#selectPageUrls'); - - // Remove whatever was put there in a previous call - uDom('#selectPageUrls > option').remove(); - var builtinOptions = uDom('#selectPageUrlsTemplate > option'); - n = builtinOptions.length; - for ( i = 0; i < n; i++ ) { - option = builtinOptions.at(i).clone(); - if ( option.val() === targetTabId ) { - option.attr('selected', true); - } - select.append(option); - } - - var entries = result.pageURLs.sort(); - var entry, pageURL, option; - n = entries.length; - for ( i = 0; i < n; i++ ) { - entry = entries[i]; - // Behind-the-scene entry is always present, no need to recreate it - if ( entry.pageURL === result.behindTheSceneURL ) { - continue; - } - option = uDom('