Microsoft's Internet Explorer browser has no built-in vector graphics machinery required for "loss-free" gradient background themes.

Please upgrade to a better browser such as Firefox, Opera, Safari or others with built-in vector graphics machinery and much more. (Learn more or post questions or comments at the Slide Show (S9) project site. Thanks!)

MAOW Firenze 2009

MAOW

Firefox Add-Ons Developer Workshop

"Hack, Remix, Develop on the OpenWeb"

from XULit.org

Luca Greco
Massimiliano Mirra

released under CC 2.5 by-nc-sa

Workshop Sections


Extension Development Overview

HANDS-ON: First Steps on Firefox

HANDS-ON: Full Metal Firefox

Extension Development Overview

GOALS

High level overview of the Firefox platform and its potential.

Why build Firefox extensions?


(from laihiu)

Why build Firefox extensions?

Use/Extend/Remix the Web


(from feedly.com)

Why build Firefox extensions?

Change the Browser Experience

(from tree style tab and ubiquity)

Why build Firefox extensions?

Mix Web and Desktop

(from Twitbin)

What can they do?

(from spigoo)

Web Renderer → Web Actor


(from gillesgonthier)

OpenWeb as a Platform

XML

HTML/XHTML/SVG/CSS

DOM / XPath

JavaScript Frameworks (jQuery, Dojo, ExtJS…)

HTML5 (canvas, audio, video)

Mozilla Platform Overview

XUL

What is XUL?

Application-oriented UI XML vocabulary

Remixable with XHTML, SVG

DOM Scriptable with JavaScript

Stylable with CSS

Overlay extension XUL UI on existent XUL UI

https://developer.mozilla.org/En/XUL

Chrome vs. Content

Chrome vs. Content

Chrome vs. Content

What is Chrome?

!GoogleChrome

Mozilla Internals URLs

(Browser UI Resources: XUL Documents, CSS…)

Privileged JavaScript Code

(accessing XPCOM Components and Services, unlimited XHR)

https://developer.mozilla.org/En/Chrome

Chrome vs. Content

https://developer.mozilla.org/en/Safely_accessing_content_DOM_from_chrome

XPCOM

What/Why/When XPCOM?

Scriptable Native Components and Services

(local files, protocols, bookmarks, history…)

IDL-interfaces

C++ or JavaScript

https://developer.mozilla.org/En/XPCOM

Users trust you

Don’t betray


(from schmollmolch)

More power, More responsibility


Don’t be Fool


(from pawelbak)


(from tonivanstraaten)

Don’t be Evil

Summary

HANDS-ON – First Steps on Firefox

GOALS

Build your workspace and bootstrap your skeleton extension.


(from epicharmus)

Create your Firefox development profile


firefox -no-remote -ProfileManager

http://developer.mozilla.org/en/Setting_up_extension_development_environment

Where is you profileDir?

http://support.mozilla.com/en-US/kb/Profiles

Linux:

~/.mozilla/firefox/xxxxxxxx.PROFILENAME/

Windows XP/Vista:

APPDATA\Mozilla\Firefox\Profiles\xxxxxxxx.PROFILENAME\

MacOSX:

~/Library/Application Support/Firefox/Profiles/xxxxxxxx.PROFILENAME/

Useful prefs in a development environment

In “about:config”:

javascript.options.showInConsole → true

nglayout.debug.disable_xul_cache → true

browser.dom.window.dump.enabled → true

http://developer.mozilla.org/en/Setting_up_extension_development_environment#Development_preferences

Useful Firefox Extensions

Extension Developer Extension

https://addons.mozilla.org/en-US/firefox/addon/7434/

ChromeList

https://addons.mozilla.org/en-US/firefox/addon/4453/

DOMInspector + InspectorWidget

https://addons.mozilla.org/en-US/firefox/addon/6622/

https://addons.mozilla.org/en-US/firefox/addon/63/

Where are Firefox Extensions installed?



PROFILE_DIR/extensions/EXTENSION_ID

Bootstrap your first extension

Take it easy… Online Firefox Extension Wizard:

http://ted.mielczarek.org/code/mozilla/extensionwiz/

EXTENSION_ID: maowfirenze09@xulit.org

Unpack under /tmp or c:\

Shadow Install your Working Dir


Locate your Firefox profile

Create a text file named after the extension id with the path of the unpacked extension

