現在のページFirefox機能拡張のポップアップとコンテンツスクリプトについて投稿日:2015年7月25日4000ポップアップ表示を通してアドオンスクリプトとコンテンツスクリプトを学ぶ「Firefox機能拡張の解説」第3弾。この投稿ではpanelモジュールを利用してポップアップする機能拡張を作成します。その流れで、アドオンスクリプトとコンテンツスクリプトの違いも解説します。混乱しやすい部分なので、イラストと実際の動作例を紹介しつつ解説します。APIで指定したhtmlファイルをコンテンツスクリプトで変更するmessage-passingを利用するコンテンツスクリプトでAjax通信をしてみるポップアップを表示する今回はポップアップを表示するためにpanelモジュールを使います。{panelEntry.show();}1行目、require(“sdk/self”).dataで機能拡張のdataフォルダを参照します。selfは機能拡張自身に関する情報を得るためのモジュールです。selfの公式ドキュメント参照するディレクトリが複数ある場合は、以下のように定義しておくと流用できます。imgディレクトリを参照3行目、panelモジュールの読み込みと定義を同時にしている例です。省略して書いているだけで、以下のように書いても同じです。data.url("content-script.js")});panelモジュールの詳細は公式ページを見てもらうとして、簡単に解説します。panelモジュールの公式ページcontentURLはポップアップで表示するhtmlファイルを指定します。contentScriptFileは後で詳しく解説しますが、上記のhtmlファイルと同時に実行されるJavaScriptファイルです。19行目~21行目、定義したpanelをshow()で表示します。popup.htmlとりあえず理解しやすくするために今回はh1でテキストを表示するだけにします。id="title">テキスト表示するよ</h1></body></html>content-script.js今回はコンソールにログを流すだけにします。機能拡張のフォルダで実行します。http://localhost:8888/ブラウザを起動してツールバーボタンをクリックするとパネルが現れます。Jでブラウザコンソールを開いて「hoge」が表示されていることも確認してください。コンテンツスクリプトについてpanelモジュール定義の際、popup.htmlとcontent-script.jsを以下のように指定しました。data.url("content-script.js")});「popup.html」内でJavaScriptを読み込んで実行することもできるのですが、あえてcontentScriptFileで「content-script.js」を追加しているのには理由があります。これからFirefoxの機能拡張を作る上で重要になるため、アドオンスクリプトと、コンテンツスクリプトの特徴を説明します。公式の解説ページがありますが、いまいちわかりにくいのでイラストを加えて補足解説します。後で実際に動作テストをするので最初はざっと把握しておいてください。今までの解説の通り、アドオンスクリプトはSDKモジュールを利用してFirefoxの様々な機能を追加・変更することができる。アドオンスクリプトは直接Webコンテンツにアクセスすることはできない。APIのactiveTab.attachなどを使う。その他、WebコンテンツにアクセスすることができるAPIはpage-mod、tabs、page-worker、context-menuなどがある。コンテンツスクリプトの特徴コンテンツスクリプトは今回利用したpanelモジュールのように、SDKモジュールで指定する。コンテンツスクリプトではSDKモジュールを使えない。APIで指定したコンテンツスクリプトのみ、直接アクセスできる。コンテンツスクリプトは「contentScript」とすることで、文字列として記述することができるが、記述ミスが起こりやすいので「contentScriptFile」で外部ファイルを取り込むのが推奨されている。※過去のバージョンではdataフォルダに配置するのが一般的だったが、JPMではdataフォルダは作成されなくなった。APIのurlで指定するhtmlファイルからはクロスオリジン対策でAjaxを使った外部との通信はできない。そのためAjax等はアドオンスクリプトか、ひも付けされたコンテンツスクリプトで行う。ドオンスクリプトとコンテンツスクリプトの通信アドオンスクリプトとコンテンツスクリプトはportオブジェクトを使って通信を行う。APIを使って取得したデータをコンテンツスクリプトで使いたい場合はport.emitを使って送信する。逆にコンテンツスクリプトからWebページのデータを受け取りたいといった場合はport.onを使う。アドオンスクリプトとコンテンツスクリプトどちらも同じ仕組でデータを送受信できる。この説明を読んだだけで理解できる人は稀だと思いますw解説だけではわかりにくいと思うので、実際に動作確認をします。コンテンツスクリプトでWebコンテンツを変更するコンテンツスクリプトでWebコンテンツを操作してみます。今回は短いコードなのでcontentScriptStringを利用しましたが、ミスの元なので実際にはcontentScriptFileを利用してください。contentScriptString});変更したら機能拡張を実行してください。無事にWebコンテンツが置き換えられていることがわかります。今回使用した以下のコードをアドオンスクリプトであるindex.jsに記述してもWebコンテンツに直接アクセスできないため何も実行されません。APIで指定したhtmlファイルをコンテンツスクリプトで変更する基本ポップアップを表示した時と同じです。id="title">テキスト表示するよ</h1></body></html>content-script.js今回はコンテンツスクリプトでDOM要素を変更してみます。"<h1>コンテンツスクリプトで置き換えたよ</h1>";ツールバーボタンをクリックしてポップアップを表示してみてください。以下の画像のように「コンテンツスクリプトで置き換えたよ」に変更されたパネルが表示されると思います。APIで指定したhtmlファイルを操作するものがあります。混同しがちなので、どちらを利用しているか意識して使い分けてください。message-passingを利用するアドオンスクリプトからコンテンツスクリプトへportオブジェクトを使ってメッセージを送信してみます。アドオンスクリプトからコンテンツスクリプトへメッセージを送信する。APIを利用してタイトルを取得。アクションボタンのクリックイベントであるhandleClick内で、panelEntryに対してport.emitを利用してtabTitleという名前のメッセージを送信します。id="title">テキスト表示するよ</h1></body></html>content-script.jsindex.jsから送信されたメッセージを受け取りますが、このときに「self」を使います。portオブジェクトのonメソッドを使ってtabTitleという名前のメッセージを受け取ります。そのままコールバック関数で受け取ったメッセージをh1で表示しています。"</h1>";});ツールバーボタンをクリックしてポップアップを表示してみてください。以下の画像はGoogleのトップ画面の例。タイトルである「Google」と表示されています。コンテンツスクリプトからアドオンスクリプトへメッセージを送信する今度は反対にコンテンツスクリプトからアドオンスクリプトへメッセージを送信してみます。index.jspanelEntry.port.onでコンテンツスクリプトからのメッセージを待ち受けます。メッセージの内容をコンソールログに流します。id="title">テキスト表示するよ</h1></body></html>content-script.jspopup.htmlのIDがtitleの文字列を取得して、self.port.emitを利用してpopupTitleという名前でアドオンスクリプトに送信します。popupTitle);機能拡張を読み込むとpopup.htmlのh1である「テキスト表示するよ」がコンソールログに流れます。これでアドオンスクリプトと、コンテンツスクリプトの双方向の通信ができたことになります。今回は単純な文字列を渡しただけですが、配列やオブジェクトも渡せます。以下のようにして試してみてください。オブジェクトコンテンツスクリプトでAjax通信をしてみるAjaxで通信するにはマニフェストファイルにパーミッションを指定する必要があります。}}index.jsAjaxを素で書くのが面倒なので「jQueryをダウロード」してdataフォルダに保存し利用します。panelのサイズがデフォルトだと小さくてわかりにくいので、サイズを指定して広げています。{panelEntry.show();}popup.htmlわかりやすくするためにcontというdivを作成。id="cont"></div></body></html>content-script.jsAjaxでGoogleのデータを読み込んで、popup.htmlのIDがcontの要素を書き換えています。jQueryを読み込んでいるので簡単に書けます。error){console.log(error);},});ツールバーボタンをクリックしてpanelを表示します。goolgeのトップ画面のhtmlが表示されています。これはあくまでサンプルなので実際の検索はできませんが、Ajaxを利用できるということは理解していただけたと思います。実装する場合はボタンイベントをハンドリングしてGoogleにPostすれば動作します。APIを利用する方法もあります。このAPIはAjaxでできることを書き換えているだけで、あまりメリットはありません。簡単な通信をサクッと書きたいといった用途以外で利用することは無いと思います。APIの解説ページマニフェストファイルでパーミッションに指定したサイト以外で通信を行うと以下のエラーが出ます。以上でポップアップ表示と、アドオンスクリプトとコンテンツスクリプトの特徴について解説しました。この辺がはまりやすいポイントで、ここさ理解できれば、後はAPIとオプションの組み合わせだけです。次のページは「Firefoxの機能拡張で外部モジュールを利用してメニューアイテムを追加する方法」です。character$(#cont).html(data);を$(“#cont”).html(data);にしたら動いた。jqueryはjquery-3.2.0.js。PMコメントありがとうございます。ご指摘の通りHTML要素なので”で囲む必要がありました。以前のバージョンでは動作していましたが、正しい記述方法ではありませんでした。記事の記述を修正しました。コメントをキャンセルコメントは認証制のため、すぐには反映されません。sukegra」をご利用ください。Share)Linuxの基本の基本。Share)他に運営しているサイトGOいけん世間を騒がせている、あの話題について言いたい。そんなあなたの「ご意見」を世に問うサイト。SUKEGRA「スケグラ」は日本語でプログラミングの悩みを解決するQ&Aサイトです。アクアリウムWikiアクアリウムに関することをみんなでまとめるWikiです。