Hack 75. Do Groundwork for Ugly Chrome Hacks
Learn the first steps required to modify Firefox without using formal release processes. At the base of Firefox is an efficient and unchangeable runtime engine. On top of that is a thick layer of interpreted content. That thick layer of content is human-readable and human-changeable. This hack describes how to find, open, and modify these files without getting burnt and without preparing an extension. Files centrally associated with the chrome are found in the Firefox install area. Because these central chrome files aren't implemented as extensions, the -safe-mode command-line option [Hack #10] doesn't apply. If you damage chrome files, there is no way to successfully restart Firefox without repair or reinstall. You've been warned. 7.2.1. Understanding ChromeThe chrome represents the entire user interface that Firefox has to offer. That's a collection of XUL, CSS, JavaScript, image, RDF, plain text, and HTML documents. RDF [Hack #70] and XUL [Hack #68] are the most important document types. The chrome appears in several concrete ways. First, the chrome is a little database of information held in Firefox's memory. This database is created at startup time from many separate RDF files. Only those pieces of user interface that are known to this database are considered chrome. RDF package registration is required to make a package known. You can't place a file in the Firefox install area and expect it to be treated as chrome unless it is part of a registered package. Second, the chrome is a set of URLs. The little chrome database in Firefox's memory maintains a list of all valid chrome: URLs. Any URL with a chrome: scheme gets the benefits of the chrome. Primary benefits are full security privileges, overlays, and locale and skin switching. Each chrome: URL translates (maps) to a "real" URL, specified during registration. In practice, whole directories are registered, not specific files. The chrome resource: chrome://mypackage/content/mypackage.xul could be mapped to this "real" URL at registration time: file:///users/fred/tests/content/mypackage.xul It's more normal, though, to see it mapped to this kind of URL, which refers to the Firefox install area folders: resource:/chrome/mypackage/content/mypackage.xul You can load either URL into the browser and the same document will be accessed. Only when you load with a chrome: URL do the special characteristics of chrome apply. Most of the chrome files are physically located in the install area. Rather than use the nonportable file: scheme, Firefox provides an extra scheme specifically for the install-area folder. It's called resource:, and it points at the top of the install area. So, chrome: URLs typically map to resource: URLs. The third expression of chrome is just a set of files on disk. These are the particular XML, script, and CSS files that make up the user interface itself, plus the RDF registration files that identify that content. These files are all content and fair game for hacking. 7.2.2. Understanding JAR FilesFirefox keeps related chrome content together in JAR files. This is entirely optional; such file can also be located as plain files on disk. A JAR file is a ZIP format archive, that's all. JAR files have the benefit of being compact, fast to read from disk, fast to download, and digitally signable. Rather than splatter scores of chrome files all over the local disk, Firefox keeps them together neatly. You can use JAR files for:
A JAR file can have a URL, just like any file. A special Firefox URL scheme allows you to refer to one of the files that is contained within the JAR file. If a JAR file /tmp/example.jar contains the file example.txt, that example.txt file can be specified by this URL: jar:file:///tmp/example.jar!
/example.txt Note the mandatory leading slash after the !. JAR files destined for the chrome usually contain one or more chrome packages. Such JAR files have restrictions on the way package content is laid out. One fairly weird rule says that the normal directory hierarchy is reversed inside the JAR file. If a package exists unarchived on disk using the standard layout: mypackage/content/... mypackage/skin/... mypackage/locale/... then all these files must be rearranged before repackaging them into a JAR file: content/mypackage/... skin/mypackage/... locale/mypackage/... This reordering is designed to make searching the archive faster at runtime. A second oddity is the placement of any contents.rdf files at the start of the archive. This is also for performance, but it is just a clever trick, not a requirement. To open a JAR file, copy it, use an unzip program like unzip -l to report the contents (save this), and then unzip it for real into a temporary directory. Edit any of the files normally. Zip the archive up again, change the file extension back to .jar, and put the file back. It's that simple. 7.2.3. Locating Standard Chrome FilesThe standard chrome files reside in the install area, in the chrome subdirectory. The topmost file is called installed-chrome.txt. It lists all the standard packages currently in the chrome, so start here. This file is written at install time, but you can add packages by hand-editing it. If this file is modified or updated, Firefox will re-read it when it next starts up. If that happens, any new packages created since the last run will be added to the set of known packages. The installed-chrome.txt file is sensitive to bad syntax. A line like this: content,install,url,resource:/chrome/help/content/ means that a content package (not a skin or locale package) in the install area (as opposed to in the rarely used profile area) is located in the chrome/help/content directory. In particular, it says that those files are stored as separate files in a normal hierarchy of folders (directories). These registration lines, however, typically refer to JAR archives, rather than to plain folder names. Here's an example: content,install,url,jar:resource:/chrome/help.jar!/content/help/ The default name for per-package registration files is contents.rdf. This is the second file of importance. This file contains the registration details that make the package available via chrome: URLs. For the first example, it would be located at: resource:/chrome/help/content/contents.rdf The remainder of the files for the package are all those residing in the same directory as the contents.rdf file or in subfolders of that directory. The most important file usually has the same name as the package namefor example: jar:resource:/chrome/help.jar!/content/help/help.xul resource:/chrome/help/content/help.xul or, after chrome registration: chrome://help/content/help.xul This XUL file is the one that everything else hangs off of. In this example, it's the main window of the help system. For more central changes, this is the place to start: chrome://browser/content/browser.xul 7.2.4. Locating Other Chrome FilesChrome files also appear in the install area under the extensions directory. There, additional packages are defined and packaged up as extensions. There is a separate registration system for extensions [Hack #84] . Finally, ordinary chrome packages and extensions can also be placed in the user profile. That's common for extensions, but rarely done for ordinary packages. 7.2.5. What to HackNearly all supplied Firefox files can be hacked [Hack #22] . If you know what you're doing, you can usually ignore installed-chrome.txt and any contents.rdf and just hack on the chrome content help inside the JAR files. Use touch afterward to update the last-modified date on the installed-chrome.txt file so that Firefox notices your changes next time it starts up. Read the rest of the hacks in this chapter for examples. |