独自のブラウザー拡張機能を作成する: 第 3 回、Safari を拡張する

Safari 用のベーシックなブラウザー拡張機能を作成する

どのブラウザーにも、それぞれに固有の長所と短所があり、支持する人もいれば、批判する人もいます。そのなかで、すべてのブラウザーに共通して言えることは、人々がブラウザーで費やす時間がますます増えているということです。この連載では、Chrome、Firefox、および Safari のベーシックな拡張機能を作成する方法を調べていきます。それによって、それぞれのブラウザーを拡張する作業とはどのようなものなのか、また共通して必要となる作業の難易度はどの程度なのか、さらには拡張機能をどのように配布するのか、といったことを学びます。今回の記事で作成するのは、Safari の機能拡張です。

2013年 4月 05日 ― 「この連載について」と「参考文献」の各セクションに第 4 回へのリンクを追加しました。

Duane O'Brien, Software developer, Freelance

Ảnh của Duane O'BrienDuane O'Brien は、へとへとに疲れたコンピューター・サイエンティストです。これまで、Web アプリケーションの開発やさまざまな PHP フレームワークに関する多数の記事を書いています。Duane についての詳細は、彼のブログツイートを調べてください。



2013年 7月 25日

この連載について

この全 4 回からなる連載では、3 つのブラウザー (Chrome、Firefox、Safari) を対象に Gawkblocker と名付けた拡張機能を作成します。

  • 第 1 回では、Google Chrome の拡張機能を作成するところから、Chrome ウェブストアに配置するまでのプロセスを説明しています。
  • 第 2 回では、Mozilla Firefox 用のアドオン (拡張機能) を作成します。
  • 今回の記事では、この拡張機能を Safari ブラウザー用に調整します。
  • 第 4 回では、作成したコードを特定のブラウザーに依存しないように微調整します。

この記事は、全 4 回にわたってブラウザーの拡張機能を作成する方法を説明する連載の第 3 回として、Safari 用の拡張機能を作成する方法を説明します。第 1 回では Chrome 用に、第 2 回では Firefox 用に Gawkblocker という拡張機能を作成しました。今回の記事では、Gawkblocker を Safari に移植します。完全なソース・コードを入手するには、「ダウンロード」を参照してください。

Gawkblocker の復習

Gawkblocker は、ユーザーがアクセスしたくない特定のドメイン (例えば、表示に時間のかかるブログなど) をブロックできるようにするための拡張機能です。Gawkblocker には以下のコンポーネントがあります。

  • ポップアップ・ウィンドウ (ブロック中のサイトを表示)
  • ブラウザーに表示されるアイコン (この拡張機能のエントリー・ポイント)
  • オプション選択ページ (ブロックするドメインと、リダイレクト先を構成するページ)

Chrome での Gawkblocker 拡張機能は、個々のタブまたはウィンドウにリスナーをアタッチし、URL をブロック対象のドメイン・リストと突き合わせます。そして、URL がブロック対象のドメインと一致する場合には、リクエストをローカル・ページにリダイレクトします。Firefox アドオンでの動作もほとんど同じです。Safari でも、同じような動作となることがかなり期待できます。

Gawkblocker は、特定の方法でブラウザー内部に入り込み、この連載で作成するすべての拡張機能で実行することになる処理を行います。Chrome および Firefox の記事で行ったのと同じく、皆さんは以下の質問に回答する必要があります。

  • ブラウザーの UI のどこかにその拡張機能の存在を示すようにする難易度はどの程度か?
  • ブラウザーのセッション間でデータを保持するために必要なものは何か?
  • 拡張機能を構成するコンポーネント同士はどのような方法でやりとりするのか?
  • ユーザーのデータのどこまでアクセスできるようにするのか?

Safari 用の Gawkblocker を作成するプロセスを完了すると、以上の質問の答えが見つかるはずです。


始める前に

