remove firefox/legacy platform, it now has its own branch: firefox-legacy

This commit is contained in:
Raymond Hill 2018-04-27 08:40:53 -04:00
parent 3923520b87
commit 443010efdc
No known key found for this signature in database
GPG key ID: 25E1490B761470C2
19 changed files with 0 additions and 5649 deletions

View file

@ -1,250 +0,0 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2017 The uBlock Origin authors
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 ADDON_UNINSTALL, APP_SHUTDOWN */
/* exported startup, shutdown, install, uninstall */
'use strict';
/******************************************************************************/
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
// Accessing the context of the background page:
// var win = Services.appShell.hiddenDOMWindow.document.querySelector('iframe[src*=ublock0]').contentWindow;
let windowlessBrowser = null;
let windowlessBrowserPL = null;
let bgProcess = null;
let version;
const hostName = 'ublock0';
const restartListener = {
get messageManager() {
return Cc['@mozilla.org/parentprocessmessagemanager;1']
.getService(Ci.nsIMessageListenerManager);
},
receiveMessage: function() {
shutdown();
startup();
}
};
/******************************************************************************/
function startup(data/*, reason*/) {
if ( data !== undefined ) {
version = data.version;
}
// Already started?
if ( bgProcess !== null ) {
return;
}
waitForHiddenWindow();
}
function createBgProcess(parentDocument) {
bgProcess = parentDocument.documentElement.appendChild(
parentDocument.createElementNS('http://www.w3.org/1999/xhtml', 'iframe')
);
bgProcess.setAttribute(
'src',
'chrome://' + hostName + '/content/background.html#' + version
);
// https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIMessageListenerManager#addMessageListener%28%29
// "If the same listener registers twice for the same message, the
// "second registration is ignored."
restartListener.messageManager.addMessageListener(
hostName + '-restart',
restartListener
);
}
function getWindowlessBrowserFrame(appShell) {
windowlessBrowser = appShell.createWindowlessBrowser(true);
windowlessBrowser.QueryInterface(Ci.nsIInterfaceRequestor);
let webProgress = windowlessBrowser.getInterface(Ci.nsIWebProgress);
let XPCOMUtils = Cu.import('resource://gre/modules/XPCOMUtils.jsm', null).XPCOMUtils;
windowlessBrowserPL = {
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIWebProgressListener,
Ci.nsIWebProgressListener2,
Ci.nsISupportsWeakReference
]),
onStateChange: function(wbp, request, stateFlags/*, status*/) {
if ( !request ) { return; }
if ( stateFlags & Ci.nsIWebProgressListener.STATE_STOP ) {
webProgress.removeProgressListener(windowlessBrowserPL);
windowlessBrowserPL = null;
createBgProcess(windowlessBrowser.document);
}
}
};
webProgress.addProgressListener(windowlessBrowserPL, Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
windowlessBrowser.document.location = "data:application/vnd.mozilla.xul+xml;charset=utf-8,<window%20id='" + hostName + "-win'/>";
}
function waitForHiddenWindow() {
let appShell = Cc['@mozilla.org/appshell/appShellService;1']
.getService(Ci.nsIAppShellService);
let isReady = function() {
var hiddenDoc;
try {
hiddenDoc = appShell.hiddenDOMWindow &&
appShell.hiddenDOMWindow.document;
} catch (ex) {
}
// Do not test against `loading`: it does appear `readyState` could be
// undefined if looked up too early.
if ( !hiddenDoc || hiddenDoc.readyState !== 'complete' ) {
return false;
}
// In theory, it should be possible to create a windowless browser
// immediately, without waiting for the hidden window to have loaded
// completely. However, in practice, on Windows this seems to lead
// to a broken Firefox appearance. To avoid this, we only create the
// windowless browser here. We'll use that rather than the hidden
// window for the actual background page (windowless browsers are
// also what the webextension implementation in Firefox uses for
// background pages).
let { Services } = Cu.import('resource://gre/modules/Services.jsm', null);
if ( Services.vc.compare(Services.appinfo.platformVersion, '27') >= 0 ) {
getWindowlessBrowserFrame(appShell);
} else {
createBgProcess(hiddenDoc);
}
return true;
};
if ( isReady() ) {
return;
}
// https://github.com/gorhill/uBlock/issues/749
// Poll until the proper environment is set up -- or give up eventually.
// We poll frequently early on but relax poll delay as time pass.
let tryDelay = 5;
let trySum = 0;
// https://trac.torproject.org/projects/tor/ticket/19438
// Try for a longer period.
let tryMax = 600011;
let timer = Cc['@mozilla.org/timer;1']
.createInstance(Ci.nsITimer);
let checkLater = function() {
trySum += tryDelay;
if ( trySum >= tryMax ) {
timer = null;
return;
}
timer.init(timerObserver, tryDelay, timer.TYPE_ONE_SHOT);
tryDelay *= 2;
if ( tryDelay > 503 ) {
tryDelay = 503;
}
};
var timerObserver = {
observe: function() {
timer.cancel();
if ( isReady() ) {
timer = null;
} else {
checkLater();
}
}
};
checkLater();
}
/******************************************************************************/
function shutdown(data, reason) {
if ( reason === APP_SHUTDOWN ) {
return;
}
if ( bgProcess !== null ) {
bgProcess.parentNode.removeChild(bgProcess);
bgProcess = null;
}
if ( windowlessBrowser !== null ) {
// close() does not exist for older versions of Firefox.
if ( typeof windowlessBrowser.close === 'function' ) {
windowlessBrowser.close();
}
windowlessBrowser = null;
windowlessBrowserPL = null;
}
if ( data === undefined ) {
return;
}
// Remove the restartObserver only when the extension is being disabled
restartListener.messageManager.removeMessageListener(
hostName + '-restart',
restartListener
);
}
/******************************************************************************/
function install(/*aData, aReason*/) {
// https://bugzil.la/719376
Cc['@mozilla.org/intl/stringbundle;1']
.getService(Ci.nsIStringBundleService)
.flushBundles();
}
/******************************************************************************/
// https://developer.mozilla.org/en-US/Add-ons/Bootstrapped_extensions#uninstall
// "if you have code in uninstall it will not run, you MUST run some code
// "in the install function, at the least you must set arguments on the
// "install function so like: function install(aData, aReason) {} then
// "uninstall WILL WORK."
function uninstall(aData, aReason) {
if ( aReason !== ADDON_UNINSTALL ) {
return;
}
// https://github.com/gorhill/uBlock/issues/84
// "Add cleanup task to remove local storage settings when uninstalling"
// To cleanup vAPI.localStorage in vapi-common.js
// As I get more familiar with FF API, will find out whetehr there was
// a better way to do this.
Cu.import('resource://gre/modules/Services.jsm', null)
.Services.prefs.getBranch('extensions.' + hostName + '.')
.deleteBranch('');
}
/******************************************************************************/

View file

@ -1 +0,0 @@
content ublock0 ./

View file

