SlideShare une entreprise Scribd logo
1  sur  40
Jetpack Library 事始め 2011/01/16 あすかぜ(海津智宏) @asukaze55
自己紹介 http://www.asukaze.net/ RemoveTabs,Tablocという、小さな拡張を公開しています。 Add-on SDK(Jetpack SDK) の開発状況を追いかけて、メモをまとめています。 Mozilla とは関係ないですが、Cassava Editor という CSV エディタを公開しています。 2010/12/01 に転職しました。転職先の会社は、Mozilla とは商売敵かもしれません :) ヒキコモリ体質のため、Mozilla の勉強会等に参加するのは初めてです。皆様よろしくお願いします。
Add-on SDK (Jetpack SDK) とは? 現在開発中の、新しい拡張開発キット。 XULなどの知識を必要とせず、HTML, JavaScript, CSSの知識だけで拡張が開発できるかも。 API は Firefox のバージョンに非依存。拡張を再パッケージングするだけで Firefox の新しいバージョンに対応できるはず。 開発した拡張は再起動不要でインストール/アンインストール可能。 サードパーティが自由に API を追加できる。
History Jetpack Prototype 開発終了 Jetpack SDK Add-on SDK Jetpack Reboot 0.1~0.9 β1 feature-stable 2009/05 2010/03 2010/12
PrototypeとSDK Jetpack Jetpack Jetpack Jetpack Jetpack Jetpack API (Jetpack Prototype 拡張) Core Core Core Firefox Firefox Jetpack Prototype Add-on SDK
Add-on SDK 1.0b1 の API(addon-kit) ページコンテンツの変更 ウィンドウ操作・タブ操作 ウィジェット表示・パネル表示 コンテキストメニュー表示 選択範囲の取得 HTTP リクエスト送信・DOM 操作 クリップボードの取得・更新 アラートメッセージ表示 プライベートブラウジングの開始・終了 ストレージへの情報保存 以上!
Add-on SDK 1.0b1 の API(addon-kit) 標準 API でGreaseMonkey+α のことはできる。 が、XUL ベースの拡張に比べると、できることは限られている。 ブラウザ自体のUIを拡張できるのはウィジェットとコンテキストメニューのみ 低レベル API を使って自作ライブラリを作れば、なんでもできる!
Add-on SDK の低レベル API(api-utils) Components オブジェクトへのアクセス {Cc, Ci, Cu, Cr, Cm, components} = require(“chrome”); tabbrowser要素やwindow要素へのアクセス require(“tab-browser”) require(“window-utils”) API 提供用のヘルパ関数 require(“unload”).ensure() require(“api-utils”).publicConstructor() require(“errors”). catchAndLog()
できることの例 ブラウザ内の任意の場所に XUL 要素を追加できる。 ブラウザ内の任意の場所にイベントリスナを仕掛けられる。
考慮すべきこと 拡張が再起動不要となるようにする Firefox, SDK のバージョンに非依存な API を提供する addon-kit の API と似た使い方を提供する construct/destroy モデル EventEmitterモデル エラー発生時のスタックトレース出力 その他
1) 再起動不要 拡張が無効化/アンインストールされたときに状態を元に戻すのはライブラリの責任。 ブラウザに対する変更を全て覚えておき、終了時に元に戻す。 api-utils内の unload モジュールを使うと、終了時の処理を登録できる。 イベントの伝播は bootstrap.js -> harness -> cuddlefish-> unload という流れ。
unload モジュール function Foo() {    // 変更処理  require("unload").ensure(this); } Foo.prototype = {   unload: function(reason) {     // 復帰処理   } }; function bar() {   // 変更処理 require("unload").when(     function(reason){       // 復帰処理     }); } ensure 関数にオブジェクトを登録する。 終了時には、オブジェクトごとに 1 回ずつ unload 関数が実行される。 when関数にコールバック関数を登録する。 複数回 when を呼び出すと、その回数分 処理が実行される。
MyExtension 2.0 MyExtension 1.0 変えちゃダメ MyLibrary 2.0 2) バージョン非依存 MyLibrary 1.0 変わらないはず addon-kit 2.x addon-kit 1.0b1 変わるかも api-utils 2.x api-utils 1.0b1 変わるかも Firefox 5.x Firefox 4.0
2) バージョン非依存 Firefox の内部構造に依存しない、汎用的な API を提供する 今後の Firefox の変化を先取りし、あらかじめ備えておく E10S 対応!!
E10S (Electrolysis) とは? firefox.exe 「プロセス分離」のコードネーム。 今後、ブラウザ本体と  Web ページのコンテンツと Jetpack 拡張は、それぞれ別プロセスで動作するようになる。 content process ←メッセージ通信-> jetpack process × 直接アクセスはできない
コンテンツプロセスの分離を考慮した API varpageSourceItem = contextMenu.Item({   label: "Edit Page Source", contentScript: 'on("click", function (node, data) {' +                              ' postMessage(document.URL);' +                              '});', onMessage: function (pageURL){ editSource(pageURL);   } }); 別プロセスで動作するスクリプト メッセージ通信 プロセス間で関数オブジェクトは受け渡しできないので、 コンテンツプロセスで動作する部分はスクリプトを文字列もしくは URLで受け渡す。 JSON 形式に変換可能なオブジェクトはメッセージ通信で受け渡し可能。
content モジュール for (window in require("window-utils").windowIterator()) {   require("content").Worker({     window: window, contentScript: 'postMessage("message!");', onMessage: function(data) { console.log(data); }   }); } Worker として登録したスクリプトは対象の window 上で動作する。 オプションは page-mod や context-menu と同様。
Jetpack プロセスの分離を考慮した API cfx run に 「--e10s」オプションを付加することで試行できる。 SDK 本体の対応もこれから。今後の動向に注目。 self-e10s-adapter などは参考になる > cfx run --e10s -b "C:rogram Filesinefieldirefox.exe" … Error: Module 'widget' requires chrome privileges and has no e10s adapter. OK …
いまここ 拡張が再起動不要となるようにする Firefox, SDK のバージョンに非依存な API を提供する addon-kit の API と似た使い方を提供する construct/destroy モデル EventEmitterモデル エラー発生時のスタックトレース出力 その他
3-1) construct/destroy モデル widgets.add(widgets.Widget({   label: …,   image: …,  onClick: … })); widgets.remove(w); widgets.Widget({   label: …,   image: …,  onClick: … }); w.destroy(); 時代は construct/destroy モデル! add/ removeモデルはもう古い! コンストラクタの中で初期化処理まで実行する。 明示的に変更を元に戻す時は destroy メソッドを使う。
コンストラクタ作成時に便利な関数 new ClassName({…}) でも ClassName({…}) だけでもオブジェクトを作れるようにする。 require(“api-utils”).publicConstructor() オプションの内容をチェックする。 require(“api-utils”).validateOptions() Array もしくは スカラ値を受け取るプロパティを作る。 require(“collection”).addCollectionProperty()
3-2) EventEmitterモデル tabs.onOpen =function(){…}; tabs.onReady = function(){…}; tabs.onActivate  =function(){   …}; tabs.onDeactivate  = function(){   …}; tabs.on(‘Open’,function(){…}); tabs.on(‘Ready’, function(){…}); tabs.on(‘Activate’, function(){   …}); tabs.on(‘Deactivate’, function(){   …}); 時代は EventEmitterモデル! onXXXプロパティはもう古い! EventEmitterを使うことで、全てのイベントについて _emit() でのイベント送信、on() でのイベント受信に統一できる。
events モジュール const { EventEmitter } = require("events"); var object = EventEmitter.compose({   constructor: function() {…},   fire: function() { this._emit('event1');   } })(); object.on('event1',  function(){   console.log("Event Fired!"); }); object.fire(); EventEmitter.compose()() は Trait という形のオブジェクトを返す。 _emit() など 「_」から始まるメソッドは、this からしか呼び出せない。
3-3) スタックトレース出力 実行時エラーの発生時、放っておくと何も言わずに処理が終了してしまう。きちんとスタックトレースを出力するように注意する。 EventEmitterを使っていれば、自動的にやってくれるので問題ない。 それ以外でコールバック関数に処理を渡すときは、require(“errors”).catchAndLog() を使う。
いまここ 拡張が再起動不要となるようにする Firefox, SDK のバージョンに非依存な API を提供する addon-kit の API と似た使い方を提供する construct/destroy モデル EventEmitterモデル エラー発生時のスタックトレース出力 その他
配布 https://builder.addons.mozilla.org/にライブラリとして登録する。 が、、、Add-on Builder ではライブラリを検索できない! 編集画面の「Use Library」で名前を検索できるのが唯一の検索手段 今後の発展を祈ります。
参考にすべきライブラリ addon-kit api-utils 本家の API がつい最近までコロコロ変わっていたので、サードパーティで十分な品質のライブラリはまだできていない(と予想。なにぶん検索できないのでよくわかりませんが)。 ベータ版が出て、API が固まりつつある今が参入時?
ライブラリ例
ロケーションバーアイコン API ロケーションバーの中にアイコンを表示するAPI を作ってみる
API 設計 パッケージ名:location-bar モジュール名: location-bar クラス名: Icon コンストラクタ:  label, tooltip, contentURL, onClick プロパティ: なし
使い方 const locationBar = require("location-bar"); const tabs = require("tabs"); locationBar.Icon({   label: "Mozilla website", contentURL: "http://www.mozilla.org/favicon.ico", onClick: function() { tabs.open("http://www.mozilla.org/");   } }); locationBar.Icon({   label: "Google website", contentURL: "http://www.google.com/favicon.ico", onClick: function() { tabs.open("http://www.google.com/");   } });
動作 アイコン追加時: 全てのウィンドウにアイコンを追加する アイコン削除時: 全てのウィンドウからアイコンを削除する ウィンドウ追加時: ウィンドウに全てのアイコンを追加する ウィンドウ削除時、拡張アンロード時: ウィンドウから全てのアイコンを削除する
コンストラクタ:オプションチェック const apiUtils = require("api-utils"); const { EventEmitter } = require("events"); const windowUtils = require("window-utils"); var icons = []; exports.Icon = EventEmitter.compose({   constructor: function Icon(options) {     options = apiUtils.validateOptions(options, {       label:      { is: ["string"] },       tooltip:    { is: ["null", "undefined", "string"] }, contentURL: { is: ["string"] }, onClick:    { is: ["null", "undefined", "function"] }     });
コンストラクタ:初期化     this.id = "locationbaricon:" + require("xpcom").makeUuid().toString(); this._label = options.label; this.tooltip = ("tooltip" in options) ? options.tooltip : this._label this.contentURL = options.contentURL;     if ("onClick" in options) { this.on("click", options.onClick);     } icons.push(this);     for (window in windowUtils.windowIterator()) { addItem(window, this);     }   },
destroy   destroy : function(){ varidx = icons.indexOf(this);     if (idx > -1) { icons.splice(idx, 1);     }     for (window in windowUtils.windowIterator()) { removeItem(window, this);     }   } });
アイコンの追加 function addItem(window, icon) { var doc = window.document; varurlbar = doc.getElementById('urlbar');   if(urlbar) { var button = doc.createElement('toolbarbutton'); button.setAttribute("id", icon.id); button.setAttribute("tooltiptext", icon.tooltip); button.style.listStyleImage = 'url(' + icon.contentURL + ')'; button.addEventListener('click', function() icon._emit('click'), false); vargoButton = doc.getElementById('urlbar-go-button'); urlbar.insertBefore(button, goButton);   } }
アイコンの削除 function removeItem(window, icon) { var doc = window.document; varurlbar = doc.getElementById('urlbar');   if(urlbar) { var button = doc.getElementById(icon.id); urlbar.removeChild(button);   } }
ウィンドウの監視 varwindowManager = {   init: function () { varwindowTracker = new (windowUtils.WindowTracker)(this);     require("unload").ensure(windowTracker);   }, onTrack: function (window) {     for(vari=0; i<icons.length; i++){ addItem(window, icons[i]);     }   }, onUntrack: function (window) {     for(vari=0; i<icons.length; i++){ removeItem(window, icons[i]);     }   } } windowManager.init();
まとめ 自作ライブラリを作ることによって、Jetpackの可能性は大きく広がる。 XUL の構造まで把握できる人がライブラリを作り、一般開発者の人がそのライブラリを活用してサクッと拡張を開発する、といった分担ができるようになることを期待します。
Thank you!

