Archive for XUL

Firefox Android: Add-ons in a Native World

One of the first things I yelled about when we were debating switching to a native Android UI for Firefox was add-on support. Using a XUL-based UI meant add-ons were free. The Mozilla platform has support for add-ons baked right in. Moving to a native UI would surely kill our ability to support add-ons, right? Wrong!

Add-ons are an important part of the Firefox story. Native UI builds of Firefox support add-ons. There are some things an add-on developer needs to be aware:

  • The add-ons system is the same one used in other Mozilla applications. We did not invent a new add-on system.
  • Native UI builds are considered a new application and are not add-on compatible with the XUL versions. The application ID for native UI builds is: {aa3c5121-dab2-40e2-81ca-7ea25febc110}
  • There is no visible XUL in the UI, so using overlays to try to add or change UI is useless.
  • There is a simple NativeWindow object that allows you to manipulate parts of the native Android UI.
  • Services like nsIPromptService and nsIAlertsService are implemented to use native Android UI.
  • Since overlays are useless for UI and JavaScript APIs are available for native UI, you should seriously consider just making a restartless add-on.

NativeWindow

We wanted to give add-on developers some APIs to manipulate the native Android UI, so we create a helper object called NativeWindow. The API is still young, but it gives you access to: Android Menu, Doorhanger Notifications, Context Menus (in web content) and Android popup toast alerts. The object is currently part of the main browser window, but we are considering moving it to a JS module. The basic API is here:


/*
 label: menu label
 icon: file:// or data: URI for an icon
 callback: JS function called when menu is tapped
 returns a menu ID that can be used to remove the menu
*/
menuID = NativeWindow.menu.add(label, icon, callback);
NativeWindow.menu.remove(menuID);

/*
 message: displayed text
 value: string based tag
 buttons: array of JS objects used to create buttons in the notification
 tabID: tab associated with this notification
 options: JS object that has 'persistence' and 'timeout' options
*/
NativeWindow.doorhanger.show(message, value, buttons, tabID, options);
NativeWindow.doorhanger.hide(value, tabID);

/*
 label: menu label
 selector: JS object that has a 'matches(element)' function. Used to show the menu.
 callback: JS function called when menu is tapped
 returns a menu ID that can be used to remove the menu
*/
menuID = NativeWindow.contextmenu.add(label, selector, callback);
NativeWindow.contextmenu.add(menuID);

/*
 message: displayed text
 duration: "short" or "long"; Used for alert timeout
*/
NativeWindow.toast.show(message, duration);

Some examples of what the API can do:

Doorhanger Notification


Menu Item


Context Menu Item


Toast Popup Alert


The NativeWindow API will continue to grow and mature, but I think even now it shows that add-ons can have first-class interactions with the native UI of Firefox. I am looking forward to developers trying it out and helping us push the API forward.

Comments (7)

Fennec – Handling Add-on Options

The add-on (extension) mechanism built into the Mozilla platform is very powerful. One of the optional features is support for options (preferences) dialogs. As discussed in my last post, Fennec doesn’t like dialogs. In addition, Fennec has a simple, clean preference system. While designing the Fennec Add-ons Manager, we discussed how we would support add-on options. We didn’t want popup dialogs of random and complicated XUL.

After brainstorming a few ideas, we settled on a simple idea. Fennec uses special <setting> XUL tags to create it’s list of preferences. Add-ons would be forced to use the same tags. The options would be merged into the Fennec Add-on Manager, not displayed as a popup dialog. Of course, add-ons can support more than one application, so we needed to make sure that the options XUL for Fennec could coexist with the options XUL for other applications. Let’s take a look at how this all works:

Install Manifest

Add-ons use install.rdf to identify the XUL used for displaying the preferences. This is optional.

<em:optionsURL>chrome://myaddon/content/options.xul</em:optionsURL>

This is needed for any add-on that wants to use an options dialog.

Chrome Manifest

Add-ons use the chrome manifest to selectively override XUL, and other resources, between different applications using the application flags

