Hatena::ブログ(Diary)

vivid memo このページをアンテナに追加 RSSフィード

vivid code というサイトのメモ代わりに記事を書いていました。
現在ははてなブログに移行し、「ひだまりソケットは壊れない」 というブログで記事を書いています。 はてな id も id:nobuoka に変更しました。

2009-04-29

AppLauncher ver.0.1 〜 Firefox 拡張機能作り方メモ 〜

この記事の内容は古くなってしまっていて、最近だと別の Firefox 拡張の開発方法もある (もちろんこの記事に書かれている方法でも開発できます) ので、2013 年における Firefox 拡張機能の開発方法について別の記事にまとめました。 そちらもあわせてご覧ください。

前々から Firefox の拡張機能 (extension: アドオン add-on の一種) を作りたいなーと思っていたので、今回実行に移すことにしました。 作成する拡張機能は、コンテキストメニューから外部アプリケーションを起動するというもの。 ありがちですけどね、最終的な目標としては現在開いているページを外部ブラウザで開けたらいいかなーと。

ちなみに同じような機能を持つ拡張機能としては既に "Launchy" というものがあります。

以下、拡張機能の作り方メモ。

AppLauncher ver.0.1 の作成

とりあえず初めての拡張機能ということで、インストールが出来るかどうか、というところから。 Ver.0.1 では中身がほとんどない拡張機能を作成し、正常にインストールでき、動作することを確認します。

参考にした web ページ

作成の流れは以下のページを参考にしました。 基本的には 「作り方メモ」 に沿っています。

開発環境

私の環境です。 別の OS でも大体の流れは一緒だと思います。 Firefox のバージョンは、3 以上であれば一緒だと思いますが、Firefox 2 とか Firefox 1.5 だと違う部分があるかもしれません。

  • Windows XP HomeEdition SP3
  • Firefox 3.0.10

拡張機能の作成を行う準備

さて、まずは拡張機能の作成を行う準備です。

  • 新しい Firefox プロファイルの作成
  • 開発用に Firefox の設定変更
  • 開発用のフォルダ作成

を行います。 ここは 作り方メモ と全く同じように行いました。 ただし、開発用のフォルダ名は "applauncher" としました。

開発中の拡張機能を Firefox にインストールする方法は 作り方メモ での方法と異なり、いちいち xpi ファイルを作成する方法を採りました。 うちの環境では Windows の右クリックメニューから ZIP 圧縮ができるためさほど手間ではないと感じたためです。

クロムマニフェスト (chrome.manifest) の作成

準備が出来たので、さっそく拡張機能の開発を始めましょう!

開発用フォルダ "applauncher" のすぐ下に "chrome.manifest" というファイルを作成します。 私の場合は以下のように記述しました。

# パッケージの定義
# 下記形式で記述する.
# content [packagename] [path/to/files]
# locale  [packagename] [localename] [path/to/files]
# skin    [packagename] [skinname]   [path/to/files]
content applauncher content/
#              => "content" ディレクトリに "chrome://applauncher/content" という
#                 パスでアクセスできるようになる.

# 他のパッケージのオーバーレイ
overlay chrome://browser/content/browser.xul chrome://applauncher/content/launcher.xul

インストールマニフェスト (install.rdf) の作成

アドオン (ここでは拡張機能) が Firefox などのアプリケーションにインストールされるときに必要な情報を "install.rdf" に記述します。

開発用フォルダ "applauncher" のすぐ下に "install.rdf" というファイルを作成し、以下のように記述しました。