Contenu connexe

Tendances

はじめてのVue.js
はじめてのVue.jsはじめてのVue.js
はじめてのVue.jsKei Yagi
 
アプリコンテスト
アプリコンテストアプリコンテスト
アプリコンテストTomonori Yamada
 
.htaccessによるリダイレクト徹底解説
.htaccessによるリダイレクト徹底解説.htaccessによるリダイレクト徹底解説
.htaccessによるリダイレクト徹底解説Cherry Pie Web
 
QML を用いた YouTube クライアントの作成 - 関東 Qt 勉強会
QML を用いた YouTube クライアントの作成 - 関東 Qt 勉強会QML を用いた YouTube クライアントの作成 - 関東 Qt 勉強会
QML を用いた YouTube クライアントの作成 - 関東 Qt 勉強会Jumpei Ogawa
 
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)Hiroaki KOBAYASHI
 
WordPressプラグイン作成入門
WordPressプラグイン作成入門WordPressプラグイン作成入門
WordPressプラグイン作成入門Yuji Nojima
 
[Ps11]ネットワーク第4回
[Ps11]ネットワーク第4回[Ps11]ネットワーク第4回
[Ps11]ネットワーク第4回Yukiko Kato
 
最強オブジェクト指向言語 JavaScript 再入門!
最強オブジェクト指向言語 JavaScript 再入門!最強オブジェクト指向言語 JavaScript 再入門!
最強オブジェクト指向言語 JavaScript 再入門!Yuji Nojima
 