この記事の説明に従うには、Safari の最新版 (この記事を執筆している時点では 6.0) を実行する Mac が必要です。Apple では、機能拡張の開発者に対して無料の Apple Developer Program (「参考文献」を参照) にサインアップすることを要求しています。また、HTML、CSS、および JavaScript を編集するためのツールも必要です。Safari とその機能拡張を使用した経験があると、記事の内容を理解するのに役立ちます。そのような経験がない場合は、使用可能な機能拡張を Safari Extensions Gallery (「参考文献」を参照) でブラウズして、この記事のためにいくつかの機能拡張を試してみてください。

作業のほとんどは、Safari 5.0 以降のバージョンに組み込まれている Safari Extension Builder (機能拡張ビルダー) で行います。Safari Extension Builder (機能拡張ビルダー) を使用すると、Safari 内部から Safari 機能拡張を作成、インストール、リロード、アンインストールすることができます。このツールを使用するには、Safari Dev Center (「参考文献」を参照) からデベロッパ証明書ユーティリティをダウンロードしてインストールした後、簡単な指示に従います。参考になるドキュメントは、「Safari Extensions Reference」(「参考文献」を参照) です。

完全なソース・コードを入手するには、「ダウンロード」を参照してください。


Safari 機能拡張の構成内容

Safari 用の Gawkblocker は、以下の要素で構成します。

  • Safari の起動時に 1 回だけロードされるページ (Safari 開発用語では、グローバル・ページまたはグローバル HTML ページと呼ばれます)。
  • コア機能が含まれる JavaScript ファイル (Chrome 拡張機能からそのままコピーします)。
  • ポップアップ/オプション選択を組み合わせたページ (Firefox アドオンから移植します)。したがって、管理するページは 1 つだけです (図 1 を参照)。
    図 1. ポップアップ/オプション選択ページ
    Safari 機能拡張のポップアップ/オプション選択ページのスクリーン・キャプチャー
  • ツールバーに表示する機能拡張用のアイコン。
  • ユーザーがツールバー・アイコンをクリックすると表示されるページ (ポップオーバー・ウィンドウ)。

JavaScript の注入

Chrome や Firefox の場合と同じく、Safari でも CSS と JavaScript をページに注入することができます。その場合、CSS や JavaScript を外部ファイルに含めて、Extension Builder (機能拡張ビルダー) でそのファイルを注入するように指定します。ただし、Gawkblocker には CSS や JavaScript を注入しません。

使用するページは、そのままの HTML、CSS、および JavaScript です。最終的な結果は、Chrome 拡張機能と Firefox 拡張機能を掛け合わせたようなものになります。

機能拡張自体は、Info.plist ファイルに定義しますが、このファイルに直接変更を加えることはしません。この Info.plist ファイルは、Safari Extension Builder (機能拡張ビルダー) から出力します。Info.plist に含める情報は、Chrome 拡張機能の manifest.json ファイルの内容と同様ですが、Info.plist は XML ファイルです。


Safari Extension Builder (機能拡張ビルダー) の使用方法

Extension Builder (機能拡張ビルダー) を使用するには、「Safari」 -> 「Preferences (環境設定)」 -> 「Advanced (詳細)」の順に選択し、「Show Develop menu in menu bar (メニューバーに”開発”メニューを表示)」チェック・ボックスにチェックを入れることで「Develop (開発)」メニューを使用できるようにする必要があります (図 2 を参照)。

図 2. 「Develop (開発)」メニューを使用可能にする
「Show Develop menu in menu bar (メニューバーに”開発”メニューを表示)」チェック・ボックスが選択された状態の「Preferences (環境設定)」ダイアログのスクリーン・キャプチャー

次に、Safari メニュー・バーから Safari Extension Builder (機能拡張ビルダー) を起動します。Extension Builder (機能拡張ビルダー) は、最初の起動時には大きな空のボックスのように表示されます。左下隅にある小さなプラス (+) アイコンをクリックして、機能拡張を作成することを指示すると、機能拡張の保存先を指定するよう求めるダイアログ・ボックスが表示されます (図 3 を参照)。

図 3. 機能拡張を作成する
新しい機能拡張の作成方法を示す Safari Extension Builder (機能拡張ビルダー) の画面のスクリーン・キャプチャー