<?xml version="1.0" encoding="UTF-8"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
  <Description about="urn:mozilla:install-manifest">
    
    <!-- 拡張機能を一意に識別するための ID. メールアドレス形式か GUID 形式 -->
    <em:id>applauncher@vividcode.info</em:id>
    <!-- アドオンのタイプ. 拡張機能であれば 2 -->
    <em:type>2</em:type>
    <!-- 拡張機能の名前 -->
    <em:name>AppLauncher</em:name>
    <!-- 拡張機能のバージョン. 規則あり -->
    <em:version>0.1</em:version>
    <!-- 拡張機能の説明 -->
    <em:description>This extension lets you launch an outer application by context menu.</em:description>
    <!-- 拡張機能の開発者 -->
    <em:creator>nobuoka</em:creator>
    <!-- 拡張機能を配布したりするための web ページアドレス -->
    <em:homepageURL>http://www.vividcode.info/firefox_addon/myextensions/applauncher/</em:homepageURL>
    <!-- 拡張機能の設定に関する XUL ファイル. 無くても良い -->
    <em:optionsURL>chrome://applauncher/content/prefs.xul</em:optionsURL>
    
    <!-- 各地域の言語情報. 無くても良い -->
    <em:localized>
      <Description>
        <em:locale>ja</em:locale>
        <em:name>AppLauncher</em:name>
        <em:description>この拡張機能を使うと、コンテキストメニューから外部アプリケーションを起動できます。</em:description>
        <em:creator>nobuoka</em:creator>
        <em:homepageURL>http://www.vividcode.info/firefox_addon/myextensions/applauncher/</em:homepageURL>
      </Description>
    </em:localized>
    
    <!-- 拡張機能の対応アプリケーション. 下の例では Firefox 3.0 に対応 -->
    <em:targetApplication>
      <Description>
        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
        <em:minVersion>3.0</em:minVersion>
        <em:maxVersion>3.0.*</em:maxVersion>
      </Description>
    </em:targetApplication>
    
  </Description>
</RDF>

拡張機能の中身を作成

肝心の中身の部分を作成します。 まず開発フォルダ "applauncher" の下に "content" というフォルダを作成します。

"chrome.manifest" に書いたパッケージの定義により、"chrome.manifest" や "install.rdf" 内の "chrome://applauncher/content" というパスはこの "content" フォルダを指すことになります。

"launcher.xul" ファイルの作成

"applauncher/content" フォルダの下に "launcher.xul" という XUL ファイルを作成します。 ファイル名は何でもいいのですが、"chrome.manifest" に書くパッケージのオーバーレイの定義で、このファイル名を指定してください。

中身は 作り方メモ とほとんど同じようにしておきました。

<?xml version="1.0" encoding="UTF-8"?>
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <!-- JavaScript を読み込み -->
  <script type="application/x-javascript" src="chrome://applauncher/content/launcher.js" />
  <!-- ステータスバーに独自のパネルを追加 -->
  <statusbar id="status-bar">
    <!-- パネルには "Hello, Firefox extension!!" と表示され、その部分をクリックすると
        JavaScript の AppLauncher.alert 関数が呼び出される -->
    <statusbarpanel id="info.vividcode.applauncher.my-panel" 
      label="Hello, Firefox extension!!" onmousedown="AppLauncher.alert('Hello');" />
  </statusbar>
</overlay>

"chrome.manifest" に、このファイルをオーバーレイとするように記述しているため、上のように書いておくとステータスバーに独自のパネルが追加されます。

"launcher.js" ファイルの作成

"applauncher/content" フォルダの下に "launcher.js" という JavaScript ファイルを作成します。 この JavaScript ファイルは、上で作成した "launcher.xul" で読み込まれるものです。

今回は、単にアラートウィンドウを開く関数だけ記述しています。

// AppLauncher の JavaScript
var AppLauncher = {
    alert: function( msg ) {
        window.alert(msg);
    }
}

"prefs.xul" ファイルの作成

最後に、設定ウィンドウの表示を記述するための "prefs.xul" ファイルを作成します。 このファイル名は "install.rdf" ファイルで指定したものです。

