Abstract
Mozilla's two new applications, Firebird and Thunderbird, support user- installable optional components called extensions that adapt or enhance application functionality in various ways. Extensions are easy to create, usually tailored to a specific task, usually written in JavaScript and XUL, and as a result are mostly small, managable compnents.
Nonetheless, extension authors and users have uncovered some problems with the current setup. These include:
These changes call for a series of changes to the way extensions are handled.
Currently extensions for all browsers bear the xpi file extension and are identified as application/x-xpinstall. There is no discrimination between intended target application.
The proposed solution is to create a variant of the xpinstall content type for each extension consumer, like so:
application/x-xpinstall;type=extension&app=firebird
application/x-xpinstall;type=extension&app=thunderbird
application/x-javaarchive;type=skin&app=firebird
application/x-javaarchive;type=skin&app=firebird
When an application is installed, it creates a listing in the system MIME registry associating itself as a handler for that type.
For example, when Firebird is installed on Windows, it creates several
keys in the Windows Registry - one associating
application/x-xpinstall;type=extension&app=firebird
with
the Firebird executable and another associating an extension (e.g.
.fbext) with that content type. This means that the file will be
appropriately handled not only when invoked via a link click from any
browser (Firebird, IE, Opera etc), but also when invoked from the
system shell (e.g. a double click on a .fbext file in Explorer).
The effect on extension authors is that they would need to give distinct file extensions to their extension installers, as defined by each application. Distribution sites would need to send the correct content-type for each extension target application.
There have been proposals restricting extensions to one file or one specific set of files in order to make extension uninstallation easier. The proposal here is that any xpinstall install operation should be reversable via a log that is created when the xpi file is installed.
Every operation performed in a xpi's install.js file should append an entry to the log, which creates a manifest that can be used to uninstall the xpi later on. Files can be removed, backups restored (when files are replaced), registry keys unset and such like.
This proposal does not go as far as dictating where this log would be stored or what format it would assume, although it is intended that the log would be atomically written after the successful completion of each xpinstall command, and that this would be built into the xpinstall implementation of the various install commands.
Little or no change would be required by the extension author. If the install log were kept with the installed files (which may be necessary in multi-user systems) then an additional function call at the commencement of the installation may be necessary to identify the log file.
To rectify the problem of extensions overwriting or tampering with core system files, extension files should be stored in a location separate from other application files. The proposed structure is:
For Application Directory Extensions:
bin/extensions/<extension_name>/chrome/
bin/extensions/<extension_name>/components/
bin/extensions/<extension_name>/preferences/
For Profile Directory Extensions:
<profile_dir>/extensions/<extension_name>/chrome/
<profile_dir>/extensions/<extension_name>/components/
<profile_dir>/extensions/<extension_name>/preferences/
The component registry and preferences systems are updated to scan for components and defaults files in these locations for installed and enabled extensions.
This mechanism gives extensions full flexibility into the kind of functionality they can provide.
Directory Scan Path Precedence - One question raised by the above proposal is the precedence in which files are loaded. In order to prevent extension dlls from clobbering core application files, the precedence would seem to be: System Components, Profile Extensions Components, System Extensions Components.
To prevent extensions designed for older versions of applications from
causing problems, they should only be loaded if the application version
falls within the range supported by the extension. An extension can
identify itself as supporting a range of versions by using the
minAppVersion
and maxAppVersion
properties on
its package contents.rdf chrome registry entry. The version scheme works
like this:
MAJOR_VERSION.MINOR_VERSION.MAINTENANCE_VERSION
For example, 0.6.1 (maintenance update to 0.6) is less than 0.8 (minor version 0.8) is less than 1.3.1 (maintenance update to 1.3). A special case is for extensions targeting trunk development builds between releases, in which case the appropriate version string assumes the form:
MAJOR_VERSION.MINOR_VERSION+
+ indicates trunk development following MINOR_VERSION, e.g. 0.7+ indicates trunk development after 0.7
When the application is started, the extensions list is enumerated and if the app version falls outside the supported range of any extension that extension is disabled (and the update mechanism is invoked). If the extension is disabled for this reason, an annotation is placed in the extension's entry in the chrome registry preventing it from being enabled in this version, and identifying the extension as being disabled because of a compatibility problem.
Extension Updating is a mechanism for determining if there are newer compatible extension versions available from the web. This is useful if either the user wants to stay on the cutting edge of their favorite set of extensions, or the user updates to a newer version of the application and the old set of extensions needs to be updated. These two use cases are outlined below.
The user will be able to periodically check for updates to the application and installed extensions, or check on demand. When one of these events occurs, a list of installed extensions and their versions is sent to the extension server and the server matches those with the versions it has available. If newer versions are available it responds with a list of available updates. The current application version is sent with the list to ensure that the retrieved list is compatible.
When a new version of the application is installed, all incompatible extensions are annotated as described above. This list is sent to the server as in the Manual Invokation case, the user is notified and given the option to visit the extension server where he or she will be presented with a list of available upates to install.
As long as there are incompatible versions in the chrome registry, the system will periodically check the extension server for new, compatible versions.
Note - if the incompatible version installed is of the same extension version number as the compatible version on the server, no download is performed, the local incompatible version's maximum application version value is incremented to that of the compatible version from the server's. This is for the case where an old extension continues to work with a newer version of the application, and the author simply updates its compatibility information on the server.
The Web Front End is designed to show extensions for Mozilla applications that are compatible. The Web FE will be part of a larger software update mechanism that will be hosted on update.mozilla.org. The Web FE will at minimum have the following elements:
The Web FE will optionally (hopefully) have these elements:
Important - the important areas of difference between this system and the current implementation on extensionroom are that the list shown is for one app only at any given time and that the list shown is only of extensions compatible with a specific version.
Each extension author will have his or her own account with the extension service. Rather than being maintained by a central authority the extension list will be updated by authors. Approval by a moderator may be required for new account requests.
The system should allow authors to create an account with an email address and a password, and their name. They will then be able to add as many extensions as they want to this account, each extension will appear in the list for the applicable application.
When adding an extension, the author will be asked for the following information:
The user will be able to see a list of his or her extensions when they log in, and will be able to edit details. For instance, if a new version of the application is released and extension X is still compatible with the new version, the author will be able to log in and increase the upper bound on the Target Application Version Range field so that users of the newer application version will be able to continue using compatible older versions of extensions.
The advantages of this author-based system is that the author is empowered to make changes and update extension files when they become available. Also, the author can maintain several versions of the same extension for different versions of the application (e.g. 1.0 vs. 1.3+)
Conclusion