override chrome://myaddon/content/options.xul chrome://myaddon/content/fennec-options.xul application={a23983c0-fd0e-11dc-95ff-0800200c9a66}

This will tell Mozilla to use fennec-options.xul anytime the options.xul resource is requested.

Options XUL

As I said, the XUL allowed for the Fennec options system is limited to a few new tags. Here is an example of a Fennec options dialog:


<?xml version="1.0"?>

<!DOCTYPE mydialog SYSTEM "chrome://myextension/locale/mydialog.dtd">

<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <setting pref="extensions.myaddon.debugging" type="boolint" on="1" off="2" title="Enable debugging"/>
  <setting pref="extensions.myaddon.profiling" type="bool" title="Enable profiling">
    Profiling can affect the performance of the application
  </setting>
  <setting pref="extensions.myaddon.logging" type="bool" title="Save logs"/>
  <setting pref="extensions.myaddon.logging.path" type="string" title="Log folder"/>
  <setting type="button" title="Clear logs">
    <button label="Clear" oncommand="MyAddon.clearLogs();"/>
  </setting>
</vbox>

Note that we don’t have any <script> support and we are limited to <setting> tags. The root <vbox> just acts as a container, it isn’t merged into the main window. Here is how the options look in Fennec:

As always, we appreciate your feedback. I’m in the process of updating the Fennec Best Practices documents with this information.

A big thank you goes out to Vivien Nicolas, a Mozilla intern in the Paris office, for turning my super-great design into a reality. Shaver told me there’d be days like this!

Comments (3)

Fennec – Prompts, Alerts and Dialogs – Oh My

If you’ve developed applications or extensions using the Mozilla platform, you know that there are tons of services and APIs available. We use those same capabilities when building Fennec. However, there are times when the default platform behavior is not desirable on mobile devices. When that happens, we could hack up our own system, or we could re-implement the platform APIs to suit our needs. We try to do the latter.

Here are some APIs that have been reimplemented in Fennec: nsIAlertsService, nsIPromptService, nsIDownloadManagerUI, and window.openDialog(). The primary reason all of these APIs have been reimplemented is that they open new XUL windows. We don’t like doing that in Fennec. Mostly because opening a XUL window is slow. But also because we love having tighter control over the look, feel and behavior of the UI elements.

Services

Since we re-implement the interfaces, nsIAlertsService, nsIPromptService and nsIDownloadManagerUI can be used just as they are on the desktop. The big difference is that none of them open new windows. The UI is embedded into the main window itself. It’s faster to display and easier to control and style the UI elements. In the case of the download manager, it’s designed to be embedded in the main window.

Dialogs

On the other hand, we couldn’t exactly match the way window.openDialog() worked, so we created a slightly different API: importDialog(). The big difference is that importDialog() actually merges the XUL dialog into the main window. It does not open a new XUL window.

importDialog(aSrc, aArguments);

  • aSrc: The chrome URL of the XUL dialog
  • aArguments: A JavaScript object used to pass data to the dialog

The XUL passed to importDialog() is very similar to XUL passed to window.openDialog(), with some limitations and caveats:

  • Only <dialog> top level elements are permitted
  • Scripts are loaded via an attribute on the <dialog> element, not via the <script> tag

Here is an example:


<?xml version="1.0"?>
<!DOCTYPE mydialog SYSTEM "chrome://myextension/locale/mydialog.dtd">
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
      script="chrome://myextension/content/mydialog.js">
  
  <label id="mydialog-title" crop="center"/>

... some other widgets ...

  <hbox pack="center">
    <button label="&ok.label;" oncommand="myDialog.doSomething();"/>
  </hbox>
</dialog>

The XUL is merged into the existing window, almost like a XUL overlay. Because of this, element ID and JavaScript conflicts are possible, just like overlays. So be careful!

Obviously, add-on developers should use these features. We are looking for feedback as well. Perhaps we could get importDialog() working more like window.openDialog().

A big thank you goes out to Fabrice Desré for working on reimplementing nsIPromptService. He created some great building blocks for Fennec.

