I realized today that one of our newer add-on features in Fennec is in Firefox Beta at this point, and I’ve never done anything to blog about it! So here it is, Prompt.jsm!

Prompt.jsm is a module that can be used to show dialogs in Fennec. We use it pretty extensively in our UI for everything from Select popups, Context menus, HTML5 date and time input elements, Certificate dialogs, etc. Previously, those were all done via a similar messaging system, but Prompt.jsm makes it a little easier to deal with and less error prone.

The API is pretty simple. Like I always like to do, I wrote a little addon to show off what you could do. This one I called ReaderPlus and lets you easily add a bunch of articles to Firefox for Android’s ReadingList (i.e. cached offline to see in ReaderMode. You can access your ReadingList through Bookmarks). The code’s a bit more complex than some of my earlier demos, but you’re welcome to peruse it on github if you want (patches welcome!)

The addon loads RSS feeds for a page, and lets you pick articles from them to add to your reading list. It adds a page action on pages where it finds feeds (I used a floppy disk here because you’re kinda “saving” the article, but I’d love something better). When you click the page action, we show a dialog listing all the feeds on the page:

The code to do something like this is pretty simple, we just import Prompt.jsm and create a new Prompt object:

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

var p = new Prompt({ title: "Select a source" })

.setSingleChoiceItems(list.map(function(listItem) {

return { label: listItem.title }

})).show(function(data) {

readerPlus.showSelectArticles(list[data.button].list);

});

The prompt constructor takes an object that can give some basic details about the prompt (i.e. a title, message, and the buttons to show). For more complex prompts, it exposes a Fluent interface, so we can chain a call to setSingleChoiceItems, which shows a list of items. If we had added “selected: true” to one of those items, the dialog would also have shown checkboxes to the right. (You can’t add other inputs to prompts that have lists in them… yet).

Finally, we can call show on the prompt, and pass a callback to be called when its dismissed. The callback gets data bout what was tapped or selected, or the value of any inputs, checkboxes or any time/colorpickers (coming soon!).

The second prompt in the demo app is pretty similar, but uses setMultiChoiceItems to create a dialog where you can check multiple rows:

The code here is pretty similar:

var p = new Prompt({

title: list.title,

buttons: ["OK", "Cancel"]

}).setMultiChoiceItems(list.map(function(listItem) {

return { label: listItem.title }

})).show(function(data) {

for (var i = 0; i < data.button.length; i++) {

if (data.button[i]) {

readerPlus.addToReadingList(list[i].link, list[i].title);

}

}

});

In this case, we have to be careful to add some buttons to the prompt so that users have a way to close it. They get passed in in the constructor. Because its possible for some items to initially selected, the return has an array that’s the same length as the list and tells you the final state for each row.

Like I mentioned, you can do lots of other interesting things with prompts, adding input elements, labels (which support a subset of HTML if you need to do some advanced formatting), I’ve tried to document them as well as I can on MDN, but feel free to ping me if you have questions! Happy add-on-ing.