@ -1,46 +0,0 @@
#uBlock0-legacy-button {
list-style-image: url('../img/browsericons/icon24.svg');
}
#uBlock0-legacy-button.off {
list-style-image: url('../img/browsericons/icon24-off.svg');
}
toolbar[iconsize="small"] #uBlock0-legacy-button {
list-style-image: url('../img/browsericons/icon16.svg');
}
toolbar[iconsize="small"] #uBlock0-legacy-button.off {
list-style-image: url('../img/browsericons/icon16-off.svg');
}
#uBlock0-legacy-button[badge]::before {
background: #555;
color: #fff;
content: attr(badge);
font: bold 10px sans-serif;
margin-top: -2px;
padding: 0 2px;
position: fixed;
}
/* This hack required because if the before content changes it de-pops the
popup (without firing any events). So just hide it instead. Note, can't
actually *hide* it, or the same thing happens.
**/
#uBlock0-legacy-button[badge=""]::before {
padding: 0;
}
/* Override off state when in palette */
toolbarpaletteitem #uBlock0-legacy-button.off {
list-style-image: url('../img/browsericons/icon24.svg');
}
/* Override badge when in palette */
toolbarpaletteitem #uBlock0-legacy-button[badge]::before {
content: none;
}
/* Prevent pale moon from showing the arrow underneath the button */
/* https://github.com/chrisaljoudi/uBlock/issues/1449#issuecomment-112112761 */
#uBlock0-legacy-button .toolbarbutton-menu-dropmarker {
display: none;
-moz-box-orient: horizontal;
}

View file

