htmlfileオブジェクトからcreatePopup

shearerで更新されたエントリーのポップアップ作ってたときの副産物。開いてるタブのDOMを汚さず、しかも複数ポップアップ*1を出せる。複数ポップアップを出すのにはポップアップからポップアップを出す手法があるけど、これだと親が消えたら一緒に消えてしまう*2。htmlfileオブジェクトを使ってcreatePopupすれば、windowオブジェクト自体を複数作れるので相互干渉せずに出したり引っ込めたりできる。

var ScriptControl = CreateObject("ScriptControl");
ScriptControl.Language = "JScript";
ScriptControl.AddObject("ScriptControl", ScriptControl);
ScriptControl.AddObject("sleipnir", sleipnir, true);
ScriptControl.AddCode(async);
ScriptControl.Run("async");

function async()
{
	var dummydoc = new ActiveXObject("htmlfile");
	var dummywindow = dummydoc.parentWindow;
	
	var popup = dummywindow.createPopup();
	var div = popup.document.createElement("div");
	div.innerText = "ここにテキスト";
	div.style.height = 100;
	div.style.backgroundColor = "yellow";
	popup.document.body.appendChild(div);
	
	popup.show(100, 100, 100, 100);
	dummywindow.setTimeout(function () {}, 10);//ScriptControlの破棄を遅延?
}

スクリプトの前半は非同期化のためのおまじない*3。これをやらずにUserActionスクリプトでcreatePopupを使ってもうまくいかない*4。多分、同じ理由で最後の一見無意味なsetTimeoutも削ると私の環境ではうまく動いてくれなかった。いったん表示されてしまえば即消えちゃうようなことはないけれど、どうしてこうなるかちゃんとはわからない。
本体のasyncは、別にSleipnirスクリプトじゃなくてもTridentエンジンなら普通に動く。@Type がSleipnir ScriptでないSeaHorseスクリプトなら直接使えるはず。この例の場合は

ScriptControl.AddObject("sleipnir", sleipnir, true);

すら要らないんだけど、普通何か作るならISleipnirは必須だと思うから残しておいた。

*1:createPopupはひとつのウィンドウに付きひとつしかポップアップを出せない

*2:階層メニュー作るときは都合がいいんだけど

*3:実際使うときはRunをtry〜catchしてデバッグ用にエラー補足したほうがいい

*4:多分表示されるより早くオブジェクトが破棄されてる