PROFILE_DIR/extensions/EXTENSION_ID:

C:\maowfirenze09

or /tmp/maowfirenze09

or your ABSOLUTE_PATH_TO/the_extension_sources

Check Chrome Registration

Search and Overlay

XUL overlay

firefoxOverlay.xul

   1  <?xml version="1.0" encoding="utf-8"?>
   2  <?xml-stylesheet href="chrome://maowfirenze09/skin/overlay.css" type="text/css"?>
   3  <!DOCTYPE overlay SYSTEM "chrome://maowfirenze09/locale/maowfirenze09.dtd">
   4  <overlay id="maowfirenze09-overlay"
   5           xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   6    ...
   7    <menupopup id="menu_ToolsPopup">
   8      <menuitem id="maowfirenze09-hello" label="&maowfirenze09.label;" 
   9                oncommand="maowfirenze09.onMenuItemCommand(event);"/>
  10    </menupopup>
  11    ...
  12  </overlay>

Apply your style

firefoxOverlay.xul

   1  <?xml-stylesheet href="chrome://maowfirenze09/skin/overlay.css" type="text/css"?>
   2  ...
   3    <menupopup id="menu_ToolsPopup">
   4      <menuitem id="maowfirenze09-hello" label="&maowfirenze09.label;" 
   5                oncommand="maowfirenze09.onMenuItemCommand(event);"/>
   6    </menupopup>
   7  ...

overlay.css

   1  #maowfirenze09-hello
   2  {
   3    color: red ! important;
   4  }

Add your JavaScript code

firefoxOverlay.xul

   1  <menuitem id="maowfirenze09-hello" label="&maowfirenze09.label;" 
   2                oncommand="maowfirenze09.onMenuItemCommand(event);"/>

overlay.js

   1  var maowfirenze09 = {
   2    onLoad: function() {
   3      ...
   4    },
   5    onMenuItemCommand: function(e) {
   6      ...
   7    }
   8  };

More XUL…

https://developer.mozilla.org/en/XUL

https://developer.mozilla.org/en/XUL_controls

https://developer.mozilla.org/en/XUL_reference

XUL Periodic Table

http://www.hevanet.com/acorbin/xul/top.xul

Extension Skeleton

PROFILE_DIR/extension/maowfirenze09

Install.rdf

EXTENSION INSTALL METADATA:

RDF (XML Metadata format)

name, description, homepageURL, creator, contributor

EXTENSION_ID, version, targetApplication

updateURL

http://developer.mozilla.org/en/Install_Manifests

Chrome.manifest

CHROME REGISTRATION MANIFEST:

plain line-based format

chrome urls / UI overlays

locales, skins, resources

http://developer.mozilla.org/En/Chrome_Registration

HANDS-ON – Full Metal Firefox: an Advanced Development Environment

GOALS

Some advanced JavaScript, Best Practices, Debugging and Interactive Development.


(from kevindooley)

TODO: introspection → http://www.flickr.com/photos/ravenelle/2524024795/

Traditional Debugging Techniques

alert()

dump()

error console

Component.utils.reportError

“chrome://global/content/console.xul” as home page

inspect call stack at any point with “alert(new Error().stack)”

Reflection


(from neychurluvr)

This is a reflective platform…

Firefox from inside

Telnet yourself into Firefox with MozRepl

http://wiki.github.com/bard/mozrepl

http://repo.hyperstruct.net/mozrepl/1.0/mozrepl.xpi

Firefox from inside

REPL loop

Interactive Development Workflow

Explore your browser

LOOK AROUND

repl.whereAmI() – repl.look() – repl.search(/pattern/)

MOVE AROUND

repl.enter(object) – repl.back() – repl.home()

INSPECT

repl.inspect(object) – repl.print(a_var)

JavaScript you may not be used to

let → (declare variables with block scope)

   1  function where_is_my_var() {
   2    var i=0;
   3    while(i<10) {
   4       var internal = 5;
   5       i++;
   6    }
   7    repl.print(i); repl.print(internal);
   8  }
   9  
  10  function where_is_my_let() {
  11    let i=0;
  12    while(i<10) {
  13       let internal = 5;
  14       i++;
  15    }
  16    repl.print(i); repl.print(internal);
  17  }

JavaScript you may not be used to