Knocked out in knockout js
Knocked out in knockout jsKnocked out in knockout js
Knocked out in knockout jsHiroyuki Tashima
 
Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方Yasutaka Kawamoto
 

Tendances (13)

はじめてのVue.js
はじめてのVue.jsはじめてのVue.js
はじめてのVue.js
 
アプリコンテスト
アプリコンテストアプリコンテスト
アプリコンテスト
 
.htaccessによるリダイレクト徹底解説
.htaccessによるリダイレクト徹底解説.htaccessによるリダイレクト徹底解説
.htaccessによるリダイレクト徹底解説
 
Form libraries
Form librariesForm libraries
Form libraries
 
QML を用いた YouTube クライアントの作成 - 関東 Qt 勉強会
QML を用いた YouTube クライアントの作成 - 関東 Qt 勉強会QML を用いた YouTube クライアントの作成 - 関東 Qt 勉強会
QML を用いた YouTube クライアントの作成 - 関東 Qt 勉強会
 
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
 
Try Jetpack
Try JetpackTry Jetpack
Try Jetpack
 
WordPressプラグイン作成入門
WordPressプラグイン作成入門WordPressプラグイン作成入門
WordPressプラグイン作成入門
 
[Ps11]ネットワーク第4回
[Ps11]ネットワーク第4回[Ps11]ネットワーク第4回
[Ps11]ネットワーク第4回
 
