Saturday, July 12, 2008

ActionShow! My first foray into firefox extension development

I love firefox. The ability to add extensions to the browser make it endlessly customizable. So, when I ran across a desire to have a button's form action displayed in the status bar (much like how IE 7 behaves), I naturally began looking for an extension to meet my needs. Surprisingly, this simple behavior does not exist in extension form. The closest thing I could find was FormFox. FormFox displays the form's action as a tool tip when hovering over buttons. Hmm. A little too distracting for me. Thus ActionShow! was born.


Get ActionShow!


Cut to the chase and download the extension here.  Right now it is an experimental extension (you have been warned!).


The Details

The concept seemed a simple enough one for my first extension. XUL ("zool") was completely new to me but I've got a pretty good grasph of javascript. The main frustration I had was trying to access the html document and operate on it via javascript as I would if I was writing javascript within a webpage. Finnally, through a bit of trail and error, I found my solution:

var htmlDom = document.getElementById('content').contentDocument.documentElement;

Once I had the htmlDom variable, it was smooth sailing. From there the script finds all forms looks for the buttons, submit or image input types within those forms and attaches two simple event handlers to each submit element: one for on mouse over, the other for on mouse out. The form's action text is hooked into firefox's browser.xul using the status-bar element:

document.getElementById('statusbar-display')

Here is the complete javascript solution (actionShow.js):

var FormStatus =
{
isStatusDone: false,
addFormActionStatusEvents: function(element, statusBar, newLabel)
{
element.addEventListener('mouseover', function() { if (!FormStatus.isStatusDone && statusBar.label == 'Done') FormStatus.isStatusDone = true; statusBar.label=newLabel; }, false);
element.addEventListener('mouseout', function() { if (FormStatus.isStatusDone) statusBar.label='Done'; else statusBar.label=''; }, false);
},
processNodeList: function(nodeList, statusBar, action)
{
for (var i=0; i < nodeList.length; i++)
{
var element = nodeList[i];
if (element.type == 'submit' || element.type == 'image')
{
FormStatus.addFormActionStatusEvents(element, statusBar, action);
}
}
},
init: function()
{
var htmlDom = document.getElementById('content').contentDocument.documentElement;
var statusBar = document.getElementById('statusbar-display');

var forms = htmlDom.getElementsByTagName('form');
for (var i = 0; i < forms.length; i++)
{
var form = forms[i];
var action = form.action;
//var method = form.method;

FormStatus.processNodeList(form.getElementsByTagName('button'), statusBar, action);
FormStatus.processNodeList(form.getElementsByTagName('input'), statusBar, action);
}
}
};

window.addEventListener('load', function () {
document.getElementById('content').addEventListener(
'DOMContentLoaded',
function() {FormStatus.init();},
true);
}, false);

And the embarrassingly simple actionShow.xul file does nothing but call the above javascript file:

<?xml version="1.0"?>
<overlay id="actionShow" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="actionShow.js"/>
</overlay>

And for completeness sake, here is the chrome.manifest file:

content     actionShow    chrome/content/
overlay chrome://browser/content/browser.xul chrome://actionShow/content/actionShow.xul


That's about it! I hope you make ActionShow! a part of your firefox add-on tool chest.

1 comment:

Anonymous said...

a good idea and a good work :-) thanks mate. we need such little friendly helpers.
but: with your ext. installed, i get wrong (shows info, that "could" relate to another open tab) tooltips when hovering over some buttons or pulldownmenus.
with your extension disabled, i get no tooltips at all.
strange, but true :-) althought your ext. show infos in the statusbar....
let me know, if i can help you.
ff 3.0.4 portable, winXP.