I am developing a toolbar for a customer, that wants a traditional IE style toolbar at the top of the window under the address bar.
This is what I have: What I have http://www.hellometro.com/toolbar/now.png
Notice that because of vertical limitations of the status bar I have to write in all-caps for the letters to be legible while being small enough to fit. (two left most elements in status bar, text field and SEARCH button)
This is what I need: What I need http://www.hellometro.com/toolbar/whatiwant.png
Notice the toolbar added to the top that has enough vertical space for legible text within text field and button. (Top left below browser's back button).
I'm looking for a way for positioning the search component at the status bar as a default location, and allow the user to change its position in the options page to let them pick top or bottom (because many if not most Firefox users don't know they can move Add-ons around).
My question is: Does Firefox Add-on SDK support what I want to do, or do I have to switch languages and approach solution from a different angle?
This isn't something that you can do with the available Add-on SDK API, with good reason - add-ons shouldn't waste screen estate unnecessarily and adding a toolbar is just that. You can achieve this goal by using low-level modules and going to the browser's XUL directly. Something like this should work (untested code and very hacky):
var widgetID = "foobar";
var buttonID = "widget:" + require("self").id + "-" + widgetID;
var toolbarName = "My Extension Toolbar";
require("widget").Widget({
id: widgetID,
...
});
if (firstRun)
{
var winUtils = require("window-utils");
for (var window in winUtils.browserWindowIterator())
{
var toolbox = window.gNavToolbox;
if (toolbox)
{
// Does the button exist already?
var button = toolbox.ownerDocument.getElementById(buttonID);
if (button && button.parentNode.getAttribute("toolbarname") == toolbarName)
continue; // Button already in the right toolbar
else if (button)
{
// Remove button from its current location
var toolbar = button.parentNode;
toolbar.removeChild(button);
// Make sure this change is persisted
toolbar.setAttribute("currentset", toolbar.currentSet);
toolbar.ownerDocument.persist(toolbar.id, "currentset");
}
var toolbar = toolbox.appendCustomToolbar("My Extension Toolbar", buttonID);
toolbar.currentSet = toolbar.getAttribute("currentset");
toolbar.ownerDocument.persist(toolbar.id, "currentset");
// Send change notification, the widget needs reinitializing
var event = toolbox.ownerDocument.createEvent("Events");
event.initEvent("customizationchange", true, true);
toolbox.dispatchEvent(event);
}
}
}
Note the undefined firstRun
variable - you want to do this only once, otherwise you will revert user's choice to move your widget elsewhere (you can store a flag via simple-prefs
module or something like that). Also note that buttonID
calculation uses internal details from the addon-kit/lib/widget.js
file in the SDK - the way the toolbar button ID is calculated can change in a future SDK version but I think that this is the only way to get hold of a widget you create with the SDK. There are plenty of internals in the other parts of the code as well of course.
Documentation: window-utils
module (browserWindowIterator
is undocumented), <xul:toolbox>
, <xul:toolbar>
.