February 2, 2006

chrome.rdf base URL creation and contents.rdf

When I'm developing a new chrome package, I like to specify that I support both the classic and modern skins. So, in skin/contents.rdf, I would by default write:

<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:chrome="http://www.mozilla.org/rdf/chrome#">

  <RDF:Seq about="urn:mozilla:skin:root">
    <RDF:li resource="urn:mozilla:skin:classic/1.0"/>
    <RDF:li resource="urn:mozilla:skin:modern/1.0"/>
  </RDF:Seq>

  <RDF:Description about="urn:mozilla:skin:classic/1.0">
    <chrome:packages>
      <RDF:Seq about="urn:mozilla:skin:classic/1.0:packages">
        <RDF:li resource="urn:mozilla:skin:classic/1.0:xulwidgets"/>
      </RDF:Seq>
    </chrome:packages>
  </RDF:Description>

  <RDF:Description about="urn:mozilla:skin:modern/1.0">
    <chrome:packages>
      <RDF:Seq about="urn:mozilla:skin:modern/1.0:packages">
        <RDF:li resource="urn:mozilla:skin:modern/1.0:xulwidgets"/>
      </RDF:Seq>
    </chrome:packages>
  </RDF:Description>
</RDF:RDF>

Naturally, I keep all my skin contents under skin/, right alongside the contents.rdf file. So, for some reason, chrome://xulwidgets/skin/contents.rdf fails.

Some debugging time later, I look in dist/bin/chrome/chrome.rdf and discover the following:

  <RDF:Description RDF:about="urn:mozilla:skin:modern/1.0:xulwidgets"
                   c:baseURL="jar:resource:/chrome/xulwidgets.jar!/xulwidgets/skin/modern/1.0"
                   c:allowScripts="false">
    <c:package RDF:resource="urn:mozilla:package:xulwidgets"/>
  </RDF:Description>

The baseURL attribute is totally bogus. It should have been c:baseURL="jar:resource:/chrome/xulwidgets.jar!/xulwidgets/skin/". So what happened?

The code for nsChromeRegistry.cpp assumes that if I provided more than one skin package listing in the contents.rdf file, I must have provided the skins in the subdirectories. It also assumes that if I provided exactly one such entry, the skin lives in the current directory.

What annoys me about this is that it gives the package developer (me) a false impression. I can't explicitly state I support more than one skin without having lots of duplicate files. There's also no immediately obvious way for me to force Mozilla to accept a different base URL (say, the correct one) through contents.rdf.

This is really not cool. This is one of the issues that has bitten me again and again over the years because it's not documented anywhere, and I finally lost my patience with it today. I remember having this problem when I first started developing Abacus, about three years ago. If there's a better way to do this, I'd really like to know what it is. Or if there's a bug on file about it, I'd like to know about that too.

UPDATE: I guess it would sort of make sense as currently implemented, if each individual skin had its own contents.rdf, and the install.js/rdf file referred to each individual contents.rdf file. But it's still not nice.

Posted by WeirdAl at February 2, 2006 3:22 PM