![[図: はてなブックマーク Firefox 拡張]](firefox-workshop-images/hatena-bookmark-firefox-extension.gif)
![[図: Context History]](firefox-workshop-images/context-history.png)
![[図: Mozilla プラットフォーム]](firefox-workshop-images/mozilla-platform.png)
<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:em="http://www.mozilla.org/2004/em-rdf#">
  <rdf:Description rdf:about="urn:mozilla:install-manifest">
    <em:id>contexthistory@extdev.org</em:id>
    <em:type>2</em:type>
    <em:name>Context History</em:name>
    <em:version>0.1</em:version>
    <em:description>Show recent pages in the context menu.</em:description>
    <em:creator>nanto_vi</em:creator>
    <em:homepageURL>http://example.org/context-history</em:homepageURL>
    <em:targetApplication>
      <rdf:Description>
        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
        <em:minVersion>3.5</em:minVersion>
        <em:maxVersion>3.5.*</em:maxVersion>
      </rdf:Description>
    </em:targetApplication>
  </rdf:Description>
</rdf:RDF><?xml version="1.0" encoding="utf-8"?>
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
</overlay>content contexthistory chrome/content/
overlay chrome://browser/content/browser.xul chrome://contexthistory/content/contexthistory.xul<popup id="contentAreaContextMenu"><popupset id="mainPopupSet"> 内にまとめられている![[図: 「最近表示したページ」メニューの追加]](firefox-workshop-images/recent-pages-menu.png)
var ContextHistory = {
  menu: null,
  popup: null,
  init: function CH_init() {
    this.menu = document.getElementById("ctxhst-recent-pages");
    this.popup = this.menu.menupopup;
  },
};
window.addEventListener("load", function () ContextHistory.init(), false);JavaScript 1.8 (Firfox 3) の新機能。次の 2 つは同じ意味。
function f() { return expr; }function f() exprECMAScript 3 では不正だが、JavaScript では妥当。ECMAScript 5 でも妥当になる予定。
var o = { foo: 42, bar: 23, }![[図: イベントの伝播]](firefox-workshop-images/event-propagation.png)
document.addEventListener("popupshowing", function () 1, true);
document.addEventListener("popupshowing", function () 4, false);
menupopup.addEventListener("popupshowing", function () 2, true);
menupopup.addEventListener("popupshowing", function () 3, false);// Web アプリケーション
function addEvent(target, type, listener) {
  if (target.addEventListener)
    target.addEventListener(type, listener, false);
  else if (target.attachEvent)
    target.attachEvent("on" + type, listener);
}
addEvent(target, function (event) { ... });// XUL アプリケーション
var listener = {
  doSomething: function () { ... },
  handleEvent: function (event) {
    this.doSomething();
  },
};
target.addEventListener(type, listener, useCapture);var ContextHistory = {
  ...
  init: function CH_init() {
    ...
    this.popup.addEventListener("popupshowing", this, false);
  },
  createMenu: function CH_createMenu() {
    ...
  },
  handleEvent: function CH_handleEvent(event) {
    switch (event.type) {
    case "popupshowing":
      this.createMenu();
      break;
    }
  },
};document.createElementNS(namespaceURI, tagName)var ContextHistory = {
  XUL_NS: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
  ...
  createMenu: function CH_createMenu() {
    let xulElement = document.createElementNS(this.XUL_NS, tagName);
  },
  ...
};JavaScript 1.7 (Firefox 2) の新機能。ブロックスコープの変数を宣言する。
var x = 42; { var x = 23; } x; // => 23let x = 42; { let x = 23; } x; // => 42gBrowser から tabbrowser 要素にアクセスできるnsISHistory インターフェース
    while (this.popup.firstChild)
  this.popup.removeChild(this.popup.firstChild);
let history = gBrowser.sessionHistory;
for (let i = 0, n = history.count; i < n; i++) {
  let entry = history.getEntryAtIndex(i, false);
  let menu = document.createElementNS(this.XUL_NS, "menuitem");
  menu.setAttribute("label", entry.title);
  menu.setAttribute("index", i);
  this.popup.insertBefore(menu, this.popup.firstChild);
}gotoHistory: function CH_gotoHistory(event) {
  let index = +event.target.getAttribute("index");
  gBrowser.webNavigation.gotoIndex(index);
},![[図: 英語版の履歴ドロップダウンのツールチップ]](firefox-workshop-images/recent-pages-tooltip-en.png)
nsIFaviconService で、ある URI に対する favicon の URI を取得できるXULBrowserWindow.setOverLink(link)