ページ

2009年10月8日木曜日

WebKit Plug-in Study (4) 全てのページでプラグインを動作させるには?

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

スクリーンショットの性格上、すべてのページでプラグインが動作して欲しい。しかし、WebKit Plugin はあらかじめ MIMEタイプでのみ動作するようになっている。つまりページ上に指定した MIMEタイプのコンテンツが現れない場合は、まったく動作できない。この点をどうにか解決する必要がある。

Evernote はどうやっているのか?MIMEタイプを調べるべく、Evernote のプラグインを開き Info.plist を覗いてみた。

WebPluginMIMETypes が定義されていない。代わりに WebPluginMIMETypesFilename が定義されている。


一方、Safariを起動して コンソール.app を見ていると 下図のようなメッセージがたびたび出力されている。


どうも MIMEタイプに関わらず全てのページでプラグインが動作するように仕込んであるようだ。どうやっているのだろうか。

調べていると Info.plist の WebPluginMIMETypesFilename で定義されているファイルに MIMEタイプが記述されていることがわかった。Evernote の場合、 com.evernote.SafariClipperPlugin.plist というファイルに書かれているということになる。このファイルは ~/Library/Preferences にあるらしい。

参考:Mac OS X 10.5 Leopard インストール Flash が再生できなくなった / おのひろきおんらいん


が、ファイルが無い。他のフォルダにも検索をかけてみたが存在しないようだ。
どういうことだろうか?


さらにネットで "WebPluginMIMETypesFilename" を調べる。

すると面白いブログが見つかった。
The End of the Input Manager and Pimping Mac OS X? - Switchers' Blog

少し古いブログ(2007年)で Tiger(当時は MacOS10.3) から Input Manager が利用しづらくなるので代替手段を調べた、という趣旨のもの。その結論として WebKit Plug-In で強制ローディングを行うという方法があると書いてあった。

以下、主要部分を抜粋する。



How to Write a Pimpin' Plugin

The main idea is to make a browser plugin in such a way that Safari will be forced to load it on startup. This is not easy as Safari is smart and will check the WebPluginMIMETypes property to determine if this plugin is needed for the page. If there is no objects on the current page that have this MIME type then Safari will not load your code. A few days deep in WebKit source code revealed the WebPluginMIMETypesFilename property that is used to tell about MIME type via external property list file. The trick is that if the file does not exist then Safari will load your plugin and ask it to create the file. Instead of creating the file we extend Safari just as any other Input Manager-based extension does.

WebPluginMIMETypesFilename で存在しないファイルを指定するのがミソらしい。Evernote でファイルが存在していなかったのはこのテクニックを使っていたからか!
WebKitはファイルが存在しないとそのファイルを作成させる為にプラグインを読み込むらしく、その為に +[load] が呼び出されるらしい。ということはこのメソッドに仕掛けをしておけば(例えば WebViewのデリゲート WebResourceLoadDelegate に潜り込ませコールバックメソッドを横取りする)ページ毎にプラグインを実行させることができるかもしれない。

# しかし明確な仕様では無さそうなのでアテにして良いものか。将来そのような動作が無くなる可能性はある。

とりあえず試してみよう(続く)。


+++++ WebKit Plug-In シリーズ +++++