とりあえず、テキストボックスを 1 つ持つ設定ウィンドウを記述しました。

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
<!-- 設定ウィンドウ -->
<prefwindow id="info.vividcode.applauncher.prefwindow" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 
    title="AppLauncher の設定" bottons="accept,cancel">
  <!-- 設定ペイン -->
  <prefpane id="info.vividcode.applauncher.prefpane">
    <!-- 必ず 1 つ以上の "preferences" 要素を含む -->
    <preferences>
      <!-- 設定項目 -->
      <preference id="info.vividcode.applauncher.pref.path" name="extensions.applauncher.path" type="string" />
    </preferences>
    <!-- 実際の表示を規定 -->
    <hbox>
      <!-- preference 属性は、preference 要素の id 属性と一致させる -->
      <textbox preference="info.vividcode.applauncher.pref.path" />
    </hbox>
  </prefpane>
</prefwindow>

XPI ファイルの作成

以上で、中身の作成は終わりました。 次に Firefox にインストールするため、作成したファイル群を XPI ファイルにまとめます。

XPI ファイルの実体は ZIP ファイルなので、作成したファイル群をとりあえず ZIP 圧縮します。 このとき注意するべきことは、開発用のフォルダごと圧縮するのではなく "chrome.manifest" ファイル、"install.rdf" ファイル、そして中身を含めた "content" フォルダの 3 つを圧縮する、ということです。 つまり、XPI ファイルの中身は以下のようになっているはずです。

[launcher.xpi]
    +--[chrome.manifest]
    +--[install.rdf]
    +--[content]
           +--[launcher.xul]
           +--[launcher.js]
           +--[prefs.xul]

"content" フォルダなどを JAR ファイルにまとめる等の方法を採ることが一般的なようですが、必ずしもそれは必要ないようです。

ZIP 圧縮ができたら、後は拡張子を "xpi" に変更すれば XPI ファイルの完成です。

インストール、動作確認

インストールは簡単で、作成した XPI ファイルを Firefox の画面上にドラッグアンドドロップするだけです。 自動的にインストールウィンドウが開き、インストールされます。 Firefox を再起動するとインストールが完了しているはずです。

インストールしたら、メニューの 「ツール」 から 「アドオン」 を選び、拡張機能の一覧の中に自作の拡張機能があるか確認してください。 もし無ければなんらかの問題が発生している可能性があります。 エラーコンソールの確認をしたり、コードに問題が無いか確認してください。 また、そのままインストールしなおそうとしても出来ない可能性があるので、新たにプロファイルを作成しなおしてください。

拡張機能の一覧の中に自作の拡張機能がある場合は、多分問題なくインストールできています。 「設定」 ボタンを押してみたり、(今回の場合) ステータスバーに追加したパネルがちゃんと表示されているか、動作はするかなど確認してみてください。

再インストール

正常にインストールできている場合は、再インストールは簡単にできます。 XPI ファイルを再度ドラッグアンドドロップすると自動的に再インストールができます。 元々の拡張機能を削除したりする必要はありませんでした。

展望

拡張機能のインストールができ、きちんと動作することが確認できました。

次回以降は外部アプリケーションの起動に向けて、中身を作っていくことになります。

mitanimitani 2010/11/05 13:25 AppLauncherをダウンロードさせていただきました。
画像を右クリックからペイントショップなどで開きたいと思ったからなのですが、そのような用途の引数はありますでしょうか。

vividcodevividcode 2010/11/05 18:50 mitani さん

コメントありがとうございます。
画像を右クリックからペイントショップなどで開くためには、AppLauncher が 「画像をローカルに保存」 -> 「保存したファイルのパスを引数にしてペイントショップなどを起動する」 ということをしないといけないと思いますが、残念ながら現在のところ画像をローカルに保存するような機能はありません。
将来のバージョンアップでそのような機能も付けたいと思います。

mitanimitani 2010/11/06 06:24 お返事ありがとうございます。
楽しみに待たせていただきます。
なお、自分の用途としては、ローカルで編集中のファイルについてのものなので、画像のフルパスを取得できればokかもしれません。
ありがとうございました。

vividcodevividcode 2010/11/07 22:10 画像のフルパスを取得する、ということでしたら簡単にできますので、さくっと実装しました。 Ver.0.8.2 で、設定の引数に "&imageurl;" と書くと画像の URL が取得できます。 ローカルで編集中の場合はそのファイルのフルパスが取得できますので、期待の動作が可能かと思います。

