Firefox 拡張機能 (Extensions) の作成方法(7) -- 表示されているページへのアクセス

C:\Program Files\Mozilla Firefox\extensions に pagehack@sample ディレクトリを作成して、
pagehack@sample.lzh の内容をコピーします



ブラウザでダウンロード
firefoxOverlay.xul
セパレータは自分で追加しているので、他の ID と重複しないように命名
する必要があります
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="chrome://ph/skin/overlay.css" type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://ph/locale/ph.dtd">
<overlay id="ph-overlay"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script src="overlay.js"/>
  <stringbundleset id="stringbundleset">
    <stringbundle id="ph-strings" src="chrome://ph/locale/ph.properties"/>
  </stringbundleset>

  <menupopup id="menu_ToolsPopup">
    <menuseparator id="phSep" />
    <menuitem id="ph-hello" label="&ph.label;" 
              oncommand="ph.onMenuItemCommand(event);"/>
  </menupopup>
</overlay>
ph.dtd
<!ENTITY ph.label "WEBページコントロール">
overlay.js
メニューが選択されると、onMenuItemCommand が呼ばれてダイアログが表示されます
この際、引数に window.content を渡してダイアログ内で利用できるようにしています。
window.content は、ブラウザが現在表示しているページの window オブジェクトです。

この window.content を介して、WEB ページにアクセスします
var ph = {
  onLoad: function() {
    // initialization code
    this.initialized = true;
    this.strings = document.getElementById("ph-strings");
  },
	onMenuItemCommand: function(e) {
		var features = "chrome, dialog, modal, centerscreen,";
		features += "resizable=yes, width=400, height=240";
		window.openDialog(
			"chrome://ph/content/about.xul",
			"",
			features
			, window.content
		);
	},

};
window.addEventListener("load", function(e) { ph.onLoad(e); }, false);
about.xul
ダイアログの画面定義ですが、action.js を参照しています。
Action1 と Action2 は action.js 内で定義されている関数です

dialog の buttons="," 指定は、ダイアログのオプションとしてのボタン 
を表示しないという記述方法です
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!DOCTYPE dialog SYSTEM "chrome://ph/locale/about.dtd">
<dialog
	title="&about; PageHack"
	xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
	buttons=","
	onload="onLoad();"
>
<script type="application/x-javascript" src="chrome://ph/content/action.js"/>
<groupbox align="center" orient="horizontal">
<vbox>
	<button
		label="このページにボタンを追加する"
		oncommand="Action1();"
	/>
	<button
		label="このページの関数を呼び出す"
		oncommand="Action2();"
	/>
	<textbox
		id="pageFunction"
		size="40"
	/>
	
</vbox>
</groupbox>
</dialog>
action.js
onLoad でこのダイアログに渡された引数を変数に保存しています。
この targetWindow が、window.content であり、表示しているページの
window オブジェクトになります。

Action1 では、ページの BODY 内の先頭に、innerHTML でボタンを追加して、
ページを全て表示したり非表示にしたりするという機能を実装しています

Action2 は、対象ページ内で定義されている function を呼び出す為の方法例です。
この、window.content は、function の参照を許していないので、div を埋め込んで
div の onClick を setAttribute で変更してイベントとして呼び出します。

このサンプルでは、関数を呼び出す文字列を入力して( JavaScript 構文 )
それを onClick にセットしてから click イベントを呼び出しています
var targetWindow;
function onLoad() {
	targetWindow = window.arguments[0];
}

// *********************************************************
// このページに表示・非表示ボタンを追加する
// *********************************************************
function Action1() {

	var str = "";

	str += "<INPUT type='button' value='非表示'";
	str += " style='float:right'";
	str += " onClick='document.getElementById(\"bodyarea\").style.display=\"none\"'";
	str += ">";
	str += "<INPUT type='button' value='表示'";
	str += " style='float:right'";
	str += " onClick='document.getElementById(\"bodyarea\").style.display=\"\"'";
	str += "><div id='bodyarea'>";

	var base
		= targetWindow.document.getElementsByTagName("BODY")[0].innerHTML;

	targetWindow.document.getElementsByTagName("BODY")[0].innerHTML
		= str + base + "</div>";

}

// *********************************************************
// このページの関数を呼び出す
// *********************************************************
function Action2() {

	var obj = targetWindow.document.getElementById("myCommand");

	if ( !obj ) {
		var str = "<div id='myCommand'></div>";
		var base
			= targetWindow.document.getElementsByTagName("BODY")[0].innerHTML;
		targetWindow.document.getElementsByTagName("BODY")[0].innerHTML
			= str + base;
	}

	var funcString = document.getElementById("pageFunction").value;

	obj = targetWindow.document.getElementById("myCommand");
	obj.setAttribute("onClick",funcString);

	var clickevent=document.createEvent("MouseEvents");
	clickevent.initEvent("click", true, true);
	targetWindow.document.getElementById("myCommand").dispatchEvent(clickevent);

}