@ -1,623 +0,0 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2017 The uBlock Origin authors
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
*/
/* exported processObserver */
'use strict';
/******************************************************************************/
// https://github.com/gorhill/uBlock/issues/800
this.EXPORTED_SYMBOLS = [
'contentObserver',
'processObserver',
'LocationChangeListener'
];
const {interfaces: Ci, utils: Cu} = Components;
const {Services} = Cu.import('resource://gre/modules/Services.jsm', null);
const {XPCOMUtils} = Cu.import('resource://gre/modules/XPCOMUtils.jsm', null);
const hostName = Services.io.newURI(Components.stack.filename, null, null).host;
const rpcEmitterName = hostName + ':child-process-message';
//Cu.import('resource://gre/modules/Console.jsm'); // Firefox >= 44
//Cu.import('resource://gre/modules/devtools/Console.jsm'); // Firefox < 44
/******************************************************************************/
const getMessageManager = function(win) {
let iface = win
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.sameTypeRootTreeItem
.QueryInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIInterfaceRequestor);
try {
return iface.getInterface(Ci.nsIContentFrameMessageManager);
} catch (ex) {
// This can throw. It appears `shouldLoad` can be called *after* a
// tab has been closed. For example, a case where this happens all
// the time (FF38):
// - Open twitter.com (assuming you have an account and are logged in)
// - Close twitter.com
// There will be an exception raised when `shouldLoad` is called
// to process a XMLHttpRequest with URL `https://twitter.com/i/jot`
// fired from `https://twitter.com/`, *after* the tab is closed.
// In such case, `win` is `about:blank`.
}
return null;
};
/******************************************************************************/
// https://github.com/gorhill/uBlock/issues/2014
// Have a dictionary of hostnames for which there are script tag filters. This
// allow for coarse-testing before firing a synchronous message to the
// parent process. Script tag filters are not very common, so this allows
// to skip the blocking of the child process most of the time.
var scriptTagFilterer = (function() {
var scriptTagHostnames;
var getCpmm = function() {
var svc = Services;
if ( !svc ) { return; }
var cpmm = svc.cpmm;
if ( cpmm ) { return cpmm; }
cpmm = Components.classes['@mozilla.org/childprocessmessagemanager;1'];
if ( cpmm ) { return cpmm.getService(Ci.nsISyncMessageSender); }
};
var getScriptTagHostnames = function() {
if ( scriptTagHostnames ) {
return scriptTagHostnames;
}
var cpmm = getCpmm();
if ( !cpmm ) { return; }
var r = cpmm.sendSyncMessage(rpcEmitterName, { fnName: 'getScriptTagHostnames' });
if ( Array.isArray(r) && Array.isArray(r[0]) ) {
scriptTagHostnames = new Set(r[0]);
}
return scriptTagHostnames;
};
var getScriptTagFilters = function(details) {
let cpmm = getCpmm();
if ( !cpmm ) { return; }
let r = cpmm.sendSyncMessage(rpcEmitterName, {
fnName: 'getScriptTagFilters',
rootURL: details.rootURL,
frameURL: details.frameURL,
frameHostname: details.frameHostname
});
if ( Array.isArray(r) ) {
return r[0];
}
};
var regexFromHostname = function(details) {
// If target hostname has no script tag filter, no point querying
// chrome process.
var hostnames = getScriptTagHostnames();
if ( !hostnames ) { return; }
var hn = details.frameHostname, pos, entity;
for (;;) {
if ( hostnames.has(hn) ) {
return getScriptTagFilters(details);
}
pos = hn.indexOf('.');
if ( pos === -1 ) { break; }
entity = hn.slice(0, pos) + '.*';
if ( hostnames.has(entity) ) {
return getScriptTagFilters(details);
}
hn = hn.slice(pos + 1);
if ( hn === '' ) { break; }
}
};
var reset = function() {
scriptTagHostnames = undefined;
};
return {
get: regexFromHostname,
reset: reset
};
})();
/******************************************************************************/
var contentObserver = {
classDescription: 'content-policy for ' + hostName,
classID: Components.ID('{7afbd130-cbaf-46c2-b944-f5d24305f484}'),
contractID: '@' + hostName + '/content-policy;1',
ACCEPT: Ci.nsIContentPolicy.ACCEPT,
REJECT: Ci.nsIContentPolicy.REJECT_REQUEST,
MAIN_FRAME: Ci.nsIContentPolicy.TYPE_DOCUMENT,
SUB_FRAME: Ci.nsIContentPolicy.TYPE_SUBDOCUMENT,
contentBaseURI: 'chrome://' + hostName + '/content/js/',
cpMessageName: hostName + ':shouldLoad',
popupMessageName: hostName + ':shouldLoadPopup',
ignoredPopups: new WeakMap(),
uniquePopupEventId: 1,
uniqueSandboxId: 1,
modernFirefox: Services.vc.compare(Services.appinfo.platformVersion, '44') > 0,
get componentRegistrar() {
return Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
},
get categoryManager() {
return Components.classes['@mozilla.org/categorymanager;1']
.getService(Ci.nsICategoryManager);
},
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIFactory,
Ci.nsIObserver,
Ci.nsIContentPolicy,
Ci.nsISupportsWeakReference
]),
createInstance: function(outer, iid) {
if ( outer ) {
throw Components.results.NS_ERROR_NO_AGGREGATION;
}
return this.QueryInterface(iid);
},
register: function() {
Services.obs.addObserver(this, 'document-element-inserted', true);
Services.obs.addObserver(this, 'content-document-global-created', true);
// https://bugzilla.mozilla.org/show_bug.cgi?id=1232354
// For modern versions of Firefox, the frameId/parentFrameId
// information can be found in channel.loadInfo of the HTTP observer.
if ( this.modernFirefox !== true ) {
this.componentRegistrar.registerFactory(
this.classID,
this.classDescription,
this.contractID,
this
);
this.categoryManager.addCategoryEntry(
'content-policy',
this.contractID,
this.contractID,
false,
true
);
}
},
unregister: function() {
Services.obs.removeObserver(this, 'document-element-inserted');
Services.obs.removeObserver(this, 'content-document-global-created');
if ( this.modernFirefox !== true ) {
this.componentRegistrar.unregisterFactory(this.classID, this);
this.categoryManager.deleteCategoryEntry(
'content-policy',
this.contractID,
false
);
}
},
getFrameId: function(win) {
return win
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.outerWindowID;
},
// https://bugzil.la/612921
shouldLoad: function(type, location, origin, context) {
// For whatever reason, sometimes the global scope is completely
// uninitialized at this point. Repro steps:
// - Launch FF with uBlock enabled
// - Disable uBlock
// - Enable uBlock
// - Services and all other global variables are undefined
// Hopefully will eventually understand why this happens.
if ( Services === undefined || !context ) {
return this.ACCEPT;
}
if ( !location.schemeIs('http') && !location.schemeIs('https') ) {
return this.ACCEPT;
}
if ( type === this.MAIN_FRAME ) {
context = context.contentWindow || context;
} else if ( type === this.SUB_FRAME ) {
context = context.contentWindow;
} else {
context = (context.ownerDocument || context).defaultView;
}
// https://github.com/gorhill/uBlock/issues/1893
// I don't know why this happens. I observed that when it occurred, the
// resource was not seen by the HTTP observer, as if it was a spurious
// call to shouldLoad().
if ( !context ) {
return this.ACCEPT;
}
// The context for the toolbar popup is an iframe element here,
// so check context.top instead of context
if ( !context.top || !context.location ) {
return this.ACCEPT;
}
let messageManager = getMessageManager(context);
if ( messageManager === null ) {
return this.ACCEPT;
}
let isTopContext = context === context.top;
var parentFrameId;
if ( isTopContext ) {
parentFrameId = -1;
} else if ( context.parent === context.top ) {
parentFrameId = 0;
} else {
parentFrameId = this.getFrameId(context.parent);
}
let rpcData = this.rpcData;
rpcData.frameId = isTopContext ? 0 : this.getFrameId(context);
rpcData.pFrameId = parentFrameId;
rpcData.type = type;
rpcData.url = location.spec;
//console.log('shouldLoad: type=' + type + ' url=' + location.spec);
if ( typeof messageManager.sendRpcMessage === 'function' ) {
// https://bugzil.la/1092216
messageManager.sendRpcMessage(this.cpMessageName, rpcData);
} else {
// Compatibility for older versions
messageManager.sendSyncMessage(this.cpMessageName, rpcData);
}
return this.ACCEPT;
},
// Reuse object to avoid repeated memory allocation.
rpcData: { frameId: 0, pFrameId: -1, type: 0, url: '' },
initContentScripts: function(win, create) {
let messager = getMessageManager(win);
let sandboxId = hostName + ':sb:' + this.uniqueSandboxId++;
let sandbox;
if ( create ) {
let sandboxName = [
win.location.href.slice(0, 100),
win.document.title.slice(0, 100)
].join(' | ');
// https://github.com/gorhill/uMatrix/issues/325
// "Pass sameZoneAs to sandbox constructor to make GCs cheaper"
sandbox = Cu.Sandbox([win], {
sameZoneAs: win.top,
sandboxName: sandboxId + '[' + sandboxName + ']',
sandboxPrototype: win,
wantComponents: false,
wantXHRConstructor: false
});
sandbox.getScriptTagFilters = function(details) {
return scriptTagFilterer.get(details);
};
sandbox.injectScript = function(script) {
let svc = Services;
// Sandbox appears void.
// I've seen this happens, need to investigate why.
if ( svc === undefined ) { return; }
svc.scriptloader.loadSubScript(script, sandbox);
};
let canUserStyles = (function() {
try {
return win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.loadSheetUsingURIString instanceof Function;
} catch(ex) {
}
return false;
})();
if ( canUserStyles ) {
sandbox.injectCSS = function(sheetURI) {
try {
let wu = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
wu.loadSheetUsingURIString(sheetURI, wu.USER_SHEET);
} catch(ex) {
}
};
sandbox.removeCSS = function(sheetURI) {
try {
let wu = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
wu.removeSheetUsingURIString(sheetURI, wu.USER_SHEET);
} catch (ex) {
}
};
}
sandbox.topContentScript = win === win.top;
// https://developer.mozilla.org/en-US/Firefox/Multiprocess_Firefox/Message_Manager/Frame_script_loading_and_lifetime#Unloading_frame_scripts
// The goal is to have content scripts removed from web pages. This
// helps remove traces of uBlock from memory when disabling/removing
// the addon.
// For example, this takes care of:
// https://github.com/gorhill/uBlock/commit/ea4faff383789053f423498c1f1165c403fde7c7#commitcomment-11964137
// > "gets the whole selected tab flashing"
sandbox.outerShutdown = function() {
sandbox.removeMessageListener();
sandbox.addMessageListener =
sandbox.getScriptTagFilters =
sandbox.injectCSS =
sandbox.injectScript =
sandbox.outerShutdown =
sandbox.removeCSS =
sandbox.removeMessageListener =
sandbox.sendAsyncMessage = function(){};
sandbox.vAPI = {};
messager = null;
};
}
else {
sandbox = win;
}
sandbox._sandboxId_ = sandboxId;
sandbox.sendAsyncMessage = messager.sendAsyncMessage;
sandbox.addMessageListener = function(callback) {
if ( sandbox._messageListener_ ) {
sandbox.removeMessageListener();
}
sandbox._messageListener_ = function(message) {
callback(message.data);
};
sandbox._broadcastListener_ = function(message) {
// https://github.com/gorhill/uBlock/issues/2014
if ( sandbox.topContentScript ) {
let details;
try { details = JSON.parse(message.data); } catch (ex) {}
let msg = details && details.msg || {};
if ( msg.what === 'staticFilteringDataChanged' ) {
if ( scriptTagFilterer ) {
scriptTagFilterer.reset();
}
}
}
callback(message.data);
};
messager.addMessageListener(
sandbox._sandboxId_,
sandbox._messageListener_
);
messager.addMessageListener(
hostName + ':broadcast',
sandbox._broadcastListener_
);
};
sandbox.removeMessageListener = function() {
if ( !sandbox._messageListener_ ) {
return;
}
// It throws sometimes, mostly when the popup closes
try {
messager.removeMessageListener(
sandbox._sandboxId_,
sandbox._messageListener_
);
} catch (ex) {
}
try {
messager.removeMessageListener(
hostName + ':broadcast',
sandbox._broadcastListener_
);
} catch (ex) {
}
sandbox._messageListener_ = sandbox._broadcastListener_ = null;
};
return sandbox;
},
injectOtherContentScripts: function(doc, sandbox) {
let docReady = (e) => {
let doc = e.target;
doc.removeEventListener(e.type, docReady, true);
if ( doc.querySelector('a[href^="abp:"],a[href^="https://subscribe.adblockplus.org/?"]') ) {
Services.scriptloader.loadSubScript(this.contentBaseURI + 'scriptlets/subscriber.js', sandbox);
}
};
if ( doc.readyState === 'loading') {
doc.addEventListener('DOMContentLoaded', docReady, true);
} else {
docReady({ target: doc, type: 'DOMContentLoaded' });
}
},
ignorePopup: function(e) {
if ( e.isTrusted === false ) { return; }
let contObs = contentObserver;
contObs.ignoredPopups.set(this, true);
this.removeEventListener('keydown', contObs.ignorePopup, true);
this.removeEventListener('mousedown', contObs.ignorePopup, true);
},
lookupPopupOpener: function(popup) {
for (;;) {
let opener = popup.opener;
if ( !opener ) { return; }
if ( opener.top ) { opener = opener.top; }
if ( opener === popup ) { return; }
if ( !opener.location ) { return; }
if ( this.reValidPopups.test(opener.location.protocol) ) {
return opener;
}
// https://github.com/uBlockOrigin/uAssets/issues/255
// - Mind chained about:blank popups.
if ( opener.location.href !== 'about:blank' ) { return; }
popup = opener;
}
},
reValidPopups: /^(?:blob|data|https?|javascript):/,
reMustInjectScript: /^(?:file|https?):/,
observe: function(subject, topic) {
// For whatever reason, sometimes the global scope is completely
// uninitialized at this point. Repro steps:
// - Launch FF with uBlock enabled
// - Disable uBlock
// - Enable uBlock
// - Services and all other global variables are undefined
// Hopefully will eventually understand why this happens.
if ( Services === undefined ) { return; }
// https://github.com/gorhill/uBlock/issues/2290
if ( topic === 'content-document-global-created' ) {
if ( subject !== subject.top || !subject.opener ) { return; }
if ( this.ignoredPopups.has(subject) ) { return; }
let opener = this.lookupPopupOpener(subject);
if ( !opener ) { return; }
subject.addEventListener('keydown', this.ignorePopup, true);
subject.addEventListener('mousedown', this.ignorePopup, true);
let popupMessager = getMessageManager(subject);
if ( !popupMessager ) { return; }
let openerMessager = getMessageManager(opener);
if ( !openerMessager ) { return; }
popupMessager.sendAsyncMessage(this.popupMessageName, {
id: this.uniquePopupEventId,
popup: true
});
openerMessager.sendAsyncMessage(this.popupMessageName, {
id: this.uniquePopupEventId,
opener: true
});
this.uniquePopupEventId += 1;
return;
}
// topic === 'document-element-inserted'
let doc = subject;
let win = doc.defaultView || null;
if ( win === null ) { return; }
// https://github.com/gorhill/uBlock/issues/260
// https://developer.mozilla.org/en-US/docs/Web/API/Document/contentType
// "Non-standard, only supported by Gecko. To be used in
// "chrome code (i.e. Extensions and XUL applications)."
// TODO: We may have to exclude more types, for now let's be
// conservative and focus only on the one issue reported, i.e. let's
// not test against 'text/html'.
if ( doc.contentType.startsWith('image/') ) { return; }
let loc = win.location;
if ( this.reMustInjectScript.test(loc.protocol) === false ) {
if ( loc.protocol === 'chrome:' && loc.host === hostName ) {
this.initContentScripts(win);
}
// What about data: and about:blank?
return;
}
// Content scripts injection.
let lss = Services.scriptloader.loadSubScript;
let sandbox = this.initContentScripts(win, true);
try {
lss(this.contentBaseURI + 'vapi-client.js', sandbox);
lss(this.contentBaseURI + 'contentscript.js', sandbox);
} catch (ex) {
//console.exception(ex.msg, ex.stack);
return;
}
// The remaining scripts are worth injecting only on a top-level window
// and at document_idle time.
if ( win === win.top ) {
this.injectOtherContentScripts(doc, sandbox);
}
}
};
/******************************************************************************/
var processObserver = {
start: function() {
scriptTagFilterer.reset();
}
};
/******************************************************************************/
var LocationChangeListener = function(docShell, webProgress) {
var mm = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
if ( !mm || typeof mm.sendAsyncMessage !== 'function' ) {
return;
}
this.messageManager = mm;
webProgress.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_LOCATION);
};
LocationChangeListener.prototype.messageName = hostName + ':locationChanged';
LocationChangeListener.prototype.QueryInterface = XPCOMUtils.generateQI([
'nsIWebProgressListener',
'nsISupportsWeakReference'
]);
LocationChangeListener.prototype.onLocationChange = function(webProgress, request, location, flags) {
if ( !webProgress.isTopLevel ) {
return;
}
this.messageManager.sendAsyncMessage(this.messageName, {
url: location.asciiSpec,
flags: flags
});
};
/******************************************************************************/
contentObserver.register();
/******************************************************************************/

