このサイトの記事更新は2019年11月に終了されました。過去記事アーカイブを公開しています。

投稿されたすべてのトピック

PR_MIN()、PR_MAX()マクロの利用から、NS_MIN()、NS_MAX()インライン関数へ

これまでGeckoの開発ではPR_MIN()PR_MAX()マクロを利用して、最小値、最大値を求めるようにしていましたが、今後はNS_MIN()NS_MAX()インライン関数を利用するようにするようです。

現在、置き換え作業が進行中です

PR_MIN()、PR_MAX()では、パフォーマンスに問題がでるミスが発生しやすい、というのがその原因のようです。

レビュー中のパッチがある方は注意しましょう。

12月19日(土)に Mozilla 勉強会を開催します

Firefox の拡張機能や Jetpack などのアドオン、あるいはアプリケーションプラットフォームとしての Mozilla の技術についての Mozilla 勉強会を 12 月19日に開催することになりました。

/events/workshop01/

今話題の Jetpack のについて一番アクティブに情報発信されている con_mame さんと、拡張機能開発の記事を連載したりインスタントメッセンジャーを拡張機能で開発されている Gemma さん をお招きしての勉強会になります。

時間割など詳しくは勉強会のページをご覧ください。ご参加いただける方は ATND にて参加登録をお願いします。また、Lightning Talk の発表者も募集しております。

意見や要望などなど

2009/12/19 に行われた第1回 Mozilla 勉強会において、 Jetpack に対する意見や要望、問題点などについて活発な議論がなされました。議事録をカテゴリごとに少しまとめた形でここに報告いたします。さらなるご提案やご意見などがございましたら、コメント欄、あるいはこのページを直接編集して書き加えてくださいませ。尚、ここで得られたご意見をもとにして、来年早々 Jetpack 開発チームへフィードバックしに行きます!!

Jetpack開発に対して

バグ

  • Bespin :日本語が入力できない
  • Firebug が 1.4 以上だとうまく動かない
    • うまくエラー補足ができない
  • Menu の上書きで、挙動がおかしくなるときがある
  • Settings の Manifest は、storage.settings を import する前に書かなければならない
    • 感覚的には import が頭にありそうだし
  • Jetpack Gallery :ソースコードのサニタイズがあやしい
  • Jetpack のアップデートアルゴリズムがへぼすぎる
    • 現状はコードを全て比較しているだけ
    • >> MD5ハッシュの比較でいいんじゃね?

セキュリティ

  • Jetpack Gallery:警告画面がなくなってしまった
  • 自動更新の怖さ
    • Jetpack Gallery にも言えること

この API は絶対欲しい!

  • パスワード系入力
    • パスワードマネージャとの連携
    • 以下のようにパスワードマネージャから情報を引っ張ってこれるAPI
      let pass = jetpack.password.get("example.com")
      // pass[0].user == "my name"
      // pass[0].password == "password"
    • 逆に、パスワードマネージャにパスワードを追加するAPIが必要か?
    • パスワードを削除するAPIは?
  • ツリースタイルタブを実現するためのAPIが欲しい
  • 拡張と Jetpack Feature 、および Feature 同士の連携
    • 双方でメッセージを送り会える仕組みが欲しい
      • アイディア1:nsIObserverServiceをモデルにしたAPI
        <受け取り側>
         jetpack.message.listen(
         'onTreeItemCreated',
         function(aData) {
         return <><button>X</button></>;
         }
         );
         <送出側>
         let myItem = '';
         let responses = jetpack.message.send('onItemCreated', 'foo');
         for each (r in responses) {
         myItem += r;
         }
         実装するときは、nsIObserverServeiceを使うといいんじゃないか?
         (Mozilla内部のメッセージは拾わない・拾えないように制限する必要あり)
      • アイディア2:DOMEventをモデルにしたAPI
  • about:xxx を自由に追加するAPI
  • 独自のプロトコルハンドラを定義するAPI
  • アドブロックのような、Firefox自身が行っている通信の内容に割り込む・フックを掛けるAPI
  • 今XPCOMを使わないと出来ない・特権が必要な機能に対応するAPIは一通り欲しい?
    • 少なくともFrozenになっているインタフェースに対応するAPIは優先して取り込んでもらいたい
  • Google Chrome用のAPIと互換性のあるAPI
    Google Chrome用拡張機能をそのまま移植できるようにする>>開発者の流出を防げる?
  • サブメニューをもう少し簡単に作りたい
  • pageModsの適用対象について、例外を指定したい
  • 外部スクリプトを簡単に読み込むAPI
    Components.utils.import()やmozIJSSubScriptLoaderみたいな
  • setting API で設定できる少ない