Comments (2)

Fennec – Of Screens and Orientation

Designing a portable application to run on many different mobile devices is a challenge. Screen sizes and pixel densities are different making it difficult to create the One Great Layout. In addition, mobile devices can change screen orientation, from portrait to landscape and back again.

This is one area where using a markup-based UI language like XUL, with it’s support for CSS, comes in handy. Currently, Fennec is being designed and tested to run on Nokia’s N810 & N900 devices, HTC’s Touch Pro and Samsung’s Omnia & Omnia II. Yes, Fennec can run on other Windows Mobile devices, but we don’t really test on every possible device… yet. Joel and the QA crew are working on that, but I digress.

Even with the target devices, we have several screen sizes, pixel densities and orientation requirements to support. Layout support in XUL and media query support in CSS really do the heavy lifting for us. The Fennec UI is the same on all these devices, but we have some layout constraints and CSS rules that allow us to morph the UI as the screen changes. Here are some of the ways we do it:

  • Use physical dimensions whenever possible. Padding and margins are set using millimeters, not pixels. This minimizes the need for special rules for every different screen size and pixel density. Also, the UI is designed for touch, and the current design size for a touchable UI element is ~7.5mm. Your finger doesn’t change sizes to match the screen :)
  • Use CSS media queries to switch between screen sizes and pixel densities. Large sized images can be used on large screens/densities, while smaller images can be used on smaller screens/densities. The result should be an image that is roughly the same physical size on either device.
  • Use CSS media queries and XUL box rules to flow the UI when the device is rotated. A toolbar that works well vertically in landscape orientation, probably needs to flow horizontally in portrait orientation. It’s all about maximizing the usable space.

Screen Size

Here is some example CSS we use for toggling between large and small screens/densities. As you can see, we use 400px as a cutoff:


/* high-res screens */
@media all and (min-device-width: 401px) {
  toolbarbutton {
    min-width: 64px !important; /* primary button size (match image pixels)*/
    min-height: 64px !important; /* primary button size (match image pixels) */
  }
}

/* low-res screens */
@media all and (max-device-width: 400px) {
  toolbarbutton {
    min-width: 36px !important; /* primary button size (match image pixels) */
    min-height: 36px !important; /* primary button size (match image pixels) */
  }
}

Orientation

The same kind of example, but this time for changing the direction of some UI elements when rotating the screen:


@media (orientation: landscape) {
  #panel-controls {
    -moz-box-orient: vertical;
    -moz-box-ordinal-group: 1; /* move to left of screen */
    -moz-box-pack: end; /* force children to align to bottom of screen */
  }
}

@media (orientation: portrait) {
  #panel-controls {
    -moz-box-orient: horizontal;
    -moz-box-ordinal-group: 1000; /* move to the bottom of the screen */
    -moz-box-pack: start; /* force children to align to left of screen */
  }
}

Landscape

Portrait

We also use the XUL box wrapping tip, I discussed previously, to allow elements to flow into multiple rows if there is not enough space to hold them in a single row.

If you’re developing add-ons for Fennec, please keep these situations in mind. Use the Fennec code as an example of how you can create a great user experience, regardless of screen size or orientation.

Comments (3)

Fennec – More Theme Goodness

Recently, we released Fennec Beta 3 for Maemo (Alpha 3 for Windows Mobile is very close). The new release has several internal changes that might be of interest to add-on developers – or people curious as to how the darn thing works.

Roy Frostig posted an nice article about the changes to the way we render web pages. The results are dramatic: panning is much smoother. The approach also gives us more ways to increase performance and user experience in the future by creating a great foundation.

We also landed what we hope is the final approach for styling the user interface. I previously posted about the affect of themes on performance and how that drives the decisions we make. We are still using the images-for-buttons approach, but we had a problem. Using images-for-buttons doesn’t work for buttons with text, which can be variable in size.

We decided to extend the image-for-buttons approach for all buttons, using the border-image CSS property. Now all of our buttons have a nice, consistent look. We still have performance concerns with border-image, but we should be able to squeeze more speed out of the code. We also use the border-image approach to improve the appearance of the toggle controls and the radio option controls.

