Files
ca-archive/bootstrap.js
2017-11-11 01:52:05 +02:00

316 líneas
9.3 KiB
JavaScript

"use strict";
var {classes: Cc, interfaces: Ci, manager: Cm, results: Cr, Constructor: CC, utils: Cu} = Components;
Cm.QueryInterface(Ci.nsIComponentRegistrar);
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const SCHEME = "caa";
const CAA_URL ="chrome://ca-archive/content/ca-archive.html";
const CAA_URI = Services.io.newURI(CAA_URL, null, null);
const nsIURI = CC("@mozilla.org/network/simple-uri;1", "nsIURI");
const ff47plus = (Services.vc.compare(Services.appinfo.version, 47) > 0);
const CAA_MODULES = [
"chrome://ca-archive/content/about.js",
"chrome://ca-archive/content/addon.js",
"chrome://ca-archive/content/db.js",
"chrome://ca-archive/content/epl.js",
"chrome://ca-archive/content/list.js",
"chrome://ca-archive/content/tcloud.js",
"chrome://ca-archive/content/versions.js"
];
let factory, gWindowListener = null, branch = "extensions.ca-archive.";
let styleSheetService = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
let styleSheetURI = Services.io.newURI("chrome://ca-archive/skin/button.css", null, null);
function $(node, childId) {
if (node.getElementById) {
return node.getElementById(childId);
} else {
return node.querySelector("#" + childId);
}
}
let button = {
meta : {
id : "ca-archive-button",
label : "Classic Add-ons Archive",
tooltiptext : "Classic Add-ons Archive",
class : "toolbarbutton-1 chromeclass-toolbar-additional"
},
install : function (w) {
let doc = w.document;
let b = doc.createElement("toolbarbutton");
for (let a in this.meta) {
b.setAttribute(a, this.meta[a]);
}
b.style.listStyleImage = 'url("chrome://ca-archive/skin/button.png")';
let toolbox = $(doc, "navigator-toolbox");
toolbox.palette.appendChild(b);
let {toolbarId, nextItemId} = this.getPrefs(),
toolbar = toolbarId && $(doc, toolbarId),
nextItem = toolbar && $(doc, nextItemId);
if (toolbar) {
if (nextItem && nextItem.parentNode && nextItem.parentNode.id.replace("-customization-target", "") == toolbarId) {
toolbar.insertItem(this.meta.id, nextItem);
} else {
let ids = (toolbar.getAttribute("currentset") || "").split(",");
nextItem = null;
for (let i = ids.indexOf(this.meta.id) + 1; i > 0 && i < ids.length; i++) {
nextItem = $(doc, ids[i])
if (nextItem) {
break;
}
}
toolbar.insertItem(this.meta.id, nextItem);
}
if (toolbar.getAttribute("collapsed") == "true") {
try { w.setToolbarVisibility(toolbar, true); } catch(e) {}
}
}
return b;
},
onCustomize : function(e) {
try {
let ucs = Services.prefs.getCharPref("browser.uiCustomization.state");
if ((/\"nav\-bar\"\:\[.*?\"ca\-archive\-button\".*?\]/).test(ucs)) {
Services.prefs.getBranch(branch).setCharPref("toolbarId", "nav-bar");
} else {
button.setPrefs(null, null);
}
} catch(e) {}
},
afterCustomize : function (e) {
let toolbox = e.target,
b = $(toolbox.parentNode, button.meta.id),
toolbarId, nextItemId;
if (b) {
let parent = b.parentNode,
nextItem = b.nextSibling;
if (parent && (parent.localName == "toolbar" || parent.classList.contains("customization-target"))) {
toolbarId = parent.id;
nextItemId = nextItem && nextItem.id;
}
}
button.setPrefs(toolbarId, nextItemId);
},
getPrefs : function () {
let p = Services.prefs.getBranch(branch);
return {
toolbarId : p.getCharPref("bar"),
nextItemId : p.getCharPref("before")
};
},
setPrefs : function (toolbarId, nextItemId) {
let p = Services.prefs.getBranch(branch);
p.setCharPref("bar", toolbarId == "nav-bar-customization-target" ? "nav-bar" : toolbarId || "");
p.setCharPref("before", nextItemId || "");
}
};
let caaIn = function (w) {
let b = button.install(w);
return {
init : function () {
w.addEventListener("customizationchange", button.onCustomize, false);
w.addEventListener("aftercustomization", button.afterCustomize, false);
b.addEventListener("command", this.run, false);
},
done : function () {
w.removeEventListener("customizationchange", button.onCustomize, false);
w.removeEventListener("aftercustomization", button.afterCustomize, false);
b.removeEventListener("command", this.run, false);
b.parentNode.removeChild(b);
b = null;
},
run : function () {
let isOpen = false;
let winenu = Services.wm.getEnumerator("navigator:browser");
loop: while (winenu.hasMoreElements()) {
let window = winenu.getNext().QueryInterface(Ci.nsIDOMWindow);
for (let tab of window.gBrowser.tabs) {
if (tab.linkedBrowser.currentURI.scheme == "caa") {
window.focus()
window.gBrowser.selectedTab = tab;
isOpen = true;
break loop;
}
}
}
if (!isOpen) {
let mrw = Services.wm.getMostRecentWindow("navigator:browser");
let url = Services.prefs.getBranch(branch).getCharPref("url");
mrw.gBrowser.selectedTab = mrw.gBrowser.addTab(url);
if (url == "caa:about") {
Services.prefs.getBranch(branch).setCharPref("url", "caa:");
}
}
}
};
};
function BrowserWindowObserver(handlers) {
this.handlers = handlers;
}
BrowserWindowObserver.prototype = {
observe: function (aSubject, aTopic, aData) {
if (aTopic == "domwindowopened") {
aSubject.QueryInterface(Ci.nsIDOMWindow).addEventListener("load", this, false);
} else if (aTopic == "domwindowclosed") {
if (aSubject.document.documentElement.getAttribute("windowtype") == "navigator:browser") {
this.handlers.onShutdown(aSubject);
}
}
},
handleEvent: function (aEvent) {
let aWindow = aEvent.currentTarget;
aWindow.removeEventListener(aEvent.type, this, false);
if (aWindow.document.documentElement.getAttribute("windowtype") == "navigator:browser") {
this.handlers.onStartup(aWindow);
}
}
};
function browserWindowStartup (aWindow) {
aWindow["ca-archive"] = caaIn(aWindow);
aWindow["ca-archive"].init()
}
function browserWindowShutdown (aWindow) {
aWindow["ca-archive"].done();
delete aWindow["ca-archive"];
}
function CAAProtocolHandler() {}
CAAProtocolHandler.prototype = Object.freeze({
classDescription: "CAA Protocol Handler",
contractID: "@mozilla.org/network/protocol;1?name=" + SCHEME,
classID: Components.ID('{f0700cf0-b198-11e7-8f1a-0800200c9a66}'),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler]),
scheme: SCHEME,
defaultPort: -1,
allowPort: function(port, scheme) {
return false;
},
protocolFlags: Ci.nsIProtocolHandler.URI_NORELATIVE |
Ci.nsIProtocolHandler.URI_NOAUTH |
Ci.nsIProtocolHandler.URI_DANGEROUS_TO_LOAD |
Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE |
Ci.nsIProtocolHandler.URI_OPENING_EXECUTES_SCRIPT,
newURI: function(aSpec, aOriginCharset, aBaseURI) {
if (aBaseURI && aBaseURI.scheme == SCHEME) {
if (aSpec != "/") {
return Services.io.newURI(aSpec, aOriginCharset, CAA_URI);
} else {
return CAA_URI;
}
}
let rv = new nsIURI();
rv.spec = aSpec;
return rv;
},
newChannel: function(aURI) {
return this.newChannel2(aURI, null);
},
newChannel2: function(aURI, aSecurity_or_aLoadInfo) {
let channel;
if (aSecurity_or_aLoadInfo || ff47plus) {
let uri = Services.io.newURI(CAA_URL, null, null);
channel = Services.io.newChannelFromURIWithLoadInfo(uri, aSecurity_or_aLoadInfo);
} else {
channel = Services.io.newChannel(CAA_URL, null, null);
}
channel.originalURI = aURI;
return channel;
}
});
function Factory(component) {
this.createInstance = function(outer, iid) {
if (outer) {
throw Cr.NS_ERROR_NO_AGGREGATION;
}
return new component();
};
this.register = function() {
Cm.registerFactory(component.prototype.classID, component.prototype.classDescription, component.prototype.contractID, this);
};
this.unregister = function() {
Cm.unregisterFactory(component.prototype.classID, this);
};
Object.freeze(this);
this.register();
}
function startup(data, reason) {
if (!styleSheetService.sheetRegistered(styleSheetURI, styleSheetService.USER_SHEET)) {
styleSheetService.loadAndRegisterSheet(styleSheetURI, styleSheetService.USER_SHEET);
}
factory = new Factory(CAAProtocolHandler);
let defaultBranch = Services.prefs.getDefaultBranch(branch);
defaultBranch.setCharPref("bar", "nav-bar");
defaultBranch.setCharPref("before", "");
defaultBranch.setCharPref("url", "caa:about");
gWindowListener = new BrowserWindowObserver({
onStartup: browserWindowStartup,
onShutdown: browserWindowShutdown
});
Services.ww.registerNotification(gWindowListener);
let winenu = Services.wm.getEnumerator("navigator:browser");
while (winenu.hasMoreElements()) {
browserWindowStartup(winenu.getNext());
}
}
function shutdown(data, reason) {
if (reason == APP_SHUTDOWN) return;
Services.ww.unregisterNotification(gWindowListener);
gWindowListener = null;
let winenu = Services.wm.getEnumerator("navigator:browser");
while (winenu.hasMoreElements()) {
browserWindowShutdown(winenu.getNext());
}
factory.unregister();
if (reason == ADDON_UNINSTALL) {
try {
let dir = Services.dirsvc.get("ProfD", Ci.nsIFile); dir.append("ca-archive");
if (dir.exists()) {
dir.remove(true);
}
} catch (e) {}
}
if (styleSheetService.sheetRegistered(styleSheetURI, styleSheetService.USER_SHEET)) {
styleSheetService.unregisterSheet(styleSheetURI, styleSheetService.USER_SHEET);
}
CAA_MODULES.forEach(Cu.unload, Cu);
}
function install(data, reason) {}
function uninstall(data, reason) {}