Firefoxのサイドバーを作ろう (XUL形式のアドオンでbrowser要素を設定する方法)
前回,下記の記事で,Firefox の簡単なアドオンの作り方を述べた。
画面上の邪魔なものを自動ブロックする Firefox プラグインの作り方 (XPI アドオンを自作しよう)
http://language-and-engineering.hatenablog.jp/entry/20081129/1227955571
これを使えば,表示したいWebページに自動で操作を加える事ができる。
今回は,ブラウザのサイドバーを作る方法。
- 表示中のWebページの横(サイド)で,いつも何か表示させておきたい
- 操作パネルみたいな物を作りたい
という時に役立つか。
ここでは,サイドバー中に何かのWebサイトを表示させてみよう。
また,JavaScriptを組み込む例として,サイドバー中でWebページが読み込まれたらアラートを表示する。
アドオンの基礎的なファイル構成については,上述の記事で既に述べたので,省略。
※完成品はこちらからダウンロードできます。
http://www.name-of-this-site.org/codi...
(1)開発フォルダへのリダイレクト
サイドバーだから名前は sidetemp にする。
組織名は暫定的に私のドメインを使う。
C:\Program Files\Mozilla Firefox 3\extensions (←FFのインストールディレクトリのプラグインフォルダ)に,sidetemp@name-of-this-site.org という名のファイルを作り
D:\dev\Extensions\sidetemp\
と書き込んで保存。
(2)設定ファイル
D:\dev\Extensions\sidetemp\ (←開発ディレクトリ)に,以下の2つのファイルを作成。
install.rdf (内容は超適当)
<?xml version="1.0"?> <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"> <em:version>1.0.1</em:version> <em:id>sidetemp@name-of-this-site.org</em:id> <em:type>2</em:type> <em:iconURL></em:iconURL> <em:targetApplication> <Description> <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <em:minVersion>3.0.1</em:minVersion> <em:maxVersion>3.*</em:maxVersion> </Description> </em:targetApplication> <em:localized> <Description> <em:locale>en-US</em:locale> <em:creator>id:language_and_engineering</em:creator> <em:name>sidebar temp</em:name> <em:description>temp</em:description> <em:homepageURL>http://d.hatena.ne.jp/language_and_engineering/</em:homepageURL> </Description> </em:localized> <em:localized> <Description> <em:locale>ja</em:locale> <em:creator>id:language_and_engineering</em:creator> <em:name>sidebar temp</em:name> <em:description>temp</em:description> <em:homepageURL>http://d.hatena.ne.jp/language_and_engineering/</em:homepageURL> </Description> </em:localized> </Description> </RDF>
chrome.manifest
content sidetemp content/ overlay chrome://browser/content/browser.xul chrome://sidetemp/content/sidetemp.xul
ちなみに今気づいたが,アドオンのIDは「〜@ドメイン名」という形式なので,これをinstall.rdfと共にWeb上に晒すと,メールアドレスと認識されてスパムメールの投稿対象になってしまう恐れが。
(3−1)アドオン実体:iframe編
サイドバーにWebページを表示させるためには,
- HTMLを組み込んでiframe要素を使う
- window要素中でbrowser要素を使う
の2つの方法がある。
まずはiframeを使う方法から。
D:\dev\Extensions\sidetemp\content を作り,その中に下記のファイルを作成。
sidetemp.xul (アドオンの全体像を記述。side_content.xulを読み込んでいる)
<?xml version="1.0"?> <overlay id="sidetempOverlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <!-- 「表示」→「サイドバー」のメニューに表示する内容 --> <menupopup id="viewSidebarMenu"> <menuitem observes="side_with_page" /> </menupopup> <broadcasterset> <broadcaster id="side_with_page" label="Webページ付きサイドバーを表示" autoCheck="false" type="checkbox" group="sidebar" sidebartitle="Webページ付きサイドバー" sidebarurl="chrome://sidetemp/content/side_content.xul" oncommand="toggleSidebar('side_with_page');" /> </broadcasterset> </overlay>
※参考:
broadcasterとは「何らかの状態を保持するもの」。
observes属性を付けた要素は「その状態を観察するもの」になる。:Mozillaのサイト:ブロードキャスタとオブザーバ
https://developer.mozilla.org/Ja/XUL_...
toggleSidebar()について:
Sidebarのtoggle対象にオレオレxulを指定する
http://moz-addon.g.hatena.ne.jp/ZIGOR...
side_content.xul (サイドバーの構成を記述。side.htmlを読み込んでいる)
<?xml version="1.0"?> <?xml-stylesheet href="chrome://global/skin" type="text/css"?> <window xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" title="temp_sidebar" id="mainwindow"> <iframe id="temp_iframe" src="side.html" flex="1" style="border:0px inset;"/> </window>
side.html (サイドバーに読み込まれるHTML。Yahooニュースを読み込んでいる)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html lang="ja"> <head> <title>temp</title> </head> <body> ネット中,ニュースが気になってしょうがない<br> <iframe id="ifr" width="100%" height="500"></iframe> <input type=button value="再読み込み" onclick="f()"> <script language="JavaScript"> function f() { var ifr = document.getElementById("ifr"); // onloadイベントを追加 ifr.addEventListener( "load", function(){alert("読み込みました");}, true ); // ページ読み込み ifr.src = "http://dailynews.yahoo.co.jp/fc/"; } </script> </body> </html>
上記のファイルをUTF8で保存してFirefoxを再起動すると,「表示」→「サイドバー」のメニューから,自分が作ったサイドバーを表示できる。
サイドバー中でボタンを押せば,Yahooニュースが表示される。押すたびに,読み込み完了のアラートも出る。
しかし,様子がおかしい。一部のDIVタグがHTMLとしてレンダリングされずに,タグ内容がそのまま文字列として表示されている。
下記のサイトを見ると,「単なるパネルではなく,ブラウザのようにまじめにコンテンツを表示させたい場合は iframe ではなく browser 要素を使え」とある。
Mozillaのサイト:コンテンツパネル
https://developer.mozilla.org/ja/XUL_...
では, browser要素を使って作りなおしてみよう。
(3−2)アドオン実体:browser編
サイドバーの構成内容だけ差し替えればよいので,前項の sidetemp.xul は変更せずそのまま使う。
side_content.xulを修正:
<?xml version="1.0"?> <?xml-stylesheet href="chrome://global/skin" type="text/css"?> <window xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" title="temp_sidebar" id="mainwindow"> <label flex="1"> ネット中,天気が無性に気になる </label> <button label="リロード" oncommand="brw_reload();" context="button-context"/> <browser id="my_browser" src="http://weather.yahoo.co.jp/weather/jp/13/4410.html" flex="1" type="content-primary" width="150" height="500"> </browser> <script type="application/x-javascript"><![CDATA[ var brw = document.getElementById("my_browser"); // onload イベントを設定 brw.addEventListener( "load", function(){alert("読み込まれました");}, true ); function brw_reload() { var brw = document.getElementById("my_browser"); // リロード brw.reload(); } ]]></script> </window>
HTMLファイルを使わずに,XUL中に直接 label, button, browser といった要素を配置している。
XUL中で利用できるタグについては下記サイトなどを参照。
3章:XUL入門〜直感的なUI作成を体験!〜XULで利用できるウィジェット
http://kittttttan.web.fc2.com/xul/ext...
これでFirefoxを再起動すると,ブラウザ用の独自CSSが適用されているものの,サイドバーにWebページが正常に表示される。
XPIに固めれば,「ネットサーフィン中にお気に入りのページをいつも脇目で見られるプラグイン」とか言って配布することもできるだろう。
補足
このエントリは,下記の質問への回答として執筆させて頂きました。
http://q.hatena.ne.jp/1228030237
Mozilla xul オブジェクトの iframe についての質問です。(※htmlオブジェクトのiframeではない※)
iframeで読み込みが完了した際のイベントを捕捉したいのですが、うまくいきません。
xulの定義に、 と記述しても、alertが表示されませんし、javascript内で、イベントハンドラを以下のように追加してもうまく行きませんでした。
var iframe=document.getElementById("test");
iframe.addEventListener('load',
function(){
alert('test');
}, true)
xul の iframe では、何か特殊な方法がありますか?
ちなみに、そのiframeはfirefoxのサイドバー内に表示されており、上記のjavascript内の、documentは、サイドバーのcontentDocumentを保持しています。
また,下記リンクが参考になりました。
firefoxのサイドバーを作りたい!
http://d.hatena.ne.jp/gede99/20070417
もじら組Forum:イベントを無効にする方法
http://forum.mozilla.gr.jp/cbbs.cgi?m...
関連する記事:
今から3分で,IE 上で .NET のDLLを動かそう (ブラウザ上で C# のコードを動かす方法)
http://language-and-engineering.hatenablog.jp/entry/20100705/p1
開いている全タブのURLとタイトルを,列挙して抽出するFirefoxアドオン (XUL形式プラグインのソースコード付)
http://language-and-engineering.hatenablog.jp/entry/20121221/p1