フォルダーの場所を指定してから、そのフォルダーに以下のものをコピーします。

  • Chrome 拡張機能の background.html ファイルと gawkblocker.js ファイル。
  • Firefox アドオンの popup.html ファイル。
  • 使用している jQuery ライブラリー (jQuery ライブラリーを使用している場合)。
  • Icon.png ファイル。実際の画像をアイコンとして表示する場合を除き、アイコンは、64 x 64 ピクセル以上の透明な正方形でなければなりません (詳しくは、「参考文献」にリンクが記載されている「Safari Extensions Reference」を参照してください)。

上記のファイルを配置したら、次は Extension Builder (機能拡張ビルダー) に情報を入力します。図 4 に、最初に入力する一連のフィールドを示します。

図 4. 機能拡張を構成する (パート 1)
Extension Builder (機能拡張ビルダー) で Gawkblocker の構成を開始する画面のスクリーン・キャプチャー

図 4 に示されているフィールドに入力する内容は、以下のとおりです。

  • Display Name (表示名): 「Extensions (機能拡張)」リストに表示する機能拡張の名前。
  • Author (作成者): 自分の名前。
  • Description (説明): 短い説明の言葉。
  • Website (Web サイト): ユーザーが詳細を調べるためにアクセスする URL。
  • Bundle Identifier (バンドル識別子): orgtype.<自分のエンティティー名>.<自分の拡張機能名> のフォーマットでの ID (例えば、com.dontgothere.gawkblocker)。
  • Display Version (バージョンを表示): ユーザーが「Extensions (機能拡張)」リストをクリックしたときに表示されるバージョン。
  • Bundle Version (バンドルのバージョン): オペレーティング・システムが更新をチェックするために使用する、より粒度の細かい内部バージョン。
  • Extension Website Access (機能拡張 Web サイトアクセス): 選択肢には、「None (なし)」「Some (and provide a list) (一部 (リストを指定))」、または「All (すべて)」があります。ブラウザーがロードする URL を取得するには、Gawkblocker が使用するアクセス・レベルは「All (すべて)」でなければなりません。
  • Global Page File (グローバルページファイル): バックグラウンドで実行されるページ。
  • Database Quota (データベースクォータ): localStorage データベースで機能拡張に対して許容される最大サイズ。この例の場合、1 MB で十分過ぎるほどです。

ここまでのプロセスは簡単ですが、スクロールダウンして「Toolbar Items (ツールバー項目)」と「Popovers (ポップオーバー)」を追加するときには、少し注意が必要です (図 5 を参照)。

図 5. 機能拡張を構成する (パート 2)
Extension Builder (機能拡張ビルダー) で Gawkblocker の構成を続行する画面のスクリーン・キャプチャー

まずは、「Popovers (ポップオーバー)」セクションでポップオーバーを定義します。このセクションで定義するのは、ユーザーがツールバーの Gawkblocker アイコンをクリックしたときに Safari が開くウィンドウです。「Identifier (識別子)」にはポップオーバーを一意に識別する名前を入力し、「File (ファイル)」にはウィンドウにロードするファイルを指定し、「Width (幅)」「Height (高さ)」にはウィンドウの幅と高さを指定します。

次に、「Toolbar Items (ツールバー項目)」セクションで新しいツールバー項目を追加します。「Label (ラベル)」にはツールチップに表示するテキストを入力し、「Image (イメージ)」にはボタンに使用する画像を指定し、「Popover (ポップオーバー)」には使用するポップオーバー (上記で作成したもの) を入力して、「Identifier (識別子)」にツールバー項目を一意に識別する名前を入力します。

Extension Builder (機能拡張ビルダー) UI の最上部で、機能拡張をビルドしてローカルにインストールするよう指示したとしても、現時点では機能しません。その前に、いくつかの変更を加える必要があります。


Gawkblocker ファイルの更新

この機能拡張で使われるファイルは、gawkblocker.js、background.html、popup.html の 3 つだけです。Chrome 拡張機能からコピーした gawkblocker.js ファイルは、変更せずにそのまま組み込むことができますが、他の 2 つのページは更新する必要があります。

グローバル・ページに Safari とやりとりさせる

