mozilla

Firefox Hub Walkthrough

This guide walks you through developing a Firefox Hub add-on for Firefox for Android. The Firefox Hub APIs allow add-ons to add new content to the Firefox for Android home page. These APIs are new in Firefox 30, and increased capabilities are planned for future releases. The two main APIs that this guide covers are the Home.panels API and the HomeProvider API. For some example code to get started, you can copy the hub boilerplate add-on from github.

This guide assumes you understand the basics of building a restartless add-on for Firefox for Android. Please see the basic Firefox for Android add-on Walkthrough guide for more information about getting started.

Overview

There are two main parts to building a Firefox Hub add-on: creating a home panel, and storing data to show in that panel. Home panels consist of different views, each of which displays data from a given dataset.

Creating a home panel

To create a home panel, first use the Home.panels API to register a panel. The register API takes a panel id and an options callback function as parameters. This options callback is called to dynamically generate an options object whenever a panel is installed or updated, which allows for dynamic locale changes.

Cu.import("resource://gre/modules/Home.jsm");

const PANEL_ID = "test.panel@mydomain.com";
const DATASET_ID = "test.dataset@mydomain.com";

function panelOptionsCallback() {
  return {
    title: "My Panel",
    views: [{
      type: Home.panels.View.LIST,
      dataset: DATASET_ID
    }]
  };
}

Home.panels.register(PANEL_ID, panelOptionsCallback);

You must always register your panel on startup, but when your add-on is installed (or whenever you want to actually add the panel to the user's home page), you must also install it.

Home.panels.install(PANEL_ID);

See the Home.panels API documentation for details about how to add more features to your panels, such as authentication and empty views. You can also register to listen for user actions, such as installing or refreshing a panel.

Storing data

Use the HomeProvider API to store data to display in your home panel. The HomeProvider API gives you access to HomeStorage objects, which allow you to asynchronously save and delete data for a given dataset. The save and deleteAll APIs return promises that are resolved when the transaction is complete. You can use Task.jsm to execute these transactions within a task.

Cu.import("resource://gre/modules/HomeProvider.jsm");
Cu.import("resource://gre/modules/Task.jsm");

let items = [
 { url: "http://example.com/1", title: "Example 1" },
 { url: "http://example.com/2", title: "Example 2" }
];

let storage = HomeProvider.getStorage(DATASET_ID);
Task.spawn(function() {
  // Delete any existing items.
  yield storage.deleteAll();
  // Save the new items.
  yield storage.save(items);

  // New way to replace items in Firefox 31+
  // yield storage.save(items, { replace: true });
}).then(null, Cu.reportError);

In practice, if you are going to use a network request to fetch your data, you should use the requestSync API to allow HomeProvider to decide if it's a good time to sync.

function syncCallback() {
  // Fetch new data and use HomeProvider APIs to store data.
}

HomeProvider.requestSync(DATASET_ID, syncCallback);

You can also use the addPeriodicSync API to request data syncing at a regular interval.

// Calls syncData callback once every 3600 seconds (1 hour)
HomeProvider.addPeriodicSync(DATASET_ID, 3600, syncCallback);

View types

Each panel you create with the Hub APIs can have a number of views. For each view, you can choose one of three different layouts: list, grid, or speed dial.

List

The list view displays items in a list, from top to bottom:

To create a list view, specify the view's type as LIST:

Cu.import("resource://gre/modules/Home.jsm");

function optionsCallback() {
  return {
    title: "My list view",
    views: [{
      dataset: DATASET_ID,
      type: Home.panels.View.LIST
    }]
  };
}

Home.panels.register(PANEL_ID, optionsCallback);

List dataset

For each item, the list view will display the following attributes from the view's dataset, if they are present:

  • title
  • description
  • the image referenced by image_url

In the dataset, you must supply at least one of these attributes for each item.

Grid

A grid view displays items in a grid, as images:

To create a grid view, specify the view's type as GRID:

Cu.import("resource://gre/modules/Home.jsm");

function optionsCallback() {
  return {
    title: "My grid view",
    views: [{
      dataset: DATASET_ID,
      type: Home.panels.View.GRID
    }]
  };
}

Home.panels.register(PANEL_ID, optionsCallback);

Grid dataset

For each item, the grid view will display the following attributes from the view's dataset, if they are present:

  • title
  • description
  • the image referenced by image_url

The grid view is primarily designed to display the image referenced by image_url.

In the dataset, you must supply at least one of these attributes for each item.

Speed dial

Starting in Firefox 41, there's a special type of grid view called a speed dial. In this view each item is presented as a background image or a background color, and optionally a title or an icon:

To create a speed dial view, specify GRID as the view's type and ICON as the view's itemType:

Cu.import("resource://gre/modules/Home.jsm");

function optionsCallback() {
  return {
    title: "My speed dial view",
    views: [{
      dataset: DATASET_ID,
      type: Home.panels.View.GRID,
      itemType: Home.panels.Item.ICON
    }]
  };
}

Home.panels.register(PANEL_ID, optionsCallback); 

Speed dial dataset

For each item, the speed dial view will display the following attributes from the view's dataset, if they are present:

  • background_color
  • the image referenced by background_url, as a background image
  • the image referenced by image_url, as an icon
  • title

In the dataset, you must supply at least one of title, description, or image_url for each item.

Headers

From Firefox 42 onwards, you can specify a header image for a grid view using the header view option:

Cu.import("resource://gre/modules/Home.jsm");

function optionsCallback() {
  return {
    title: "My speed dial view",
    views: [{
      dataset: DATASET_ID,
      type: Home.panels.View.GRID,
      itemType: Home.panels.Item.ICON,
      header: {
        image_url: "http://path/to/pumpkin.png",
        url: "http://www.mozilla.org"
      }
    }]
  };
}

Home.panels.register(PANEL_ID, optionsCallback);

Header images are placed at the top of the page and extend right across the page:

Best practices

Here are some tips for developing hub add-ons:

  • Use unique ids for panels and datasets.
  • Register panels in your add-on's startup() function.
  • Unregister panels in your add-on's shutdown() function.
  • Delete panel data when a panel is uninstalled.

Example add-ons

Here are some open source add-ons that use these hub APIs:

Document Tags and Contributors

Contributors to this page: wbamberg, leibovic, diegocr
Last updated by: wbamberg,
Hide Sidebar