diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index de3686e..ea37bf7 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -572,6 +572,22 @@ "description": "Message asking user to confirm reset" }, + "mainBlockedPrompt1": { + "message": "uMatrix has prevented the following page from loading:", + "description": "English: uMatrix has prevented the following page from loading:" + }, + "mainBlockedPrompt2": { + "message": "Because of the following rule", + "description": "English: Because of the following rule" + }, + "mainBlockedBack" : { + "message": "Go back", + "description": "English: Go back" + }, + "mainBlockedClose" : { + "message": "Close", + "description": "English: Close" + }, "commandRevertAll" : { "message": "Remove all temporary changes", diff --git a/src/css/noop.css b/src/css/noop.css deleted file mode 100644 index e69de29..0000000 diff --git a/src/js/background.js b/src/js/background.js index fba362f..0d8cb5e 100644 --- a/src/js/background.js +++ b/src/js/background.js @@ -123,8 +123,6 @@ return { behindTheSceneScope: 'behind-the-scene', // Commonly encountered strings - chromeExtensionURLPrefix: 'chrome-extension://', - noopCSSURL: vAPI.getURL('css/noop.css'), fontCSSURL: vAPI.getURL('css/fonts/Roboto_Condensed/RobotoCondensed-Regular.ttf'), noopFunc: function(){}, diff --git a/src/js/main-blocked.js b/src/js/main-blocked.js new file mode 100644 index 0000000..eed66bf --- /dev/null +++ b/src/js/main-blocked.js @@ -0,0 +1,76 @@ +/******************************************************************************* + + µMatrix - a browser extension to block requests. + Copyright (C) 2015 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/uBlock +*/ + +/* global uDom */ + +/******************************************************************************/ + +(function() { + +'use strict'; + +/******************************************************************************/ + +var details = {}; + +(function() { + var matches = /details=([^&]+)/.exec(window.location.search); + if ( matches === null ) { + return; + } + details = JSON.parse(atob(matches[1])); +})(); + +/******************************************************************************/ + +uDom('.what').text(details.url); +uDom('#why').text(details.why.slice(3)); + +if ( window.history.length > 1 ) { + uDom('#back').on('click', function() { window.history.back(); }); + uDom('#bye').css('display', 'none'); +} else { + uDom('#bye').on('click', function() { window.close(); }); + uDom('#back').css('display', 'none'); +} + +/******************************************************************************/ + +// See if the target hostname is still blacklisted, and if not, navigate to it. + +var messager = vAPI.messaging.channel('main-blocked.js'); + +messager.send({ + what: 'mustBlock', + scope: details.hn, + hostname: details.hn, + type: 'doc' +}, function(response) { + if ( response === false ) { + window.location.replace(details.url); + } +}); + +/******************************************************************************/ + +})(); + +/******************************************************************************/ diff --git a/src/js/messaging.js b/src/js/messaging.js index e59a6c1..205fe26 100644 --- a/src/js/messaging.js +++ b/src/js/messaging.js @@ -71,6 +71,14 @@ function onMessage(request, sender, callback) { µm.utils.gotoURL(request); break; + case 'mustBlock': + response = µm.mustBlock( + request.scope, + request.hostname, + request.type + ); + break; + case 'reloadHostsFiles': µm.reloadHostsFiles(); break; @@ -168,7 +176,7 @@ var matrixSnapshot = function(tabId, details) { // Allow examination of behind-the-scene requests if ( - tabContext.rawURL.lastIndexOf(vAPI.getURL(''), 0) === 0 || + tabContext.rawURL.lastIndexOf(vAPI.getURL('dashboard.html'), 0) === 0 || tabContext.rawURL === µm.behindTheSceneURL ) { tabId = µm.behindTheSceneTabId; diff --git a/src/js/tab.js b/src/js/tab.js index ac88ac5..ce0dbc0 100644 --- a/src/js/tab.js +++ b/src/js/tab.js @@ -49,6 +49,20 @@ var µm = µMatrix; if ( vAPI.isBehindTheSceneTabId(tabId) ) { return 'http://behind-the-scene/'; } + + // If the URL is that of our "blocked page" document, return the URL of + // the blocked page. + if ( pageURL.lastIndexOf(vAPI.getURL('main-blocked.html'), 0) === 0 ) { + var matches = /main-blocked\.html\?details=([^&]+)/.exec(pageURL); + if ( matches && matches.length === 2 ) { + try { + var details = JSON.parse(atob(matches[1])); + pageURL = details.url; + } catch (e) { + } + } + } + var uri = this.URI.set(pageURL); var scheme = uri.scheme; if ( scheme === 'https' || scheme === 'http' ) { @@ -453,13 +467,6 @@ vAPI.tabs.registerListeners(); return this.pageStores[tabId]; } - // https://github.com/gorhill/httpswitchboard/issues/303 - // Don't rebind pages blocked by µMatrix. - var blockedRootFramePrefix = this.webRequest.blockedRootFramePrefix; - if ( tabContext.rawURL.lastIndexOf(blockedRootFramePrefix, 0) === 0 ) { - return null; - } - var normalURL = tabContext.normalURL; var pageStore = this.pageStores[tabId] || null; diff --git a/src/js/traffic.js b/src/js/traffic.js index 9b99130..c0dd4f8 100644 --- a/src/js/traffic.js +++ b/src/js/traffic.js @@ -33,65 +33,6 @@ // The `id='uMatrix'` is important, it allows µMatrix to detect whether a // specific data URI originates from itself. -var rootFrameReplacement = [ - '', - '', - '', - '', - '', - 'Blocked by μMatrix', - '', - '', - '
', - '
{{hostname}} blocked by μMatrix
', - '
', - '', - '' -].join(''); - var subFrameReplacement = [ '', '', @@ -152,43 +93,6 @@ var subFrameReplacement = [ /******************************************************************************/ -// If it is HTTP Switchboard's root frame replacement URL, verify that -// the page that was blacklisted is still blacklisted, and if not, -// redirect to the previously blacklisted page. - -var onBeforeChromeExtensionRequestHandler = function(details) { - var requestURL = details.url; - - // console.debug('onBeforeChromeExtensionRequestHandler()> "%s": %o', details.url, details); - - // rhill 2013-12-10: Avoid regex whenever a faster indexOf() can be used: - // here we can use fast indexOf() as a first filter -- which is executed - // for every single request (so speed matters). - var matches = requestURL.match(/url=([^&]+)&hostname=([^&]+)/); - if ( !matches ) { - return; - } - - var µm = µMatrix; - var pageURL = decodeURIComponent(matches[1]); - var pageHostname = decodeURIComponent(matches[2]); - - // Blacklisted as per matrix? - if ( µm.mustBlock(µm.scopeFromURL(pageURL), pageHostname, 'doc') ) { - return; - } - - µMatrix.asyncJobs.add( - 'gotoURL-' + details.tabId, - { tabId: details.tabId, url: pageURL }, - µm.utils.gotoURL, - 200, - false - ); -}; - -/******************************************************************************/ - // Intercept and filter web requests according to white and black lists. var onBeforeRootFrameRequestHandler = function(details) { @@ -199,7 +103,7 @@ var onBeforeRootFrameRequestHandler = function(details) { µm.tabContextManager.push(tabId, requestURL); var tabContext = µm.tabContextManager.mustLookup(tabId); - var pageStore = µm.bindTabToPageStats(tabId, 'weak'); + var pageStore = µm.bindTabToPageStats(tabId); // Disallow request as per matrix? var block = µm.mustBlock(tabContext.rootHostname, details.hostname, 'doc'); @@ -215,19 +119,15 @@ var onBeforeRootFrameRequestHandler = function(details) { } // Blocked + var query = btoa(JSON.stringify({ + url: requestURL, + hn: details.hostname, + why: '?' + })); - // If it's a blacklisted frame, redirect to frame.html - // rhill 2013-11-05: The root frame contains a link to noop.css, this - // allows to later check whether the root frame has been unblocked by the - // user, in which case we are able to force a reload using a redirect. - var html = rootFrameReplacement; - html = html.replace('{{cssURL}}', µm.noopCSSURL); - html = html.replace(/{{hostname}}/g, encodeURIComponent(requestHostname)); - html = html.replace('{{originalURL}}', encodeURIComponent(requestURL)); - html = html.replace('{{now}}', String(Date.now())); - var dataURI = 'data:text/html;base64,' + btoa(html); - - return { 'redirectUrl': dataURI }; + vAPI.tabs.replace(tabId, vAPI.getURL('main-blocked.html?details=') + query); + + return { cancel: true }; }; /******************************************************************************/ @@ -258,11 +158,6 @@ var onBeforeRequestHandler = function(details) { var requestURL = details.url; - // Is it µMatrix's noop css file? - if ( requestType === 'css' && requestURL.lastIndexOf(µm.noopCSSURL, 0) === 0 ) { - return onBeforeChromeExtensionRequestHandler(details); - } - // Ignore non-http schemes if ( requestScheme.indexOf('http') !== 0 ) { return; @@ -603,8 +498,7 @@ var requestTypeNormalizer = { vAPI.net.onBeforeRequest = { urls: [ "http://*/*", - "https://*/*", - "chrome-extension://*/*" + "https://*/*" ], extra: [ 'blocking' ], callback: onBeforeRequestHandler @@ -641,7 +535,6 @@ var start = function() { /******************************************************************************/ return { - blockedRootFramePrefix: 'data:text/html;base64,' + btoa(rootFrameReplacement).slice(0, 80), start: start }; diff --git a/src/main-blocked.html b/src/main-blocked.html new file mode 100644 index 0000000..3bd5e59 --- /dev/null +++ b/src/main-blocked.html @@ -0,0 +1,72 @@ + + + + + + + + +
+
+

+

+
+ + + +
+

+

+
+ + + + + + + +