background.html ページで chrome.windows (Chrome API) を呼び出すことができないのは明らかなので、これに対応する Safari API 呼び出しで置き換える必要があります。さらに、Chrome でのように instead.html を使用してユーザーをローカル・ページにリダイレクトすることもできません。代わりに、YouTube でホストされている動画 Madness に直接ユーザーをリダイレクトする必要があります (リスト 1 を参照)。

リスト 1. ユーザーを YouTube でホストされている動画にリダイレクトする
...
if (!GB.getWatchThisInstead()) {
    GB.setWatchThisInstead("http://www.youtube.com/watch?v=N-uyWAe0NhQ");
}
...

Safari イベント・リスナーの動作は、Chrome イベント・リスナーとは少し異なります。Safari では、リッスン対象のイベントとそのイベントのハンドラーを指定しておくと、該当するイベントが発生したときにそのイベントが指定のハンドラーに渡されます。したがって、リッスン対象のイベントを処理する関数が必要です (リスト 2 を参照)。

リスト 2. Safari イベント・リスナー
function shouldIBlockThis(event) {
    var site;
    for (site in GB.getBlockedSites()) {
        if (event.url && event.url.match(site)) {
            event.preventDefault();
            event.target.url = GB.getWatchThisInstead();
        }
    }
}

イベントを処理する関数を用意しさえすれば、イベントをリッスンするのは簡単です。Safari には、URL が呼び出される前に発生する beforeNavigate イベントが用意されています。

safari.application.addEventListener("beforeNavigate", shouldIBlockThis, true);

全体として、background.html ページでの変更はごく小さなものです。popup.html の変更も、それほど根本的なものではありません。

ポップアップ・ページに Safari とやりとりさせる

Firefox では、main.js とポップアップ・ページの間でかなりのメッセージ・パッシングを行いました。Safari の場合は、Chrome での手法と同様にグローバル・ページを呼び出すことができます。値の取得 (get) と設定 (set) は、GB オブジェクトの中で直接行うことができるので、現在のリダイレクト先ランディング・ページを取得し、その値を適切なフィールドに設定します。

$("#watchthatinstead").val(
   safari.extension.globalPage.contentWindow.GB.getWatchThisInstead());

メッセージを main.js に渡すすべての箇所を、グローバル・ページの適切な呼び出しに置き換えてしまえば、他に必要な作業はそれほど多くありません。Chrome のポップアップ・ウィンドウとは異なり、ポップオーバーはその状態を維持するので、ポップアップ・ウィンドウが開くたびに状態をリセットします。それを容易にするのが、Safari が提供する以下のイベントです。

safari.application.addEventListener(
   "popover", function() { $("#onestep").show();$("#options").hide();}, true);

ブロック・リストを更新する方法も、リスト 3 のようにして整理することができます。