APIポリシー

  • HTML5 で出来ることは HTML5 でやる。独自のAPIは作らない。
  • XPConnectは使えないようにした方がいいんじゃないのか?
    使えるようにしてしまうと
    =>それを使ったFeatureが出てくる
    =>普及する
    =>ユーザがそれに依存した生活を送るようになる
    =>今更XPConnectを禁止できなくなる
    というシナリオが考えられるので、今のうちに禁止した方がいいのでは?
  • rawも使えないようにした方がいいんじゃないの?
    使えるようにしてしまうと
    =>それを使ったFeatureが出てくる
    =>普及する
    =>ユーザがそれに依存した生活を送るようになる
    =>今更rawを禁止できなくなる
    というシナリオが考えられるので、今のうちに禁止した方がいいのでは?
  • API、ライブラリのバージョンについて
    バージョン指定してAPIやライブラリを読み込む機能 like gem of Ruby
    後方互換性を損なう変更をAPIに加えたくなる時はいつか絶対に来るので今から備えておいた方がよい
  • Firefox本体のUIの文法、作法から外れるような事も実現できるようにしていいのでは?
    例:Backボタンの挙動を乗っ取るAPIなど。
    Operaの「巻き戻し(Rewind)」を実現しようと思ったら、Backボタンの挙動を完全に乗っ取らないといけない。
    そういうこともできるように自由度を高く。
    APIとのバランスか。
  • fuel の二の舞にはならないように
    • 中途半端な機能しかなかった
    • メモリリークがひどかった
  • イノベーションにAPIは必要なのか?
    Greasemonkeyは貧弱なAPIしかないのにあれだけイノベーションが起こった
    Jetpackもそのくらいでいいのかもしれない

ドキュメント

  • 解説記事が少ない
  • アドオン開発者がJetpackをさわるまでのパスを作る。
    アドオンではこうやってたところがJetpackではこうなります。
    =>むしろ、全然別物として作り始めた方がわかりやすいという現実はある。
  • ドキュメント場所に一貫性が無いっつー話
    フリーズしたAPIからどんどんMDCに移動して!

Jetpack拡張について

  • 内蔵エディタによる開発はめんどくさい
    • いちいちタブを切り替える必要がある
    • 外部エディタが使えれば問題がない
  • エディタおよびインストーラ含め開発効率が悪い
    ※具体的な案が欲しいっすね

Jetpackギャラリーについて

  • 一度「削除」すると、同じ名前ではFeatureを登録できない
    =>セキュリティ的には、できなくていいんじゃないか
    Twitterで、すでに退会したユーザと同じ名前でアカウントを取り直して乗っ取るということができてしまう。
  • AMOでできることはできるように
    • レビューシステムによる安全性の担保
    • 対応バージョン判別(APIバージョン?)
    • セキュアな自動アップデート