View file

@ -1,62 +0,0 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2016 The uBlock Origin authors
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
*/
/******************************************************************************/
// https://developer.mozilla.org/en-US/Firefox/Multiprocess_Firefox/Frame_script_environment
(function(context) {
'use strict';
if ( !context.docShell ) {
return;
}
let webProgress = context.docShell
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebProgress);
if ( !webProgress ) {
return;
}
// https://github.com/gorhill/uBlock/issues/1514
// Fix?
let domWindow = webProgress.DOMWindow;
if ( domWindow !== domWindow.top ) {
return;
}
let {LocationChangeListener} = Components.utils.import(
Components.stack.filename.replace('Script', 'Module'),
null
);
// https://github.com/gorhill/uBlock/issues/1444
// Apparently, on older versions of Firefox (31 and less), the same context
// is used for all frame scripts, hence we must use a unique variable name
// to ensure no collision.
context.ublock0LocationChangeListener = new LocationChangeListener(
context.docShell,
webProgress
);
})(this);
/******************************************************************************/

View file

@ -1,58 +0,0 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2016 The uBlock Origin authors
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
*/
/******************************************************************************/
// https://developer.mozilla.org/en-US/Firefox/Multiprocess_Firefox/Frame_script_environment
(function(context) {
'use strict';
if ( !context.content ) {
return;
}
let {contentObserver} = Components.utils.import(
Components.stack.filename.replace('Script0', 'Module'),
null
);
let injectContentScripts = function(win) {
if ( !win || !win.document ) {
return;
}
contentObserver.observe(win.document);
if ( win.frames && win.frames.length ) {
let i = win.frames.length;
while ( i-- ) {
injectContentScripts(win.frames[i]);
}
}
};
injectContentScripts(context.content);
})(this);
/******************************************************************************/

View file

