background_pageとoptions_pageは違う

バックグラウンドページ、オプションページ、コンテキストメニュー初期化スクリプトはこんな感じです。

chromeを起動して拡張が読み込まれた時も、オプションページを開いた時も、コンテキストメニュー初期化処理を実行させたくてこう書きました。



ところが、拡張を有効にした時はコンテキストメニューがちゃんと表示されるのですが、オプションページでコンテキストメニュー関連の設定を変更し、コンテキストメニューを初期化するとコンテキストメニューをクリックしても登録した関数のclick()が実行されません。

数分悩んだのですが、拡張を有効にした時はバックグラウンドページでコンテキストメニューの初期化処理が実行され、コンテキストメニューがクリックした時はバックグラウンドページでclick()が実行されます。

ところが、オプションページで再度コンテキストメニュー初期化処理を実行し、コンテキストメニューをクリックすると、オプションページでclick()が実行され、オプションページにclick()が無いのでエラーとなっていました。

この現象を改善するには、オプションページからではなく、バックグラウンドページでコンテキストメニュー初期化処理を実行させる必要があります。

そのためには、オプションページでchrome.extension.sendRequest({},function(){});の通信を行うと無事オプションページからバックグラウンドページに通信が行われ、バックグラウンドページでコンテキストメニューの初期化が行われ、コンテキストメニューをクリックした時にはバックグラウンドページのclick()が実行されました。

WebRequest APIには署名が必要です

一ヶ月近く前からWebRequest APIのblocking機能を使ったGoogleChromeの拡張を公開しています。

先日その拡張のアップデートをしたのですが、何故か即公開になりません。

検出の誤作動かなと思って数日待っていたら、メールが来てサインを書いてグーグルに送れと言われました。

どうやらサインを送るまでは、web storeのデベロッパーダッシュボードから非公開にする以外の編集は一切できないみたいです。



必要な項目は、名前、会社名(任意)、メールアドレス、eMailアドレス、電話、ファックス、国、webサイトURL、グーグルアカウント、署名、日付。

このメールアドレスというのは、住所を書けという事でしょうか。記入欄も大きいし、そういう事なのかな。

そしてchromeewbstore-reviews@google.comに送れと。

メール本文は
From: "Justin"

To: ****@gmail.com

Cc: chromewebstore-reviews@google.com

Subject: Review notification for "ニコニコ直ダウンローダー"

Hi,

Thanks for uploading your item to our Google Chrome Web Store. Your item

was placed in a manual review queue because it uses the WebRequest API in

a blocking fashion.

The process for approving your item is quite straightforward. Due to the

greater performance implications of such extensions, we ask that you

complete the attached PDF form and return it to us. Please attach it as a

reply-all to this email (chromewebstore-reviews@google.com). After

receiving your completed form, your item will be published in the store

and a manual review to ascertain any performance issues will be scheduled.

You will be contacted if any concerns are surfaced by that review.

*IMPORTANT - PLEASE READ.

If we do not receive a signed agreement, your item may be subject to

removal from the store.

Feel free to reply-all to this email if you have any further questions.

All the best,

Justin

Google Chrome Web Store team
こんな感じ。

この拡張機能は先月から公開して、何回かバージョンアップしてたんだけど、WebRequest APIのblocking機能は最初のバージョンから使ってるんですよね。最新バージョンはオプションページの機能を追加しただけで、特別な権限が必要な処理は一切増やしていません。

3月から規約が変わったのかなと思いますが、どこに情報書いてあるのか。リファレンスにも書いてないっぽいし。

この機能はWebRequest API でワザとリクエスト送信を遅くしてみた – hogehoge @teramakoや、上記のリファレンスに「XmlHttpRequests使うとデッドロックする可能性あるから使うな」って書いてある通り、かなり遅くなるから慎重にする事にしたのかな。

うー、めんどくさい。以下、拡張のコード。機能的にもう完成だから、これから直接落としてもいいかもね。
2012-05-13追記

Google ChromeのAPIについて、最新情報や開発のノウハウなどを日本語で共有するGoogle 準公式のコミュニティがあるらしい。そこで直談判したらGoogleの方から返事が来て、公開されるようになりました。


以前のはてブ

GoogleChromeのデベロッパーツールのconsoleオブジェクト

googleChromeのデベロッパーツール、特にコンソールはとても便利です。

v17でのconsoleオブジェクトについてまとめました。

consoleオブジェクトの以下21個のメソッドについてまとめました。

  • assert
  • count
  • debug
  • dir
  • dirxml
  • error
  • group
  • groupCollapsed
  • groupEnd
  • info
  • log
  • markTimeline
  • memory
  • profile
  • profileEnd
  • profiles
  • time
  • timeEnd
  • timeStamp
  • trace
  • warn

以下のサイトを参考にしました。

assert