Jetpack Featureのパッケージング、インストールおよびアップデートについて

  • インストール・アップデートにおけるセキュリティ関連
    現状では、新しかったら問答無用でインストールされてしまう。
    悪意のある開発者が、無害なFeatureを登録した後アップデートでマルウェアを登録したら、ユーザの環境にそれが勝手に貼ってしまう!
  • セキュリティのモデル
  • マニフェスト
    • バージョンアップの仕組み
    • 外部スクリプトとの連携
  • パッケージ化
    画像、HTMLなどをパッケージングして提供できるように。
    一つのJSファイルの中に全部置かなきゃ行けないのはつらい。

みらい

  • Jetpack の位置づけがあいまいだ
    メインになるかならないか。はっきりして欲しい。開発者が本気で取り組めない。
  • グリースモンキーとの共存は? 完全に置き換えるの?
    • むしろ、GMスクリプトを全く修正なしに動かせるようにしていいのでは?
    • そういう意味では Google Chrome 拡張も?
  • ユーザがプログラムを書ける時代がやってくるか?
    • エディタを賢く
      • コード補完
      • リファレンス
      • ローカライズ
      • 国際化
    • ビジュアルプログラミングは?
  • 外部アプリケーションとの連携(iTunes)って本当に必要か?
    • 必要だとしたらどんなAPIが必要か?
    • OS化してきているブラウザにとっては、アプリ連携は必須なのかもしれない?
  • アドオンでJetpackのAPIを追加できるようにしてほしい
  • プロポーサルの方法
    プロポーサルを出す文化が日本には無い

    • バグトラックみたいなシステムがあればやりやすい
    • 日本でそういうチームを作る!

UI

参考URL: https://developer.mozilla.org/en/Jetpack/UI

Menu

参考URL: https://developer.mozilla.org/en/Jetpack/UI/Menu
参考URL: https://wiki.mozilla.org/Labs/Jetpack/JEP/14

ツールメニューやコンテキストメニューなどのメニュー群を扱います。

ピクチャ 6



※メニューAPIは全て確定ではないので、以下のようにインポートしてから利用します。

jetpack.future.import("menu");

コード例:

jetpack.future.import("menu");
jetpack.menu.context.page.on("a").add(function (context) ({
  label: "Jetpacker!",
  command: function () console.log("押したのは::"+context.node.href)
}));

Constructors

空のメニューを作る : jetpack.Menu()

var menu = new jetpack.Menu();

アイテム付きでメニューを作る : jetpack.Menu(menuitems)

var menu = new jetpack.Menu(["メニュー1", "メニュー2", "メニュー3"]);

プロパティ付きでメニューを作る : jetpack.Menu(properties)

var menu = new jetpack.Menu({
        label: "sample menus",
        beforeShow: function (menu) {
          console.info("表示の前に呼ばれますわ。");  
        }  
}) ;

上記メニューを「ツール」メニューに装着

ピクチャ 2

var menu = new jetpack.Menu({
        label: "sample menus",
        beforeShow: function (menu) {
          console.info("表示の前に呼ばれますわ。");  
        }  
}) ;
jetpack.menu.tools.add(menu);

Properties

メニュー表示前に呼ばれます : beforeShow

以下は、メニューのラベルを現在時刻にするサンプルです。

var menu = new jetpack.Menu({
        beforeShow: function (menu) {
            menu.set(new Date().toString());
        }  
}) ;

メニューが非表示になる前に呼ばれます : beforeHide

var menu = new jetpack.Menu({
        beforeHide: function (menu) {
            console.info("メニューが消される前に呼ばれるっす。");
        }  
}) ;

メニューの表示状態です : isShowing

if (menu.isShowing == true) {
    //表示中
} else {
    //非表示中
}

メニューの持つアイテム配列 : items

console.info("メニューが持つアイテム数は:"+menu.items.length);

Methods

メニューの末尾にアイテムを追加します : add(items)

例では「ファイル」メニューに追加しています。

ピクチャ 3

var items = ["追加1", "追加2"];
jetpack.menu.file.add(items);

メニューから全てのアイテムを削除します : clear()

menu.clear();

:contextOn(node)

メニューを非表示にします:hide()

menu.hide();