Web Component概要
Web Component概要Web Component概要
Web Component概要
 
最強オブジェクト指向言語 JavaScript 再入門!
最強オブジェクト指向言語 JavaScript 再入門!最強オブジェクト指向言語 JavaScript 再入門!
最強オブジェクト指向言語 JavaScript 再入門!
 
Knocked out in knockout js
Knocked out in knockout jsKnocked out in knockout js
Knocked out in knockout js
 
Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方
 

En vedette

Instrumental analysis BY Muhammad Fahad Ansari 12IEEM14
Instrumental analysis BY  Muhammad Fahad Ansari 12IEEM14Instrumental analysis BY  Muhammad Fahad Ansari 12IEEM14
Instrumental analysis BY Muhammad Fahad Ansari 12IEEM14fahadansari131
 
The Little Baker
The Little BakerThe Little Baker
The Little BakerCachi Chien
 
Desertification BY Muhammad Fahad Ansari 12IEEM14
Desertification BY Muhammad Fahad Ansari  12IEEM14Desertification BY Muhammad Fahad Ansari  12IEEM14
Desertification BY Muhammad Fahad Ansari 12IEEM14fahadansari131
 
Surrealism (Jacek Yerka)
Surrealism (Jacek Yerka)Surrealism (Jacek Yerka)
Surrealism (Jacek Yerka)Cachi Chien
 
Ergonomics BY Muhammad Fahad Ansari 12IEEM14
Ergonomics BY  Muhammad Fahad Ansari 12IEEM14Ergonomics BY  Muhammad Fahad Ansari 12IEEM14
Ergonomics BY Muhammad Fahad Ansari 12IEEM14fahadansari131
 
Naïve Art by Juan Borrás II
Naïve Art by Juan Borrás IINaïve Art by Juan Borrás II
Naïve Art by Juan Borrás IICachi Chien
 
Trinity Kings World Leadership: Family Franchising Systems: Creating A Cultur...
Trinity Kings World Leadership: Family Franchising Systems: Creating A Cultur...Trinity Kings World Leadership: Family Franchising Systems: Creating A Cultur...
Trinity Kings World Leadership: Family Franchising Systems: Creating A Cultur...Terrell Patillo
 
Female Soldiers Of The World
Female Soldiers Of The WorldFemale Soldiers Of The World
Female Soldiers Of The WorldNY13itch
 
Beauty by Ramzi Taskiran
Beauty by Ramzi TaskiranBeauty by Ramzi Taskiran
Beauty by Ramzi TaskiranCachi Chien
 
Announcement about annual meeting
Announcement about annual meetingAnnouncement about annual meeting
Announcement about annual meetingZorigoo Bayar
 
Scavenger hunt slideshow
Scavenger hunt slideshowScavenger hunt slideshow
Scavenger hunt slideshowdsauerp6
 
Trinity Kings World Leadership: Family Franchise Systems:The President, The S...
Trinity Kings World Leadership: Family Franchise Systems:The President, The S...Trinity Kings World Leadership: Family Franchise Systems:The President, The S...
Trinity Kings World Leadership: Family Franchise Systems:The President, The S...Terrell Patillo
 
Snow Art by Simon Beck
Snow Art by Simon BeckSnow Art by Simon Beck
Snow Art by Simon BeckCachi Chien
 
OGD for Culture and Art
OGD for Culture and ArtOGD for Culture and Art
OGD for Culture and ArtJohann Höchtl
 
Media biovaxid pharmavoicejune2007-1
Media biovaxid pharmavoicejune2007-1Media biovaxid pharmavoicejune2007-1
Media biovaxid pharmavoicejune2007-1The Navicor Group
 
21st century learner
21st century learner21st century learner
21st century learnerMegan Nebe
 

En vedette (19)

Instrumental analysis BY Muhammad Fahad Ansari 12IEEM14
Instrumental analysis BY  Muhammad Fahad Ansari 12IEEM14Instrumental analysis BY  Muhammad Fahad Ansari 12IEEM14
Instrumental analysis BY Muhammad Fahad Ansari 12IEEM14
 
Ttyrefdg
TtyrefdgTtyrefdg
Ttyrefdg
 
The Little Baker
The Little BakerThe Little Baker
The Little Baker
 
Desertification BY Muhammad Fahad Ansari 12IEEM14
Desertification BY Muhammad Fahad Ansari  12IEEM14Desertification BY Muhammad Fahad Ansari  12IEEM14
Desertification BY Muhammad Fahad Ansari 12IEEM14
 
Surrealism (Jacek Yerka)
Surrealism (Jacek Yerka)Surrealism (Jacek Yerka)
Surrealism (Jacek Yerka)
 
Ergonomics BY Muhammad Fahad Ansari 12IEEM14
Ergonomics BY  Muhammad Fahad Ansari 12IEEM14Ergonomics BY  Muhammad Fahad Ansari 12IEEM14
Ergonomics BY Muhammad Fahad Ansari 12IEEM14
 