リスト 3. ブロック・リストの更新方法を整理する
function showBlockList () {
    var blockList = safari.extension.globalPage.contentWindow.GB.getBlockedSites();
    $("#blockedlist").children().remove();
    $("#blocklist").children().remove();
    var i=1;
    $.each(blockList, function (index, value) {
        $("#blockedlist").append("<div class='siterow' title='"+value+"'><div
 class='sitename'>"+index+"</div><span class='sitedesc'> : "+value+"
 </span></div>");
        $("#blocklist").append("<div id='site-"+i+"'><input type='button' 
 id='unblock-"+i+"' value='OH GO ON THEN' /> " + index + "</div>");
        $("#unblock-"+i).click(function () {
            safari.extension.globalPage.contentWindow.GB.removeBlockedSite(index);
            showBlockList();
        });
        i++;
    });
}

全体的に見て、それほど多くの変更は必要ありませんでした。Gawkblocker の Chrome 版と Firefox 版の成果物を使用して、最小限の作業量で、有効な Safari 機能拡張に仕上げることができました。


Extension Builder (機能拡張ビルダー) からテストする

Extension Builder (機能拡張ビルダー) には、テストに役立つツールがあります。まず、Extension Builder (機能拡張ビルダー) の左上にある「Install/Uninstall (インストール/アンインストール)」ボタンと「Reload (リロード)」ボタンを使用すれば、テスト対象の変更内容を簡単にインストールすることができます。また、「Inspect Global Page (グローバルページの検査)」をクリックすることで、背景ページの Web Inspector ビューを表示することができます。図 6 に、Web Inspector が実行されている様子を示します。

図 6. グローバル・ページの Web Inspector
グローバル・ページの Web Inspector のスクリーン・キャプチャー

機能拡張の配布

作成した機能拡張を大勢の人々に配布する準備ができたと判断したら、いくつかの選択肢のなかから配布方法を選ぶことになります。例えば、パッケージ化した機能拡張をダウンロードして配布するという方法、あるいは機能拡張を Safari Extensions Gallery (機能拡張ギャラリー) に提出するという方法があります。

パッケージ化した機能拡張の配布

パッケージ化した機能拡張を配布する場合は、Extension Builder (機能拡張ビルダー) からそのパッケージをダウンロードします。「Build Package (パッケージをビルド)」をクリックすると、誰でもインストールできる .safariextz ファイルが取得されるので、このファイルをお好みの方法 (e-メール、ホスト形式、インストーラー、またはその他の方法) で配布することができます。ただし、更新とホスティングには責任を持って対処する必要があります。

Extensions Gallery (機能拡張ギャラリー) への提出

機能拡張をレビューおよび追加してもらうことを目的に、機能拡張を Extensions Gallery (機能拡張ギャラリー) に提出することができます。その場合に必要なステップとして、追加の署名、Apple との契約、追加詳細の提供がありますが、Extensions Gallery (機能拡張ギャラリー) に提出する方法は、皆さんが作成した機能拡張を Safari ユーザーが発見する可能性が最も高い方法となります。


質問に対する回答

Safari 機能拡張が完成したところで、質問に対する答えが Chrome と Firefox での答えと比べてどのような結果になるのかを検討してみましょう。

ブラウザーの UI のどこかにその拡張機能の存在を示すようにする難易度はどの程度か?
おそらく、Chrome での場合よりもさらに簡単です。Safari Extension Builder (機能拡張ビルダー) が、このプロセスの曖昧な部分をほとんどなくしてくれます。
ブラウザーのセッション間でデータを保持するために必要なものは何か?
Chrome 用に作成した localStorage ラッパーを流用して、ブラウザーのセッション間で簡単にデータを維持することができます。
拡張機能を構成するコンポーネント同士はどのような方法でやりとりするのか?
グローバル・ページに直接アクセスすることで、拡張機能のさまざまな部分と簡単に情報をやりとりすることができます。
ユーザーのデータのどこまでアクセスできるようにするのか?
Safari では、要求可能なパーミッションのレベルが細かく分かれていますが、ユーザー・ページにスクリプトを注入して、ユーザーが訪れたすべてのページにアクセスできるため、ユーザーのデータに奥深く入り込むことができます。さらに、注目すべき点として、Safari ではパーミッションの警告を Chrome と同じ方法でポップアップ表示することはしません。

まとめ

Gawkblocker 拡張機能を 3 回 (Chrome 用、Firefox 用、および Safari用に) 作成した今、皆さんは、コアとなる 2 つの JavaScript ファイルを 1 つのファイルにまとめて、3 つすべてのブラウザーで使用できるようにする方法を探していることでしょう。実際、それが第 4 回で取り組む内容です。また、第 4 回では Safari 機能拡張をさらに活用することができます。


ダウンロード

内容ファイル名サイズ
Gawkblocker source codesafari-sourcecode.zip39KB

参考文献

学ぶために

製品や技術を入手するために

  • IBM 製品の評価をご自分に最適な方法で行ってください。評価の方法としては、製品の評価版をダウンロードすることも、オンラインで製品を試してみることも、クラウド環境で製品を使用することもできます。また、SOA Sandbox では、数時間でサービス指向アーキテクチャーの実装方法を効率的に学ぶことができます。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Open source, Web development
ArticleID=937599
ArticleTitle=独自のブラウザー拡張機能を作成する: 第 3 回、Safari を拡張する
publish-date=07252013