メニューアイテムを引数のtargetの上に追加します:insertBefore(newItems, target)

ピクチャ 4

//「オフライン作業」の上に item1 を追加
var items1 = ["item1"];
jetpack.menu.file.insertBefore(items1, "オフライン作業");

//正規表現で id や xulid を指定できるとあるんだけど、うまくいかないなぁ。
//var items2 = ["item2"];
//jetpack.menu.file.insertBefore(items2, /menu_newNavigator/);

//指定したインデックスにアイテムを挿入
//0 は一番上
var items3 = ["item3"];
jetpack.menu.file.insertBefore(items3, 0);
//マイナスは一番下のメニューからの順番(一番下に入れる場合は add を使う)
var items4 = ["item4"];
jetpack.menu.file.insertBefore(items4, -1);

target で指定されたアイテムを返します:item(target)

//0番目のアイテム、つまり一番上のアイテムを取る
var item = jetpack.menu.file.item(0);

:popupOn(node)

target で指定したアイテムをメニューから取り外します:remove(target)

//一番上のアイテムを取り外す
jetpack.menu.file.remove(0);

target で指定したアイテムと newItems を入れ替えます:replace(target, newItems)

サンプルでは オフライン作業 と item1 item2 を入れ替えます。

ピクチャ 5

var items = ["item1", "item2"];
jetpack.menu.file.replace("オフライン作業", items);

メニューをリセットします:reset()

//Jetpack で操作する前の状態に戻ります
jetpack.menu.file.reset();

//Jetpack で作った menu に対しては clear() と同じ意味を持ちます。

メニューのアイテムを items に差し替える:set(items)

var items = ["item1", "item2"];
menu.set(items);

メニューを即座に表示します:show(anchorNode)

//anchorNode は DOM NODE あるいは NODE をくるんだ jQuery オブジェクトが入ります。
menu.show(anchorNode);

Menuitems

メニューに追加できるアイテムの属性例です。

ピクチャ 6

var item = {
  command: function() {
    //このメニューアイテムが選ばれたときに、この function が呼ばれます。
    console.info("ここ");
  }, 
  disabled: true, //false であれば有効になります。
  icon: "/wp-content/themes/modest/images/footer-logo.png", //メニューアイコン
  label: "アイテムのラベル",
  mnemonic: "A", //ショートカットキー
  xulId: "sample_menu_item1" //xulid を指定できます
}

var separator = {
    type: "separator" // ここに入れられるのは "separator" のみ。これが指定されるとセパレータになる。
}

var item2 = {
  disabled: false,
  icon: "/wp-content/themes/modest/images/footer-logo.png", //メニューアイコン
  label: "アイテムのラベル2"
}

jetpack.menu.file.add(item);
jetpack.menu.file.add(separator);
jetpack.menu.file.add(item2);

Menu bar menus

定義されている menu 群

jetpack.menu.file

ピクチャ 7

var items = ["Jetpacker!"];
jetpack.menu.file.add(items);

jetpack.menu.edit

ピクチャ 8

var items = ["Jetpacker!"];
jetpack.menu.edit.add(items);

jetpack.menu.view

ピクチャ 9

var items = ["Jetpacker!"];
jetpack.menu.view.add(items);

jetpack.menu.history

ピクチャ 10

var items = ["Jetpacker!"];
jetpack.menu.history.add(items);

jetpack.menu.bookmarks

ピクチャ 11

var items = ["Jetpacker!"];
jetpack.menu.bookmarks.add(items);

jetpack.menu.tools

ピクチャ 12

var items = ["Jetpacker!"];
jetpack.menu.tools.add(items);

System

参考URL: https://developer.mozilla.org/en/Jetpack/System

Clipboard

クリップボードを扱うことができます。

コード例:

//ロード
jetpack.future.import("clipboard");
//クリップボードに文字列をいれます
jetpack.clipboard.set("クリップボードに入れ!");
//クリップボードに入っている文字列を取り出します
var message = jetpack.clipboard.get();
console.info(message);//ここでは"クリップボードに入れ!"が表示されるはず。