@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" height="16px" width="16px">
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<path stroke-linejoin="round" d="M8,16c7-4,7-4,7-14-3,0-4,0-7-2m0,16c-7-4-7-4-7-14,3,0,4,0,7-2" fill-rule="nonzero" stroke="#FFF" stroke-linecap="round" stroke-miterlimit="4" stroke-width="0.12500024" fill="#808080"/>
<path style="color:#000000;" fill="#FFF" d="m9.5001,4.9981c-1.3748,0-2.5,1.1252-2.5,2.5s1.1252,2.5,2.5,2.5,2.5-1.1252,2.5-2.5-1.1252-2.5-2.5-2.5zm0,1c0.83435,0,1.5,0.66565,1.5,1.5s-0.66565,1.5-1.5,1.5-1.5-0.66565-1.5-1.5,0.66565-1.5,1.5-1.5z"/>
<path fill="#FFF" stroke-width="0" stroke-miterlimit="4" d="m7.9996,8.0002c0,1.375-0.625,2-2,2s-2-0.625-2-2v-2.9998h1.0001v3c0,0.875,0.125,1,1,1s1-0.125,1-1v-3h1z"/>
</svg>

Before

Width:  |  Height:  |  Size: 788 B

View file

@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" height="16px" width="16px">
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<path stroke-linejoin="round" d="M8,16c7-4,7-4,7-14-3,0-4,0-7-2m0,16c-7-4-7-4-7-14,3,0,4,0,7-2" fill-rule="nonzero" stroke="#FFF" stroke-linecap="round" stroke-miterlimit="4" stroke-width="0.12500024" fill="#800000"/>
<path style="color:#000000;" fill="#FFF" d="m9.5001,4.9981c-1.3748,0-2.5,1.1252-2.5,2.5s1.1252,2.5,2.5,2.5,2.5-1.1252,2.5-2.5-1.1252-2.5-2.5-2.5zm0,1c0.83435,0,1.5,0.66565,1.5,1.5s-0.66565,1.5-1.5,1.5-1.5-0.66565-1.5-1.5,0.66565-1.5,1.5-1.5z"/>
<path fill="#FFF" stroke-width="0" stroke-miterlimit="4" d="m7.9996,8.0002c0,1.375-0.625,2-2,2s-2-0.625-2-2v-2.9998h1.0001v3c0,0.875,0.125,1,1,1s1-0.125,1-1v-3h1z"/>
</svg>

Before

Width:  |  Height:  |  Size: 788 B

View file

@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" height="24px" width="24px">
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<path stroke-linejoin="round" d="M8,16c7-4,7-4,7-14-3,0-4,0-7-2m0,16c-7-4-7-4-7-14,3,0,4,0,7-2" fill-rule="nonzero" stroke="#FFF" stroke-linecap="round" stroke-miterlimit="4" stroke-width="0.12500024" fill="#808080"/>
<path style="color:#000000;" fill="#FFF" d="m9.5001,4.9981c-1.3748,0-2.5,1.1252-2.5,2.5s1.1252,2.5,2.5,2.5,2.5-1.1252,2.5-2.5-1.1252-2.5-2.5-2.5zm0,1c0.83435,0,1.5,0.66565,1.5,1.5s-0.66565,1.5-1.5,1.5-1.5-0.66565-1.5-1.5,0.66565-1.5,1.5-1.5z"/>
<path fill="#FFF" stroke-width="0" stroke-miterlimit="4" d="m7.9996,8.0002c0,1.375-0.625,2-2,2s-2-0.625-2-2v-2.9998h1.0001v3c0,0.875,0.125,1,1,1s1-0.125,1-1v-3h1z"/>
</svg>

Before

Width:  |  Height:  |  Size: 788 B

View file

@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" height="24px" width="24px">
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<path stroke-linejoin="round" d="M8,16c7-4,7-4,7-14-3,0-4,0-7-2m0,16c-7-4-7-4-7-14,3,0,4,0,7-2" fill-rule="nonzero" stroke="#FFF" stroke-linecap="round" stroke-miterlimit="4" stroke-width="0.12500024" fill="#800000"/>
<path style="color:#000000;" fill="#FFF" d="m9.5001,4.9981c-1.3748,0-2.5,1.1252-2.5,2.5s1.1252,2.5,2.5,2.5,2.5-1.1252,2.5-2.5-1.1252-2.5-2.5-2.5zm0,1c0.83435,0,1.5,0.66565,1.5,1.5s-0.66565,1.5-1.5,1.5-1.5-0.66565-1.5-1.5,0.66565-1.5,1.5-1.5z"/>
<path fill="#FFF" stroke-width="0" stroke-miterlimit="4" d="m7.9996,8.0002c0,1.375-0.625,2-2,2s-2-0.625-2-2v-2.9998h1.0001v3c0,0.875,0.125,1,1,1s1-0.125,1-1v-3h1z"/>
</svg>

Before

Width:  |  Height:  |  Size: 788 B

View file

@ -1,64 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>uBlock0@raymondhill.net</em:id>
<em:version>{version}</em:version>
<em:name>{name}</em:name>
<em:description>{description}</em:description>
<em:homepageURL>{homepage}</em:homepageURL>
<em:creator>{author}</em:creator>
<em:developer>Deathamns</em:developer>
<em:developer>Alex Vallat</em:developer>
<em:developer>Manuel Reimer</em:developer>
<em:type>2</em:type>
<em:bootstrap>true</em:bootstrap>
<em:multiprocessCompatible>true</em:multiprocessCompatible>
<em:optionsType>2</em:optionsType>
{localized}
<!-- Firefox -->
<em:targetApplication>
<Description>
<em:id>{{ec8030f7-c20a-464f-9b0e-13a3a9e97384}}</em:id>
<em:minVersion>32.0</em:minVersion>
<em:maxVersion>56.0a1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Fennec -->
<em:targetApplication>
<Description>
<em:id>{{aa3c5121-dab2-40e2-81ca-7ea25febc110}}</em:id>
<em:minVersion>32.0</em:minVersion>
<em:maxVersion>56.0a1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- SeaMonkey -->
<em:targetApplication>
<Description>
<em:id>{{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}}</em:id>
<em:minVersion>2.24</em:minVersion>
<em:maxVersion>*</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Pale Moon -->
<em:targetApplication>
<Description>
<em:id>{{8de7fcbb-c55c-4fbe-bfc5-fc555c87dbc4}}</em:id>
<em:minVersion>27.0</em:minVersion>
<em:maxVersion>27.*</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Thunderbird -->
<em:targetApplication>
<Description>
<em:id>{{3550f703-e582-4d05-9a08-453d09bdfdc6}}</em:id>
<em:minVersion>31.0</em:minVersion>
<em:maxVersion>45.*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>

View file

@ -1,9 +0,0 @@
<?xml version="1.0" ?>
<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<setting type="control">
<vbox>
<button id="showDashboardButton"/>
<button id="showNetworkLogButton"/>
</vbox>
</setting>
</vbox>

View file

