XREA.COM Logo XREA.COM Ad

Sleipnir2スレ

1l ★:2006/11/10(金) 23:37:03 ID:???
「作ったもの」スレが埋め尽くされつつあるので、Sleipnir関連はこっちに隔離することに。
4l ★:2006/11/11(土) 04:11:52 ID:???
UserActionから自由にデザイン可能な入力ダイアログを表示する

スクラップブックスクリプトに追加するときに、コメントやタグなどを入力できるようにしたいので、組み込みスクリプトからフォームを表示して入力内容を受け取る方法について考える。
ページ中に勝手にフォームを書き込めば良さそうなものだが、なんか不格好だし、OKボタンを押されたことを知るのが難しそうなんで避けたい。
window.showModalDialog()というやつでダイアログを表示出来ることを知る。
ダイアログ内では、Sleipnirでスクリプトを無効にしていても、IE側で有効ならばスクリプトが実行できる。
window.returnValueに代入されていた値がshowModalDialog()の返り値になる。
これを利用すれば、組み込みスクリプトから入力ダイアログっぽいものが表示できそうである。
だが、とりあえず「about:<input...」のようなURLで「about:」以降の内容をHTMLで表示させるという方法を試してみたところ、ダイアログは表示されるものの、なぜかreturnValueによる返り値の受け取りが出来なかった。
そこで、HTMLをローカルファイルに保存してみたら、インターネット上のページで実行しようとしたときに「アクセスが拒否されました」というエラーになる。
あきらめてwindow.open()でフォームページを表示する方法などを試してみたが、アクセス制限などの都合でことごとく失敗した。
色々と試してみた結果、window.openで空のウィンドウを開き、そのwindowオブジェクトのshowModalDialog()を使うことで、返り値の受け取りが可能なことを突き止めた。
ダミーのページが目障りなのはあきらめよう。

コードは以下のような感じ。

w=_window.open("","","",false);
val=w.showModalDialog('about:<body color="buttontext" bgcolor="buttonface"><input type="text" id="comment" value="aaa"><input type="button" onClick="window.returnValue=comment.value;window.close();" value="OK"></body>',"",
'status:no;help:no;dialogWidth:300px;dialogHeight:40px');
w.close();




IE7で動作するかが心配だ。
5l ★:2006/11/12(日) 22:37:35 ID:???
Sleipnir組み込みスクリプト用汎用ダイアログクラス

>>4の奴を元に、手軽に色々なことに使えるライブラリを作ってみることに。
フォームのデザイン方法で迷ったが、AutoHotkeyのGUIのようにメソッドで追加していく方式にした。
メソッドが呼ばれるたびにインスタンス変数にHTMLコードを追加していって、show()メソッドで表示する。
returnValueを生成するコードは、別途インスタンス変数に格納しておいて、HTMLに埋め込む。
とりあえず、テキストやチェック、ラジオ、リストなど、HTMLのフォームで作成可能なコントロールを一通り作った。
labelタグでラベルを表示したり、「&C」のような文字をaccsesskeyに割り当てたりする機能も付けた。
無駄に多機能になったが、こんなもの活用する機会はあるのだろうか。
そもそも、IE7で動作するかもまだ未検証だ。

投稿ファイル名: lDialog.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_5.zip
サイズ: 2945 bytes
6l ★:2006/11/12(日) 22:38:55 ID:???
>>5の使用例
こんな感じのスクリプトでダイアログを出せる。

function print(msg){
with(sleipnir.Output){visible=true;Print(msg);}
}
function cls(){
with(sleipnir.Output){visible=false;Clear();}
}
with(new Dialog('入力')){
addText('&Text','text',"aaa",2);
addPassword('&Pass','pass',"a<7D",2);br();
addTextArea('&TextArea','text2',"aaa");br();
addFile('&File','file');br();
addCheckBox('&ON/OFF','chk');br();
beginGroup('R&adio');
addRadio('左(&L)','r',"i1",true);
addRadio('右(&R)','r',"i2",false);
endGroup();
addSelect("選択(&S)",'sel',["1111","2222","3333"],2,3);
addSelect("選択2(&S)",'sel2',["aaaaaaaaa","bbbbbbb","ccccccccc"],[0,1],3);
v=show();
}
cls();
if(v!=null){
print('Text:' v.text);
print('TextArea:' v.text2);
print('File:' v.file);
print('Check:' v.chk);
print('Radio:' v.r);
print('Select:' v.sel);
print('Sel2:' v.sel2);
}else{
print('キャンセル');
}


投稿ファイル名:1.bmp.png
サイズ: 7807
画像: http://lukewarm.s151.xrea.com/b/file/1163165308_6.png
320 x 215
7l ★:2006/11/14(火) 00:59:29 ID:???
・Sleipnirでキャッシュを開いたときに指定フォルダにコピー

Sleipnir2では、画像をドラッグしてSleipnir2のウィンドウ上でドロップすると、そのキャッシュファイルを開いてしまうという仕様がある。
IEなどでは、表示部分から表示部分自身へ画像などをD&Dすることは出来ないようになっているが、なぜかSleipnir2では普通にD&Dできてしまう。
酷く鬱陶しいこの仕様を逆手にとって、このようにしてキャッシュファイルが開かれたときに、SeaHorseスクリプトで指定フォルダにコピーしてしまうと言うことを考えた。

ついでに、開かれたページ自身は閉じてやる。

なお、キャッシュを開く動作自体を殺したいなら、URIアクションで「何もしない」に登録してしまえばいいらしい。
URIアクションで組み込みスクリプトを実行させたり出来るようにはならないもんか。

投稿ファイル名: SaveCache.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_7.zip
サイズ: 644 bytes
8l ★:2006/11/14(火) 01:11:31 ID:???
組み込みスクリプトメモ

色々試していて気付いたこととか。

・表示中のページをワープロソフトのように編集できるようにする
_document.designMode='On';
_document.execCommand();
//コマンド一覧:http://msdn.microsoft.com/library/ja/jpisdk/dhtml/commandids/commandids.asp


・Sleipnir組み込みスクリプトからドキュメントのイベントハンドラを割り当て
_window.execScript('document.onclick=function(){alert("clicked");};');

_document.write()でscriptタグを書き込んで実行してもいいだろうけど。

スクリプトの実行を無効にしていると使えないからどうでもいい。


・ファイルの読み書き
本体のファイル読み書き機能は中途半端で期待できないので、Scripting.FileSystemObjectを使う

・WScript.Shellオブジェクト
外部プログラムの実行とかも出来る

・InternetExplorer.Applicationオブジェクト
別ウィンドウで何かを表示したりしたいときに使えるかも。

・HTMLを取得して文字コードを変換
ADODB.Streamで出来る。
http://msdn.microsoft.com/library/ja/jpado260/htm/mdmscadoapireference.asp
セキュリティパッチで使用不可にされたとかいう話があったような気がしたが、それはブラウザ上のスクリプトの話で、WSHやSleipnir組み込みスクリプトからは普通に使えることに気付いた。
これで、Windows標準機能だけで文字コードがShift_JISのページのHTMLをGETして処理することも出来そうだ。

・組み込みスクリプト実行中はSleipnir2は操作不能になる
「以前の WSH を利用したものとは異なりメインスレッドで動作する」ということだったので、wscript.exeのような外部プログラムを実行せずに、Sleipnir.exe内でマルチスレッド実行されるということかと思ったら、本当にウィンドウメッセージとかを処理したりするメインスレッドで実行されてやがる。
スクリプトが実行されている間は、Sleepとかしても全然操作できない。舐めんな。
登録したRSSを巡回したりするスクリプトは、小細工が必要そうだ。
同じJScriptなんだから、巡回するときはwscript.exeに任せればいいのか。
9l ★:2006/11/19(日) 22:31:44 ID:???
Sleipnir2メニュー編集スクリプト

前に作ろうと思って途中で投げ出した奴を多少まともにして公開。

