I've been working on a really cool new project, to be announced soon, where I've built a Rails-based web app that has two interfaces: one for humans to interact with inside of a browser, and a RESTful API for browser plugins to interact with via GETs and POSTs. We want people to be able to interact with our site while visiting other sites.
I had seen other Firefox plugins that were click-to-install, but I had a hard time figuring out how to make it work for our plugin. Firefox users were having to "Save Link As.." and open the downloaded .xpi file manually. Very old-fashioned. So here's a quick note to help future Mozilla or Firefox developers who need to create a click-to-install plugin:
1) It's all done through Javascript, so anyone without Javascript will have to install your plugin the old-fashioned way. The Mozilla site documents the API call you need to make.
2) I'm a huge proponent of unobtrusive javascript (UJS), which I learned by using Dan Webb's excellent LowPro framework. Thus I wanted to make sure that the click-to-install javascript was offered as a progressive enhancement to the normal HTML links we provided. That way, everyone could have a link to the plugin file itself for manual installation, but people with Javascript could enjoy click-to-install.
In this part of the site, we weren't using any other Javascript libraries, so it seemed like overkill to include Prototype and LowPro just for this one effect. So it was a great chance to learn how to roll my own UJS without library support. I whipped up a quick UJS click-to-install technique following inspiration from this presentation. Here's what I came up with:
<script defer="defer" type="text/javascript">
//<![CDATA[
function doXPITrigger() {
if (!document.getElementsByTagName) return false;
var links = document.getElementsByTagName("a");
for (var i=0; i < links.length; i++) {
if (links[i].className.match("firefox")) {
links[i].onclick = function() {
xpi={'Awesome New Project Toolbar':'/downloads/awesome_project.xpi'};
InstallTrigger.install(xpi);
return false;
}
}
}
}
window.onload = doXPITrigger
//]]>
3) I've seen other advice recommending you configure your web server to recognize the .xpi mimetype appropriately. I did this but it didn't make much difference in my case. Still, it's probably worth doing. I added this line to our Apache config:
AddType application/x-xpinstall .xpi