Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

This article includes code snippets to help you write an add-on for Firefox for Android. For additional code samples, check out the Firefox for Android Add-ons Github repo.

Obtain NativeWindow and BrowserApp object with add-on SDK

The NativeWindow and BrowserApp object are only available to privileged code running on Firefox for Android, and is intended for use by Firefox for Android add-ons.
// Obtain component object : Chrome Authority
// https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Chrome_Authority
var { Cu } = require("chrome");

// Obtain commonly used services : Services.jsm
// https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Services.jsm
Cu.import("resource://gre/modules/Services.jsm");

function getNativeWindow() {

	let window = Services.wm.getMostRecentWindow("navigator:browser");
	return window.NativeWindow;

}

function getBrowserApp() {

	let window = Services.wm.getMostRecentWindow("navigator:browser");
	return window.BrowserApp;

}

Tabs and Browsers

Most tab and browser management happens through the BrowserApp object. Because Firefox on Android uses both a native UI and a JavaScript Gecko layer, tabs need to be synchronized. Every tab has an ID which is used to identify it when interacting with the native UI.

Waiting for UIReady

Before trying to access any methods or properties of the BrowserApp object, you must wait for the code to be properly initialized. That typically happens in the "load" handler for the chrome browser window. This can lead to races if an add-on also uses the "load" event to do it's initialization. An easy way around this is to use the BrowserApp "UIReady" event.

let addPageLoadListener = function() {
  BrowserApp.deck.addEventListener("load", onPageLoad, false);
};

if(BrowserApp.deck) {
  // BrowserApp.deck has been initialized.
  addPageLoadListener();
} else {
  // Use the global chrome window to wait for BrowserApp to initialize.
  window.addEventListener("UIReady", function onUIReady(){
    window.removeEventListener("UIReady", onUIReady, false);
    addPageLoadListener();
  }, false);
}

Selected Tab and Browser

// gets the array of open tabs
BrowserApp.tabs;

// gets the selected tab
BrowserApp.selectedTab;

// gets the selected browser
BrowserApp.selectedTab.browser;

// gets the selected browser (a shortcut)
BrowserApp.selectedBrowser;

Looking up Tabs and Browsers

Sometimes you have a reference to an object and want to lookup the Tab or Browser associated with that object.

// Lookup tab using an ID
let tab = BrowserApp.getTabForId(aID);

// Lookup tab using a browser
let tab = BrowserApp.getTabForBrowser(aBrowser);

// Lookup tab using a DOM window
let tab = BrowserApp.getTabForWindow(aWindow);

// Lookup browser using a tab
let browser = tab.browser;

// Lookup browser using a DOM window
let browser = BrowserApp.getBrowserForWindow(aWindow);

// Lookup browser using a DOM document
let browser = BrowserApp.getBrowserForDocument(aDocument);

Tab Management

// Adding a tab
let tab = BrowserApp.addTab();

// Close a tab
BrowserApp.closeTab(aTab);

// Select a tab
BrowserApp.selectTab(aTab);

// Listening for tab events
function watchTab(aEvent) {
  // the target is a XUL browser element
  let browser = aEvent.target;
}

BrowserApp.deck.addEventListener("TabOpen", watchTab, false);
BrowserApp.deck.addEventListener("TabClose", watchTab, false);
BrowserApp.deck.addEventListener("TabSelect", watchTab, false);

Detecting Page Loads

function onPageLoad(aEvent) {
  // the target is an HTMLDocument
  let doc = aEvent.originalTarget;
  let browser = BrowserApp.getBrowserForDocument(doc);
  let tab = BrowserApp.getTabForBrowser(browser);
}

BrowserApp.deck.addEventListener("load", onPageLoad, true);

Detecting Private Browsing Mode

Private browsing mode in Firefox for Android is per-tab, not per-window

function isPrivateTab(aTab) {
  return aTab.browser.docShell.QueryInterface(Components.interfaces.nsILoadContext).usePrivateBrowsing;
}

BrowserApp.addTab("https://developer.mozilla.org/", {isPrivate: isPrivateTab(BrowserApp.selectedTab)});

Supporting both desktop and mobile

The same add-on can support both desktop and mobile versions of Firefox. Some of the capabilities between the platforms are different, and may require some pieces of separate logic.

Detecting XUL support

Mobile add-ons do not support using XUL for the UI. Mobile UI can be implemented in HTML. To detect if the platform supports XUL:

function isXULAvailable() {
  return Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime)
    .widgetToolkit.toLowerCase() != "android"
}

Document Tags and Contributors

 Contributors to this page: wbamberg, leibovic, backy0175, Np, Tobias Schmidbauer, MarkFinkle
 Last updated by: wbamberg,