functional-style javascript → (closure, lambda and function expressions)

   1  // IMPERATIVE STYLE
   2  var input = [1, 3, 5];
   3  var results = [];
   4  for(var i=0; i<input.length; i++) {
   5     results.push(input[i] + 2);
   6  }
   7  alert(results.toSource()); // -> [3, 5, 7]
   8  
   9  // FUNCTIONAL STYLE
  10  var input = [1, 3, 5];
  11  results = input.map(function(item) item + 2);
  12  alert(results.toSource()); // -> [3, 5, 7]

JavaScript you may not be used to

getter and setter → (lazy loading, iterators/generators)

   1  var obj = {
   2     _foo: null,
   3     setFoo: function(val) { this._foo = val; },
   4     getFoo: function() { return this._foo; }
   5  };
   6  
   7  obj.setFoo(42); alert(obj.getFoo());
   8  
   9  var obj = {
  10     _foo: null,
  11     set foo(val) { this._foo = val; },
  12     get foo() { return this._foo; }
  13  };
  14  
  15  obj.foo = 42; alert(obj.foo);

JavaScript you may not be used to

E4X → (XML literal syntax in your JavaScript code)

   1  var db = <users>
   2            <user>
   3              <name>peter</name>
   4              <surname>parker</surname>
   5            </user>
   6            <user>
   7              <name>clark</name>
   8              <surname>kent</surname>
   9            </user>
  10          </users>;
  11  
  12  for each(var user in db.*) {
  13     alert(user.name + ' ' + user.surname);
  14  }

Use some XPCOM Components/Services

“Components” is the gatekeeper object (overlay.js)

   1  var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
   2                      .getService(Components.interfaces.nsIPromptService);
   3  promptService.alert(window, this.strings.getString("helloMessageTitle"),
   4                      this.strings.getString("helloMessage"));

Components.classes[“@mozilla.org/embedcomp/prompt-service;1”]

Components.interfaces.nsIPromptService

http://books.mozdev.org/html/mozilla-chp-5-sect-4.html

XPCOMViewer

http://xpcomviewer.mozdev.org/

Use some XPCOM Components/Services

System notification

   1  var srvAlert = Components.classes['@mozilla.org/alerts-service;1']
   2      .getService(Components.interfaces.nsIAlertsService);
   3  
   4  srvAlert.showAlertNotification('http://http.cdnlayer.com/.../spam.gif', 
   5                                 'Notifier', 'You have mail!', 
   6                                 false, '', null);

Use some XPCOM Components/Services

Preferences

   1  var srvPref = Components.classes['@mozilla.org/preferences-service;1']
   2      .getService(Components.interfaces.nsIPrefBranch);
   3  
   4  var prefBranch = prefs.getBranch('extensions.foobar.');
   5  
   6  prefBranch.setBoolPref('beNice', true);

Use some XPCOM Components/Services

Console Service

   1  var srvConsole = Components.classes["@mozilla.org/consoleservice;1"]
   2      .getService(Components.interfaces.nsIConsoleService);
   3  srvConsole.logStringMessage('hello, console!');

Base FUEL API

Simpler API:

Windows

Tabs

Bookmarks

Installed Extensions

Preferences

https://developer.mozilla.org/en/FUEL

JavaScript Modules

Componentizing your extension in lightweight reusable modules

https://developer.mozilla.org/en/Using_JavaScript_code_modules

https://developer.mozilla.org/en/Components.utils.import

https://developer.mozilla.org/En/JavaScript_modules

How to learn more?

DEVMO

http://developer.mozilla.org

https://developer.mozilla.org/En/Firefox_addons_developer_guide

Creating Application With Mozilla (Ebook)

http://books.mozdev.org

…more Firefox Extension Tutorials on DEVMO

https://developer.mozilla.org/en/Extensions

https://developer.mozilla.org/en/Setting_up_extension_development_environment

https://developer.mozilla.org/en/Building_an_Extension

https://developer.mozilla.org/en/Extension_Packaging

https://developer.mozilla.org/en/Submitting_an_add-on_to_AMO

Firefox Sidebar Tutorial on DEVMO

http://developer.mozilla.org/en/Creating_a_Firefox_sidebar

http://developer.mozilla.org/samples/extension-samples/emptysidebar.zip

MAOW Firenze 2009

27 June 2009

released under CreativeCommons 2.5 by-nc-sa

Luca Greco / Massimiliano Mirra
XULit.org