Sleipnir2ではメインメニューやタブのポップアップメニューなどを自由にカスタマイズできるが、XMLファイルを直接編集しなければならないので面倒くさい。
そこで、編集用のGUIを作ることに。

最初はDMonkeyかAutoHotkeyでやろうかと思ったが、Sleipnir2の標準機能だけで動作するようにJScriptで作ることに。
UserActionにしようかとも思ったが、いちいちプラグインをインストールしないと使えないのでは本末転倒なので、単なるWSHにした。

Sleipnir2のユーザー設定フォルダが取得できないのが面倒くさい。
APIを使えば取得できるだろうが、無効になっている場合もあるのでできれば使いたくない。
とりあえず、(new ActiveXObject('WScript.Network')).UserNameでユーザー名を取得して何とかした。
マルチユーザー機能を使っていない場合や、ApplicationDataディレクトリに設定を保存している場合のことは面倒なんで無視した。

設定ファイルはADODB.Streamで読み込み、Microsoft.XMLDOMで取得したDOMツリーに再帰的にHTML生成関数を実行する。
Sleipnir2のXMLフォーマットが紛い物なので、MSXMLでは正しくパース出来ない。
「&」が「&」とエスケープされていないのが原因だった。
とりあえずrelpace()で対策したが、他にもあるかも知れない。

ADODB.Streamはバイトオーダーマーク付きのUTF-8ファイルをBOMごと読み込んでしまう。ファイルの先頭から「<」の前までを削除するようにして対策した。

編集画面は、InternetExplorer.Applicationオブジェクトでツリー上のHTMLとして表示する。
JavaScriptでツリー項目をD&Dできるようにしたり、「ゴミ箱」部分にドロップしたら削除されるという機能を付けたりした。
新規項目は、下部に別途ツリーを用意しておいてそこからD&Dで追加することに。
この新規項目パレットは、sleipnirスタイルのMainMenu.xmlから読み込む。

「OK」ボタンが押されたことの確認には、documentオブジェクトに適当なプロパティを設定して、WSH側でwhileループしながらそのプロパティを監視するという方法をとることに。
割とそれらしい動きになった。

とりあえず動作確認をしてみたところ、「デフォルト(&D)」という項目名が「デフォル(&D)」になるという不具合が発生。
どうやら、ADODB.StreamでReadTextした時点でおかしくなっているらしいので、どうしようもない。
表示名がおかしくなる程度であれば、我慢すれば使えるので問題ないだろう。

バックアップ機能とかも付けていないが、飽きたのでとりあえず完成ということに。
どうせ自分では使わないだろうし。

投稿ファイル名: MenuEdit.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_9.zip
サイズ: 4592 bytes
10l ★:2006/11/19(日) 22:33:16 ID:???
>>9のスクリーンショット

投稿ファイル名:1.bmp.png
サイズ: 7609
画像: http://lukewarm.s151.xrea.com/b/file/1163165308_10.png
240 x 320
11l ★:2006/11/30(木) 23:41:02 ID:???
Sleipnir2メニュー編集スクリプト改良

色々と改良してまともに使えるようにした。
とりあえず、UserActionから実行されたときは、sleipnir.ScriptFullNameをwscript.exeに渡してWSHで自身を起動し直すようにした。
SeaHorseからも呼び出せるようにしようかと思ったが、ScriptFullNameが参照できなくて頭に来たのでやめた。あまり意味ないし、どうでもいいか。

編集対象のメニューを選択できるようにした。
選択画面は、InternetExplorer.Applicationを使い回す。
一覧は適当にスクリプト内に埋め込んだ。

ファイルパスの取得には、Sleipnir.APIを使うことに。
APIが使えない場合は、Sleipnirの基本フォルダの2階層下にスクリプトがあることを前提に、WScript.ScriptFullNameから求める。

UserActionのスクリプトファイルも適当に取得し、新規項目候補に追加するようにした。

単一ファイルで動作するように、編集画面のスクリプトとスタイルシートはメインスクリプトに埋め込んだ。
スクリプト内の関数をIEで表示しているページのイベントに割り当てたところうまくいったが、妙に時間がかかるようになった気がする。まあ、我慢すれば使えるので問題ないだろう。

ツールバーも編集できるようにしようかと思ったが、ファイルフォーマットがよく分からないのでやめた。
UserActionのコマンドを新規作成する機能も付けようかと思ったが、まとまりが悪くなりそうなのでそのうち別スクリプトとして作ることにした。

投稿ファイル名: MenuEdit.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_11.zip
サイズ: 5242 bytes
12l ★:2006/12/04(月) 17:50:08 ID:???
メモ
Sleipnir2起動後に追加したUserActionスクリプトは、Sleipnir2を再起動しないと使えない。
TabPopupメニューなどに追加した場合は、グレイアウト状態になる。
13l ★:2007/01/23(火) 03:34:33 ID:???
WSHにはalert()などの手軽な出力関数がないので、いちいちalert=function(t){WScript.Echo(t);};とかやらなきゃならなくて面倒なんで、よく使う関数をライブラリ化することを思いついた。
eval((new ActiveXObject("Scripting.FileSystemObject")).OpenTextFile(basedir "lib\\Util.js",1,false).ReadAll());
のようにすることで、外部のスクリプトファイルを読み込んでその場で実行できる。
Utils.jsの中で、
function load(n){
var s;
with(new ActiveXObject("ADODB.Stream")){
Charset="_autodetect";Open();loadFromFile(n);s=ReadText();Close();
}
return(s);
}
という関数を宣言してあるので、以後は「eval(load(dir "SQL.js"));」のような記述で済むようになる。
perlのuse文だったかみたいな感じで使える。

難点は、この方法で読み込まれた関数の内部でエラーが発生したとき、具体的な行が表示されないことだ。
ライブラリ作成時のデバッグは、直接ライブラリのコードの後ろにテストコードを書いて実行してやる必要がある。
テキストとして読み込んだ後に1行ずつ細工をしてエラー位置が分かるようにすることも可能かも知れないが面倒だ。
14l ★:2007/03/03(土) 12:42:57 ID:???
フレーム内が別ドメインだとDocumentオブジェクトが参照できない問題について
何とかならないか調べてみたが、スクリプトではどうしようもないらしい。
なにやら対策法はあるらしいが、DocumentのIOleContainerを得てEnumObjectsでOLECONTF_EMBEDDINGSを列挙しなきゃならないらしい。
http://www.codepieces.net/index.php/ihtmldocument2-failed-for-frames-from-another-domain/
これで本当に解決できるかは知らん。
15l ★:2007/03/05(月) 22:38:35 ID:???
WSHからSleipnir2のdocumentのイベント関数を割り当てることが出来る。
こうして割り当てたイベントは、なぜかページのJavaScript実行がOFFになっていても動作する。
割り当てたイベントからは、WSH側のオブジェクトも使用可能。
ServerXMLHTTPとかでデータも取得できる。

api=new ActiveXObject("Sleipnir.API");
id=api.NewWindow('about:blank',true);
doc=api.GetDocumentObject(id);
doc.write('<input type="text" value="http://lukewarm.s151.xrea.com/b/" /><input type="button" value="ok" />');
doc.getElementsByTagName('input')[1].onclick=function(){
var http=new ActiveXObject('MSXML2.ServerXMLHTTP.3.0');
http.open('GET',doc.getElementsByTagName('input')[0].value,false);
http.send();
doc.write(http.responseText);
WScript.Quit()
};
while(1){WScript.Sleep(100);}WScript.Quit();
16l ★:2007/03/19(月) 05:09:25 ID:???
フレーム内の別ドメインページのドキュメントオブジェクトにアクセスするテスト