Naïve Art by Juan Borrás II
Naïve Art by Juan Borrás IINaïve Art by Juan Borrás II
Naïve Art by Juan Borrás II
 
Trinity Kings World Leadership: Family Franchising Systems: Creating A Cultur...
Trinity Kings World Leadership: Family Franchising Systems: Creating A Cultur...Trinity Kings World Leadership: Family Franchising Systems: Creating A Cultur...
Trinity Kings World Leadership: Family Franchising Systems: Creating A Cultur...
 
Female Soldiers Of The World
Female Soldiers Of The WorldFemale Soldiers Of The World
Female Soldiers Of The World
 
Beauty by Ramzi Taskiran
Beauty by Ramzi TaskiranBeauty by Ramzi Taskiran
Beauty by Ramzi Taskiran
 
Announcement about annual meeting
Announcement about annual meetingAnnouncement about annual meeting
Announcement about annual meeting
 
Scavenger hunt slideshow
Scavenger hunt slideshowScavenger hunt slideshow
Scavenger hunt slideshow
 
Trinity Kings World Leadership: Family Franchise Systems:The President, The S...
Trinity Kings World Leadership: Family Franchise Systems:The President, The S...Trinity Kings World Leadership: Family Franchise Systems:The President, The S...
Trinity Kings World Leadership: Family Franchise Systems:The President, The S...
 
Snow Art by Simon Beck
Snow Art by Simon BeckSnow Art by Simon Beck
Snow Art by Simon Beck
 
~網頁介紹~
~網頁介紹~~網頁介紹~
~網頁介紹~
 
Eissturm
EissturmEissturm
Eissturm
 
OGD for Culture and Art
OGD for Culture and ArtOGD for Culture and Art
OGD for Culture and Art
 
Media biovaxid pharmavoicejune2007-1
Media biovaxid pharmavoicejune2007-1Media biovaxid pharmavoicejune2007-1
Media biovaxid pharmavoicejune2007-1
 
21st century learner
21st century learner21st century learner
21st century learner
 

Similaire à Jetpack Library 事始め

ScaLa+Liftとか
ScaLa+LiftとかScaLa+Liftとか
ScaLa+Liftとかyouku
 
Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略takezoe
 
クラウド時代の並列分散処理技術
クラウド時代の並列分散処理技術クラウド時代の並列分散処理技術
クラウド時代の並列分散処理技術Koichi Fujikawa
 
React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門spring_raining
 
scala+liftで遊ぼう
scala+liftで遊ぼうscala+liftで遊ぼう
scala+liftで遊ぼうyouku
 
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsugSpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsugY Watanabe
 
JavaScript + CSS3を活用して スマートフォンサイト/アプリに 動きを付けてみよう
JavaScript + CSS3を活用して スマートフォンサイト/アプリに 動きを付けてみようJavaScript + CSS3を活用して スマートフォンサイト/アプリに 動きを付けてみよう
JavaScript + CSS3を活用して スマートフォンサイト/アプリに 動きを付けてみようHiroaki Wakamatsu
 
Titanium Mobile
Titanium MobileTitanium Mobile
Titanium MobileNaoya Ito
 
CodeIgniterによるPhwittr
CodeIgniterによるPhwittrCodeIgniterによるPhwittr
CodeIgniterによるPhwittrkenjis
 
Flash Builder4 と FlashCatalyst を使ってみた
Flash Builder4 と FlashCatalyst を使ってみたFlash Builder4 と FlashCatalyst を使ってみた
Flash Builder4 と FlashCatalyst を使ってみたguest0ba46c3
 
Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方Shinsuke Sugaya
 
Ruby向け帳票ソリューション「ThinReports」の開発で知るOSSの威力
Ruby向け帳票ソリューション「ThinReports」の開発で知るOSSの威力Ruby向け帳票ソリューション「ThinReports」の開発で知るOSSの威力
Ruby向け帳票ソリューション「ThinReports」の開発で知るOSSの威力ThinReports
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejsTakayoshi Tanaka
 
LabVIEW NXG Web Module Training Slide
LabVIEW NXG Web Module Training SlideLabVIEW NXG Web Module Training Slide
LabVIEW NXG Web Module Training SlideYusuke Tochigi
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platformToru Yamaguchi
 
お父さんのための実用JavaScriptプログラミング~入門篇~
お父さんのための実用JavaScriptプログラミング~入門篇~お父さんのための実用JavaScriptプログラミング~入門篇~
お父さんのための実用JavaScriptプログラミング~入門篇~Che Renkov
 
Mvc conf session_2_shibamura
Mvc conf session_2_shibamuraMvc conf session_2_shibamura
Mvc conf session_2_shibamuraHiroshi Okunushi
 

Similaire à Jetpack Library 事始め (20)

ScaLa+Liftとか
ScaLa+LiftとかScaLa+Liftとか
ScaLa+Liftとか
 
Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略
 
jQuery超入門編
jQuery超入門編jQuery超入門編
jQuery超入門編
 
