This is a specification for a project that will be implemented for the Google Summer of Code, and it can still change as feedback is received. There are no concrete plans of making this a part of Firefox in the near future. Read my previous post for more info.
Part 2 – URL resolution
Here’s a simple chrome.manifest file, as exemplified in part 1:
content xulschoolhello jar:chrome/xulschoolhello.jar!/content/
skin xulschoolhello classic/1.0 jar:chrome/xulschoolhello.jar!/skin/
locale xulschoolhello en-US jar:chrome/xulschoolhello.jar!/locale/en-US/
overlay chrome://browser/content/browser.xul chrome://xulschoolhello/content/browserOverlay.xul
There are two things I find silly about it:
- The file and directory structure is too complicated for a simple add-on. It could be simpler, but the form above is the current recommended way of doing things.
- If this is the default, recommended way of doing things, then why is it necessary to explicitly declare it?
This part of the specification aims to remove as much redundancy as possible from chrome (and other) declarations, as well as provide sensible defaults so that simple add-ons are simple to develop.
The simplest manifest
Let’s begin with the new manifest file introduced in the previous part of the spec:
{
"id" : "helloworld@xulschool.com",
"name" : "XUL School Hello World",
"description" : "Welcome to XUL School!",
"version" : "0.1",
"authors" : "Appcoast",
"homepageURL" : "https://developer.mozilla.org/en/XUL_School",
"type" : "2",
"targetApplications" : {
"id" : "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}",
"minVersion" : "3.0",
"maxVersion" : "3.6.*"
},
"domains" : "xulschoolhello",
"overlays" : {
"source" : "chrome://xulschoolhello/content/overlay.xul",
"target" : "chrome://browser/content/browser.xul"
}
}
A couple of notes before diving in:
- There’s an ongoing discussion of what format is best for the manifest, JSON or some form of XML or HTML. Examples are being presented as JSON but could change eventually. If you want to join the discussion, please do so in Part 1.
- The “domains” property is now plural, as it should be. (Thanks Wladimir!)
The highlighted sections are the equivalent of the chrome.manifest file presented above. The “domains” declaration covers the “content”, “skin” and “locale” declarations in the old format. However, the file layout also needs to change, since the defaults for the new format are much simpler than in the old one. Here are the default resolutions for all URLs and other special folders:
- “content” and “skin” URLs default to the root directory, where the manifest file is located. This means that the simplest of add-ons would consist of the manifest file and an overlay file zipped together. Complex add-ons would of course require directory structures in order to keep everything organized, but that’s left to the authors to determine.
- “locale” URLs are a little more involved. If the author only wishes to ship the add-on in one locale, then the locale files can be located in the root directory, just like “content” and “skin” files. If there are more languages, they can be organized under “/locale/en-US/” and similar. The “locale” directory in the root would have that special meaning, and all directories within it are considered locale folders and are automatically registered. There’s no need for chrome declarations even in this case.
- “resource” URLs will also default to the root directory, and will use the same domain. In the example extension above, “resource://xulschoolhello/hello.jsm” would point to the “hello.jsm” file in the root of the add-on package.
- The “components” and “platform” folders will continue to have their special meaning.
- The default preferences file will be named “defaultPrefs.js” and will also reside in the package root.
Advanced manifests
The defaults defined above should be adequate for most add-ons I’ve ever seen (and I’ve seen a lot!), but we can’t leave out add-ons that require more than this. It’s very important that the new system is as flexible as possible for authors, and that add-ons can be migrated to it without requiring significant changes or refactoring.
First of all, the “domains” attribute can be extended to include declarations similar to old-style manifests. Here’s the equivalent of the first chrome.manifest declarations in the first example:
"domains" : {
"name" : "xulschoolhello",
"content" : {
"location" : "jar:chrome/xulschoolhello.jar!/content/"
},
"skin" : {
"location" : "jar:chrome/xulschoolhello.jar!/skin/"
},
"locale" : {
"locale" : "en-US",
"location" : "jar:chrome/xulschoolhello.jar!/locale/en-US/"
}
},
Some notes about this expanded format:
- “domains” can be an array, in case multiple domains need to be defined.
- The name of the skin is still redundant, so there’s no need to specify it.
- “content”, “skin”, “locale” and “resources” can be arrays, to specify multiple entries.
- “content”, “skin”, “locale” and “resources” support a “flags” attribute, in order to support manifest flags. This attribute can also be specified on overlays, overrides and style declarations, which are not exemplified but are the same as the overlay declaration shown before.
Moreover, it should be possible to change the locations of any of our “special” files and folders, in order to give developers maximum flexibility. For this, the manifest can have a “locations” attribute, exemplified here:
"locations" : {
"defaultPrefs" : "prefs/myPrefs.js",
"components" : "code/myComponents/",
"platform" : "code/platform/"
},
The only file that has a mandated name and location would be the manifest file. The rest can be organized to the authors’ preference, provided they don’t like the defaults and they want to tinker with the manifest.
Manifest Localization
Localizing manifests is an arduous task. The most modern way to do it involves adding all the localized information in the manifest file, which isn’t yet supported by the most popular add-on localization community, Babelzilla. Keeping the manifest properly localized becomes a burden to add-on developers, and most don’t even bother.
The suggested solution in the new system is to take advantage of the existing localization infrastructure. The manifest localization file will default to the location “chrome://firstDeclaredDomain/locale/manifest.properties”, or can be explicitly defined (needs to be a chrome locale URL):
"localized" : "chrome://xulschoolhello/locale/manifest.properties",
This localized file would hold strings corresponding to the localizable attributes:
name = Hola Mundo de XUL School
description = Bienvenido a XUL School!
translator.1 = Jorge
translator.2 = Somebody else
The .1 and .2 suffix is just a way to handle multi-valued attributes.
Moving this information out of the manifest has one drawback: the add-on installer needs to do some additional effort to show these values during installation, since it will require to figure out the location of the localized file. This isn’t too hard to figure out using the manifest, though, and the advantages outweigh a few additional ms during installation.
Part 3 of this specification will cover add-on installation and any pending topics. It will also introduce a wiki page where the full spec will be fleshed out and all edge cases will be covered.
Tagged google, gsoc, idea, mozilla, projects