Tuesday, May 19, 2009

Using NASA Night Launch with Firefox 3.0.x on the Mac with OS X


People using the current NNL version can ignore everything said in this post. For NNL versions 0.6.20091031 and newer, the described functionality is built-in, and you don't need to do anything extra to get it.

If you've been using userstyle 11097 to fix up the OS X menubar with NNL, you can stop using it. Once you've upgraded, you won't need that any more.

Here's a reminder [1] for Mac users: if you're using NASA Night Launch with Firefox 3.0.x on OS X, you need to take special steps to make the Bookmarks and History menus appear as they should in the OS X desktop menubar.

The special steps are:

1 - Install the Stylish Add-on from AMO
2 - Within Stylish, install Userstyle 11097 - OS X Bookmark Menu Icons for NASA Night Launch
3 - Restart Firefox, after which the menus should again be good to go.

This is needed on OS X only (and not on either Windows or Linux). In fact, you should not use this on either Windows or Linux, or else your menubar will look funny.

If you're not familiar with Stylish, see the userstyles.org home page for instructions. That's all you need to know - now go forth and install, if you're a Mac user, or read on for some background.


The problem is that bookmark icons used by NNL on Windows don't work when used in the OS X desktop menubar. The following image shows what we mean.

If you're not an Apple Mac user, the thing you need to know is that Windows and OS X have two very different ways of handling menus and menu bars. Under Windows, each window can have its own menu, displayed at the top of each application's window. In contrast, on the Mac, there's one and only one menubar, displayed at the top of the desktop, changing to show whatever menu pertains to whichever window you're using.

The other relevant fact is that Firefox themes can't touch the appearance of the OS X desktop menubar, other than to change the icons shown next to each menu item for Firefox. The shape, text and background color, and other parts of the menubar appearance are all controlled by OS X settings. OS X uses dark text on a light background.

The upshot is that NNL, as a dark theme designed to work by default with menus having dark backgrounds, needs to use icons for the OS X menubar that work with its light background, which are different from the icons NNL uses for dark-background-color Firefox menus on Windows. There's no good way for NNL to do this from within a single theme file.

There's more (explained below), but you already have the gist of the problem. You don't need to read the technical explanation unless you're a theme developer or add-on developer.

Bottom line: if using NNL on OS X with Firefox 3.0.x, get Stylish and Userstyle 11097.

Geeky Technical Explanation

At a more detailed technical level, there are two major things going on. This section describes the situation with Firefox 3.0.x. FIrefox 3.5 may be different.

This explanation assumes that you're already familiar with
  • theme development for Firefox
  • differences in the Firefox 3.0 UI for OS X and Windows
  • theme packaging with chrome.manifest
  • CSS in general
  • the use of CSS properties list-style-image and -moz-image-region to apply an icon image from an image file containing multiple icons in a single file
Issue 1 - Unlike with Windows, CSS property -moz-image-region doesn't work when used to assign icons within Firefox's Mac desktop menubar. This feature wasn't needed with Firefox's own default-theme icon implementation and so never made it to the top of the bug-fixing priority list. See Firefox Bug 418774 for further discussion of what Firefox is doing here. (And please keep in mind that Bugzilla posts should be limited to discussion of technical issues about Firefox source code.)

Issue 2 - Even if -moz-image-region did work for the OS X menubar, NNL (possibly in addition to other dark themes) still needs to use different icon sets in the menubar for Windows vs. OS X, and there's no good way using theme technology (chrome packaging, CSS and XBL) alone to detect whether you're running OS X vs. Windows and then to apply the correct icons for the situation.

Regarding Issue 1, the approach taken by many theme developers, and certainly a viable one, is to identify all icon files used within the Firefox menubars, and to split each multiple-icon image file into separate files such that each file contains only one icon. Also required would be to recode (and retest) the CSS rules which apply these icons to the menubars, menus, and to any other places in the UI where the same icons are used.

Regarding Issue 2, preferable would be some XUL element attribute found on the OS X menubar element but not on the Windows version of the menubar. In other words, if the two menubar elements were designed like this in XUL source code:
<!-- osx --> <menubar class="i_am_on_osx"></menubar>
<!-- win --> <menubar></menubar>

then we could write different CSS selectors within the theme to work differently on different platforms, and all would be golden:
menubar #someBookmarksMenuItem {
list-style-image: url("some-windows-icon.png");
menubar.i_am_on_osx #someBookmarksMenuItem {
list-style-image: url("some-osx-icon.png");
Unfortunately, there's no such attribute, nor is there any other readily-apparent way to write CSS selectors which will match on OS X but not Windows.

One could use chrome.manifest with "os" modifiers to mount OS-specific packages from within the theme, but this would require duplicating both the "browser" and "global" packages within the theme -- having one pair for Windows and another almost-identical pair for OS X. This is undesirable because of the resulting increase in theme download size and because of the extra developer burden of maintaining two different versions of the same code. (Additionally -- this would need to be verified -- but this might also render the chrome.manifest file invalid for Firefox 2 use, which again would be a no-go for use with NNL since we're still supporting Firefox 2. If you're a theme developer and you only care about Firefox 3+, it would certainly be technically possible to take this approach, although it would still raise size issues.)

One could decide simply to offer two different versions of the theme or add-on -- one for Windows, one for OS X. Depending on your situation as a developer, this might work for you.