クラウド時代の並列分散処理技術
クラウド時代の並列分散処理技術クラウド時代の並列分散処理技術
クラウド時代の並列分散処理技術
 
sveltekit-ja.pdf
sveltekit-ja.pdfsveltekit-ja.pdf
sveltekit-ja.pdf
 
React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門
 
scala+liftで遊ぼう
scala+liftで遊ぼうscala+liftで遊ぼう
scala+liftで遊ぼう
 
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsugSpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
 
JavaScript + CSS3を活用して スマートフォンサイト/アプリに 動きを付けてみよう
JavaScript + CSS3を活用して スマートフォンサイト/アプリに 動きを付けてみようJavaScript + CSS3を活用して スマートフォンサイト/アプリに 動きを付けてみよう
JavaScript + CSS3を活用して スマートフォンサイト/アプリに 動きを付けてみよう
 
Titanium Mobile
Titanium MobileTitanium Mobile
Titanium Mobile
 
CodeIgniterによるPhwittr
CodeIgniterによるPhwittrCodeIgniterによるPhwittr
CodeIgniterによるPhwittr
 
Flash Builder4 と FlashCatalyst を使ってみた
Flash Builder4 と FlashCatalyst を使ってみたFlash Builder4 と FlashCatalyst を使ってみた
Flash Builder4 と FlashCatalyst を使ってみた
 
Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方
 
Ruby向け帳票ソリューション「ThinReports」の開発で知るOSSの威力
Ruby向け帳票ソリューション「ThinReports」の開発で知るOSSの威力Ruby向け帳票ソリューション「ThinReports」の開発で知るOSSの威力
Ruby向け帳票ソリューション「ThinReports」の開発で知るOSSの威力
 
Ext.direct
Ext.directExt.direct
Ext.direct
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs
 
LabVIEW NXG Web Module Training Slide
LabVIEW NXG Web Module Training SlideLabVIEW NXG Web Module Training Slide
LabVIEW NXG Web Module Training Slide
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platform
 
お父さんのための実用JavaScriptプログラミング~入門篇~
お父さんのための実用JavaScriptプログラミング~入門篇~お父さんのための実用JavaScriptプログラミング~入門篇~
お父さんのための実用JavaScriptプログラミング~入門篇~
 
Mvc conf session_2_shibamura
Mvc conf session_2_shibamuraMvc conf session_2_shibamura
Mvc conf session_2_shibamura
 

Dernier

デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 

Dernier (8)

デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 

