I'm creating simple add-on for
Mozilla Firefox and even I did such add-ons before I run into the troubles. It's because of new Firefox
UI called
Australis and because I want this add-on to be bootstrapped (so it doesn't require browser restart to complete the installation).
After a short googling I found
CustomizableUI.jsm and I finally got the working solution.
So here is my
bootstrap.js
which adds the sidebar:
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const { classes: CC, interfaces: CI, utils: CU } = Components;
const self = {
id: "tagssidebar@ondrejd.info",
name: "TagsSidebar",
path: {
chrome: "chrome://tagssidebar/"
}
};
const prefPrefix = "extensions." + self.id + ".";
CU.import("resource://gre/modules/Services.jsm");
CU.import("resource:///modules/CustomizableUI.jsm");
var gStylesSrv;
var gStylesURI;
// Bootstrap API: install(aData, aReason)
function install(aData, aReason) {
if (aReason == ADDON_INSTALL) {
// Set default preferences
let prefs = Services.prefs.getBranch(prefPrefix);
prefs.setBoolPref("showInSidebar", true);
prefs.setBoolPref("showTagCloud", false);
prefs.setBoolPref("showFavicons", false);
}
} // end install(aData, aReason)
// Bootstrap API: uninstall(aData, aReason)
function uninstall(aData, aReason) {
if (aReason == ADDON_UNINSTALL) {
// Remove default preferences
Services.prefs.deleteBranch(prefPrefix);
}
} // end uninstall(aData, aReason)
// Bootstrap API: startup(aData, aReason)
function startup(aData, aReason) {
// Create new toolbar button
CustomizableUI.createWidget({
id: "tagssidebar-toolbarbutton",
defaultArea: CustomizableUI.AREA_NAVBAR,
label: "TagsSidebar",
tooltiptext: "Toggle visibility of TagsSidebar.",
type: "button",
onBeforeCreated: function(aDocument) {
// We need to add more UI than the toolbarbutton (broadcaster, key and menuitem):
// Broadcaster
let bcset = aDocument.getElementById("mainBroadcasterSet");
if (bcset) {
let bc = aDocument.createElementNS(XUL_NS, "broadcaster");
bc.setAttribute("autoCheck", "false");
bc.setAttribute("group", "sidebar");
bc.setAttribute("id", "viewSidebar_tagssidebar");
bc.setAttribute("oncommand", "toggleSidebar('viewSidebar_tagssidebar');");
bc.setAttribute("sidebarurl", "chrome://tagssidebar/content/sidebar.xul");
bc.setAttribute("sidebartitle", "TagsSidebar");
bc.setAttribute("type", "checkbox");
bcset.appendChild(bc);
}
// Key
let keyset = aDocument.getElementById("mainKeyset");
if (keyset) {
let key = aDocument.createElementNS(XUL_NS, "key");
key.setAttribute("command", "viewSidebar_tagssidebar");
key.setAttribute("id", "key_openSidebar_tagssidebar");
key.setAttribute("key", "t");
key.setAttribute("modifiers", "accel,shift");
keyset.appendChild(key);
}
// Menuitem
let mp = aDocument.getElementById("viewSidebarMenu");
if (mp) {
let mi = aDocument.createElementNS(XUL_NS, "menuitem");
mi.setAttribute("key", "key_openSidebar_tagssidebar");
mi.setAttribute("label", "TagsSidebar");
mi.setAttribute("observes", "viewSidebar_tagssidebar");
mi.setAttribute("tooltiptext", "Toggle visibility of TagsSidebar!");
mp.appendChild(mi);
}
},
onCreated: function(aNode) {
// Add ID of broadcaster we created before as a command:
aNode.setAttribute("command", "viewSidebar_tagssidebar");
return aNode;
}
});
// Load stylesheet
gStylesSrv = CC["@mozilla.org/content/style-sheet-service;1"].getService(CI.nsIStyleSheetService);
gStylesURI = Services.io.newURI(self.path.chrome + "skin/overlay.css", null, null);
gStylesSrv.loadAndRegisterSheet(gStylesURI, gStylesSrv.USER_SHEET);
} // end startup(aData, aReason)
// Bootstrap API: shutdown(aData, aReason)
function shutdown(aData, aReason) {
if (aReason == APP_SHUTDOWN) return;
// Destroy our widget
CustomizableUI.destroyWidget("tagssidebar-toolbarbutton");
// Unload stylesheet
if (gStylesSrv.sheetRegistered(gStylesURI, gStylesSrv.USER_SHEET)) {
gStylesSrv.unregisterSheet(gStylesURI, gStylesSrv.USER_SHEET);
}
} // end shutdown(aData, aReason)