removing unsupported firefox/legacy platform
parent
28d50f2347
commit
a0c72fc302
@ -1,245 +0,0 @@
|
||||
/*******************************************************************************
|
||||
|
||||
uMatrix - a browser extension to block requests.
|
||||
Copyright (C) 2014-2017 The uMatrix/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/uMatrix
|
||||
*/
|
||||
|
||||
/* 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*=umatrix]').contentWindow;
|
||||
|
||||
let windowlessBrowser = null;
|
||||
let windowlessBrowserPL = null;
|
||||
let bgProcess = null;
|
||||
let version;
|
||||
const hostName = 'umatrix';
|
||||
const restartListener = {
|
||||
get messageManager() {
|
||||
return Cc['@mozilla.org/parentprocessmessagemanager;1']
|
||||
.getService(Ci.nsIMessageListenerManager);
|
||||
},
|
||||
|
||||
receiveMessage: function() {
|
||||
shutdown();
|
||||
startup();
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/2493
|
||||
// Fix by https://github.com/gijsk
|
||||
// imported from https://github.com/gorhill/uBlock/pull/2497
|
||||
|
||||
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() {
|
||||
// https://bugzil.la/719376
|
||||
Cc['@mozilla.org/intl/stringbundle;1']
|
||||
.getService(Ci.nsIStringBundleService)
|
||||
.flushBundles();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
function uninstall(data, aReason) {
|
||||
if ( aReason !== ADDON_UNINSTALL ) {
|
||||
return;
|
||||
}
|
||||
// To cleanup vAPI.localStorage in vapi-common.js, aka
|
||||
// "extensions.umatrix.*" in `about:config`.
|
||||
Cu.import('resource://gre/modules/Services.jsm', null)
|
||||
.Services.prefs.getBranch('extensions.' + hostName + '.')
|
||||
.deleteBranch('');
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
@ -1 +0,0 @@
|
||||
content umatrix ./
|
@ -1,356 +0,0 @@
|
||||
/*******************************************************************************
|
||||
|
||||
µBlock - a browser extension to block requests.
|
||||
Copyright (C) 2014 The µBlock 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/uMatrix
|
||||
*/
|
||||
|
||||
/* global Components */
|
||||
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/800#issuecomment-146580443
|
||||
this.EXPORTED_SYMBOLS = ['contentObserver', '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;
|
||||
|
||||
// Cu.import('resource://gre/modules/Console.jsm');
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var contentObserver = {
|
||||
classDescription: 'content-policy for ' + hostName,
|
||||
classID: Components.ID('{c84283d4-9975-41b7-b1a4-f106af56b51d}'),
|
||||
contractID: '@' + hostName + '/content-policy;1',
|
||||
ACCEPT: Ci.nsIContentPolicy.ACCEPT,
|
||||
MAIN_FRAME: Ci.nsIContentPolicy.TYPE_DOCUMENT,
|
||||
contentBaseURI: 'chrome://' + hostName + '/content/js/',
|
||||
cpMessageName: hostName + ':shouldLoad',
|
||||
uniqueSandboxId: 1,
|
||||
modernFirefox:
|
||||
Services.vc.compare(Services.appinfo.platformVersion, '44') > 0 && (
|
||||
Services.appinfo.ID === '{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}' ||
|
||||
Services.appinfo.ID === '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}'
|
||||
),
|
||||
|
||||
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);
|
||||
|
||||
if ( !this.modernFirefox ) {
|
||||
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');
|
||||
|
||||
if ( !this.modernFirefox ) {
|
||||
this.componentRegistrar.unregisterFactory(
|
||||
this.classID,
|
||||
this
|
||||
);
|
||||
this.categoryManager.deleteCategoryEntry(
|
||||
'content-policy',
|
||||
this.contractID,
|
||||
false
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIContentPolicy
|
||||
// https://bugzil.la/612921
|
||||
shouldLoad: function(type, location, origin, context) {
|
||||
if ( Services === undefined || !context ) {
|
||||
return this.ACCEPT;
|
||||
}
|
||||
|
||||
if ( !location.schemeIs('http') && !location.schemeIs('https') ) {
|
||||
return this.ACCEPT;
|
||||
}
|
||||
|
||||
var contextWindow;
|
||||
if ( type === this.MAIN_FRAME ) {
|
||||
contextWindow = context.contentWindow || context;
|
||||
} else if ( type === this.SUB_FRAME ) {
|
||||
contextWindow = context.contentWindow;
|
||||
} else {
|
||||
contextWindow = (context.ownerDocument || context).defaultView;
|
||||
}
|
||||
|
||||
// https://github.com/gorhill/uMatrix/issues/706
|
||||
if ( !contextWindow ) {
|
||||
return this.ACCEPT;
|
||||
}
|
||||
|
||||
// The context for the toolbar popup is an iframe element here,
|
||||
// so check context.top instead of context
|
||||
if ( !contextWindow.top || !contextWindow.location ) {
|
||||
return this.ACCEPT;
|
||||
}
|
||||
|
||||
let messageManager = getMessageManager(contextWindow);
|
||||
if ( messageManager === null ) {
|
||||
return this.ACCEPT;
|
||||
}
|
||||
|
||||
let details = {
|
||||
rawType: type,
|
||||
url: location.asciiSpec
|
||||
};
|
||||
|
||||
if ( typeof messageManager.sendRpcMessage === 'function' ) {
|
||||
// https://bugzil.la/1092216
|
||||
messageManager.sendRpcMessage(this.cpMessageName, details);
|
||||
} else {
|
||||
// Compatibility for older versions
|
||||
messageManager.sendSyncMessage(this.cpMessageName, details);
|
||||
}
|
||||
|
||||
return this.ACCEPT;
|
||||
},
|
||||
|
||||
initContentScripts: function(win, sandbox) {
|
||||
let messager = getMessageManager(win);
|
||||
let sandboxId = hostName + ':sb:' + this.uniqueSandboxId++;
|
||||
|
||||
if ( sandbox ) {
|
||||
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.injectScript = function(script) {
|
||||
Services.scriptloader.loadSubScript(script, sandbox);
|
||||
};
|
||||
}
|
||||
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);
|
||||
};
|
||||
|
||||
messager.addMessageListener(
|
||||
sandbox._sandboxId_,
|
||||
sandbox._messageListener_
|
||||
);
|
||||
messager.addMessageListener(
|
||||
hostName + ':broadcast',
|
||||
sandbox._messageListener_
|
||||
);
|
||||
};
|
||||
|
||||
sandbox.removeMessageListener = function() {
|
||||
try {
|
||||
messager.removeMessageListener(
|
||||
sandbox._sandboxId_,
|
||||
sandbox._messageListener_
|
||||
);
|
||||
messager.removeMessageListener(
|
||||
hostName + ':broadcast',
|
||||
sandbox._messageListener_
|
||||
);
|
||||
} catch (ex) {
|
||||
// It throws sometimes, mostly when the popup closes
|
||||
}
|
||||
|
||||
sandbox._messageListener_ = null;
|
||||
};
|
||||
|
||||
return sandbox;
|
||||
},
|
||||
|
||||
observe: function(doc) {
|
||||
let win = doc.defaultView;
|
||||
if ( !win ) {
|
||||
return;
|
||||
}
|
||||
|
||||
let loc = win.location;
|
||||
if ( !loc ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/260
|
||||
// TODO: We may have to skip more types, for now let's be
|
||||
// conservative, i.e. let's not test against `text/html`.
|
||||
if ( doc.contentType.lastIndexOf('image/', 0) === 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( loc.protocol !== 'http:' && loc.protocol !== 'https:' && loc.protocol !== 'file:' ) {
|
||||
if ( loc.protocol === 'chrome:' && loc.host === hostName ) {
|
||||
this.initContentScripts(win);
|
||||
}
|
||||
|
||||
// What about data: and about:blank?
|
||||
return;
|
||||
}
|
||||
|
||||
let lss = Services.scriptloader.loadSubScript;
|
||||
let sandbox = this.initContentScripts(win, true);
|
||||
|
||||
// Can throw with attempts at injecting into non-HTML document.
|
||||
// Example: https://a.pomf.se/avonjf.webm
|
||||
try {
|
||||
lss(this.contentBaseURI + 'vapi-client.js', sandbox);
|
||||
lss(this.contentBaseURI + 'contentscript-start.js', sandbox);
|
||||
} catch (ex) {
|
||||
return; // don't further try to inject anything
|
||||
}
|
||||
|
||||
let docReady = (e) => {
|
||||
let doc = e.target;
|
||||
doc.removeEventListener(e.type, docReady, true);
|
||||
lss(this.contentBaseURI + 'contentscript-end.js', sandbox);
|
||||
};
|
||||
|
||||
if ( doc.readyState === 'loading') {
|
||||
doc.addEventListener('DOMContentLoaded', docReady, true);
|
||||
} else {
|
||||
docReady({ target: doc, type: 'DOMContentLoaded' });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
const locationChangedMessageName = hostName + ':locationChanged';
|
||||
|
||||
var LocationChangeListener = function(docShell) {
|
||||
if ( !docShell ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var requestor = docShell.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
var ds = requestor.getInterface(Ci.nsIWebProgress);
|
||||
var mm = requestor.getInterface(Ci.nsIContentFrameMessageManager);
|
||||
|
||||
if ( ds && mm && typeof mm.sendAsyncMessage === 'function' ) {
|
||||
this.docShell = ds;
|
||||
this.messageManager = mm;
|
||||
ds.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_LOCATION);
|
||||
}
|
||||
};
|
||||
|
||||
LocationChangeListener.prototype.QueryInterface = XPCOMUtils.generateQI([
|
||||
'nsIWebProgressListener',
|
||||
'nsISupportsWeakReference'
|
||||
]);
|
||||
|
||||
LocationChangeListener.prototype.onLocationChange = function(webProgress, request, location, flags) {
|
||||
if ( !webProgress.isTopLevel ) {
|
||||
return;
|
||||
}
|
||||
this.messageManager.sendAsyncMessage(locationChangedMessageName, {
|
||||
url: location.asciiSpec,
|
||||
flags: flags,
|
||||
});
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
contentObserver.register();
|
||||
|
||||
/******************************************************************************/
|
@ -1,72 +0,0 @@
|
||||
/*******************************************************************************
|
||||
|
||||
µBlock - a browser extension to block requests.
|
||||
Copyright (C) 2014 The µBlock 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/uMatrix
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var locationChangeListener; // Keep alive while frameScript is alive
|
||||
|
||||
(function() {
|
||||
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
let {contentObserver, LocationChangeListener} = Components.utils.import(
|
||||
Components.stack.filename.replace('Script', '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]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let onLoadCompleted = function() {
|
||||
removeMessageListener('umatrix-load-completed', onLoadCompleted);
|
||||
injectContentScripts(content);
|
||||
};
|
||||
|
||||
addMessageListener('umatrix-load-completed', onLoadCompleted);
|
||||
|
||||
if ( docShell ) {
|
||||
let Ci = Components.interfaces;
|
||||
let wp = docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress);
|
||||
let dw = wp.DOMWindow;
|
||||
if ( dw === dw.top ) {
|
||||
locationChangeListener = new LocationChangeListener(docShell);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
Binary file not shown.
Before Width: | Height: | Size: 750 B |
Binary file not shown.
Before Width: | Height: | Size: 777 B |
@ -1,45 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.mozilla.org/2004/em-rdf#">
|
||||
<r:Description about="urn:mozilla:install-manifest">
|
||||
<id>uMatrix@raymondhill.net</id>
|
||||
<version>{version}</version>
|
||||
<name>{name}</name>
|
||||
<description>{description}</description>
|
||||
<homepageURL>{homepage}</homepageURL>
|
||||
<creator>{author}</creator>
|
||||
<developer>Deathamns</developer>
|
||||
<developer>Alex Vallat</developer>
|
||||
<type>2</type>
|
||||
<bootstrap>true</bootstrap>
|
||||
<multiprocessCompatible>true</multiprocessCompatible>
|
||||
<optionsType>2</optionsType>
|
||||
{localized}
|
||||
|
||||
<!-- Firefox -->
|
||||
<targetApplication>
|
||||
<r:Description>
|
||||
<id>{{ec8030f7-c20a-464f-9b0e-13a3a9e97384}}</id>
|
||||
<minVersion>24.0</minVersion>
|
||||
<maxVersion>56.*</maxVersion>
|
||||
</r:Description>
|
||||
</targetApplication>
|
||||
|
||||
<!-- SeaMonkey -->
|
||||
<targetApplication>
|
||||
<r:Description>
|
||||
<id>{{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}}</id>
|
||||
<minVersion>2.24</minVersion>
|
||||
<maxVersion>*</maxVersion>
|
||||
</r:Description>
|
||||
</targetApplication>
|
||||
|
||||
<!-- Pale Moon -->
|
||||
<targetApplication>
|
||||
<r:Description>
|
||||
<id>{{8de7fcbb-c55c-4fbe-bfc5-fc555c87dbc4}}</id>
|
||||
<minVersion>26.0</minVersion>
|
||||
<maxVersion>27.*</maxVersion>
|
||||
</r:Description>
|
||||
</targetApplication>
|
||||
</r:Description>
|
||||
</r:RDF>
|
@ -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="showLoggerButton"/>
|
||||
</vbox>
|
||||
</setting>
|
||||
</vbox>
|
@ -1,95 +0,0 @@
|
||||
/*******************************************************************************
|
||||
|
||||
uMatrix - 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/uMatrix
|
||||
|
||||
This file has been originally imported from:
|
||||
https://github.com/gorhill/uBlock/tree/master/platform/chromium
|
||||
|
||||
*/
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// Patching for Pale Moon which does not implement ES6 Set/Map.
|
||||
// Test for non-ES6 Set/Map: check if property `iterator` is present.
|
||||
// The code is strictly to satisfy uBO's core, not to be an accurate
|
||||
// implementation of ES6.
|
||||
|
||||
if ( self.Set.prototype.iterator instanceof Function ) {
|
||||
//console.log('Patching non-ES6 Set() to be more ES6-like.');
|
||||
self.Set.prototype._values = self.Set.prototype.values;
|
||||
self.Set.prototype.values = function() {
|
||||
this._valueIter = this._values();
|
||||
this.value = undefined;
|
||||
this.done = false;
|
||||
return this;
|
||||
};
|
||||
self.Set.prototype.next = function() {
|
||||
try {
|
||||
this.value = this._valueIter.next();
|
||||
} catch (ex) {
|
||||
this._valueIter = undefined;
|
||||
this.value = undefined;
|
||||
this.done = true;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
if ( self.Map.prototype.iterator instanceof Function ) {
|
||||
//console.log('Patching non-ES6 Map() to be more ES6-like.');
|
||||
self.Map.prototype._entries = self.Map.prototype.entries;
|
||||
self.Map.prototype.entries = function() {
|
||||
this._entryIter = this._entries();
|
||||
this.value = undefined;
|
||||
this.done = false;
|
||||
return this;
|
||||
};
|
||||
self.Map.prototype.next = function() {
|
||||
try {
|
||||
this.value = this._entryIter.next();
|
||||
} catch (ex) {
|
||||
this._entryIter = undefined;
|
||||
this.value = undefined;
|
||||
this.done = true;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,225 +0,0 @@
|
||||
/*******************************************************************************
|
||||
|
||||
uMatrix - a browser extension to block requests.
|
||||
Copyright (C) 2014-2017 The uMatrix/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/uMatrix
|
||||
*/
|
||||
|
||||
/* jshint esnext: true */
|
||||
/* global addMessageListener, removeMessageListener, sendAsyncMessage */
|
||||
|
||||
// For non background pages
|
||||
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
(function(self) {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// https://bugs.chromium.org/p/project-zero/issues/detail?id=1225&desc=6#c10
|
||||
if ( self.vAPI === undefined || self.vAPI.uMatrix !== true ) {
|
||||
self.vAPI = { uMatrix: true };
|
||||
}
|
||||
|
||||
var vAPI = self.vAPI;
|
||||
vAPI.firefox = true;
|
||||
vAPI.sessionId = String.fromCharCode(Date.now() % 25 + 97) +
|
||||
Math.random().toString(36).slice(2);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
vAPI.setTimeout = vAPI.setTimeout || function(callback, delay) {
|
||||
return setTimeout(function() { callback(); }, delay);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
vAPI.shutdown = (function() {
|
||||
var jobs = [];
|
||||
|
||||
var add = function(job) {
|
||||
jobs.push(job);
|
||||
};
|
||||
|
||||
var exec = function() {
|
||||
//console.debug('Shutting down...');
|
||||
var job;
|
||||
while ( (job = jobs.pop()) ) {
|
||||
job();
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
add: add,
|
||||
exec: exec
|
||||
};
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
vAPI.messaging = {
|
||||
listeners: new Set(),
|
||||
pending: new Map(),
|
||||
requestId: 1,
|
||||
connected: false,
|
||||
|
||||
setup: function() {
|
||||
this.addListener(this.builtinListener);
|
||||
if ( this.toggleListenerCallback === null ) {
|
||||
this.toggleListenerCallback = this.toggleListener.bind(this);
|
||||
}
|
||||
window.addEventListener('pagehide', this.toggleListenerCallback, true);
|
||||
window.addEventListener('pageshow', this.toggleListenerCallback, true);
|
||||
},
|
||||
|
||||
shutdown: function() {
|
||||
if ( this.toggleListenerCallback !== null ) {
|
||||
window.removeEventListener('pagehide', this.toggleListenerCallback, true);
|
||||
window.removeEventListener('pageshow', this.toggleListenerCallback, true);
|
||||
}
|
||||
this.removeAllListeners();
|
||||
//service pending callbacks
|
||||
var pending = this.pending;
|
||||
this.pending.clear();
|
||||
for ( var callback of pending.values() ) {
|
||||
if ( typeof callback === 'function' ) {
|
||||
callback(null);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
connect: function() {
|
||||
if ( !this.connected ) {
|
||||
if ( this.messageListenerCallback === null ) {
|
||||
this.messageListenerCallback = this.messageListener.bind(this);
|
||||
}
|
||||
addMessageListener(this.messageListenerCallback);
|
||||
this.connected = true;
|
||||
}
|
||||
},
|
||||
|
||||
disconnect: function() {
|
||||
if ( this.connected ) {
|
||||
removeMessageListener();
|
||||
this.connected = false;
|
||||
}
|
||||
},
|
||||
|
||||
messageListener: function(msg) {
|
||||
var details = JSON.parse(msg);
|
||||
if ( !details ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( details.broadcast ) {
|
||||
this.sendToListeners(details.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( details.requestId ) {
|
||||
var listener = this.pending.get(details.requestId);
|
||||
if ( listener !== undefined ) {
|
||||
this.pending.delete(details.requestId);
|
||||
listener(details.msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
messageListenerCallback: null,
|
||||
|
||||
builtinListener: function(msg) {
|
||||
if ( typeof msg.cmd === 'string' && msg.cmd === 'injectScript' ) {
|
||||
var details = msg.details;
|
||||
if ( !details.allFrames && window !== window.top ) {
|
||||
return;
|
||||
}
|
||||
self.injectScript(details.file);
|
||||
}
|
||||
},
|
||||
|
||||
send: function(channelName, message, callback) {
|
||||
this.connect()
|
||||
|
||||
message = {
|
||||
channelName: self._sandboxId_ + '|' + channelName,
|
||||
msg: message
|
||||
};
|
||||
|
||||
if ( callback ) {
|
||||
message.requestId = this.requestId++;
|
||||
this.pending.set(message.requestId, callback);
|
||||
}
|
||||
|
||||
sendAsyncMessage('umatrix:background', message);
|
||||
},
|
||||
|
||||
toggleListener: function({type, persisted}) {
|
||||
if ( type === 'pagehide' && !persisted ) {
|
||||
vAPI.shutdown.exec();
|
||||
this.shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type === 'pagehide' ) {
|
||||
this.disconnect();
|
||||
} else /* if ( type === 'pageshow' ) */ {
|
||||
this.connect();
|
||||
}
|
||||
},
|
||||
toggleListenerCallback: null,
|
||||
|
||||
sendToListeners: function(msg) {
|
||||
for ( var listener of this.listeners ) {
|
||||
listener(msg);
|
||||
}
|
||||
},
|
||||
|
||||
addListener: function(listener) {
|
||||
this.listeners.add(listener);
|
||||
this.connect()
|
||||
},
|
||||
|
||||
removeListener: function(listener) {
|
||||
this.listeners.delete(listener);
|
||||
},
|
||||
|
||||
removeAllListeners: function() {
|
||||
this.disconnect();
|
||||
this.listeners.clear();;
|
||||
}
|
||||
};
|
||||
|
||||
vAPI.messaging.setup()
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// 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 ) {
|
||||
vAPI.shutdown.add(function() {
|
||||
vAPI = null;
|
||||
});
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
})(this);
|
||||
|
||||
/******************************************************************************/
|
@ -1,191 +0,0 @@
|
||||
/*******************************************************************************
|
||||
|
||||
uMatrix - a browser extension to block requests.
|
||||
Copyright (C) 2014-2017 The uMatrix/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/uMatrix
|
||||
*/
|
||||
|
||||
/* 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 === undefined || self.vAPI.uMatrix !== true ) {
|
||||
self.vAPI = { uMatrix: 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.insertHTML = (function() {
|
||||
const parser = Components.classes['@mozilla.org/parserutils;1']
|
||||
.getService(Components.interfaces.nsIParserUtils);
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/845
|
||||
// Apparently dashboard pages execute with `about:blank` principal.
|
||||
|
||||
return function(node, html) {
|
||||
while ( node.firstChild ) {
|
||||
node.removeChild(node.firstChild);
|
||||
}
|
||||
|
||||
node.appendChild(parser.parseFragment(
|
||||
html,
|
||||
parser.SanitizerAllowStyle,
|
||||
false,
|
||||
Services.io.newURI('about:blank', null, null),
|
||||
document.documentElement
|
||||
));
|
||||
};
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
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);
|
||||
|
||||
/******************************************************************************/
|
@ -1 +0,0 @@
|
||||
/* Firefox: no platform-specific code */
|
@ -1,120 +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
|
||||
from xml.sax.saxutils import escape
|
||||
|
||||
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
|
||||
|
||||
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']
|
||||
|
||||
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 umatrix en ./locale/en/\n')
|
||||
|
||||
for alpha2 in language_codes:
|
||||
if alpha2 == 'en':
|
||||
continue
|
||||
|
||||
f.write(u'locale umatrix ' + alpha2 + ' ./locale/' + alpha2 + '/\n')
|
||||
|
||||
rmtree(source_locale_dir)
|
||||
|
||||
# update install.rdf
|
||||
proj_dir = pj(os.path.split(os.path.abspath(__file__))[0], '..')
|
||||
chromium_manifest = pj(proj_dir, 'platform', 'chromium', 'manifest.json')
|
||||
|
||||
with open(chromium_manifest, encoding='utf-8') as m:
|
||||
manifest = json.load(m)
|
||||
|
||||
# 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*$' "
|
||||
|
||||
match = re.search('^(\d+\.\d+\.\d+)(\.\d+)$', manifest['version'])
|
||||
if match:
|
||||
buildtype = int(match.group(2)[1:])
|
||||
if buildtype < 100:
|
||||
builttype = 'b' + str(buildtype)
|
||||
else:
|
||||
builttype = 'rc' + str(buildtype - 100)
|
||||
manifest['version'] = match.group(1) + builttype
|
||||
|
||||
manifest['homepage'] = 'https://github.com/gorhill/uMatrix'
|
||||
manifest['description'] = escape(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 + '<localized><r:Description>\n' +
|
||||
t3 + '<locale>' + alpha2 + '</locale>\n' +
|
||||
t3 + '<name>' + manifest['name'] + '</name>\n' +
|
||||
t3 + '<description>' + escape(descriptions[alpha2]) + '</description>\n' +
|
||||
t3 + '<creator>' + manifest['author'] + '</creator>\n' +
|
||||
# t3 + '<translator>' + ??? + '</translator>\n' +
|
||||
t3 + '<homepageURL>' + manifest['homepage'] + '</homepageURL>\n' +
|
||||
t*2 + '</r:Description></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))
|
||||
f.truncate()
|
@ -1,42 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This script assumes a linux environment
|
||||
|
||||
echo "*** uMatrix.firefox: Copying files"
|
||||
|
||||
DES=dist/build/uMatrix.firefox
|
||||
rm -rf $DES
|
||||
mkdir -p $DES
|
||||
|
||||
cp -R assets $DES/
|
||||
|
||||
|
||||
cp -R src/* $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/firefox/bootstrap.js $DES/
|
||||
cp platform/firefox/frame*.js $DES/
|
||||
cp -R platform/chromium/img $DES/
|
||||
cp platform/firefox/chrome.manifest $DES/
|
||||
cp platform/firefox/install.rdf $DES/
|
||||
cp platform/firefox/*.xul $DES/
|
||||
cp LICENSE.txt $DES/
|
||||
|
||||
echo "*** uMatrix.firefox: Generating meta..."
|
||||
python tools/make-firefox-meta.py $DES/
|
||||
|
||||
if [ "$1" = all ]; then
|
||||
echo "*** uMatrix.firefox: Creating package..."
|
||||
pushd $DES/
|
||||
zip ../uMatrix.firefox.xpi -qr *
|
||||
popd
|
||||
fi
|
||||
|
||||
echo "*** uMatrix.firefox: Package done."
|
Loading…
Reference in New Issue