Wyszukiwarka google - Dostosowywanie Opery do własnych potrzeb - Opera Community[via Shishimushi GooglePreview for Opera] にて紹介されている google-preview.js をガッツリ refactoring して もともとのGoogle, Y! 以外に,Y!Jgoo.ne.jpMSNLive.comに対応させてみたよってな お話

お持ち帰りは dokodemo-preview.jsからどうぞ

##経緯

件のscriptを 2ch.net のOperaスレ (【Opera10】Opera Part66【まだか】),Shishimushi - GooglePreview for OperaWyszukiwarka google - Dostosowywanie Opery do własnych potrzeb - Opera Communityという流れで知る.同時にスレ的にはY!Jへの対応の需要があることを知る.

前後してリンク先を「チラ見」できるブログアクセサリーが提供開始 という話を聞いて,これをUserJSの範疇でできないだろうかと考えてた事もあって,そういうものへの需要が自分の中にもあった.

最終的には「どこのページでも,どんな情報でも」を目標として,手始めにY!J対応からやってみる事に.

##Y!Jパッチ

もともとのコードの大雑把な流れは

という風になっているので,「Y!の検索結果のURLなら」の処理と同様にして,「Y!Jの検索結果のURLなら」という処理を追加すれば良いことになる.実際には Y! と Y!J のURLや検索検索のページ構成に共通する部分が多かったので,

という程度の修正で済み,結果として,こんなパッチが出来上がった.

##さらにべつの検索結果への対応

Y! の場合とほとんど同じ処理だったため Y!J への対応は,コードもほとんど増えずに容易に行いえた.しかし,他の検索サイトの結果に対応しようとした場合,追加しようとする検索エンジンの数だけURLの判定やredirectの除去処理といった処理を追加しなければならないといった問題点があり,実際には面倒なものとなる.また,対象のページの構成やredirect処理の方法が変化した場合,対象リンクの抽出処理やredirectの除去処理をすべて書き換える必要があるといったプログラムの構成上の問題も,追加処理を難しくしている.

より簡単に対象の検索サイトを追加したり,より小さな影響でページの構成の変更に対応したりするために,オブジェクト化してみることにした.

試行錯誤の後,こんなクラスになった.

lang:javascript
Filter.prototype = { 
  name : "name", 
  domain : "", 
  /* loc(= location.href) が domain と一致するかどうか */ 
  is_my_domain : function ( loc ) {}, 
  /* anc(= Anchor Element ) が 検索結果サイトへのリンクの anchorかどうかの各検索エンジンごとの判定処理 */ 
  is_target : function ( anc ) { }, 
  /* anc(= Anchor Element ) が検索結果サイトへのリンクの anchorかどうかの各検索エンジンに共通の判定処理 */ 
  is_target_def : function ( anc ) {}, 
  /* anc(= Anchor Element ) を元にThumbnailなどを生成して挿入 */ 
  ins_thumb : function ( anc ) {}, 
  /* url から redirect分を除去 */ 
  get_real_url : function ( url ) {}, 
  /* 追加処理 */ 
  and_more : function () {} 
};

これを各サイトごとに,各関数を必要に応じて上書きする形で instance (filter)を作成し,main の処理として,生成した各filterに is_my_domain() で 対象ページかどうかを判定.対象ページならページ内の各anchorに is_target() で対象anchorかどうか判定. 対象anchorならThumbnailなどを生成して挿入.というループを回すという形になった.

lang:javascript
var filters = [ /* instances of Filter */ ];
for( var i = 0, flen = filters.length; i < flen; i++ ) {
  var ftr = filters[ i ];
  if ( ftr.is_my_domain( url ) ) {
    var j = 0;
    var anc = document.getElementsByTagName("a")[j++];
    while ( anc != null ) {
      if ( ftr.is_target( anc ) ){
        insed_previews++;
        ftr.ins_thumb( anc );
      }
      anc = document.getElementsByTagName("a")[j++];
    }
    break; // break for(i)
  }
}
return insed_previews;

そうすることで,メインのロジックを変更することなしに,検索対象サイトを増やせるようになった.

##まとめ

Wyszukiwarka google - Dostosowywanie Opery do własnych potrzeb - Opera Community[via Shishimushi GooglePreview for Opera] のscriptをいじって Y!J 対応にしてみた.

他のサイトを追加しようとすると結構めんどいので Filter ってクラスを作って各サイトごとのデータとコードをまとめて扱えるようにしてみた.それを使って,Google, Y! 以外に,Y!Jgoo.ne.jpMSNLive.comに対応させてみた.

おおむね良好.

##ver0.2に向けて

現状の ver. 0.1 ではThumbnail以外のgadgetを追加できないので,それを改善する. anchor を受け取って gadget を生成して DOMtree 上に追加する objectを作れば,そこに 何でも入れられるだろう.

あとは,もともとのgoogle-preview.1.0.js 由来のコードを全部置き換えて load eventで何度も実行されるのを一回で済むようにしたい.そんなとこかなぁ