2010/12/09

任意のWebページをIEコンポーネントに読み込ませて処理する

NILScriptのCOMユニットやATLユニットを使えば、IEコンポーネントでWebページを表示し、様々な操作を行うことも可能です。
しかし、NILScript上のCOMオブジェクトは明示的にfree()メソッドを呼び出して解放しなければならないため、多数のDOMノードオブジェクトを使用する処理などは記述が面倒です。

そこでおすすめなのが、HTTPD機能で生成した動的WebページをIEコンポーネント上に表示し、Webページ側のJavaScriptで処理を行わせる方法です。
HTTPDには、Webページ上のJavaScriptとNILScript側の関数を連携させるためのclientSide関数とserverSide関数という機能が用意されています。
clientSide関数はブラウザ上で実行されるため、DOMオブジェクトの明示的開放が要らないだけでなく、jQueryオブジェクトも利用できるので、複雑なDOM操作も手軽に記述可能です。

任意のURLをIE上に読み込んでDOMを利用して情報の取得などを行いたい場合には、HTTPD上に用意したWebページのように自由にスクリプトを埋め込んで実行させることは出来ませんが、ブックマークレット機能を利用することで同様のことが行なえます。
ブックマークレットとは、「javascript:」に続いてスクリプトを記述したURIをブックマークなどから開くことで、Webページ上で任意の処理を実行させられるという手法のことです。
NILScriptのHTTPDでは、NILScript上で定義したclientSide/serverSide関数を利用した処理をブックマークレットとして呼び出せるようにする機能が用意されています。
このブックマークレットのURLをIEコンポーネントのnavigate()メソッドで読み込ませれば、表示しているWebページ上でNILScript上の機能を利用した任意の処理を実行させられます。

以下は、この手法の利用してWebページのbody要素の高さを調べて表示するという例です。
use('Window','ATL','HTTPD');
var result;
var httpd=HTTPD.create({
    serverSide:{
        report:function(value){
            //受取った解析結果を変数に代入し、ウィンドウを閉じる(4)
            result=value;
            w.close();
        },
    },
    bookmarklets:{
        analyze:function(){
            //ブラウザ上でWebページを解析し、結果をserverSide関数に渡す(3)
            report([$(document.body).height()]);
        },
    },
});
var w=PlainWindow.create({
    width:800,height:600,
    children:{
        ie:{
            type:Trident,
            top:0,bottom:0,left:0,right:0,
        }
    }
});
w.request(function(){
    this.ie.object.observe('DWebBrowserEvents2_DocumentComplete',function(o){
        //読み込みが完了したらブックマークレットを読み込ませる(2)
        this.navigate(httpd.bookmarkletURL('analyze'));
    });
    //解析したいWebページを読み込ませる(1)
    this.ie.object.navigate("http://lukewarm.s151.xrea.com/nilscript.html");
});
//ウィンドウが閉じられたら、解析結果を利用した処理を行う(5)
w.wait('destroy');
println(result);
HTTPD上では、analyzeというブックマークレット関数とreport()というserverSide関数を定義しています。
ブックマークレット上では、「$」でjQueryオブジェクトが利用できる他、serverSideで定義した関数の呼び出しが可能です。
serverSide関数は、第1引数に関数に渡す引数の配列、第2引数に返り値を受取るコールバック関数(省略可)を指定するという特殊な呼び出し方になっていることに注意してください。
また、bookmarkletsの関数は一旦文字列化されてブラウザ上で実行されるため、NILScript側の変数を直接参照することは出来ず、ブラウザのスクリプトエンジンがサポートしていない構文も利用できないことにも注意が必要です。

次に、Tridentコントロールを一つだけ配置したPlainWindowオブジェクトを生成します。
そして、このIEコンポーネントのCOMオブジェクトのobserve()で、Webページの読み込み完了時にブックマークレットの実行を行うというイベントハンドラを登録し、さらに調査したいURLを読み込ませます。
この処理は、ウィンドウの初期化が完了される前に実行されてしまわないように、ウィンドウを所有しているスレッド上で処理を実行させるrequest()メソッドを利用して呼び出します。
Webページの読み込みが行われると、スクリプト中のコメントの後ろに付けられた番号の順番で処理が実行されていき、最終的に調査結果の表示が行われます。

0 件のコメント:

コメントを投稿