@ -1,43 +0,0 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2016-2017 The uBlock Origin authors
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
*/
// For background page or non-background pages
/* exported objectAssign */
'use strict';
/******************************************************************************/
/******************************************************************************/
// As per MDN, Object.assign appeared first in Firefox 34.
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Browser_compatibility
var objectAssign = Object.assign || function(target, source) {
var keys = Object.keys(source);
for ( var i = 0, n = keys.length, key; i < n; i++ ) {
key = keys[i];
target[key] = source[key];
}
return target;
};
/******************************************************************************/

View file

@ -1,47 +0,0 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2016 The uBlock Origin authors
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
*/
/******************************************************************************/
// https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIProcessScriptLoader
// Some module tasks need to run once per-content process. This is the purpose
// of this content process script.
(function() {
'use strict';
let {processObserver} = Components.utils.import(
Components.stack.filename.replace('processScript.js', 'frameModule.js'),
null
);
// https://developer.mozilla.org/en-US/Firefox/Multiprocess_Firefox/Message_Manager/Frame_script_loading_and_lifetime#Unloading_frame_scripts
// There is no way to unload a frame script, so when the extension will
// update, it may happen `processObserver` is not available because of
// trying to import from an older module version.
// TODO: remove the test once everybody is updated to 1.9.10+.
if ( processObserver ) {
processObserver.start();
}
})();
/******************************************************************************/

File diff suppressed because it is too large Load diff

View file

@ -1,399 +0,0 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2017 The uBlock Origin authors
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 HTMLDocument, XMLDocument,
addMessageListener, removeMessageListener, sendAsyncMessage, outerShutdown
*/
'use strict';
// For non background pages
/******************************************************************************/
(function(self) {
// https://github.com/chrisaljoudi/uBlock/issues/464
if ( document instanceof HTMLDocument === false ) {
// https://github.com/chrisaljoudi/uBlock/issues/1528
// A XMLDocument can be a valid HTML document.
if (
document instanceof XMLDocument === false ||
document.createElement('div') instanceof HTMLDivElement === false
) {
return;
}
}
/******************************************************************************/
// https://bugs.chromium.org/p/project-zero/issues/detail?id=1225&desc=6#c10
if ( !self.vAPI || self.vAPI.uBO !== true ) {
self.vAPI = { uBO: true };
}
var vAPI = self.vAPI;
/******************************************************************************/
vAPI.firefox = true;
vAPI.randomToken = function() {
return String.fromCharCode(Date.now() % 26 + 97) +
Math.floor(Math.random() * 982451653 + 982451653).toString(36);
};
vAPI.sessionId = vAPI.randomToken();
/******************************************************************************/
vAPI.setTimeout = vAPI.setTimeout || function(callback, delay, extra) {
return setTimeout(function(a) { callback(a); }, delay, extra);
};
/******************************************************************************/
vAPI.shutdown = {
jobs: [],
add: function(job) {
this.jobs.push(job);
},
exec: function() {
var job;
while ( (job = this.jobs.pop()) ) {
job();
}
},
remove: function(job) {
var pos;
while ( (pos = this.jobs.indexOf(job)) !== -1 ) {
this.jobs.splice(pos, 1);
}
}
};
/******************************************************************************/
(function() {
if ( !self.getScriptTagFilters ) {
return;
}
var hostname = location.hostname;
if ( !hostname ) {
return;
}
var filters = self.getScriptTagFilters({
rootURL: self.location.href,
frameURL: self.location.href,
frameHostname: hostname
});
if ( typeof filters !== 'string' || filters === '' ) {
return;
}
var reFilters = new RegExp(filters);
document.addEventListener('beforescriptexecute', function(ev) {
if ( reFilters.test(ev.target.textContent) ) {
ev.preventDefault();
ev.stopPropagation();
}
});
})();
/******************************************************************************/
var insertUserCSS = self.injectCSS || function(){},
removeUserCSS = self.removeCSS || function(){};
var processUserCSS = function(details, callback) {
var cssText;
var aa = details.add;
if ( Array.isArray(aa) ) {
for ( cssText of aa ) {
insertUserCSS(
'data:text/css;charset=utf-8,' +
encodeURIComponent(cssText)
);
}
}
aa = details.remove;
if ( Array.isArray(aa) ) {
for ( cssText of aa ) {
removeUserCSS(
'data:text/css;charset=utf-8,' +
encodeURIComponent(cssText)
);
}
}
if ( typeof callback === 'function' ) {
callback();
}
};
/******************************************************************************/
vAPI.messaging = {
channels: new Map(),
pending: new Map(),
auxProcessId: 1,
connected: false,
messageListener: function(msg) {
var details = JSON.parse(msg);
if ( !details ) { return; }
// Sent to all channels
if ( details.broadcast && !details.channelName ) {
for ( var channelName of this.channels.keys() ) {
this.sendToChannelListeners(channelName, details.msg);
}
return;
}
// Response to specific message previously sent
if ( details.auxProcessId ) {
var listener = this.pending.get(details.auxProcessId);
this.pending.delete(details.auxProcessId);
if ( listener ) {
listener(details.msg);
return;
}
}
// Sent to a specific channel
this.sendToChannelListeners(details.channelName, details.msg);
},
builtinListener: function(msg) {
if ( msg.cmd === 'injectScript' ) {
// injectScript is not always present.
// - See contentObserver.initContentScripts in frameModule.js
if ( typeof self.injectScript !== 'function' ) { return; }
var details = msg.details;
// Whether to inject in all child frames. Default to only top frame.
var allFrames = details.allFrames || false;
if ( allFrames !== true && window !== window.top ) { return; }
// https://github.com/gorhill/uBlock/issues/876
// Enforce `details.runAt`. Default to `document_end`.
var runAt = details.runAt || 'document_end';
if ( runAt === 'document_start' || document.readyState !== 'loading' ) {
self.injectScript(details.file);
return;
}
var injectScriptDelayed = function() {
document.removeEventListener('DOMContentLoaded', injectScriptDelayed);
self.injectScript(details.file);
};
document.addEventListener('DOMContentLoaded', injectScriptDelayed);
return;
}
if ( msg.cmd === 'shutdownSandbox' ) {
vAPI.shutdown.exec();
vAPI.messaging.stop();
if ( typeof self.outerShutdown === 'function' ) {
outerShutdown();
}
// https://github.com/gorhill/uBlock/issues/1573
// Will let uBO's own web pages close themselves. `window.top` is
// used on the assumption that uBO's own web pages will never be
// embedded in anything else than its own documents.
try {
var top = window.top;
if ( top.location.href.startsWith(vAPI.getURL('')) ) {
top.close();
}
} catch (ex) {
}
return;
}
},
toggleListener: function({type, persisted}) {
if ( type === 'pagehide' && !persisted ) {
vAPI.shutdown.exec();
this.stop();
if ( typeof self.outerShutdown === 'function' ) {
outerShutdown();
}
return;
}
if ( type === 'pagehide' ) {
this.disconnect();
} else /* if ( type === 'pageshow' ) */ {
this.connect();
}
},
toggleListenerCallback: null,
start: function() {
this.addChannelListener('vAPI', this.builtinListener);
if ( this.toggleListenerCallback === null ) {
this.toggleListenerCallback = this.toggleListener.bind(this);
}
window.addEventListener('pagehide', this.toggleListenerCallback, true);
window.addEventListener('pageshow', this.toggleListenerCallback, true);
},
stop: function() {
if ( this.toggleListenerCallback !== null ) {
window.removeEventListener('pagehide', this.toggleListenerCallback, true);
window.removeEventListener('pageshow', this.toggleListenerCallback, true);
}
this.disconnect();
this.channels.clear();
// service pending callbacks
var pending = this.pending;
this.pending = new Map();
for ( var callback of pending.values() ) {
if ( typeof callback === 'function' ) {
callback(null);
}
}
},
connect: function() {
if ( !this.connected ) {
addMessageListener(this.messageListener.bind(this));
this.connected = true;
}
},
disconnect: function() {
if ( this.connected ) {
removeMessageListener();
this.connected = false;
}
},
send: function(channelName, message, callback) {
// User stylesheets are handled content-side on legacy Firefox.
if ( channelName === 'vapi' && message.what === 'userCSS' ) {
return processUserCSS(message, callback);
}
if ( !this.connected ) {
if ( typeof callback === 'function' ) { callback(); }
return;
}
// Too large a gap between the last request and the last response means
// the main process is no longer reachable: memory leaks and bad
// performance become a risk -- especially for long-lived, dynamic
// pages. Guard against this.
if ( this.pending.size > 25 ) {
vAPI.shutdown.exec();
}
this.connect();
var auxProcessId;
if ( callback ) {
auxProcessId = this.auxProcessId++;
this.pending.set(auxProcessId, callback);
}
sendAsyncMessage('ublock0:background', {
channelName: self._sandboxId_ + '|' + channelName,
auxProcessId: auxProcessId,
msg: message
});
},
// TODO: implement as time permits.
connectTo: function(from, to, handler) {
handler({
what: 'connectionRefused',
from: from,
to: to
});
},
disconnectFrom: function() {
},
sendTo: function() {
},
addChannelListener: function(channelName, listener) {
var listeners = this.channels.get(channelName);
if ( listeners === undefined ) {
this.channels.set(channelName, [ listener ]);
} else if ( listeners.indexOf(listener) === -1 ) {
listeners.push(listener);
}
this.connect();
},
removeChannelListener: function(channelName, listener) {
var listeners = this.channels.get(channelName);
if ( listeners === undefined ) { return; }
var pos = listeners.indexOf(listener);
if ( pos === -1 ) { return; }
listeners.splice(pos, 1);
if ( listeners.length === 0 ) {
this.channels.delete(channelName);
}
},
removeAllChannelListeners: function(channelName) {
this.channels.delete(channelName);
},
sendToChannelListeners: function(channelName, msg) {
var listeners = this.channels.get(channelName);
if ( listeners === undefined ) { return; }
listeners = listeners.slice(0);
var response;
for ( var listener of listeners ) {
response = listener(msg);
if ( response !== undefined ) { break; }
}
return response;
}
};
vAPI.messaging.start();
// https://www.youtube.com/watch?v=Cg0cmhjdiLs
/******************************************************************************/
// https://bugzilla.mozilla.org/show_bug.cgi?id=444165
// https://github.com/gorhill/uBlock/issues/2256
// Not the prettiest solution, but that's the safest/simplest I can think
// of at this point. If/when bugzilla issue above is solved, we will need
// version detection to decide whether the patch needs to be applied.
vAPI.iframeLoadEventPatch = function(target) {
if ( target.localName === 'iframe' ) {
target.dispatchEvent(new Event('load'));
}
};
/******************************************************************************/
// No need to have vAPI client linger around after shutdown if
// we are not a top window (because element picker can still
// be injected in top window).
if ( window !== window.top ) {
// Can anything be done?
}
/******************************************************************************/
})(this);
/******************************************************************************/

