17

I'm quite new to addon development with firefox. I picked the addon sdk for porting my chrome extension to firefox.

What would you suggest to display a options page / options panel / options window to a user?

Loading a options.html file from my addon directory works quite fine (addTab(data.url("options.html"));), but i can't attach page-mods to it, as far as a i know. Therefore i can't communicate with the main.js to save my options, right?

Also how should the user access it? In chrome this is quite easy. Rightclick your icon -> options and it opens up for you. Are there ways to create a simliar behaviour for firefox?

Any suggestions on that?

Wladimir Palant
  • 56,865
  • 12
  • 98
  • 126
patchrail
  • 2,007
  • 1
  • 23
  • 33

3 Answers3

25

Starting with the Add-on SDK 1.4 you have the simple-prefs module. It will automatically generate inline options for your add-on - these are displayed directly on your extension's page in the Add-ons Manager. That should be the preferred way to display options. The downside: opening the options programmatically is non-trivial, even for classic add-ons. And the SDK doesn't seem to support complicated controls (documentation of what's possible with inline options), only the most basic ones.

If you want to roll your own, you probably want to integrate an "Options" button into a drop-down panel. You should also be able to attach a content script to it via page-mod package, something like this should work:

var pageMod = require("page-mod");
pageMod.PageMod({
  include: data.url("options.html"),
  ...
});

var tabs = require("tabs");
tabs.open(data.url("options.html"));

Downside here: using the standardized way to display add-on options (via Add-ons Manager) won't be possible, the SDK doesn't support anything but inline options.

Wladimir Palant
  • 56,865
  • 12
  • 98
  • 126
  • All right, used the simple-prefs module. Works fine, thanks for that! – patchrail Feb 08 '12 at 19:04
  • finally i completed a nice implementation of what you said. I'll surely post the working sample of what i did.. thanks for the hints.. – pratikabu Nov 07 '12 at 13:02
  • To hide address and search bars you can use `addon-page` module. Downside is it demands file to be called "index.html", so until they make it right there is a user made module [addon-tab](https://github.com/lduros/addon-tab). – Igor Jerosimić Mar 30 '13 at 21:59
1

Thanks Wladimir Palant for pointing out the direction, yet it still took me quite a while to figure out the final code. I put my result here for reference of others in the future. (I simplified the code a little bit here for elaboration purpose, but the main structure should be correct.)

content.js: (click a link to open the options page)

  $("#options").click(function(){
    self.port.emit("open_options", {});
  });

background.js:

//regsiter the event
backgroundInit = function(worker) {
  worker.port.on("open_options", function(request){
    var tabs = require("sdk/tabs");
    tabs.open({
      //open a new tab to display options page
      url: self.data.url("options.html"),
    });
  }

  worker.port.on("pull_preferences", function(request){
    var preferences = null;
    //get preferences (from simple storage or API)
    woker.emit("update_content_preferences", {preferences:preferences});
  });


  worker.port.on("push_preferences", function(request){
    var preferences = request.preferences;
    //write the preferences (to simple storage or API)
  });
}

//register the page, note that you could register multiple ones
pageMod.PageMod({
  include: self.data.url('options.html'),
  contentScriptFile: [ self.data.url("lib/jquery-1.11.3.min.js"),
                        self.data.url("options.js")],
  contentScriptWhen: 'end',  
  onAttach: backgroundInit

});

options.js: (this page is also on the content script context)

$(document).ready(function(){
  self.port.on("update_content_preferences", function(request){
    var preferences = request.preferences;
    //update options page values using the preferences
  });

  $("#save").click(function(){
    var preferences = null;
    //get preferences from options page
    self.port.emit("push_preferences", {preferences:preferences});
  });

  self.port.emit("pull_preferences", {}); //trigger the pull upon page start
});

Reference: https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/tabs

Walty Yeung
  • 3,396
  • 32
  • 33
-1

In this case you need to use Port.on()/Port.emit() to send a controll option from options.html, like click on setting button. And "tabs" module

 options.html

        var panelIsOpen = 0;

        $('#settings').click(function() {
                self.port.emit("statusoptions", {optionsIsOpen:1});
            });

 popup.html

        Panel.port.on("statusoptions", function (panda) {
                if(panda.optionsIsOpen === 1){
                    Panel.hide();
                    tabs.open({
                        url: "options.html",
                        onReady: function onReady(tab) {
                           Panel.hide();
                        },
                        contentScriptFile: [
                            data.url("js/jquery-2.0.0.min.js"),
                            data.url("js/options.js")],
                    });
                }
            });
  • I tried, and the it did not work. In particular, it's impossible to access `self.port` from the `options.html`. – Walty Yeung Feb 08 '16 at 09:26