ちなみにファイル名に日本語などが含まれていると、文字コードの問題が発生しますので、"<<Shift_JIS|&imageurl;>>" (Windows の場合) という風に引数の設定を行ってください。

mitanimitani 2010/11/09 06:39 対応していただき本当にありがとうございます。

早速試したのですが、どうもうまくパスを取得してくれません。
firefoxはver 3.6.6で、OSはWindowsVistaですが、
「設定」で引数を「&eimageurl;」として、
「file:///C:/test.jpg」をfirefoxで開き、右クリックで「IrfanView」で開いたところ、
「file%3A%2F%2F%2FC%3A%2Ftest.jpg:ヘッダが読み取れません!」
と言われてしまいました。
また、引数を「&imageurl;」にすると何も取得しないです。なんでだろう?

vividcodevividcode 2010/11/09 12:31 うちの環境で試してみました。 "&imageurl;" を引数にして IfranView で開くと、同じように "file: : ヘッダが読み取れません" という警告が表示されてしまいました。
"&imageurl;" という引数が何も取得していないのかというとそうではなくて、たとえば PhotoShop Elements を "&imageurl;" という引数を指定して開くとちゃんとその画像を開いてくれます。

で、ここからはまだちゃんと調べていないのですが...
"&imageurl;" という引数はローカルの画像ファイルに対して "file:///C:..." というパスを返しますが、この頭の "file:///" という部分が邪魔をしていて IfranView では開けないのかなぁと思います。 ちょっと時間がかかってしまうかもしれませんが、また調査して対応したいと思います。

mitanimitani 2010/11/11 04:09 >PhotoShop Elements を "&imageurl;" という引数を指定して開くとちゃんとその画像を開いてくれます。

「リリースノート」に書いてあった「URL エンコード」の意味が分からず、勝手に「fire:///」をヘッダに追加することを言っているのかなと解釈し、「&imageurl;」では「何も取得しない」と思ってしまいました。

自分も、右クリックからAppLauncherを通して再びfirefoxで開いたところ、画像を開いてくれましたので、何も取得しないことはないです。

たぶん、「:///」が2バイト文字に変換されているのではないかと思います。気の利いたソフトはそれでもちゃんと解釈して開いてくれますが、そうでないソフトでは開けないのではないかと。
なぜなら、引数を「&eimageurl;」にすると、「:///」が2バイト文字としてMIMEエンコードされているみたいに見えるからです。

ご厚意で公開していただいているのですし、暇なときにでも対応していただければうれしいです。楽しみに待たせていただきます。

mitanimitani 2010/11/11 04:44 >この頭の "file:///" という部分が邪魔をしていて IfranView では開けないのかなぁと思います。

この通りでした。手持ちのランチャから引数を"file:///"をつけた場合と付けないばあを試してみたら、同じ結果となりました。

>「たぶん、「:///」が2バイト文字に変換されているのではないかと思います。気の利いたソフトはそれでもちゃんと解釈して開いてくれますが、そうでないソフトでは開けないのではないかと。」これは忘れてください。

PhotoShop Elementsでは、"file:///"がついていてもちゃんと開いてくれるのですね。自分は「ペイントショップなど」といいましたが、これが一番通りがいいだろうと思って言ったのですが、実はペイントショップは持っていなくて、「Azpainter2」を使っていて、やはり"file:///"が邪魔をしているようです。

vividcodevividcode 2010/11/15 03:50 返事がおそくなってしまいすみません。 どうやって解決するのがいいかなぁとちょっと悩んでましたが、いい解決策が思いつかなかったのでとりあえず Windows 向けにローカル画像のパスを取得するための置換文字列 "&ImgFilePathWin;" というものを作ってしまいました。 AppLauncher ver.0.8.3 から使えるようになっていますので、試してみてください。

上でも述べましたが、ファイルパスに日本語などの多バイト文字が入っている場合は Shift_JIS に文字コード変換しないとダメですので、引数には "<<Shift_JIS|&ImgFilePathWin;>>" という風に書いてくださいませ。