2007年 12月 25日

userChrome.js で設定画面をつくる

XUL で UI つくりたいなぁってちょっと思ったんです。なんかいろいろやったんですがこうしたら一応できた。なんかもっと、スマートな方法がありそうだけど……

function openChromeWindow (xml, opts) {
	// create temporary content dir.
	var t = IO.getFile("Temp", "content" + Math.random() * 0xffff);
	t.createUnique(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0700);

	// write manifest
	var f = IO.getFile("PrefD", "extensions");
	f.append("{1280606b-2510-4fe0-97ef-9b5a22eafe64}"); // userchromejs
	f.append("chrome.manifest");
	var prev = read(f);
	write(f, "content userchromejs file://" + t.path + "/\n");

	// write chrome xul
	var c = t.clone();
	c.append("temp.xul");
	c.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0700);
	write(c, xml.toXMLString());

	// refresh chrome registry
	Components.classes["@mozilla.org/chrome/chrome-registry;1"]
	          .getService(Components.interfaces.nsIChromeRegistry)
	          .checkForNewChrome();

	// open
	window[opts.fun || "openDialog"]("chrome://userchromejs/content/temp.xul", opts.name || "temp", opts.opts || "chrome");

	// remove temp files and restore original
	t.remove(true);
	write(f, prev);

	// refresh chrome registry
	Components.classes["@mozilla.org/chrome/chrome-registry;1"]
	          .getService(Components.interfaces.nsIChromeRegistry)
	          .checkForNewChrome();


	function read (f) {
		var res = "", str, strm = IO.newInputStream(f, "text");
		while (str = strm.readString(4096)) res += str;
		strm.close();
		return res;
	}

	function write (f, str) {
		var strm  = IO.newOutputStream(f, "text");
		strm.writeString(str);
		strm.close();
	}
}

こんなふうにつかう

default xml namespace = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
openChromeWindow(
	<window>
		<script type="application/javascript">
			const prefs = Components.classes["@mozilla.org/preferences;1"]
			                        .getService(Components.interfaces.nsIPrefBranch);
			alert(prefs.getCharPref("browser.startup.homepage"));
		</script>
	</window>
);
  • 一つのウィンドウとして開きたい
  • chrome 特権を行使したい
    • chrome 特権を行使するには chrome: じゃないとだめらしい
    • chrome: は manifest かかないとだめらしい