Jetpack Library 事始め

  • 1. Jetpack Library 事始め 2011/01/16 あすかぜ(海津智宏) @asukaze55
  • 2. 自己紹介 http://www.asukaze.net/ RemoveTabs,Tablocという、小さな拡張を公開しています。 Add-on SDK(Jetpack SDK) の開発状況を追いかけて、メモをまとめています。 Mozilla とは関係ないですが、Cassava Editor という CSV エディタを公開しています。 2010/12/01 に転職しました。転職先の会社は、Mozilla とは商売敵かもしれません :) ヒキコモリ体質のため、Mozilla の勉強会等に参加するのは初めてです。皆様よろしくお願いします。
  • 3. Add-on SDK (Jetpack SDK) とは? 現在開発中の、新しい拡張開発キット。 XULなどの知識を必要とせず、HTML, JavaScript, CSSの知識だけで拡張が開発できるかも。 API は Firefox のバージョンに非依存。拡張を再パッケージングするだけで Firefox の新しいバージョンに対応できるはず。 開発した拡張は再起動不要でインストール/アンインストール可能。 サードパーティが自由に API を追加できる。
  • 4. History Jetpack Prototype 開発終了 Jetpack SDK Add-on SDK Jetpack Reboot 0.1~0.9 β1 feature-stable 2009/05 2010/03 2010/12
  • 5. PrototypeとSDK Jetpack Jetpack Jetpack Jetpack Jetpack Jetpack API (Jetpack Prototype 拡張) Core Core Core Firefox Firefox Jetpack Prototype Add-on SDK
  • 6. Add-on SDK 1.0b1 の API(addon-kit) ページコンテンツの変更 ウィンドウ操作・タブ操作 ウィジェット表示・パネル表示 コンテキストメニュー表示 選択範囲の取得 HTTP リクエスト送信・DOM 操作 クリップボードの取得・更新 アラートメッセージ表示 プライベートブラウジングの開始・終了 ストレージへの情報保存 以上!
  • 7. Add-on SDK 1.0b1 の API(addon-kit) 標準 API でGreaseMonkey+α のことはできる。 が、XUL ベースの拡張に比べると、できることは限られている。 ブラウザ自体のUIを拡張できるのはウィジェットとコンテキストメニューのみ 低レベル API を使って自作ライブラリを作れば、なんでもできる!
  • 8. Add-on SDK の低レベル API(api-utils) Components オブジェクトへのアクセス {Cc, Ci, Cu, Cr, Cm, components} = require(“chrome”); tabbrowser要素やwindow要素へのアクセス require(“tab-browser”) require(“window-utils”) API 提供用のヘルパ関数 require(“unload”).ensure() require(“api-utils”).publicConstructor() require(“errors”). catchAndLog()
  • 9. できることの例 ブラウザ内の任意の場所に XUL 要素を追加できる。 ブラウザ内の任意の場所にイベントリスナを仕掛けられる。
  • 10. 考慮すべきこと 拡張が再起動不要となるようにする Firefox, SDK のバージョンに非依存な API を提供する addon-kit の API と似た使い方を提供する construct/destroy モデル EventEmitterモデル エラー発生時のスタックトレース出力 その他
  • 11. 1) 再起動不要 拡張が無効化/アンインストールされたときに状態を元に戻すのはライブラリの責任。 ブラウザに対する変更を全て覚えておき、終了時に元に戻す。 api-utils内の unload モジュールを使うと、終了時の処理を登録できる。 イベントの伝播は bootstrap.js -> harness -> cuddlefish-> unload という流れ。
  • 12. unload モジュール function Foo() { // 変更処理 require("unload").ensure(this); } Foo.prototype = { unload: function(reason) { // 復帰処理 } }; function bar() { // 変更処理 require("unload").when( function(reason){ // 復帰処理 }); } ensure 関数にオブジェクトを登録する。 終了時には、オブジェクトごとに 1 回ずつ unload 関数が実行される。 when関数にコールバック関数を登録する。 複数回 when を呼び出すと、その回数分 処理が実行される。
  • 13. MyExtension 2.0 MyExtension 1.0 変えちゃダメ MyLibrary 2.0 2) バージョン非依存 MyLibrary 1.0 変わらないはず addon-kit 2.x addon-kit 1.0b1 変わるかも api-utils 2.x api-utils 1.0b1 変わるかも Firefox 5.x Firefox 4.0
  • 14. 2) バージョン非依存 Firefox の内部構造に依存しない、汎用的な API を提供する 今後の Firefox の変化を先取りし、あらかじめ備えておく E10S 対応!!
  • 15. E10S (Electrolysis) とは? firefox.exe 「プロセス分離」のコードネーム。 今後、ブラウザ本体と Web ページのコンテンツと Jetpack 拡張は、それぞれ別プロセスで動作するようになる。 content process ←メッセージ通信-> jetpack process × 直接アクセスはできない
  • 16. コンテンツプロセスの分離を考慮した API varpageSourceItem = contextMenu.Item({ label: "Edit Page Source", contentScript: 'on("click", function (node, data) {' + ' postMessage(document.URL);' + '});', onMessage: function (pageURL){ editSource(pageURL); } }); 別プロセスで動作するスクリプト メッセージ通信 プロセス間で関数オブジェクトは受け渡しできないので、 コンテンツプロセスで動作する部分はスクリプトを文字列もしくは URLで受け渡す。 JSON 形式に変換可能なオブジェクトはメッセージ通信で受け渡し可能。
  • 17. content モジュール for (window in require("window-utils").windowIterator()) { require("content").Worker({ window: window, contentScript: 'postMessage("message!");', onMessage: function(data) { console.log(data); } }); } Worker として登録したスクリプトは対象の window 上で動作する。 オプションは page-mod や context-menu と同様。
  • 18. Jetpack プロセスの分離を考慮した API cfx run に 「--e10s」オプションを付加することで試行できる。 SDK 本体の対応もこれから。今後の動向に注目。 self-e10s-adapter などは参考になる > cfx run --e10s -b "C:rogram Filesinefieldirefox.exe" … Error: Module 'widget' requires chrome privileges and has no e10s adapter. OK …
  • 19. いまここ 拡張が再起動不要となるようにする Firefox, SDK のバージョンに非依存な API を提供する addon-kit の API と似た使い方を提供する construct/destroy モデル EventEmitterモデル エラー発生時のスタックトレース出力 その他
  • 20. 3-1) construct/destroy モデル widgets.add(widgets.Widget({ label: …, image: …, onClick: … })); widgets.remove(w); widgets.Widget({ label: …, image: …, onClick: … }); w.destroy(); 時代は construct/destroy モデル! add/ removeモデルはもう古い! コンストラクタの中で初期化処理まで実行する。 明示的に変更を元に戻す時は destroy メソッドを使う。
  • 21. コンストラクタ作成時に便利な関数 new ClassName({…}) でも ClassName({…}) だけでもオブジェクトを作れるようにする。 require(“api-utils”).publicConstructor() オプションの内容をチェックする。 require(“api-utils”).validateOptions() Array もしくは スカラ値を受け取るプロパティを作る。 require(“collection”).addCollectionProperty()
  • 22. 3-2) EventEmitterモデル tabs.onOpen =function(){…}; tabs.onReady = function(){…}; tabs.onActivate =function(){ …}; tabs.onDeactivate = function(){ …}; tabs.on(‘Open’,function(){…}); tabs.on(‘Ready’, function(){…}); tabs.on(‘Activate’, function(){ …}); tabs.on(‘Deactivate’, function(){ …}); 時代は EventEmitterモデル! onXXXプロパティはもう古い! EventEmitterを使うことで、全てのイベントについて _emit() でのイベント送信、on() でのイベント受信に統一できる。
  • 23. events モジュール const { EventEmitter } = require("events"); var object = EventEmitter.compose({ constructor: function() {…}, fire: function() { this._emit('event1'); } })(); object.on('event1', function(){ console.log("Event Fired!"); }); object.fire(); EventEmitter.compose()() は Trait という形のオブジェクトを返す。 _emit() など 「_」から始まるメソッドは、this からしか呼び出せない。
  • 24. 3-3) スタックトレース出力 実行時エラーの発生時、放っておくと何も言わずに処理が終了してしまう。きちんとスタックトレースを出力するように注意する。 EventEmitterを使っていれば、自動的にやってくれるので問題ない。 それ以外でコールバック関数に処理を渡すときは、require(“errors”).catchAndLog() を使う。
  • 25. いまここ 拡張が再起動不要となるようにする Firefox, SDK のバージョンに非依存な API を提供する addon-kit の API と似た使い方を提供する construct/destroy モデル EventEmitterモデル エラー発生時のスタックトレース出力 その他
  • 26. 配布 https://builder.addons.mozilla.org/にライブラリとして登録する。 が、、、Add-on Builder ではライブラリを検索できない! 編集画面の「Use Library」で名前を検索できるのが唯一の検索手段 今後の発展を祈ります。
  • 27. 参考にすべきライブラリ addon-kit api-utils 本家の API がつい最近までコロコロ変わっていたので、サードパーティで十分な品質のライブラリはまだできていない(と予想。なにぶん検索できないのでよくわかりませんが)。 ベータ版が出て、API が固まりつつある今が参入時?
  • 30. API 設計 パッケージ名:location-bar モジュール名: location-bar クラス名: Icon コンストラクタ: label, tooltip, contentURL, onClick プロパティ: なし
  • 31. 使い方 const locationBar = require("location-bar"); const tabs = require("tabs"); locationBar.Icon({ label: "Mozilla website", contentURL: "http://www.mozilla.org/favicon.ico", onClick: function() { tabs.open("http://www.mozilla.org/"); } }); locationBar.Icon({ label: "Google website", contentURL: "http://www.google.com/favicon.ico", onClick: function() { tabs.open("http://www.google.com/"); } });
  • 32. 動作 アイコン追加時: 全てのウィンドウにアイコンを追加する アイコン削除時: 全てのウィンドウからアイコンを削除する ウィンドウ追加時: ウィンドウに全てのアイコンを追加する ウィンドウ削除時、拡張アンロード時: ウィンドウから全てのアイコンを削除する
  • 33. コンストラクタ:オプションチェック const apiUtils = require("api-utils"); const { EventEmitter } = require("events"); const windowUtils = require("window-utils"); var icons = []; exports.Icon = EventEmitter.compose({ constructor: function Icon(options) { options = apiUtils.validateOptions(options, { label: { is: ["string"] }, tooltip: { is: ["null", "undefined", "string"] }, contentURL: { is: ["string"] }, onClick: { is: ["null", "undefined", "function"] } });
  • 34. コンストラクタ:初期化 this.id = "locationbaricon:" + require("xpcom").makeUuid().toString(); this._label = options.label; this.tooltip = ("tooltip" in options) ? options.tooltip : this._label this.contentURL = options.contentURL; if ("onClick" in options) { this.on("click", options.onClick); } icons.push(this); for (window in windowUtils.windowIterator()) { addItem(window, this); } },
  • 35. destroy destroy : function(){ varidx = icons.indexOf(this); if (idx > -1) { icons.splice(idx, 1); } for (window in windowUtils.windowIterator()) { removeItem(window, this); } } });
  • 36. アイコンの追加 function addItem(window, icon) { var doc = window.document; varurlbar = doc.getElementById('urlbar'); if(urlbar) { var button = doc.createElement('toolbarbutton'); button.setAttribute("id", icon.id); button.setAttribute("tooltiptext", icon.tooltip); button.style.listStyleImage = 'url(' + icon.contentURL + ')'; button.addEventListener('click', function() icon._emit('click'), false); vargoButton = doc.getElementById('urlbar-go-button'); urlbar.insertBefore(button, goButton); } }
  • 37. アイコンの削除 function removeItem(window, icon) { var doc = window.document; varurlbar = doc.getElementById('urlbar'); if(urlbar) { var button = doc.getElementById(icon.id); urlbar.removeChild(button); } }
  • 38. ウィンドウの監視 varwindowManager = { init: function () { varwindowTracker = new (windowUtils.WindowTracker)(this); require("unload").ensure(windowTracker); }, onTrack: function (window) { for(vari=0; i<icons.length; i++){ addItem(window, icons[i]); } }, onUntrack: function (window) { for(vari=0; i<icons.length; i++){ removeItem(window, icons[i]); } } } windowManager.init();
  • 39. まとめ 自作ライブラリを作ることによって、Jetpackの可能性は大きく広がる。 XUL の構造まで把握できる人がライブラリを作り、一般開発者の人がそのライブラリを活用してサクッと拡張を開発する、といった分担ができるようになることを期待します。