AutoHotkeyでActiveXを扱えるようになったということなので(http://lukewarm.s101.xrea.com/test/read.cgi/bbs/1146398137/34)、
>>14の方法で別ドメインフレーム内のドキュメントオブジェクトにアクセスできるか試してみることに。
そのままAutoHotkeyに移植してみたところ、期待通りに動作しているような気がする。
ついでに、以前作ったアクティブフレームのドキュメントオブジェクトを得る関数なども移植してみた。

動作するのはよいが、選択文字列を取得するだけで500ミリ秒もかかって遅すぎる。
AutoHotkeyで無理してブラウザ操作なんてするもんじゃないな。

投稿ファイル名: IE.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_16.zip
サイズ: 1228 bytes
17l ★:2007/03/21(水) 13:28:08 ID:???
アクティブなドキュメントに対してスクリプトを実行(異ドメインフレーム対応)

MSScriptControl.ScriptControl.1という奴でJavaScriptを実行できると言うことなので、AutoHotkeyでアクティブドキュメントを取得した後JavaScriptに処理を任せるというのを試してみた。
ScriptControlでは、スクリプト実行前にAddObjectというメソッドでグローバルスコープにオブジェクトを追加できる。
これで、取得したアクティブドキュメントオブジェクトを追加して、JavaScript内からアクセスできるようにしてやればよい。
AddObjectはIDispatchを直接送ってやる必要があるので、inv()を使わず別途関数を用意した。

スクリプトを実行している間、AutoHotkeyはハングアップ状態になるので、キーボードフックなどを行っていると困ったことになる気がする。
AutoHotkeyスクリプト自体を常駐させたりせず、Sleipnir2のユーザー定義ツールなどとして使うのが良さそうだ。

とりあえず、実行するJavaScriptは、AutoHotkeyスクリプト内でファイル名を定義しておくことに。
以前作ったgoo辞書の奴を移植してみたところ、それなりに動作した。

投稿ファイル名: ActiveFrame.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_17.zip
サイズ: 5140 bytes
18l ★:2007/04/03(火) 15:16:45 ID:???
Googleのタイトルの頭に目印を付けるSeaHorseスクリプト

Googleの検索結果ページは、「検索語句 - Google検索」というようなタイトルになる。
タブの幅を100ピクセルくらいで固定していると、「Google検索」の部分が表示できないことが多い。
必要なページが見つかったから検索結果のページは閉じようというときに、キーワードの先頭部分しか表示されないと、他のページと見分けが付かなくて困る。
そこで、SeaHorseで先頭に目印を付けるようにした。

// ==UserScript==
// @name GoogleTitle
// @description Googleのタイトルの頭に目印を付ける
// @include http://www.google.co*
// @type SleipnirScript
// ==/UserScript==
(function(){_document.title='' _document.title.replace(/^(G:)?(.*) - Google .*$/i,'G:$2');})();
19l ★:2007/04/04(水) 20:31:02 ID:???
画像をドラッグスクロール出来るようにするSeaHorseスクリプト
JaneStyleとかの内蔵ビューアに付いている、左ボタンで掴んでスクロールさせる奴を作った。

マウスイベントを割り当てているため、JavaScriptがONになっている必要がある。
URIアクションで変更させればいいが、別個に設定しなきゃならないのは面倒だ。
SeaHorseスクリプト内に「// @require JavaScript,ActiveX」みたいな感じで書いておけばURIアクションと同じように自動切り替えされるような機能でも付かないものか。

投稿ファイル名: ImageDragScroll.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_19.zip
サイズ: 489 bytes
20l ★:2007/04/11(水) 20:45:05 ID:???
ページの色々な情報を表示するUserActionスクリプト
時々、ページのLastModifiedを知りたくなったり、使われているCookieが気になったり、リンクされているRSSのURLをコピーしたくなったりする。
プロパティやソースの表示から取得できるが、面倒なので一つのアクションで表示できるようにした。
ついでに、GooglePageRankの奴も埋め込んだ。
適当にSleipnir上に新規タブで開いて表示するという適当さだが、とりあえず目的の機能は実現できたのでよしとする。


投稿ファイル名: ViewInfo.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_20.zip
サイズ: 1739 bytes
21l ★:2007/04/23(月) 00:47:05 ID:???
インクリメンタルサーチ式のブックマークっぽいもの
AutoHotkeyを流行らせるページとかいうサイトのコマンドリファレンスのインクリメンタルサーチをパクって作ってみた。
Sleipnirで無くても動く気がするが。

HTML上のJavaScriptとして動作する。
入力欄に入力が行われるごとに、一致する項目を一覧表示する。
リンクをクリックしたり、上下カーソルキーで選択してEnterで、そのURLに移動する。
URLやお気に入り内でのファイルパスを検索対象とする。
半角スペース区切りで、複数キーワードのAND検索も可能。

元のスクリプトでは、対象項目をHTMLとして用意して、いちいちそこから検索していたため、やたら遅かった。
そこで、対象項目はJavaScriptの配列として用意することに。
bookmark.jsというファイル内に「bookmark=[];」というようにして宣言しておいて、scriptタグで読み込む。
とりあえず、IEのお気に入りフォルダからインポートするスクリプトを別途用意した。

bookmark配列の項目は、urlとtitleのメンバを持つオブジェクトだが、検索時にそれぞれにindexOf()を行うのは面倒くさい。
そこで、別途detailメンバを用意し、そいつを検索対象にすることに。
このメンバには、項目のURLと、お気に入りフォルダ内でのパスを改行区切りで格納しておく。
手動で項目を追加・編集する機能が付けば、コメントなども入れられるはず。
「http」で検索したとき全てのURLにマッチしたりすると困るので、「http://」や「.url」などは取り除くことに。

そんなわけで、一通り動作するものができた。
重複項目の除去やソートがないが、まあいいだろう。


投稿ファイル名: LiteBookmark.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_21.zip
サイズ: 2549 bytes
22l ★:2007/04/24(火) 04:17:55 ID:???
about:blankに外部からdocument.writeすると、アドレスバーのURLが「http:///」になる。
URL偽装の対策か何かだろうか。
以下のように、window.execScript()でウィンドウにwrite()させると回避できる模様。
api=new ActiveXObject('Sleipnir.API');
id=api.NewWindow('about:blank',true);
api.SetSecurity(id,true,false,false,false,true,false,false);
w=api.GetWindowObject(id);
w.execScript('document.write("aaaaaaaaaaaaaaaaaa")');

あと、Sleipnir2は、アクティブタブのURLがabout:blankだとNewWindow()がそのウィンドウを返す模様。舐めんな。
23l ★:2007/04/25(水) 15:48:59 ID:???
Sleipnirスクリプトで無理矢理非同期実行を実現
Sleipnirのスクリプト実行機能は、スクリプトの実行中メインスレッドが停止するというふざけた仕様だが、スクリプトコントロールを作って、_windowのプロパティにくっつけて、そこでスクリプトを実行させてやれば、バックグラウンドで実行できる。
Sleipnirスクリプトが終了するとsleipnirオブジェクトが使えなくなってしまうので、あまり意味がない気がするが、クロスドメイン対応のXMLHTTPオブジェクトなどは、windowのプロパティとしてくっつけてやれば動作した。
また、ページのスクリプト実行がOFFになっていても動作する。

so=new ActiveXObject('MSScriptControl.ScriptControl.1');
so.Language='JScript';
so.AddObject('document',_document);
so.AddObject('window',_window);
so.AddObject('sleipnir',sleipnir);
_window.ScriptControl=so;
_window.XMLHTTP=new ActiveXObject("Microsoft.XMLHTTP");
so.Eval('window.setTimeout("try{with(window.XMLHTTP){open(\'GET\',\'http://lukewarm.s151.xrea.com/\',false);send();alert(responseText.substr(0,400));}}catch(e){alert(e.message);}",1000);');
24l ★:2007/04/25(水) 15:55:07 ID:???
こんなことしないでも、window.execScript()使えば出来るな。
ページのスクリプト実行がOFFだと動作しないけど。
25l ★:2007/04/25(水) 23:12:20 ID:???
Sleipnirスクリプトから無理矢理非同期実行を実現
なんだかよく分からないが、以下のようなものができた。

if(typeof(_window.ScriptControls)=='undefined'){
_window.ScriptControls=new Array;
}
_window.ScriptControls.push(new ActiveXObject('MSScriptControl.ScriptControl.1'));
with(_window.ScriptControls[_window.ScriptControls.length-1]){
Language='JScript';AddObject('document',_document);AddObject('window',_window);
Eval('('+(function(){
//スクリプトコントロールで実行
//使いたい関数やオブジェクトなどは、全部ここで用意する
sleipnir=new ActiveXObject('Sleipnir.API');
XMLHTTP=new ActiveXObject("Microsoft.XMLHTTP");
print=function(msg){sleipnir.OutputAddString(msg);};
window._AsynchronousProcedure=function(){
//setTimeoutから非同期で呼び出される
//スクリプトコントロール内の変数を使用可能
with(XMLHTTP){
open('GET','http://lukewarm.s151.xrea.com/',false);
send();
print(responseText);
}

};
window.setTimeout('_AsynchronousProcedure()',0);
}).toString()+')();');
}

まず、スクリプトコントロールを生成してwindowにセットし、その他の準備を行い、実行させたいコードをEvalする。
この時、コードは文字列として与えなければならないが、引用符などをエスケープして記述するのは面倒である。
そこで、「'('+(function{...}).toString()+')();'」として、関数として記述したコードを一旦文字列に変換後その関数を即座に実行するように書き加えたものをEval()することに。
Evalされるコード内では、ActiveXObjectや関数などを定義した後、非同期実行したいコードをwindowにセットしてsetTimeout()で実行させている。


この方法には、SleipnirScript、window側のスクリプト機能、new ActiveXObjectで生成したものの3つのスクリプトコントロールが関わってくるので、非常にややこしい。
26l ★:2007/04/27(金) 07:56:35 ID:???
SeaHorseをいちいち再読込しなくていいようにする
SeaHorseスクリプトは、スクリプトを修正したらオプション画面から再読込しなければならず、デバッグ時に面倒極まりない。

そこで、スクリプト本体を別ファイルに記述しておいて、何らかの方法で読み込んでevalするというのを考えた。

以下のようにする。

// ==UserScript==
// @name test
// @description test
// @type SleipnirScript
// @include file://*
// ==/UserScript==
basedir=sleipnir.API.AppPath.replace(/bin\\$/,"Test\\");
eval((new ActiveXObject("Scripting.FileSystemObject")).OpenTextFile(basedir+"lib\\Std.js").ReadAll());

ページを読み込むたびにスクリプトの読み込みが行われるので、@includeの範囲を広げすぎるのはお奨めできない。
27l ★:2007/04/27(金) 08:24:29 ID:???
SleipnirScriptの余計なデフォルトグローバル変数による汚染を浄化する
SleipnirScriptには、ドキュメントに書かれているsleipnir,_document,_window以外にも、色々な変数・関数が最初から定義されているようである。
alert()などがすぐに使えるのはWSHに比べて親切だが、思いがけない関数が定義済みでバグの元になることがある。
例えば、print()関数を実行すると、Webページの印刷ダイアログが表示される。
また、URL変数では、ページのURLを取得したり、値を設定することでそのページを表示することが出来る。

これらの変数は、「URL=」で上書きすることも「URL=undefined」として削除することも出来ない。
同じ名前のグローバル変数を定義したいとき、邪魔なことこの上ない。死ね。

頭に来たので、別途スクリプトコントロールを生成して、必要なオブジェクトだけを持ち越し、ゴミのない清らかな環境で実行することに。
以下のようにする。

with(new ActiveXObject('MSScriptControl.ScriptControl.1')){
Language='JScript';AddObject('document',_document);AddObject('window',_window);AddObject('sleipnir',sleipnir);
Eval('('+(function(){
basedir=sleipnir.API.AppPath.replace(/bin\\$/,"ScrapBook\\");
eval((new ActiveXObject("Scripting.FileSystemObject")).OpenTextFile(basedir+"lib\\Std.js").ReadAll());
use('URL');
alert((new URL(document.location)).path.file);
}).toString()+')();');
}

ちなみに、Eval()から戻ってSleipnirScriptが終了する前なら、スクリプトコントロールにsleipnirオブジェクトをもちこして利用することが出来る。
28l ★:2007/04/27(金) 08:34:29 ID:???
URL処理ライブラリ

>>27で使っていた奴。
URLの分割や相対パスの変換などを行う。
「?」以降のクエリ文字列を解析してオブジェクト化することも可能。



投稿ファイル名: URL.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_28.zip
サイズ: 1918 bytes
29l ★:2007/04/27(金) 08:59:48 ID:???
スクリプトコントロールによる詳細なエラー行の表示
SleipnirScriptは、忌々しいことにエラーが起きてもエラー内容しか表示されないが、スクリプトコントロールを使えば、自前で詳しいエラーを表示してやることが出来る。

var path=sleipnir.API.AppPath.replace(/bin\\$/,"test.js");
var code=(new ActiveXObject("Scripting.FileSystemObject")).OpenTextFile(path).ReadAll();
with(new ActiveXObject('MSScriptControl.ScriptControl.1')){
Language='JScript';AddObject('document',_document);AddObject('window',_window);AddObject('sleipnir',sleipnir);
try{
Eval(code);
}catch(e){
sleipnir.Output.Visible=true;
sleipnir.Echo('Error('+Error.Source+') @ line '+(Error.Line));
sleipnir.Echo(' => '+code.split(/\n/)[Error.Line-1]);
sleipnir.Echo(' '+Error.Description);
}
}

行番号だけでなく行の内容も表示するようにしたので、WSHのエラー表示よりも便利だ。
30l ★:2007/04/27(金) 10:36:33 ID:???
・SeaHorseからスクリプトやSleipnirのパスが取得できない件
何でAPIにはAppPathがあるのにSleipnirScriptには無いんだ?そもそも、何でSeaHorseからはsleipnir.ScriptFullNameが参照できないんだ?舐めんな。

とりあえず、APIが使える環境ならAppPathを元に割り出せる。
API無しでも、sleipnir.UserFolderで設定フォルダは参照できるので、それを元に割り出すことに。
ポータブル環境の場合は、settingsフォルダに固定のはずなので、簡単に得られる。
UserFolderの末尾が「settings\」の場合はマルチユーザー無効とみなす。ユーザー名がsettingsになっているとダメだが、そんな奴は居ないだろう。
AppDataフォルダに設定を保存する環境には対応できないが、そもそもAPIが使えないケースというのはポータブル環境くらいだろうから構うまい。

無理矢理1行にまとめるとこうなる。
basedir=sleipnir.API?sleipnir.API.AppPath.replace(/bin\\/,''):sleipnir.UserFolder.replace(sleipnir.UserFolder.match(/\\settings\\$/)?/(bin\\\.\.\\)?settings\\$/:/(bin\\\.\.\\)?settings\\[^\\]*\\$/,'');
31l ★:2007/04/29(日) 23:20:54 ID:???
スクラップブックスクリプト
http://lukewarm.s151.xrea.com/test/read.cgi/b/1149783578/13の奴を真面目に作り直した。

まだ作りかけだが、とりあえずファイル構成やデータベースのテーブル定義は決まったので、とりあえず公開する。

キーワード検索機能なども用意した。
この間のURL解析スクリプトを利用することで、「**件中 **〜**件目」というような奴が比較的簡単に作れた。

編集機能も付けた。
「編集」のリンクから編集モードでページを表示すると、contentEditableをtrueにして各要素を編集可能にする。
その状態でもう一度スクラップブック追加スクリプトを実行すると、編集後の内容を取得してデータベースに上書きする。

削除機能、検索結果のソート、タグ付けなどの機能はまだ。

投稿ファイル名: ScrapBook.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_31.zip
サイズ: 23117 bytes
32l ★:2007/04/30(月) 23:32:48 ID:???
スクラップブックスクリプト構想

プラグイン方式で色々と追加できるようにしたい。
検索やページ内容の表示などもプラグインにしてしまうことを思いついたので、
個別表示ページのURLが多少変更される予定。
33l ★:2007/04/30(月) 23:38:03 ID:???
・file://のページでそのファイル自身(?以降が違う)へのリンクをたどっても、戻る/進む履歴に残らない件
Trident側の仕様らしい。

ScrapBookでは、ScrapBook.htmlというファイルをSeaHorseでクエリ文字列に従って書き換えてページを表示しているが、
上記の問題により戻る/進むが効かず、大変不便だ。
「ScrapBook.html」→「ScrapBook2.html?q=」→「ScrapBook.html?id=」という感じにしてやれば大丈夫っぽい。
34l ★:2007/05/03(木) 21:25:48 ID:???
プラグイン拡張機構のベース部分は完成した、ような気がしないでもない。

このPluggable.jsライブラリを使うことで、拡張可能なクラスが作成できる。
そのクラスにaddCommand()で動作を追加し、
更にそのコマンドにaddFilter()で事前処理・事後処理フィルタを追加したりできる。
フィルタ自体もコマンドなので、更に拡張することも可能。
プラグイン読み込み関数が用意されており、指定フォルダ内の*.jsファイルを読み込んで実行することで、プラグインによる拡張が実行される。プラグインの導入は、ファイルをコピーするだけでよい。

そうして拡張したクラスのインスタンスを生成し、
execCommand()でコマンドを呼び出したり、execFilters()でフィルタだけを実行したりできる。
コマンドの中からコマンドを呼んだり、コマンドを普通のメソッドとして実行したりすることも可能。
更に、execute()では、パラメータに与えられたオブジェクトのプロパティを調べて自動的にコマンドを決定してくれる。
例えば、params.commandがあれば、そのプロパティで指定されたコマンドが、
params.idがあれば、idに対応したデフォルトコマンドが、
params.qがあれば、qに対応したデフォルトコマンドが、
そのいずれもなければ、パラメータ未指定時のデフォルトコマンドが実行されるという具合。
コマンドラインやクエリ文字列で指定された操作を自動識別してくれるのである。

このシステムに従って拡張クラスを作れば、拡張機構の作成を意識することなく、自由に拡張可能なシステムが構築できる、かもしれないっぽいのではないかと思うのだがどうだろう。

投稿ファイル名: Pluggable.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_34.zip
サイズ: 961 bytes
35l ★:2007/05/05(土) 23:27:49 ID:???
スクラップブック 改良

一般利用者(もし居れば)にとってはどうでもいいことだが、全体をプラグイン方式で拡張可能にした。
これにより、スクリプト本体に手を加えなくても色々と機能を追加できるようになるはずだが、
コードを分散させまくった弊害で、自分でもどこに何の処理を書いたか分からなくなってしまっている。
既に駄目そうだ。

その他、ひとまず前回のバージョンにあった機能は一通り揃えた。
また、編集機能(これもプラグインである)には、サイドバーのメニューから「新規メモ」で空のページを作成して表示する機能を付けた。
削除機能も適当に付けた。いちいち確認が出るのが鬱陶しい。

HTMLのデザインを変更し、サイドバーに色々表示するようにした。
>>33の方法で、戻る/進むが使えない問題も解決。

その他、色々と修正。
編集して保存したときにURLの情報を消し飛ばす機能(これはひどい)は削除した。

投稿ファイル名: ScrapBook.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_35.zip
サイズ: 41027 bytes
36l ★:2007/05/06(日) 12:20:56 ID:???
・スクラップブック用データベースファイルサイズ表示プラグイン
せっかくプラグイン機構を採用したのだから、そのうち要らなくなって外しそうなどうでもいい機能を付けてみることに。
データベースの実体であるScrapBook.dbのファイルサイズをサイドバーに表示する。
30ページですでに200KBくらいになっているのだが、この調子で何千ページも追加していって大丈夫だろうか?

投稿ファイル名: DBStatus.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_36.zip
サイズ: 454 bytes
37l ★:2007/05/07(月) 10:14:05 ID:???
・スクラップブック用検索ワードハイライトプラグイン
適当に10行で作った。

CSSにも
.Highlight0{
background-color:#ffff33;
}
のようなものを書き足してやる必要がある。

投稿ファイル名: Highlight.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_37.zip
サイズ: 389 bytes
38l ★:2007/05/09(水) 08:50:36 ID:???
スクラップブック 少し改良

微妙な修正を行った。
検索結果とかを表示したときにフォームの入力内容を復元する機能を
復活させるのを忘れていたので直した。

2つのHTMLファイルを利用して戻る/進むの履歴を正常に機能させる方法には、
訪問済みURLの記録が正しく行われないという難点があったため、
内部リンクではa:visitedの色を変えないように修正した。

ハイライトの奴とか、プラグインは面倒なんで全部同梱した。

投稿ファイル名: ScrapBook.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_38.zip
サイズ: 43553 bytes
39l ★:2007/05/10(木) 06:57:53 ID:???
・スクラップブック 修正とか

ページ右上のコマンドフォームを実装した。
検索結果などの項目にチェックボックスが付き、
チェックした項目群に対して何らかの操作を行うという物なのだが、
チェックボックスをフォームの子要素としつつ、リスト項目に位置を合わせて
表示するというのを実現するのに手こずった。

コマンドフォームのデフォルトコマンドは、選択したページ群を
まとめて表示するという、役に立つかどうか微妙な感じの機能。
検索結果から有用なものを抜き出して、
まとめたページをブックマークしたりすれば、多少は便利かも知れない。

それから、削除機能が機能の変更でぶっ壊れていた気がするので直した。
削除機能も、コマンドフォームから一括実行できる。

投稿ファイル名: ScrapBook.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_39.zip
サイズ: 45473 bytes
40l ★:2007/05/11(金) 06:02:49 ID:???
新規ページが開かれるとき、一瞬違うウィンドウサイズになっている件

スクラップブックスクリプトのリスト項目選択チェックボックスは、
ページ表示後にウィンドウサイズの変更などでリストアイテムの高さが変化すると、
垂直位置を追随できないので、ずれる。
ウィンドウの位置・サイズは完全に固定して使っているので、気にする必要はないはずだが、
なぜかScrapBook.htmlを新たに開いたときにも、リサイズしていないのにずれて困る。
どうやら、ウィンドウが開かれた直後は、表示領域のサイズとは違うサイズになっていて、
ページを読み込みつつ表示領域のサイズに合わせ直しているようだ。
Tridentの仕様なのかも知れないが、何とかなるならして欲しいものだ。
41l ★:2007/05/11(金) 10:57:28 ID:???
スクラップブック タグ機能追加

長らく放置してあった、タグによる管理機能を追加した。

まず、右上のコマンドフォームから、表示中のページやリストで選択したページへの
タグの追加が行える。タグは複数いっぺんに付けることも可能。

ページ内容表示画面では、ナビゲーションに「タグ(1)」のようなリンクが表示される。
括弧内の数字は、ページに付けられたタグの数。
リンクをマウスでポイントすると、付けられたタグがツールチップで表示される。
リンクをクリックすると、現存するタグの一覧が表示され、
「+」「-」のリンクで追加/削除が行える。

検索フォームに「タグ」コマンドが追加され、指定のタグの付いたページを検索できる。
複数のタグを列挙してのAND検索、「-」を付けての除外検索も可能。

メニューには、「タグ一覧」のリンクが追加される。
タグ一覧画面では、データベースに現存する全てのタグの、
タグ名とそのタグが付けられたページの数が一覧表示され、
各タグ名をクリックすると、そのタグの付いたページが検索される。
タグ一覧は、タグ名かページ数でソート可能。


そんな感じで、最近流行りのような気がするタグによる管理を可能にしてみたが、
いちいち自分でタグを付けなきゃならないのが面倒くさい。
普通に全文検索で探した方が便利な気がする。
だが、ページに自由に属性を付けられるという仕組みは、色々と応用できそうである。
とりあえず、「後で読む」機能などが予定されている。

投稿ファイル名: ScrapBook.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_41.zip
サイズ: 47959 bytes
42l ★:2007/05/12(土) 17:07:45 ID:???
スクラップブック 保存設定ダイアログと「後で読む」

スクラップ追加時に設定ダイアログを表示できるようにした。
ダイアログ表示コマンドの前フィルタで入力欄を追加し、
後フィルタで入力された値に応じた処理を行うようになっており、
プラグインでの拡張も可能。
とりあえず、タイトルの変更や、タグの入力を行えるようにした。

また、タグ機能を利用した「後で読む」プラグインを作成。
追加ダイアログのチェックボックスや、右上のコマンドフォームから、
「後で読む」タグを付けることが出来る。
このタグが付いた項目があると、サイドバーに古いものから順にリンクが表示される。
そして、このタグが付いたページを開くと、ナビゲーション欄に
「読了」というリンクが表示され、クリックすることでタグを外せる。
そんな感じで、効率よく未読を消化できる、といいな…。どうせ使わないんだけど。

あと、データベースのフィールドとしては用意しておきながら、長らく放置してあった
前回利用日時と通算利用回数の記録・表示機能を付けた。役に立つかどうかは不明。

投稿ファイル名: ScrapBook.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_42.zip
サイズ: 50093 bytes
43l ★:2007/05/15(火) 12:47:48 ID:???
スクラップブック 相対リンクの修正など

スクラップブックに保存するときに、a href/img srcなどで相対URLが指定されていると、リンク切れになってしまう。
そこで、相対URLを絶対URLに変換するプラグインを作ることに。

new ActiveXObject('htmlfile')でIHTMLDocument2オブジェクトらしきものを作って、base要素のhref属性を設定してやれば、getElementsByTagName('img')[0].srcなどとして絶対URLで属性値を参照できるようになる。
そのURLを属性値自身に代入すると、getElementsByTagName('body')[0].innerHTML等で取得されるHTMLに反映される。
とりあえず、そんな感じでリンク切れの修正が出来るようになった。
元からbase hrefが設定されていたりすると駄目そうだが、今の所問題になってはいないから別にいいや。
リンク先の画像をダウンロードする機能も付けようかと思ったけど、面倒なんでやめた。

その他、スクラップダイアログに概要欄を追加したりした。

投稿ファイル名: ScrapBook.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_43.zip
サイズ: 51918 bytes
44l ★:2007/05/16(水) 08:25:01 ID:???
相対リンク修正をbase hrefに対応させた。
Sleipnir公式のプラグインページを取り込もうとしたら、base hrefのせいで画像が取り込めなかったので、直した。

例の如く、動作確認以外では全然使ってない。どうしたものか。

投稿ファイル名: ResolveLink.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_44.zip
サイズ: 532 bytes
45l ★:2007/05/17(木) 07:20:35 ID:???
スクラップブックスクリプト ページ評価設定機能追加

残っていた放置フィールド・Ratingを操作する機能を付けた。
このフィールドには、ページの評価を設定する。
値は、-100から100の範囲に収められる。

コマンドフォームから、表示中のページやリストでチェックを入れたページの評価を変更できる。
「++」や「----」などを入力すると、1文字に付き25ずつ値を増減させられるという機能も付けてみた。

ページの個別表示では、音量メーターのようなバーで値を表示・設定できるようにした。
このバーはスタイルシートを駆使して表現しているのだが、Trident以外ではまともに表示されない。今に始まったことではないし、今の所Sleipnir2専用のスクリプトだからいいや。

スクラップダイアログからも設定できるようにしようと思っていたのだが、忘れた。まあいいや。

後、ページのスタイルシートをいじったりした。
固定幅サイドバー+可変幅メイン部分という構成を採用しているのだが、以前のスタイルシートだと、ページ表示部に画像等があって横にはみ出してしまう場合、メイン部分がサイドバーの下に移動してしまうという問題があった。
横幅が足りないときは、レイアウトを変えずに横スクロールバーを出すようにしたい。
Wikipediaのスタイルシートをパクったら何とかなった模様。
marginに負の値を指定できるとかいう訳の分からないテクニックを使っているらしい。

投稿ファイル名: ScrapBook.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_45.zip
サイズ: 53890 bytes
46l ★:2007/05/17(木) 11:24:45 ID:???
Googleノートブックのフレームウィンドウを表示するUserActionスクリプト
IE用の拡張をインストールすると追加されるボタンを押すことで画面右下に表示されるようになる奴を、Sleipnirでも使えるようにする。

Proxomitronのヘッダログで監視したところ、表示に使われているURLが分かったので、それをフレームとしてページに追加することに。
画面右下に固定されるように、スクロールやリサイズにイベントを割り当てて位置を追従させる。
clientWidthとかscrollLeftとかの関係が分かりづらくて困る。
動きがやたらとぎこちないが、まあいいだろう。

とりあえず普通に表示できたが、閉じるボタンを押してもフレームが閉じないのが間抜けだ。
自前の閉じるボタンを付けようかと思ったが、途中で面倒になったので、同じコマンドを再実行したら閉じることにした。
ついでに、スタイルシートのclipという奴で、タイトルバーの部分を隠してやることに。

そんなわけで、Sleipnirでも選択部分をD&Dでノートブックに保存したり出来るようになった。
すばらしい。
もうスクラップブックスクリプトなんて紛い物は要らないね。

投稿ファイル名: GoogleNotebook.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_46.zip
サイズ: 583 bytes
47aaa:2007/06/01(金) 17:28:35 ID:v1KgzVqA
>>380
ttp://lukewarm.s151.xrea.com/test/read.cgi/b/1163165308/
ここのどこかで実験してたよ
48aaa:2007/06/01(金) 17:30:14 ID:v1KgzVqA
すんません。誤爆orz
49l ★:2007/06/02(土) 10:22:18 ID:???
AutoPagerizerらしきもの
せっかくXPathが使えるようになったので、作ってみた。

window.onscrollでページの末尾近くまでスクロールしたことを検知して処理を実行させる。
ブラウザ側のJavaScriptで動作するかよく分からなかったので、>>25の方法を利用してスクリプトコントロールを常駐させる。
JavaScriptがOFFでも動作するのがよろしい。

nextLinkのhrefを取得しようとしたら、URLが勝手にデコードされて、なぜか文字化けしやがる。
encodeURI()しても正しく再エンコードできない。
「goungoun blog. ≫ Blog Archive ≫ getAttribute href、MSIE6が勝手にURLデコードする問題?(http://goungoun.dip.jp/app/blog/index.php/2006/08/27/19/)」に対策が載っていた。
この方法では、ソースに記述された生のURLが得られるが、相対パスの場合もあるのが難点。
以前作ったURLモジュールのbuild()メソッドで結合すればよい。
片方がサーバルートからのパスだったときに正しく動作しないことに気付いたので修正した。

取得したHTMLもなぜか文字化けする。
HTTPモジュールの自動文字コード変換が適当だったのが原因らしい。
ADODBの適当な判別に任せず、真面目にレスポンスヘッダやmetaタグからcharsetを取得するようにしたらまともになった。

取得したHTMLから表示する部分と次ページへのリンクを抽出する部分は、ActiveXObject('htmlfile')を利用する。

とりあえず、はてなブックマークのエントリリストで試してみたところ、それなりに動作しているようだった。
http://swdyh.infogami.com/autopagerizeの定義情報を取得してスクリプトを生成できるようにしようかと思ったが、面倒なんでやめた。
定義情報に書いてあるURLパターンがSeaHorseのincludeに互換性があるかどうか怪しいし。

投稿ファイル名: AutoPagerizer.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_49.zip
サイズ: 16650 bytes
50l ★:2007/06/02(土) 12:03:40 ID:???
>>49修正
なぜかwindow.windowとなっていて動作しなくなっている部分があったので直した。
後、XPathで//divのような部分をgetElementyByTagName()に変換する処理を追加してみたが、あまり速くなっていないような気がする。

投稿ファイル名: AutoPagerizer.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_50.zip
サイズ: 16724 bytes
51l ★:2007/06/02(土) 13:41:00 ID:???
・タグ内ではない場所の特定の単語にマッチする正規表現

var re=new RegExp('\\bhref\\b(?=[^>]*(?:<|$))','ig');
document.body.innerHTML=document.body.innerHTML.replace(re,'<span style="background-color:yellow">$&</span>');
こんな感じでやれば、タグ内の文字列に誤爆せずにページ上の単語をハイライト出来るような気がする。
Sleipnirのハイライトより3倍くらい速いような気がするが、何か間違っているような気がしないでもない。

あと、SleipnirがハイライトしたHTMLを見たら、全てのspanタグにid=SleipnirHighlightが付いていて吹いた。
52l ★:2007/06/02(土) 18:08:49 ID:???
・全てのテキストノードに正規表現でハイライトをかける
>>51の方法は、ノードが再生成されるから色々と駄目な気がする。
スクリプトで割り当てたイベントとかがぶっ飛んだり、iframeが再読込されたりとか。
そこで、DOMツリーをたどり、全てのテキストノードに対してハイライト処理を行うというのを考えた。

var code='('+function(){
function hilightChild(doc,node,ptn){
for(var cn=node.firstChild;cn;cn=cn.nextSibling){
switch(cn.nodeType){
case(3):{
var p=0;
var nv=cn.nodeValue;
nv.replace(ptn,function(found){
var offset=arguments[arguments.length-2];
if(p<offset){
node.insertBefore(doc.createTextNode(nv.substring(p,offset)),cn);
}
if(found){
var elem=doc.createElement('span');
elem.innerText=found;
elem.style.backgroundColor='yellow';
node.insertBefore(elem,cn);
}
p=offset+found.length;
});
cn.nodeValue=nv.substr(p);
break;
}case(1):{
arguments.callee(doc,cn,ptn)
break;
}
}
}
}
p=new RegExp('href','ig');
hilightChild(document,document.documentElement,p);

case(3)以降が、各テキストノードに対してハイライト処理を行う部分。
nodeValueに対してString.replace()を適用する。一致箇所が見つかるごとに、第2引数に渡した関数が呼ばれる。
関数の中では、対象ノードの前に前回一致から今回一致までの間のテキストをテキストノードとして挿入し、innerTextにマッチ文字列を入れたspan要素を挿入する。
childNodesをfor(...;i<l;i++)で回していると、要素が増えることによるインデックスの変化が生じてややこしいので、firstChildとnextSiblingでチェックするようにした。

body.innerHTMLの置換に比べるとかなり遅いが、まだSleipnirのハイライトよりは速いような気がする。
53l ★:2007/06/03(日) 17:39:41 ID:???
>>52のハイライトだが、textarea内のテキストへの誤爆対策をしていない。
どうなるかと思って試してみたら、普通にテキストエリア内のテキストに背景色が付いた。
このまま投稿してみたらどうなるのだろう。
とりあえず「テスト」をハイライトして試してみる
54l ★:2007/06/03(日) 17:40:45 ID:???
どうもならなかった。投稿されるのはtextareaのinnerTextなのだろうか。
55l ★:2007/06/04(月) 16:20:23 ID:???
>>52の方法では、複数のキーワードを「|」区切りでまとめて検索してハイライトすることも可能なはずである。
例えば、['Sleipnir','JavaScript']が渡されたら、color['sleipnir']=''#FFFF00';のようにして単語と色を設定しておき、
sleipnir|javascriptを検索して、spanのスタイル設定でelem.style.backgroundColor=color[found.toLowerCase()]とすればいい。

などと言うことをやろうかとおもったが、飽きた。
56l ★:2007/06/04(月) 20:53:41 ID:???
はてなダイアリーAutoPager
>>49の奴を応用して作った。
「//div[@class="calendar"][last()]/a[contains(string(text()),"前の")]」のような複雑なXPathもそれなりに動作しているようで何よりだ。

はてなダイアリーのHTMLでは、「class="main"」の要素の下に「class="calendar"」で前後のページへのリンクがあり、その後に「class="day"」で各日付ごとの要素がある。
この各日付ごとの要素を全て抜き出して表示したいが、前回のバージョンでは、最初のノードのHTMLしか表示していなかったので、全てのノードのHTMLを表示するように修正した。

実行には>>50の奴が必要。

投稿ファイル名: HDiaryAutoPager.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_56.zip
サイズ: 1302 bytes
57l ★:2007/06/04(月) 21:01:43 ID:???
AutoPagerを有効にしたら、永久にページ末尾にたどり着けなくなった。
58l ★:2007/06/05(火) 13:46:30 ID:???
SleipnirScriptの中でsleipnir.Database.Open()したデータベースは、SleipnirScriptが終了しても使える
ぷよラボ(http://www.google.co.jp/notebook/public/10297603972126706440/BDRO8IgoQwtm4pKQi)のどこだったかで知った。

「_window.sleipnir=sleipnir」というようにして他所のオブジェクトにSleipnirScriptの組み込みオブジェクトを追加してやっても、SleipnirScriptが一旦終了してしまうと使えなくなってしまう。
確か、sleipnir.Databaseを追加してやってもダメだった気がする。
スクリプト実行機能側で、実行終了後に毎回オブジェクトを解放しているのだろう。
しかし、「_window.mydatabase=sleipnir.Database.Open('myDatabase')」とした場合、SleipnirScriptが終了していても使える。
メソッドで動的に生成したオブジェクトまでは、いちいち解放してないのだろう。
これで、ブラウザ上のスクリプトなどからもSleipnirのデータベース機能が利用できる。
データベースさえ使えるようになれば、残りの機能はAPIなどで補える。
実行中にSleipnirがハングアップする組み込みスクリプトの問題を回避しつつ、ほぼ全ての機能を利用できそうだ。

ブラウザのJavaScriptは、Sleipnirのプロセス内で実行されているので、オブジェクトをそのまま使えるのは分からなくもない。
では、wscript.exeなどの別プロセスではどうだろうか。以下のようにして試してみた。

try{
var api=sleipnir.API;
api.GetWindowObject(api.GetDocumentID(api.ActiveIndex)).sleipnir_db=sleipnir.Database.Open("ScrapBook");
(new ActiveXObject("WScript.Shell")).Run('cscript "'+sleipnir.ScriptFullName+'"',0);
}catch(e){
basedir=WScript.ScriptFullName.replace(/(\\[^\\]+){3}$/,"\\ScrapBook\\");
eval((new ActiveXObject("Scripting.FileSystemObject")).OpenTextFile(basedir+"lib\\Std.js").ReadAll());

api=new ActiveXObject('Sleipnir.API');
win=api.GetWindowObject(api.GetDocumentID(api.ActiveIndex));
WScript.Sleep(1000);
res=win.sleipnir_db.Query('SELECT count(ID) FROM Pages');

win.alert(res.Current().At(0));


obj=(new ActiveXObject("WScript.Shell")).Exec('ping google.com');
win.alert(obj.StdOut.ReadAll());
}

普通に使えているようである。
これで、WScriptオブジェクトを使ったり、非表示のcscript.exeから起動した非表示のコンソールプログラムの標準入力に書き込んだりすることも可能になりそうだ。(標準出力の方はプロセスが終了するまで読み出せない腐れ仕様なので対策が必要だが)

また、プロセス間で共有できるのだから、勝手に作ったスクリプトコントロールでも利用できるに違いない。
・Webページのイベントやタイマーに割り当てられて
・JavaScript無効でも動作して
・Sleipnirのデータベース機能を利用でき
・実行中にSleipnirがハングアップしたりせず
・クロスドメイン制限のないXMLHTTPRequestやADODB.Streamなども使え
・外部プロセスを呼び出したりしない
というようなスクリプト実行も可能だろう。

以前頑張って作ったsqlite3.exeを使ったデータベース読み書きモジュールが無駄になってしまったが、まあいいか。
59l ★:2007/06/07(木) 22:22:58 ID:???
AutoPagerの奴更新


なぜか継ぎ足した部分のHTMLが崩れると思ったら、抜き出した要素そのものではなくinnerHTMLを挿入していたのが悪かった。
outerHTMLにしたら直った気がする。

XPathライブラリは、いくつかの未実装箇所を適当に実装した。
ノードの重複除去とソートは、Step()でNodeSetに追加していくところで行うことに。
上手く重複を防止する方法が思いつかなかったので、既存の項目と一つずつ照らし合わせて、既に登録されていたら登録しないという安直な処理になった。
重複が起こりえない箇所ではチェックを省き、ある程度は効率化したつもり。

だいぶまともになったが、「|」演算子によるノード集合の結合が適当なままだ。
重複の除去は出来無くないが、どうやってノードをソートしたものか。
HTMLのエレメントならsourceIndexを比較すればいいのだが。

その他、preceding基準点とfollowing基準点を実装したり、不具合を直したりした。

あと、HTTPライブラリの文字コード判別がおかしかったのを修正。

投稿ファイル名: AutoPagerizer.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_59.zip
サイズ: 18892 bytes
60l ★:2007/06/09(土) 11:51:39 ID:???
sleipnirオブジェクトもSleipnirScriptが終了しても普通に使える
らしい(http://d.hatena.ne.jp/Puyo2/20070608/p1

以下のスクリプトをUserActionで試してみたところ

code='('+(function(){
window.mainfunc=function(){
sleipnir.Echo('main');
}
window.attachEvent('onunload',function(){
sleipnir.Echo('unload');
});
window.setTimeout('window.mainfunc()',1000);
})+')();';
sc=new ActiveXObject('MSScriptControl.ScriptControl.1');
(_window.__ScriptControls__||(_window.__ScriptControls__=new Array)).push(sc);
with(sc){
Language='JScript';
AddObject('window',_window);
AddObject('document',_document);
AddObject('sleipnir',sleipnir);
Eval(code);
}
sleipnir.Echo('Exit from SleipnirScript');

確かにsetTimeoutでもイベントでも普通に動作した。
なんで以前試したときうまく行かなかったのか謎だが、とりあえず今は動いているから構うまい。

このようにしてwindowにスクリプトコントロールを付けていると、ページに仕込まれたJavaScriptからスクリプトコントロールのEvalで好き放題やられる恐れがある。
ページのJavaScriptをONにすることなんて滅多にないので別にどうでもいいが、何とか対策をしたいところ。

Eval('var sc=window.__ScriptControls__.pop();window.attachEvent("onunload",function(){sc=null;});'+code);

という風に改変してやれば、Evalされるコードとそこで作られた関数からしか見えない変数になり、ページ上のJavaScriptからは参照できなくなるような気がする。
関数がwindowのイベントにアタッチされて生存している間は、そこから参照可能なオブジェクトも生き延びるはず。
試してみたところ、動作しているような気がする。

スクリプトコントロールが正しく解放されているのかは、

window.mainfunc=function(){
ex=(new ActiveXObject("WScript.Shell")).Exec('cmd');
}

としてやれば試せるはず。
こうして生成されたWshScriptExecオブジェクトは、解放されるときに子プロセスを終了する。
実行してみたところ、確かに1秒後にコマンドプロンプトが表示され、ウィンドが閉じられるのに連動して終了した。
なお、sc=nullの部分を削除したら、正しく解放されなくなった。
どこから参照されているのかよく分からんが、恐ろしや。

そんなわけで、とりあえずwindowに安全にスクリプトコントロールを付加してイベントなどからsleipnirオブジェクトの全機能を利用することは出来そうである。
しかし、この方法では、ウィンドウが閉じられたときにスクリプトコントロールが使えなくなってしまう気がする。
非表示で起動したcscript.exeに受け渡すことは出来るだろうか。
61l ★:2007/06/09(土) 12:15:09 ID:???
cscript.exeにsleipnirオブジェクトを渡すこともできた
アクティブなページのwindow経由で普通に渡せた。

try{
var api=sleipnir.API;
api.GetWindowObject(api.GetDocumentID(api.ActiveIndex)).sleipnir=sleipnir;
(new ActiveXObject("WScript.Shell")).Run('cscript "'+sleipnir.ScriptFullName+'"',0);
sleipnir.Echo('Exit from SleipnirScript');
}catch(e){

api=new ActiveXObject('Sleipnir.API');
sleipnir=api.GetWindowObject(api.GetDocumentID(api.ActiveIndex)).sleipnir;
sleipnir.Echo('this is '+WScript.Name);

sleipnir.Echo(sleipnir.Database.Open("ScrapBook").Query('SELECT count(ID) FROM Pages').Current().At(0));
obj=(new ActiveXObject("WScript.Shell")).Exec('ping google.com');
sleipnir.Echo(obj.StdOut.ReadAll());
}

Sleipnir.APIが使えない環境でもどうにかしたいところ。
http://www.vector.co.jp/soft/winnt/prog/se430605.htmlによると、InternetExplorer.Applicationを経由して受け渡せばいいらしいが、起動に時間がかかりそうで鬱陶しい。
まあ、代替手段だし別にいいか。
62l ★:2008/01/30(水) 03:51:55 ID:???
Googleの検索結果から要らないページを消し去るユーザースクリプト

オンラインRSSリーダーとか、ソーシャルブックマークとか、書籍の目次とか、Googleの検索結果には見ても時間が無駄になるだけのゴミ検索結果が多すぎる。
例えば、PHPでMySQLを使ってどうのこうのする方法を知りたくて「PHP MySQL どうのこうの」と検索したとして、
「PHPの文字コード」「MySQLのチューンナップ」「C#でどうのこうのする方法」というページが登録されているだけのソーシャルブックマークやRSSリーダーのページが見つかっても何の役にも立たない。
「PHPでMySQLをどうのこうのする方法」というページへリンクしているだけのブックマーク情報ページも要らない。元のページだけ見つかれば十分だ。
また、「PHPでMySQLをどうのこうの」という内容を含んでいるらしい本の目次が載ったオンライン書籍通販サイトのページも、見つけたところで探している知識を得られるわけではないのでゴミ同然だ。

SeaHorseスクリプトでこれらのゴミサイトへのリンクを一掃してやる。
ゴミサイトのドメインを配列で用意しておき、連結して正規表現オブジェクトを作り、document.linksからhrefがマッチするリンクを探し、しかるべき加工をする。
消し去られたことすら分からないくらい跡形もなく消し去ってしまうと、書籍の評判を検索したいときとかに不便かも知れないので、
リンクだけは文字サイズを小さくして残し、残りの情報部分はリンクのツールチップに書き込んで消すことにした。

検索結果のページから消したいサイトの登録を行えるようにしようかと思ったが、検索結果を表示する度にリストを読み込むのは無駄だし、作るのが面倒だったのでやめた。
だが、ルール部分をスクリプトに埋め込んでしまうと、しょっちゅう編集するのは面倒くさい。
そこで、あらかじめそれっぽいサイトを一通り登録しておくことに。
少し検索するだけで、20以上のサイトが集まってしまった。ゴミページばかり増やしやがって。


投稿ファイル名: GoogleKillUselessSite.user.zip
http://lukewarm.s151.xrea.com/b/file/1163165308_62.zip
サイズ: 774 bytes
57KB
名前: E-mail:
ファイル:
0ch BBS 2005-10-08