View file

@ -1,167 +0,0 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2017 The uBlock Origin authors
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 sendAsyncMessage */
// For background page or non-background pages
'use strict';
/******************************************************************************/
(function(self) {
/******************************************************************************/
const {Services} = Components.utils.import(
'resource://gre/modules/Services.jsm',
null
);
// https://bugs.chromium.org/p/project-zero/issues/detail?id=1225&desc=6#c10
if ( !self.vAPI || self.vAPI.uBO !== true ) {
self.vAPI = { uBO: true };
}
var vAPI = self.vAPI;
/******************************************************************************/
vAPI.setTimeout = vAPI.setTimeout || function(callback, delay, extra) {
return setTimeout(function(a) { callback(a); }, delay, extra);
};
/******************************************************************************/
// http://www.w3.org/International/questions/qa-scripts#directions
var setScriptDirection = function(language) {
document.body.setAttribute(
'dir',
['ar', 'he', 'fa', 'ps', 'ur'].indexOf(language) !== -1 ? 'rtl' : 'ltr'
);
};
/******************************************************************************/
vAPI.download = function(details) {
if ( !details.url ) {
return;
}
var a = document.createElement('a');
a.href = details.url;
a.setAttribute('download', details.filename || '');
a.dispatchEvent(new MouseEvent('click'));
};
/******************************************************************************/
vAPI.getURL = function(path) {
return 'chrome://' + location.host + '/content/' + path.replace(/^\/+/, '');
};
/******************************************************************************/
vAPI.i18n = (function() {
var stringBundle = Services.strings.createBundle(
'chrome://' + location.host + '/locale/messages.properties'
);
return function(s) {
try {
return stringBundle.GetStringFromName(s);
} catch (ex) {
return '';
}
};
})();
setScriptDirection(navigator.language);
/******************************************************************************/
vAPI.closePopup = function() {
sendAsyncMessage(location.host + ':closePopup');
};
/******************************************************************************/
// A localStorage-like object which should be accessible from the
// background page or auxiliary pages.
// This storage is optional, but it is nice to have, for a more polished user
// experience.
vAPI.localStorage = {
pbName: '',
pb: null,
str: Components.classes['@mozilla.org/supports-string;1']
.createInstance(Components.interfaces.nsISupportsString),
init: function(pbName) {
this.pbName = pbName;
this.pb = Services.prefs.getBranch(pbName);
},
getItem: function(key) {
try {
return this.pb.getComplexValue(
key,
Components.interfaces.nsISupportsString
).data;
} catch (ex) {
return null;
}
},
setItem: function(key, value) {
this.str.data = value;
this.pb.setComplexValue(
key,
Components.interfaces.nsISupportsString,
this.str
);
},
getBool: function(key) {
try {
return this.pb.getBoolPref(key);
} catch (ex) {
return null;
}
},
setBool: function(key, value) {
this.pb.setBoolPref(key, value);
},
setDefaultBool: function(key, defaultValue) {
Services.prefs.getDefaultBranch(this.pbName).setBoolPref(key, defaultValue);
},
removeItem: function(key) {
this.pb.clearUserPref(key);
},
clear: function() {
this.pb.deleteBranch('');
}
};
vAPI.localStorage.init('extensions.' + location.host + '.');
/******************************************************************************/
})(this);
/******************************************************************************/

