Getting started

with Mozilla's Add-on SDK

FSOSS, October 29th 2011

Follow along

This talk is a website!

http://talks.canuckistani.ca/fsoss/#2

...and on github

A Brief History

Current release: SDK 1.2

Next release: 1.3 on Nov. 29.

Current State

Roadmap

Who's using the SDK?

Mozilla uses the SDK

Mozilla Labs projects currently using the SDK:

Mozilla adds features to Firefox via add-ons, using the SDK

Let's Get set up!

Local development

Requirements:

Set-up

Online development with Builder

Hacking with the SDK

Style notes

Basic JS style similar in feel to Node.js

  1. require('some-module')
  2. create a new instance; pass in an options object
  3. Rock out!

Example:

var someModule = require("some-module");
var instance = someModule.someClass({
  thisoption: 'my option',
  thatoption: 42,
  onSomeEvent: function(data) {},
});
instance.someMethod();

Addon-kit Module overview

Code, plz kthxbai


[ Install example add-on. ]

Content scripts

Simple Example: Page Exterminator

var data = require("self").data;

var pageMod = require("page-mod").PageMod({
  include: ['http://talks.canuckistani.ca/*'],
  contentScript: 'if (confirm("EXTERMINATE???")) ' + 
    '{ document.body.innerHTML = ' +
    '\'<img src="http://dailypop.files.wordpress.com/2010/04/dalek.gif">\';' + 
    'document.body.style.display="block"; ' + 
    '};',
  contentScriptWhen: 'end',
});
Link

Anatomy of this page-mod

  1. include: ['http://talks.canuckistani.ca/*']
    A string url pattern, or array of url patterns.
  2. contentScript: "..."
    A string of JavaScript code to run.
  3. contentScriptWhen: 'end'
    When do we run this code? The default is 'end', meaning that the script is not run until the page is done loading

Context Meu

var cm = require("context-menu");
cm.Item({
  label: "Context Menu Test",
  context: cm.URLContext('http://aer.local:8080/fsoss*'),
  contentScript: 'self.on("click", function (node, data) {' +
                 '  alert("Click on context menu!"); ' +
                 '});',
  onMessage: function() {
    tabs.activeTab
  }
});

Widget

require("widget").Widget({
    id: "mozilla-icon",
    label: "This is the widget demo!",
    contentURL: "http://www.mozilla.org/favicon.ico",
    panel: xPanel
});

var xPanel = require("panel").Panel({
    height: 340,
    width: 600,
    contentURL: 'http://www.reddit.com/r/programming/.compact'
});

Show a Panel

content script:

$("#panelify").click(function() {
    self.port.emit('panelify', true);
    return false;
});

main.js:

var xPanel = require("panel").Panel({
    height: 340,
    width: 600,
    contentURL: 'http://www.reddit.com/r/programming/.compact'
});

/* pop up the panel */
worker.port.on('panelify', function(m) {
  xPanel.show();
});

Make a Web Request

var shorten = function(url, callback) {    
    let requestJSON = JSON.stringify({longUrl: url});
    let googlRequest = require("request").Request({
        url: 'https://www.googleapis.com/urlshortener/v1/url',
        content: requestJSON,
        contentType: 'application/json',
        onComplete: function(response) {
          callback(response.json);
        }
    });
    googlRequest.post();
}

Show a Notification

content script:

$("#notify").click(function() {
    self.port.emit('notify', true);
    return false;
}); 

main.js:

worker.port.on('notify', function(m) {
  require("notifications").notify({
    title:  "hello from Growl!",
    text:   "of course, you need Growl installed for this to work...",
    iconUrl: "http://www.mozilla.org/favicon.ico"
  });
});

Rocketeers!!

Q&A