Visual Effects

Devices

iPod, や USB devices など、周辺デバイスとの連携も視野においております。

Storage

参考URL: https://developer.mozilla.org/en/Jetpack/Storage

Simple Storage

参考URL: https://wiki.mozilla.org/Labs/Jetpack/JEP/11
※将来、仕様が変更する可能性があります。

データを保持するシンプルなストレージです。

利用例

データの保持

//simple storage をインポートする
jetpack.future.import("storage.simple");
var myStorage = jetpack.storage.simple;
//配列を fribblefrops として保持
myStorage.fribblefrops = [1, 3, 3, 7];
//連想配列を heimelfarbs として保持
myStorage.heimelfarbs = { bar: "baz" };

データの取り出し

var myStorage = jetpack.storage.simple;
myStorage.fribblefrops.forEach(function (elt) console.log(elt));
var bar = myStorage.heimelfarbs.bar;

Methods

データを保存する: sync

Simple Strorage では自動的にデータを保存(ディスクへの書き出しなどを)していますが、明示的にこれを行いたい場合はこのメソッドを使います。

var myStorage = jetpack.storage.simple;
myStorage.sync();

データを読み込む: open

データを明示的に読み込みたい場合このメソッドを使います。

var myStorage = jetpack.storage.simple;
myStorage.open();

File Access

ファイルI/O

Settings

参考URL: https://wiki.mozilla.org/Labs/Jetpack/JEP/24
参考URL; https://developer.mozilla.org/en/Jetpack/Storage/Settings
※将来、仕様が変更する可能性があります。

ユーザの設定情報などを保持します。設定画面は 「about:jetpack」 →「Installed Feature」内で インストールされている Feature の一覧を見ることができますが、各 Feature の横に 「Settings」というボタンがあります。これを押下すれば、設定画面が出てきます。
※設定項目の無い Feature では出現しません。それなら、ボタン自体、出さない方がいいっすね。
スクリーンショット:

ピクチャ 5

設定できる値は、

  • テキスト: text
  • パスワード: password
  • 真偽値: boolean
  • 数値: number
  • 範囲: range
  • 選択: member

です。

先のスクリーンショットのソースコードを示します。

var manifest = {
  settings: [
    {
      name: "sample_group",
      type: "group",
      label: "sample_group",
      settings: [
        { name: "username", type: "text", label: "Username" },
        { name: "password", type: "password", label: "Password" }
      ]
    },
    { name: "text_value", type: "text", label: "text_label", default: "default text" },
    { name: "password_value", type: "password", label: "password_label"},
    { name: "boolean_value", type: "boolean", label: "boolean_label", default: true},
    { name: "number_value", type: "number", label: "number_label", default: 2},
    { name: "range_value", type: "range", label: "range_label", min: 0, max: 10, default: 5 },
    { name: "member_value", type: "member", label: "member_label", set: ["member1", "member2", "member3"] }
  ]
};
jetpack.future.import("storage.settings");

//値は以下のようにとります
console.info("VALUE:"+jetpack.storage.settings.sample_group.username);
console.info("VALUE:"+jetpack.storage.settings.text_value);

また、実際に上の Settings を試す Jetpack Feature を作りました。ダウンロードしてお試しください。

Basics

参考URL: https://developer.mozilla.org/en/Jetpack/Basics

Class Console

エラーコンソールに情報を書き込めます。エラーコンソールは、「ツール」→「エラーコンソール」で表示できます。

ピクチャ 1

コード例:

console.log("Hello World!");

log のほかに、info, error, exception などがあります。

console.info("Hello World!");

Class Notifications

notification を表示します。

ピクチャ 3

コード例:

jetpack.notifications.show("jetpacker!");