View file

@ -1,122 +0,0 @@
#!/usr/bin/env python3
import os
import json
import re
import sys
from io import open
from shutil import rmtree
from collections import OrderedDict
if len(sys.argv) == 1 or not sys.argv[1]:
raise SystemExit('Build dir missing.')
def mkdirs(path):
try:
os.makedirs(path)
finally:
return os.path.exists(path)
pj = os.path.join
# Find path to project root
proj_dir = os.path.split(os.path.abspath(__file__))[0]
while not os.path.isdir(os.path.join(proj_dir, '.git')):
proj_dir = os.path.normpath(os.path.join(proj_dir, '..'))
# Check that found project root is valid
version_filepath = os.path.join(proj_dir, 'dist', 'version')
if not os.path.isfile(version_filepath):
print('Version file not found.')
exit(1)
build_dir = os.path.abspath(sys.argv[1])
source_locale_dir = pj(build_dir, '_locales')
target_locale_dir = pj(build_dir, 'locale')
language_codes = []
descriptions = OrderedDict({})
title_case_strings = ['pickerContextMenuEntry', 'contextMenuTemporarilyAllowLargeMediaElements']
for alpha2 in sorted(os.listdir(source_locale_dir)):
locale_path = pj(source_locale_dir, alpha2, 'messages.json')
with open(locale_path, encoding='utf-8') as f:
strings = json.load(f, object_pairs_hook=OrderedDict)
alpha2 = alpha2.replace('_', '-')
descriptions[alpha2] = strings['extShortDesc']['message']
del strings['extShortDesc']
language_codes.append(alpha2)
mkdirs(pj(target_locale_dir, alpha2))
locale_path = pj(target_locale_dir, alpha2, 'messages.properties')
with open(locale_path, 'wt', encoding='utf-8', newline='\n') as f:
for string_name in strings:
string = strings[string_name]['message']
if alpha2 == 'en' and string_name in title_case_strings:
string = string.title()
f.write(string_name)
f.write(u'=')
f.write(string.replace('\n', r'\n'))
f.write(u'\n')
# generate chrome.manifest file
chrome_manifest = pj(build_dir, 'chrome.manifest')
with open(chrome_manifest, 'at', encoding='utf-8', newline='\n') as f:
f.write(u'\nlocale ublock0 en ./locale/en/\n')
for alpha2 in language_codes:
if alpha2 == 'en':
continue
f.write(u'locale ublock0 ' + alpha2 + ' ./locale/' + alpha2 + '/\n')
rmtree(source_locale_dir)
# update install.rdf
chromium_manifest = pj(proj_dir, 'platform', 'chromium', 'manifest.json')
with open(chromium_manifest, encoding='utf-8') as m:
manifest = json.load(m)
# Fetch extension version
# https://developer.mozilla.org/en-US/Add-ons/AMO/Policy/Maintenance#How_do_I_submit_a_Beta_add-on.3F
# "To create a beta channel [...] '(a|alpha|b|beta|pre|rc)\d*$' "
version = ''
with open(version_filepath) as f:
version = f.read().strip()
match = re.search('^(\d+\.\d+\.\d+)(\.\d+)$', version)
if match:
buildtype = int(match.group(2)[1:])
if buildtype < 100:
builttype = 'b' + str(buildtype)
else:
builttype = 'rc' + str(buildtype - 100)
version = match.group(1) + builttype
manifest['version'] = version
manifest['homepage'] = 'https://github.com/gorhill/uBlock'
manifest['description'] = descriptions['en']
del descriptions['en']
manifest['localized'] = []
t = ' '
t3 = 3 * t
for alpha2 in descriptions:
if alpha2 == 'en':
continue
manifest['localized'].append(
'\n' + t*2 + '<em:localized><Description>\n' +
t3 + '<em:locale>' + alpha2 + '</em:locale>\n' +
t3 + '<em:name>' + manifest['name'] + '</em:name>\n' +
t3 + '<em:description>' + descriptions[alpha2] + '</em:description>\n' +
t3 + '<em:creator>' + manifest['author'] + '</em:creator>\n' +
# t3 + '<translator>' + ??? + '</translator>\n' +
t3 + '<em:homepageURL>' + manifest['homepage'] + '</em:homepageURL>\n' +
t*2 + '</Description></em:localized>'
)
manifest['localized'] = '\n'.join(manifest['localized'])
install_rdf = pj(build_dir, 'install.rdf')
with open(install_rdf, 'r+t', encoding='utf-8', newline='\n') as f:
install_rdf = f.read()
f.seek(0)
f.write(install_rdf.format(**manifest))

View file

@ -1,56 +0,0 @@
#!/usr/bin/env bash
#
# This script assumes a linux environment
echo "*** uBlock0.firefox: Copying files"
DES=dist/build/uBlock0.firefox
rm -rf $DES
mkdir -p $DES
bash ./tools/make-assets.sh $DES
cp -R src/css $DES/
cp -R src/img $DES/
cp -R src/js $DES/
cp -R src/lib $DES/
cp -R src/_locales $DES/
cp src/*.html $DES/
mv $DES/img/icon_128.png $DES/icon.png
cp platform/firefox/css/* $DES/css/
cp platform/firefox/polyfill.js $DES/js/
cp platform/firefox/vapi-*.js $DES/js/
cp platform/chromium/vapi-usercss.real.js $DES/js/
cp platform/webext/vapi-usercss.js $DES/js/
cp platform/firefox/bootstrap.js $DES/
cp platform/firefox/processScript.js $DES/
cp platform/firefox/frame*.js $DES/
cp -R platform/firefox/img $DES/
cp platform/firefox/chrome.manifest $DES/
cp platform/firefox/install.rdf $DES/
cp platform/firefox/*.xul $DES/
cp LICENSE.txt $DES/
echo "*** uBlock0.firefox: concatenating content scripts"
cat $DES/js/vapi-usercss.js > /tmp/contentscript.js
echo >> /tmp/contentscript.js
grep -v "^'use strict';$" $DES/js/vapi-usercss.real.js >> /tmp/contentscript.js
echo >> /tmp/contentscript.js
grep -v "^'use strict';$" $DES/js/contentscript.js >> /tmp/contentscript.js
mv /tmp/contentscript.js $DES/js/contentscript.js
rm $DES/js/vapi-usercss.js
rm $DES/js/vapi-usercss.real.js
echo "*** uBlock0.firefox: Generating meta..."
python tools/make-firefox-meta.py $DES/
if [ "$1" = all ]; then
set +v
echo "*** uBlock0.firefox: Creating package..."
pushd $DES/ > /dev/null
zip ../uBlock0.firefox.xpi -qr *
popd > /dev/null
fi
echo "*** uBlock0.firefox: Package done."