## Thursday, March 25, 2010

### The Anatomy of a Firefox 3.5 Extension

The directory structure of a Firefox 3.5.x extension looks like this:

.
|-chrome
|---content
|---modules
|---skin
|-----css
|-----images
|-defaults
|---preferences
|-locale
|---en-US
|-chrome.manifest
|-install.rdf


# chrome.manifest

This structure is not mandated by Firefox; you'll have to let it know in your chrome.manifest, which looks like this:

content  myextension chrome/content/
content  myextension chrome/content/ contentaccessible=yes
locale   myextension en-US locale/en-US/
skin     myextension classic/1.0 chrome/skin/
resource myextension chrome/modules/
overlay  chrome://browser/content/browser.xul chrome://myextension/content/myOverlay.xul


Old versions of Firefox allowed you to serve up images with chrome URI's (ie, starting with chrome://), but that feature was removed in Firefox 3.x. To emulate the old behavior, you'll need to add contentaccessible=yes. Since older versions of Firefox don't recognize that contentaccessible (in fact, they ignore it; see below), you'll need to put both lines in the manifest.

# install.rdf

The manifest is for describing some things about your extension, but you'll have to put the rest of the information in a file called install.rdf. Here's a sample:

<?xml version="1.0"?>
<RDF xmlns:em="http://www.mozilla.org/2004/em-rdf#"
xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<em:id>myextension@lousycoder.com</em:id>
<em:name>My Extension</em:name>
<em:version>1.0.0</em:version>
<em:type>2</em:type>
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>3.5</em:minVersion>
<em:maxVersion>3.6.*</em:maxVersion>
</Description>
</em:targetApplication>
<em:iconURL>chrome://myextension/skin/images/logo.png</em:iconURL>
<em:updateURL>https://www.lousycoder.com/update.rdf</em:updateURL>
<em:creator>Me!</em:creator>
<em:description>
A test extension for funsies.
</em:description>
<em:homepageURL>http://www.writeonglass.com</em:homepageURL>
</Description>
</RDF>


Most of the data there is self explanatory, but the version numbers can be tricky when it comes to auto update. Extension versions must follow a very specific format, and auto-update does some very complicated logic to determine which version is greater than another. For example, version 1.0 is considered the same as version 1.1-1 (because 1 - 1 = 0); yes arithmetic is conveniently done for you! Also, strings are compared bytewise instead of alphabetically. For this reason, I would advise extension version strings to only consist of numbers and periods... unless the extension is being hosted by AMO in the beta channel (in which case, version strings are ignored, and the newest version is the one last uploaded).

# Overlays

XUL overlays are "merged" with whatever XUL document you are overlaying onto; in the case above it would be chrome://browser/content/browser.xul. In this way, you can add menus and/or buttons to Firefox's UI. There are special considerations for Javascript executing in the context of a browser overlay; for example, the window refers to a chrome window, and the document object refers to a XUL document, as opposed to their normal web page counterparts. Additionally, setting any global variables on window makes them available for other overlays (and extensions), so it's quite easy to clobber other extensions if you are not careful.

# Modules

Code modules are executed in their own context, and the global object is not any window. In fact, the window and document objects are not even defined within code modules. There is no way to clobber variables with other extensions, as the only variables exposed by a module are the ones declared in the special EXPORTED_SYMBOLS array (see modules at MDC).

# Gotchas

If you have any syntax errors in your XUL files (eg the overlay files), your extension will be shown as installed, but no errors will appear in the Error Console. If you open the XUL file directly in Firefox, via File -> Open -> file://path/to/xul/file.xul, you'll see any errors that Firefox did not report.

If you do not place the trailing slash after any path in chrome.manifest (eg chrome/content instead of chrome/content/), then Firefox will silently ignore that line in the manifest.

# References

https://developer.mozilla.org/en/Chrome_Registration
https://developer.mozilla.org/en/Toolkit_version_format
https://developer.mozilla.org/index.php?title=en/Extension_Versioning,_Update_and_Compatibility
https://developer.mozilla.org/En/Code_snippets/Modules

## Monday, March 22, 2010

### Windows XP: How many different versions are there?

Because it's so confusing:
• OEM
• Usually sold with the computer
• Certificate of authenticity usually says OEM
• CD says "only for distribution with a new PC"
• CD is branded by Dell or HP or etc
• Retail (bought standalone from a store or if Windows CD says "Upgrade")
• Branded (specifically branded by a big company)
• Action Pack (part of MS Action Pack)

## Friday, March 19, 2010

### EeePC with an external monitor

Triumph! For the longest time, I wondered why X would never honor my DPI settings, even if i passed it the -dpi 96 command line flag. My fonts would look fine using the EeePC screen but look too small on my external monitor (or if I fiddle with my xorg.conf it'd be the other way around). It turns out I have to add sections for each monitor and name the identifiers something special to normalize that DPI:

Section "Monitor"
Identifier  "LVDS"
Option    "DPMS"
DisplaySize 270 158 # 1024x600 @ 96dpi
EndSection

Section "Monitor"
Identifier "VGA"
Option    "DPMS"
DisplaySize 488 304 # 1920x1200 @ 96dpi
EndSection