mobile/android/modules/PageActions.jsm
author Florian Quèze <florian@queze.net>
Mon, 09 Jan 2017 20:27:26 +0100
changeset 328554 d816f539d536fcb917e1ce8ba012e7f2873bc3e6
parent 297739 ccc23c5390aeebab035a0fdd9bc1de318e7201aa
child 331065 45316394ec1d7a06fa15404ba21c67f1ca4027d6
permissions -rw-r--r--
Bug 1329182 - remove trailing newURI null parameters in the rest of the tree, r=jaws.

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Messaging.jsm");

XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
                                   "@mozilla.org/uuid-generator;1",
                                   "nsIUUIDGenerator");

this.EXPORTED_SYMBOLS = ["PageActions"];

// Copied from browser.js
// TODO: We should move this method to a common importable location
function resolveGeckoURI(aURI) {
  if (!aURI)
    throw "Can't resolve an empty uri";

  if (aURI.startsWith("chrome://")) {
    let registry = Cc['@mozilla.org/chrome/chrome-registry;1'].getService(Ci["nsIChromeRegistry"]);
    return registry.convertChromeURL(Services.io.newURI(aURI)).spec;
  } else if (aURI.startsWith("resource://")) {
    let handler = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
    return handler.resolveURI(Services.io.newURI(aURI));
  }
  return aURI;
}

var PageActions = {
  _items: { },

  _inited: false,

  _maybeInit: function() {
    if (!this._inited && Object.keys(this._items).length > 0) {
      this._inited = true;
      Services.obs.addObserver(this, "PageActions:Clicked", false);
      Services.obs.addObserver(this, "PageActions:LongClicked", false);
    }
  },

  _maybeUninit: function() {
    if (this._inited && Object.keys(this._items).length == 0) {
      this._inited = false;
      Services.obs.removeObserver(this, "PageActions:Clicked");
      Services.obs.removeObserver(this, "PageActions:LongClicked");
    }
  },

  observe: function(aSubject, aTopic, aData) {
    let item = this._items[aData];
    if (aTopic == "PageActions:Clicked") {
      if (item.clickCallback) {
        item.clickCallback();
      }
    } else if (aTopic == "PageActions:LongClicked") {
      if (item.longClickCallback) {
        item.longClickCallback();
      }
    }
  },

  isShown: function(id) {
    return !!this._items[id];
  },

  synthesizeClick: function(id) {
    let item = this._items[id];
    if (item && item.clickCallback) {
      item.clickCallback();
    }
  },

  add: function(aOptions) {
    let id = aOptions.id || uuidgen.generateUUID().toString()

    Messaging.sendRequest({
      type: "PageActions:Add",
      id: id,
      title: aOptions.title,
      icon: resolveGeckoURI(aOptions.icon),
      important: "important" in aOptions ? aOptions.important : false
    });

    this._items[id] = {};

    if (aOptions.clickCallback) {
      this._items[id].clickCallback = aOptions.clickCallback;
    }

    if (aOptions.longClickCallback) {
      this._items[id].longClickCallback = aOptions.longClickCallback;
    }

    this._maybeInit();
    return id;
  },

  remove: function(id) {
    Messaging.sendRequest({
      type: "PageActions:Remove",
      id: id
    });

    delete this._items[id];
    this._maybeUninit();
  }
}