第一引数がtrueの時は何も出力しません。falseの時はエラー表示と共に残りの引数を出力します。

debug dirxml info log warn error

黄色マークが付くwarnと赤マークが付き呼び出し元が表示されるerror以外は違いが見つかりませんでした。

元ネタと思われるFirebugでは違いがあるのですが、GoogleChromeでは上位の機能が取り込まれているようです。

引数が一つの場合は単純にそれを表示します。



文字列の他に数値、配列、オブジェクト、DOMオブジェクトも表示する事が出来ます。



また、これらの命令は引数が二つ以上、かつ第一引数に”%s”の様な単語があると、残りの引数を順番に当てはめます。

Firebugのドキュメントによるとパターンは%s、%d、%i、%f、%o、%cの六種類の様ですが、GoogleChromeにおいてはいくつかのパターンが同じ動作をします。

%d、%i、%fは数字の表記方法を区別するはずですが、全て%sの文字列の表記になります。

%oはクリックで展開する事も出来ます。

dir

上記のdebug等は複数の引数を受け取ることが出来ましたが、dirは一つの引数を受け取るだけです。

配列を[“a”,”b”]と表示するdebug等に比べ、配列も折りたたみで表示をしてprototypeも表示してくれるのが一番大きな変更点です。

一つの変数をしっかり確認したい時に使うと良いと思います。

trace

今までは引数に渡された値を詳しく知る為の関数でしたが、consoleの機能はそれだけではありません。

console.trace();は呼び出された時点での呼び出し元を表示します。画像ではデベロッパーツールから呼び出されたのでInjecedScriptが表示されていますが、webページ内から呼び出した場合は(anonymous function)が一番下になります。console.error関数でも同じ物を呼び出すことが出来ます。値の確認も同時に行いたい時はerrorと使いわけると良いと思います。

count

行ごとに呼び出された回数を表示します。引数は無くても構いません。関数の頭に書いておいて、何回関数が呼ばれたか・・・を調べるのに使えそうです。



コンソール画面では一度実行した後でも再度同じコードを実行すると値が引き継がれます

MemoryInfo

MemoryInfoは関数ではなくプロパティです。

名前からメモリの情報をしる事が出来ると思っていたのですが、現状はgoogleMapでもニコニコ動画でも全てゼロのままでした。

また、関数ではないので、コンソールではなくhtml中から呼び出す時はconsole.dir(console.MemoryInfo);と呼び出す必要があります。

markTimeline timeStamp

console画面ではなくtimeline画面の為の関数です。こまめにこの関数を書いておけば、重い処理の原因特定をより容易に行う事が出来るでしょう。

この二つの関数も違いは分かりませんでした。

time timeEnd

二つの関数はセットで使います。timeが呼び出されてからtimeEndが呼び出されるまでのミリ秒を表示します。

引数にタイトルを付けて、同じタイトル同士で紐付けされます。

profile profileEnd profiles

これらの関数はセットで使います。timeと似ていますが、経過時間より細かい情報を調べることが出来ます。

また、timeはtimeEndで結果が呼び出せましたが、profileはprofilesプロパティで結果を調べる必要があります。

group groupCollapsed groupEnd

コンソール画面にインデント構造を作ります。groupとgroupCollapsedでインデントを下げる。groupEndで上げます。

groupとgroupCollapsedの違いは初期状態で開いているか閉じているかです。



以上がconsoleオブジェクトの機能です。

今まで処理時間を調べる時は毎回書いていたのですが、time関数で簡単に測定できそうです。

また最後に、v17からコンソールに単語補完機能が付きました。

現在のファイルを解析してとまではいきませんが、組み込み関数名の入力は短縮化されそうです。

ついにGoogleChromでスタンドアロンのダウンローダーとブロックツールを作る事が出来た!

期待を持っていたGoogleChromeの拡張機能である「webRequest」がいつの間にか正式にリリースされていました。

これによってリクエスト/レスポンスヘッダをスクリプトから変更する事が可能に。

Web Requests – Google Chrome Extensions – Google Code

下記サイトがこの上なく参考になりました。

webRequest APIをざっくり理解する。(あるいはChrome拡張の作り方) | mzsm.me

この機能を使ってニコニコ動画の視聴ページ(/watch)から動画をダウンロード&時報ブロックの拡張を作ってみました。

自分も今までいくつかのニコニコダウンロード拡張を使っていたのですが、外部サービス経由でユーザーが増えるとダウンタイムが増えたり、ファイル名が”smile.mp4″固定だったり・・と。どうにも使い勝手が悪かった。

その理由がニコニコの動画サーバーから送られてくるこのレスポンスヘッダ。
Content-Disposition: inline; filename="smile.mp4"

ファイル名が”smile.mp4″なのはまさにこれが原因です。また、URLを新しいタブで開いてもダウンロード開始せずにブラウザ内で再生されるのは”inline”が原因です。動画保存に手間をかけさせたいという運営の努力の痕が見えます。

