diff --git a/platform/chromium/vapi-background.js b/platform/chromium/vapi-background.js index 34e8d1c1218e9..770d27b355f91 100644 --- a/platform/chromium/vapi-background.js +++ b/platform/chromium/vapi-background.js @@ -655,8 +655,8 @@ vAPI.messaging.listen = function(listenerName, callback) { /******************************************************************************/ vAPI.messaging.onPortMessage = (function() { - var messaging = vAPI.messaging; - var toAuxPending = {}; + var messaging = vAPI.messaging, + toAuxPending = {}; // Use a wrapper to avoid closure and to allow reuse. var CallbackWrapper = function(port, request, timeout) { @@ -703,8 +703,8 @@ vAPI.messaging.onPortMessage = (function() { }; var toAux = function(details, portFrom) { - var port, portTo; - var chromiumTabId = toChromiumTabId(details.toTabId); + var port, portTo, + chromiumTabId = toChromiumTabId(details.toTabId); // TODO: This could be an issue with a lot of tabs: easy to address // with a port name to tab id map. @@ -761,6 +761,32 @@ vAPI.messaging.onPortMessage = (function() { wrapper.callback(details.msg); }; + var toFramework = function(msg, sender) { + var tabId = sender && sender.tab && sender.tab.id; + if ( !tabId ) { return; } + switch ( msg.what ) { + case 'userCSS': + if ( msg.toRemove ) { + chrome.tabs.removeCSS(tabId, { + code: msg.toRemove, + cssOrigin: 'user', + frameId: sender.frameId, + matchAboutBlank: true + }); + } + if ( msg.toAdd ) { + chrome.tabs.insertCSS(tabId, { + code: msg.toAdd, + cssOrigin: 'user', + frameId: sender.frameId, + matchAboutBlank: true, + runAt: 'document_start' + }); + } + break; + } + }; + return function(request, port) { // Auxiliary process to auxiliary process if ( request.toTabId !== undefined ) { @@ -774,6 +800,13 @@ vAPI.messaging.onPortMessage = (function() { return; } + // Content process to main process: framework handler. + // No callback supported/needed for now. + if ( request.channelName === 'vapi-background' ) { + toFramework(request.msg, port.sender); + return; + } + // Auxiliary process to main process: prepare response var callback = messaging.NOOPFUNC; if ( request.auxProcessId !== undefined ) { @@ -781,8 +814,8 @@ vAPI.messaging.onPortMessage = (function() { } // Auxiliary process to main process: specific handler - var r = messaging.UNHANDLED; - var listener = messaging.listeners[request.channelName]; + var r = messaging.UNHANDLED, + listener = messaging.listeners[request.channelName]; if ( typeof listener === 'function' ) { r = listener(request.msg, port.sender, callback); } diff --git a/platform/webext/manifest.json b/platform/webext/manifest.json index 5e77bef90ac5b..772e430c341c0 100644 --- a/platform/webext/manifest.json +++ b/platform/webext/manifest.json @@ -37,6 +37,7 @@ ], "js":[ "js/vapi-client.js", + "js/vapi-usercss.js", "js/contentscript.js" ], "run_at":"document_start", diff --git a/platform/webext/vapi-usercss.js b/platform/webext/vapi-usercss.js new file mode 100644 index 0000000000000..aea2a2bf501c8 --- /dev/null +++ b/platform/webext/vapi-usercss.js @@ -0,0 +1,77 @@ +/******************************************************************************* + + uBlock Origin - a browser extension to block requests. + Copyright (C) 2017 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 +*/ + +'use strict'; + +// For content pages + +/******************************************************************************/ + +(function() { + if ( typeof vAPI !== 'object' ) { return; } + + vAPI.userCSS = { + _userCSS: '', + _disabled: false, + _send: function(toRemove, toAdd) { + vAPI.messaging.send('vapi-background', { + what: 'userCSS', + toRemove: toRemove, + toAdd: toAdd + }); + }, + add: function(cssText) { + if ( cssText === '' ) { return; } + var before = this._userCSS, + after = before; + if ( after !== '' ) { after += '\n'; } + after += cssText; + this._userCSS = after; + if ( this._disabled ) { return; } + this._send(before, after); + }, + remove: function(cssText) { + if ( cssText === '' || this._userCSS === '' ) { return; } + var before = this._userCSS, + after = before; + after = before.replace(cssText, '').trim(); + this._userCSS = after; + if ( this._disabled ) { return; } + this._send(before, after); + }, + toggle: function(state) { + if ( state === undefined ) { + state = this._disabled; + } + if ( state !== this._disabled ) { return; } + this._disabled = !state; + if ( this._userCSS === '' ) { return; } + var toAdd, toRemove; + if ( state ) { + toAdd = this._userCSS; + } else { + toRemove = this._userCSS; + } + this._send(toRemove, toAdd); + } + }; + vAPI.hideNode = vAPI.unhideNode = function(){}; +})(); diff --git a/tools/make-webext.sh b/tools/make-webext.sh index e9fda83149acf..2f64bf9268529 100755 --- a/tools/make-webext.sh +++ b/tools/make-webext.sh @@ -23,11 +23,12 @@ cp -R platform/chromium/img $DES/webextension/ cp platform/chromium/*.html $DES/webextension/ cp platform/chromium/*.json $DES/webextension/ cp platform/webext/polyfill.js $DES/webextension/js/ +cp platform/webext/vapi-usercss.js $DES/webextension/js/ +cp platform/webext/manifest.json $DES/webextension/ cp LICENSE.txt $DES/webextension/ cp platform/webext/background.html $DES/webextension/ cp platform/webext/from-legacy.js $DES/webextension/js/ -cp platform/webext/manifest.json $DES/webextension/ cp platform/webext/bootstrap.js $DES/ cp platform/webext/chrome.manifest $DES/ cp platform/webext/install.rdf $DES/