Revision 237373 of Initialization and Cleanup

  • Revision slug: Extensions/Mobile/Initialization_and_Cleanup
  • Revision title: Initialization and Cleanup
  • Revision id: 237373
  • Created:
  • Creator: wbamberg
  • Is current revision? No
  • Comment 4 words added, 4 words removed

Revision Content

Android add-ons don't have to be restartless, but with Firefox for Android you can't use XUL overlays to create your user interface, so there's much less incentive to write overlay-based add-ons.

Restartless add-ons must contain a file called "bootstrap.js" to handle initialization and cleanup. In this guide we'll present a template implementation of "bootstrap.js" that simplifies initialization and cleanup tasks such as adding and removing the add-on's user interface.

To read more about restartless extensions (also known as bootstrapped extensions), refer to the bootstrapped extensions documentation.

bootstrap.js

The "bootstrap.js" file must contain implementations of two functions: startup() and shutdown().

startup()

startup()is called by the host application when the add-on is installed or enabled, or when the host application is launched.

Inside startup() the add-on should put all the code needed to initialize the add-on, including any code to construct persistent user interface elements like menu items.

shutdown()

shutdown() is called by the host application when the add-on is uninstalled or disabled, or when the host application shuts down. Inside shutdown() the add-on needs to undo any persistent changes it's made.

template code

Here's a version of "bootstrap.js" that implements startup() and shutdown():

const Cc = Components.classes;
const Ci = Components.interfaces;

function loadIntoWindow(window) {
  if (!window)
    return;
  // Add any persistent UI elements
  // Perform any other initialization
}

function unloadFromWindow(window) {
  if (!window)
    return;
  // Remove any persistent UI elements
  // Perform any other cleanup
}

var windowListener = {
  onOpenWindow: function(aWindow) {
    // Wait for the window to finish loading
    let domWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
    domWindow.addEventListener("load", function() {
      domWindow.removeEventListener("load", arguments.callee, false);
      loadIntoWindow(domWindow);
    }, false);
  },
 
  onCloseWindow: function(aWindow) {},
  onWindowTitleChange: function(aWindow, aTitle) {}
};

function startup(aData, aReason) {
  let wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);

  // Load into any existing windows
  let windows = wm.getEnumerator("navigator:browser");
  while (windows.hasMoreElements()) {
    let domWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
    loadIntoWindow(domWindow);
  }

  // Load into any new windows
  wm.addListener(windowListener);
}

function shutdown(aData, aReason) {
  // When the application is shutting down we normally don't have to clean
  // up any UI changes made
  if (aReason == APP_SHUTDOWN)
    return;

  let wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);

  // Stop listening for new windows
  wm.removeListener(windowListener);

  // Unload from any existing windows
  let windows = wm.getEnumerator("navigator:browser");
  while (windows.hasMoreElements()) {
    let domWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
    unloadFromWindow(domWindow);
  }
}

function install(aData, aReason) {}
function uninstall(aData, aReason) {}

To use this template you just implement loadIntoWindow() to initialize your add-on. You can use the window argument to access the NativeWindow and BrowserApp objects, which you can use to add user interface elements and interact with the browser.

Conversely, you implement unloadFromWindow() to remove any UI elements and perform any other cleanup.

Revision Source

<p>Android add-ons don't have to be restartless, but with Firefox for Android you can't use XUL overlays to create your user interface, so there's much less incentive to write overlay-based add-ons.</p>
<p>Restartless add-ons must contain a file called "bootstrap.js" to handle initialization and cleanup. In this guide we'll present a template implementation of "bootstrap.js" that simplifies initialization and cleanup tasks such as adding and removing the add-on's user interface.</p>
<p>To read more about restartless extensions (also known as <em>bootstrapped</em> extensions), refer to the <a href="/en/Extensions/Bootstrapped_extensions" title="en/Extensions/Bootstrapped_extensions">bootstrapped extensions documentation</a>.</p>
<h2>bootstrap.js</h2>
<p>The "bootstrap.js" file must contain implementations of two functions: <code>startup()</code> and <code>shutdown()</code>.</p>
<h3>startup()</h3>
<p><code>startup()</code>is called by the host application when the add-on is installed or enabled, or when the host application is launched.</p>
<p>Inside <code>startup()</code> the add-on should put all the code needed to initialize the add-on, including any code to construct persistent user interface elements like menu items.</p>
<h3>shutdown()</h3>
<p><code>shutdown()</code> is called by the host application when the add-on is uninstalled or disabled, or when the host application shuts down. Inside <code>shutdown()</code> the add-on needs to undo any persistent changes it's made.</p>
<h3>template code</h3>
<p>Here's a version of "bootstrap.js" that implements <code>startup()</code> and <code>shutdown()</code>:</p>
<pre class="brush: js">const Cc = Components.classes;
const Ci = Components.interfaces;

function loadIntoWindow(window) {
  if (!window)
    return;
  // Add any persistent UI elements
  // Perform any other initialization
}

function unloadFromWindow(window) {
  if (!window)
    return;
  // Remove any persistent UI elements
  // Perform any other cleanup
}

var windowListener = {
  onOpenWindow: function(aWindow) {
    // Wait for the window to finish loading
    let domWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
    domWindow.addEventListener("load", function() {
      domWindow.removeEventListener("load", arguments.callee, false);
      loadIntoWindow(domWindow);
    }, false);
  },
 
  onCloseWindow: function(aWindow) {},
  onWindowTitleChange: function(aWindow, aTitle) {}
};

function startup(aData, aReason) {
  let wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);

  // Load into any existing windows
  let windows = wm.getEnumerator("navigator:browser");
  while (windows.hasMoreElements()) {
    let domWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
    loadIntoWindow(domWindow);
  }

  // Load into any new windows
  wm.addListener(windowListener);
}

function shutdown(aData, aReason) {
  // When the application is shutting down we normally don't have to clean
  // up any UI changes made
  if (aReason == APP_SHUTDOWN)
    return;

  let wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);

  // Stop listening for new windows
  wm.removeListener(windowListener);

  // Unload from any existing windows
  let windows = wm.getEnumerator("navigator:browser");
  while (windows.hasMoreElements()) {
    let domWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
    unloadFromWindow(domWindow);
  }
}

function install(aData, aReason) {}
function uninstall(aData, aReason) {}
</pre>
<p>To use this template you just implement <code>loadIntoWindow()</code> to initialize your add-on. You can use the <code>window</code> argument to access the <a href="/en/Extensions/Mobile/API/NativeWindow" title="https://developer.mozilla.org/en/Extensions/Mobile/API/NativeWindow"><code>NativeWindow</code></a> and <a href="/en/Extensions/Mobile/API/BrowserApp" title="https://developer.mozilla.org/en/Extensions/Mobile/API/BrowserApp"><code>BrowserApp</code></a> objects, which you can use to add user interface elements and interact with the browser.</p>
<p>Conversely, you implement unloadFromWindow() to remove any UI elements and perform <a class="external" href="http://maglione-k.users.sourceforge.net/bootstrapped.xhtml" title="http://maglione-k.users.sourceforge.net/bootstrapped.xhtml">any other cleanup</a>.</p>
Revert to this revision