One could define and apply an XBL binding within the theme itself, which binding would apply an OS-identifying attribute to the DOM elements of the OS X menubar. The problem there is that while it would solve the OS X issue, the wrong icons would then be used with Windows -- again, because there's no way to write CSS selectors which would apply the binding with OS X but not with Windows.

Given all of the above, we decided the best approach for now is the one described at the very of top of this post, using Stylish. This has the following advantages:
  1. avoids the effort of having to split multi-icon images into separate images
  2. avoids the effort of recoding the theme to use single-icon images (what we scientists refer to using the technical term royal pain)
  3. avoids the risk and need to retest coming from any coding change
  4. avoids the delay and/or visible flash that can occur while loading an image to show an icon in the hover state, which could happen with icons stored one-to-a-file but not when storing multiple icons in a single image file
  5. avoids the size increase and download time increase that would come with duplicated packages within the theme
  6. provides platform-specific styling as required
  7. Just Works, with no action required, for the vast majority of NNL users, namely, those using NNL with Firefox on Windows
  8. completely avoids impacting Firefox when the user switches to other themes (because they're not written with CSS to use the attribute added by the Stylish stylesheet).
The downside, obviously, is that it puts the burden on certain users -- that is, people using NNL on OS X, of which there are 36,846, as of today's AMO statistics. That's a lot of people. We're not totally wild about having to ask them to do this, but it's only a little extra effort, as long as you know to do it. Further, these menubar issues may be resolved in future versions of Firefox such that there's no action needed by users at all.

The Code

There are three places where code was added or changed. The relevant code follows.

1 - in new NNL theme file global/skin/macMenus.xml
2 - in NNL theme file browser.css
3 - in Stylish userstyle 11097

In new theme file chrome://global/skin/macMenus.xml

<?xml version="1.0"?>

<bindings id="macMenus"

<binding id="mac-desktop-menu" extends="chrome://global/content/bindings/menu.xml#menu-menubar">
<content class="mac-desktop-menu">
<xul:label class="menubar-text" xbl:inherits="value=label,accesskey,crop" crop="right"/>
<children includes="menupopup"/>


In existing theme file chrome://browser/skin/browser.css:

/* ::::: for Fx3 Mac OSX ::::: */

#unified-back-forward-button #back-button dropmarker,
#unified-back-forward-button #forward-button dropmarker {
display: none !important;

/* For Mac-specific Bookmarks menu icons, apply the following binding in userChrome.css or as a Stylish style:
* #history-menu, #bookmarksMenu { -moz-binding: url(chrome://global/skin/macMenus.xml#mac-desktop-menu) !important }
* This will add the class "mac-desktop-menu" to the history and bookmarks menus and trigger the following
* Mac-specific rules. We do it this way so we can write rules that only apply on OSX.
* These rules are written for Mac+Fx3 only, and don't even consider the Fx2-on-OSX and/or RTL cases.
* It appears that the only thing to handle in the history menu is the plain document icon, while
* the bookmarks menu presents other several cases as well.

#bookmarksMenu.mac-desktop-menu .menuitem-iconic,
#history-menu.mac-desktop-menu .menuitem-iconic {
list-style-image: url("chrome://global/skin/icons/osx.document-item.png");
-moz-image-region: auto;

#bookmarksMenu.mac-desktop-menu .menu-iconic[container] {
list-style-image: url("chrome://global/skin/icons/osx.folder-item.png");
-moz-image-region: auto;

#bookmarksMenu.mac-desktop-menu .menu-iconic[container][livemark] {
/* needs !important because other livemark rules have important */
list-style-image: url("chrome://browser/skin/osx.livemark-folder.png") !important;
-moz-image-region: auto;

#bookmarksMenu.mac-desktop-menu .menu-iconic[container][livemark] .menuitem-iconic {
list-style-image: url("chrome://browser/skin/osx.livemark-item.png");
-moz-image-region: auto;

#bookmarksMenu.mac-desktop-menu .menu-iconic[container][query] {
list-style-image: url("chrome://browser/skin/places/osx.query.png");
-moz-image-region: auto;

#bookmarksMenu.mac-desktop-menu .menu-iconic[container][tagContainer] {
list-style-image: url("chrome://mozapps/skin/places/osx.tagContainerIcon.png");
-moz-image-region: auto;

#bookmarksMenu.mac-desktop-menu #bookmarksToolbarFolderMenu {
list-style-image: url("chrome://browser/skin/places/osx.bookmarksToolbar.png");
-moz-image-region: auto;

And, finally, the Stylish stylesheet which, when added to Stylish, applies the binding from within the theme to add the attribute which triggers the CSS rules which apply the appropriate icons for OS X. That Jack built.
@namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);
#history-menu, #bookmarksMenu {
-moz-binding: url(chrome://global/skin/macMenus.xml#mac-desktop-menu) !important

If you're a theme developer, feel free to use any of the code in this post. And if you have a better solution, feel free to let us know about that too. :)


[1] Or maybe a first introduction, since it wasn't widely publicized when first made available.

1 comment:

  1. hi there,
    Mcdavis...I am a great fan of night launch theme...and recently I wrote a post on Mozilla firefox addons...where I have showcased your theme by one of it's images and linked up to your them extension page at mozilla addons...I just wanted you to know that there are many ppl who are fan to your work...
    Please visit my blog and comment...

    keep up the good work...
    your fan
    varquazar (Vishal Kuberkar, India)