dissabte, agost 02, 2008

Enhancing content with XBL (2)

When I migrated my personal tweaks from Firefox 2 to Firefox 3, I realized that one of my hacks didn't work any longer. I had bound XBL content via Stylish to a search form in the web site of Munich's public library. The code amounted to these lines:

@namespace url(http://www.w3.org/1999/xhtml);

@-moz-document url("https://ssl.muenchen.de/EF/opac.html"),
url("https://ssl.muenchen.de/AK/opac.html") {
select.input[name="NNORRQ"] {
-moz-binding: url(http://esquifit.googlepages.com/listsize_2.xml#listsize) !important;
}
}


The XBL file listsize_2.xml looked like this:

<bindings xmlns="http://www.mozilla.org/xbl">

<!-- 1 - Allow for larger result sets -->
<binding id="listsize">
<implementation>
<constructor>
<![CDATA[
var newOption = function(selElm, val){
var sel = document.createElement('OPTION');
sel.setAttribute('value', val);
sel.appendChild(document.createTextNode(val));
//this.appendChild(sel);
selElm.insertBefore(sel,selElm.firstChild);
}
newOption(this, '50');
newOption(this, '100');
newOption(this, '200');
newOption(this, '500');
newOption(this, '1000');
]]>
</constructor>
</implementation>
</binding>
</bindings>


This should add five new option values to a select box. In fact, this is still working fine in Firefox 2, but it stopped working in Firefox 3. I asked in
mozilla.dev.tech.xbl, and in a matter of minutes Mr. Zbarsky came with a lapidary assertion:
"[...] XBL can now only be loaded from the same origin as the origin doing the loading [...]"

What this means, is that styles loaded from chrome or from domains different from that of the page to which they apply cannot bind XBL behaviours via the proprietary -moz-binding CSS directive. Fortunately there is a way around this:
  1. In Stylish, create a style containing only an @include directive to some css hosted somewhere in the Internet

    @import url("http://esquifit.googlepages.com/OPAC_Muenchen.css");

  2. The CSS contains a @-moz-document that restricts the applicability of the styles to the relevant url or domains
    @-moz-document url("https://ssl.muenchen.de/EF/opac.html"),
    url("https://ssl.muenchen.de/AK/opac.html") {
    ...
    }
  3. From within this stylsheet you are allowed to bind XBL files hosted in the same domain:
    select.input[name="NNORRQ"] {
    -moz-binding:url(http://esquifit.googlepages.com/OPAC_Muenchen.xbl#listsize);
    }

That's it.

I am working right now in a small web application that will allow users to define and manage code snippets that can be published under some definite url http://.../something.css. The basic idea is that users can 'subscribe' from userContent.css or Stylish to one 'master' stylesheet hosted by the application; the content of this stylesheet is a collection of snippets that apply to different pages and that can be configured by the user by choosing available snippets from a shared repository or creating/cloning/modifying snippets. The interesting point is that this provides a way to share url-specific scripts, thus coming near to the dream of a extension free shared Greasemonkey for the masses (which is the actual motivation behind all this hassle).