※OSXにて Unable to display notification がエラーコンソールに出て、使えないことがあります。OSXの場合は、Growlというのを利用しているようで、これをインストールしていないとエラーが出ます。インストールし、Growl を起動、その後、Firefox を再起動すれば有効になります。

タイトルやボディ、アイコンも変更できる

ピクチャ 4

jetpack.notifications.show({title: "Jetpack title", body: "BODYだよ", icon:"/images/jetpack.ico"});

Class Tabs

Firefox のタブを扱うクラスです。タブにページを開いたり、タブ数の取得やフォーカスをはじめ、ドキュメントの読み込み完了やフォーカスが移った場合のイベントを取得することができます。

ピクチャ 2

Properties

開いているタブの数を知る : length

var length = jetpack.tabs.length;
console.info("タブ数="+length);

閲覧中のタブを得る : focused

var currentTab = jetpack.tabs.focused;
var currentDocument = currentTab.contentDocument;
console.info("閲覧中のドキュメントタイトルは:"+currentDocument.title);

Events

タブ内のドキュメントの読み込み完了を得る : onReady

jetpack.tabs.onReady(function(targetDocument) {
  if (targetDocument.defaultView.frameElement) {
    //ドキュメント内に存在した frame か iframe 内のドキュメント完了はこちらで取得
    return;
  }
  console.info("読み込み完了したドキュメントのタイトルは:"+targetDocument.title);
});

タブのフォーカスの移動を得る : onFocus

jetpack.tabs.onFocus(function() {
  var currentTab = jetpack.tabs.focused;
  var currentDocument = currentTab.contentDocument;
  console.info("フォーカスされたドキュメントのタイトルは:"+currentDocument.title);
});

Methods

新しいタブでドキュメントを開く : open

jetpack.tabs.open("http://www.example.com");

APIリファレンス

MDC  https://developer.mozilla.org/en/Jetpack で公開されているドキュメントのAPIそのものというより、どのように使うかにフォーカスをあてたページにしたい。
参考URL: https://developer.mozilla.org/ja/Jetpack 日本語訳

Basics

console、notification、tab など、基本的なクラス群です。

System

clipboard、visual effect、device など OS との連携を実現します。

Multimedia

Audio、Video、Music などマルチメディアをサポートします。

Storage

Feature で利用するデータを保持するための Simple Storage やユーザの設定データを保持する Settings などが利用できます。

Extenders

Meta

UI

Jetpack で利用できる UI 関連をまとめています。

Content

自分のサイトで配布しているアドオンを AMO に登録する

Mozilla Add-ons Blog で伝えられているとおり、 Add-ons for Firefox のサイト(以下AMO)に、自分のサイトで配布しているアドオンを登録することができるようになりました。

どういう意味かといいますと、 通常 AMO にアドオンを登録するには、アドオンのファイルをアップロードして承認を得てようやく公開という手順を踏む必要がありますが、今後は新たに、アドオンの配布は自分のサイトで行いつつも紹介ページのみを AMO に掲載するという運用が可能となったということです。

新しい方式で登録したアドオンは、通常のアドオンと同様に紹介ページにスクリーンショットを掲載したり、レビューやタグ付け、コレクションへの追加などもできます。逆に、インストーラのファイルを AMO 上に置いたり、バージョン情報を更新したりすることはできません。また、アドオンマネージャから検索することもできません。

さっそく私も FoxAge2ch という拡張機能を新しい方式で AMO に登録してみました。

foxage2ch-on-amo

FoxAge2ch は2ちゃんねるユーザ向けの拡張機能=ほぼ日本人限定ですので、 AMO での配布はふさわしくないと思い、自分のサイトで配布していますが、今後は AMO から探し出すことも可能となります。

ただし、なぜか AMO の検索バーに「foxage2ch」と入力しても「該当するアドオンはありません。」と表示されてしまいました。なぜか「検索オプション」でバージョンとプラットフォームを「すべて」にして検索したら、無事にヒットしました。