これを上書きできるwebRequestApiの前では残念ながら無力ですけど。

作った拡張を例に、そんな素晴らしいwebRequestApiを解説してみます。

動画ファイルにアクセスする際動画IDがヒストリーに含まれたクッキーが必要なのですが、クッキーの処理はブラウザがやってくれるので今回は関係ありません。

先ずmanifest.jsonについて。

permissionsに”webRequest”を追加するのはもちろんですが、アクセス先のホストのマッチパターンも書きます。このホストが拡張のインストール時に表示されます。res.nimg.jpは後述の時報ブロックの為。


バックグラウンドページです。

webRequestの準備を行います。addListenerの第一引数が実際に処理を行う関数です。

関数の引数のresponseHeadersを調べ、Content-Dispositionヘッダを書き換え、それをreturnする事でヘッダを書き換え、任意のファイル名でダウンロードを行う事が出来ます。

動画にはmp4やflvと言った様々な種類があるのに注意。

25行目の[“responseHeaders”]を指定しないと、レスポンスヘッダを書き換える事が出来ません。
“blocking”を指定するとアクセスブロックが出来ます。おまけで時報ブロック機能も入れておきました。

flash内から呼び出されるURLのタイプはobjectらしいです。
webRequestの使い方はこんな感じ。

webRequestは様々な関数があるけど、使い分け方は不勉強でわかりません。
  • onAuthRequired
  • onAuthRequired
  • onBeforeRedirect
  • onBeforeRequest
  • onBeforeSendHeaders
  • onCompleted
  • onErrorOccurred
  • onHeadersReceived
  • onResponseStarted
  • onSendHeaders
特にonAuthRequiredにワクワクするけど、どういう意味なのかな。

以下全コードです。webRequestApiと関係ないから端折った視聴ページにボタンを追加する処理とか、タイトルを取得するコードも書いてあります。 以上が全コードです。

非表示ではなく、アクセス遮断を行う広告ブロッカーも近い将来に登場する事でしょう。

もちろん、これより優れたダウンローダーも。

便利な便利な「ポータブル版」

PCが絶不調。具体的に言うとフォルダを開いたりブラウザで新しいリンクをクリックしたりと何かのアクションをする度に、30秒近くのプチフリーズが起こるようになってしまいました。プロセスをチェックしてみても何かが動いてる様子も無し、CPU使用率は穏やかなもんでした。

どうこうしている内に何故か再インストールをしていたのですが、前準備をしていない再インストールは非常に苦痛なものです。

自分は日常的に使うソフトは9割orchisというランチャーソフトから起動しています。このランチャーソフトは登録してあるプログラムのフルパスを記録するというごく一般的なランチャーかと思われます。

さて、再インストールされ旧システムのProgram Filesフォルダ、Program Files (x86)フォルダ、Windowsフォルダ、usersフォルダがc:windows.oldフォルダに移動され、このフォルダに存在したファイルのフルパスが変更されてしまいました。この状態から再インストール以前のランチャーをそのまま使うにはどうしたらよいかと言うと、ファイルを全て元の場所に戻すことです。

ファイルを全て元の場所に戻すには、そのプログラムが使うファイルを全て把握する必要があります。

昔、プログラムがexeとiniとあと数個のファイルで完結していた時代は、そのプログラムが入ったフォルダをそのまま配置するだけで動きました。しかし最近は、特に1パソコン≠1ユーザーが崩れたxp以降はこの様なプログラムは減ってきています。

プログラム本体とその保存データが全く別の場所にあるソフトは今では珍しくありません。が、こういうのは後々、というか今本当に困ります。

プログラムの実体はググって再インストールすればいいのですが、設定をまた1からやり直したり、スカイプやメッセンジャー、iTunesはログファイル、音楽ファイルを同じ構成に戻すのは困難です。

とりあえず、レジストリは毎時任意のキーをエクスポートするbatファイルを書きだすようにしよう。そうしよう。

設定がどこに保存されているか、どうすれば環境を再現できるかはreadmeに必ず書いて欲しいレベルですマジで。

スカイプは方法があるのね。しかし公式には載ってないから何時使えなくなっても文句言えないと・・はぁ。

Lethe Skypeをポータブルにしよう! http://recapture.blog70.fc2.com/blog-entry-188.html

GoogleChromeで完璧なAdblockが来る日も近いであろう

GoogleChromeは拡張から通信を操作出来ないので、FireFoxの様な広告を読み込まない拡張を作るのは不可能でした。現時点でのGoogleChrome用Adblockはロード後非表示にする事しか出来ません。ですが、GoogleChromeの新しい拡張機能で任意の通信を切断する事が出来るかも知れません。実際に任意の通信を切断する拡張機能を付せて紹介します。 続きを読む GoogleChromeで完璧なAdblockが来る日も近いであろう