New Toggles and Buttons

New Radios

In fact, add-ons can, and will in some cases, use the new button styles too. We are in the process of updating the Best Practices document with how to make use of the themes and styles.

Comments off

New Life for Old Projects

So much to do, so little time. My workspace is littered with projects I started but couldn’t find the time to keep going. It’s kinda sad and I do feel guilty.

Sometimes those projects find a new life. Recently, two of my old projects found new life: FizzyPop and js-ctypes are both active again.

Doug Warner has started building a Mozilla Project Wizard on the FizzyPop source code. Doug is requesting feedback for improvements. You can try it out here.

Dan Witte has started looking into moving js-ctypes into the Mozilla tree! There are also plans to add a nice JavaScript wrapper API around the XPCOM too.

I feel less guilty now.

Comments (4)

XULRunner 1.9.0.11

The newest official XULRunner has been released. XULRunner 1.9.0.11 matches the Firefox 3.0.11 release. For XULRunner developers, most of the changes in 1.9.0.11 are related to security and stability fixes. SQLite was upgraded to version 3.6.7.

Runtimes
SDKs
Source tarball

The coolest thing about this XULRunner release is how it was done. Mozilla’s Release Engineering group is now doing official XULRunner releases at the same time as Firefox releases. Previously, someone would manually file a bug, make a patch, spin the builds and push the bits. A big thank you to the release crew for adding this to their release process.

Want to get started building XULRunner applications? We have an article for that. It’s way better than the crappy XML UI framework you’re currently using :)

Comments (4)

Ready for a Challenge?

Mozdev and Mozilla Europe have teamed up to create a Firefox Mobile (Fennec) Add-ons Challenge. The goal is to create or port add-ons to Fennec. You only need to propose a concept for now, but you’ll need to get the add-on ready for the upcoming Mozilla/Maemo developer weekend in Copenhagen on May 30-31.

See Brian King’s post for more details.

I am interested to see innovative ideas for using the limited UI in Fennec, add-ons that focus on mobile-specific functionality, and code that exposes more of the Maemo device functionality to Mozilla (yes, XPCOM is likely involved).

I also wouldn’t mind some applets (either as add-ons or XUL apps) running on Maemo. Think about mobile-specific Chatzilla or FireFTP for example. By mobile-specific, I mean dramatically different UIs, not just porting the existing desktop UI. If many little focused applets work for the iPhone, why not for other mobile platforms? And with XUL/JS, it’s pretty easy to build them. Anyone got a XUL-based Twitter app? :)

As always, we love to hear feedback from anyone building add-ons or apps on our mobile stack. Post comments, file bug reports, visit the IRC channels (#mobile & #extdev).

Comments (3)

XULRunner 1.9.0.7

While I was on vacation last week, the newest official XULRunner was spun up and has now been released. XULRunner 1.9.0.7 matches the Firefox 3.0.7 release. For XULRunner developers, most of the changes in 1.9.0.7 are related to security fixes. There are some cookie and XHR fixes in there too. You can also look at the full list of fixed bugs.

Runtimes
SDKs
Source tarball

Thanks to Dave Townsend and Nick Thomas for getting 1.9.0.7 out the door.

Want to get started building XULRunner applications? We have an article for that.

Comments (1)

XULRunner 1.9.0.6

The newest official XULRunner has been released. XULRunner 1.9.0.6 matches the Firefox 3.0.6 release. For XULRunner developers, most of the changes in 1.9.0.6 are related to security fixes. You can also look at the full list of fixed bugs.

Runtimes
SDKs
Source tarball

Update: We now have XULRunner builds for Windows Mobile! XULRunner runtimes now exist for Windows, Windows Mobile, OS X, Linux and Maemo (a mobile Linux). Another XULRunner port is underway: Symbian OS (S60).

Want to get started building XULRunner applications? We have an article for that.

Comments (2)

« Previous entries Next Page » Next Page »