/*********************************************************************
 * 右クリック禁止 NoRightClick.js v1.0
 *
 *         Copyright(C) 2010 ASANO, Sei All Rights Reserved.
 *--------------------------------------------------------------------
 * 実際には閲覧者に嫌がられるだけで何のメリットもないのですが、ウェブ
 * ブラウザ上での右クリックを禁止したいというサイト管理人は少なくない
 * ようです(画像のコピーを防ぎたいのでしょう)。そこで、ここではIEと
 * Firefoxで動作を確認した右クリック無効化スクリプトを例示しました。
 * 
 * 限られたブラウザでもこれだけのコードが必要ですし、そもそもJavaScript
 * を無効にしている／対応していないブラウザでは何の役にも立ちません。
 * Firefoxなどは右クリック禁止を無効にする設定がありますから、それを
 * 設定していれば、たとえJavaScriptを有効にしていても動作しません。
 * Operaの場合は、右クリックを検出するならあらかじめユーザが設定して
 * おかなければならなかったりします(それ以前にOperaでは、コンテキスト
 * メニューを非表示にすることはできないようです)。
 * 
 * それでも悪あがきをしたいという人は、このスクリプトを使ってください。
 * たぶんそのうちどうでも良くなってくるんじゃないでしょうか。
 * 自分としてはむしろ、これをきっかけにもっと有用なスクリプトの作成に
 * 興味を持ってもらえればと思います。
 *--------------------------------------------------------------------
 * [機能]
 * ・ウェブページ上でのコンテキストメニュー無効化。ただし無効にすると
 * 　さらに著しく利便性を損なうテキスト入力域、アンカー(リンク)は対象外。
 * ・文字選択無効化。これもテキスト入力域、アンカー(リンク)は対象外。
 * ・IE6のイメージツールバー無効化。
 *--------------------------------------------------------------------
 * [使い方] HTMLヘッダ内に以下のように記載。
 * <script type="text/javascript" language="JavaScript" src="NoRightClick.js" charset="UTF-8"></script>
 *--------------------------------------------------------------------
 * [動作確認] ※ OSはいずれも WindowsXP SP2
 * ・IE(6.0)
 * ・Firefox(3.0.1)
 * ・Firefox(3.5.7)
 *--------------------------------------------------------------------
 * このスクリプトはフリーソフトです。改造や再配布は自由に行なってかまい
 * ませんが、その際に金銭やそれに準ずるものの授受を禁止します。また
 * プログラム内にある著作権表記は削除しないでください（改造者として
 * 追記するのはかまいません）。
 *********************************************************************/
var NoRightClick_MOUSE_CODE = {
	NONE   : -1
	,LEFT  : 0
	,RIGHT : 2
}
var NoRightClick_IGNORE_ELEMENT = {
	text  : 1
	,file : 1
	,password : 1
	,textarea : 1
	,a : 1
}
NoRightClick_initialize();
NoRightClick_addMetaTag();
/*********************************************************************
 * 初期化処理。
 *--------------------------------------------------------------------
 * [引数] なし
 * [戻り] なし
 *********************************************************************/
function NoRightClick_initialize() {
	if (document.addEventListener) { //W3C Event Model
		document.addEventListener("contextmenu", NoRightClick_noEvent, false);
		document.addEventListener("mousedown",   NoRightClick_mouseDown, false);
		document.addEventListener("mousemove",   NoRightClick_mouseMove, false);
	} else if (document.attachEvent) { //IE Event Model
		document.attachEvent("oncontextmenu", NoRightClick_noEvent);
		document.attachEvent("onselectstart", NoRightClick_noEvent);
	} else { //Other
	/*
	
		if (window.onload) {
			var oldfunc = window.onload;
			window.onload = new function() {
				oldfunc();
				NoRightClick_addEventHandler(event);
			}
		} else {
			window.onload = NoRightClick_addEventHandler;
		}
		*/
	}
}
/*********************************************************************
 * IE6.0のイメージツールバーを無効化するMETAタグをdocumentに追加する。
 *--------------------------------------------------------------------
 * [引数] なし
 * [戻り] なし
 *********************************************************************/
function NoRightClick_addMetaTag() {
	var tag = document.createElement("meta");
	tag.setAttribute("http-equiv", "imagetoolbar");
	tag.setAttribute("content", "no");
	document.getElementsByTagName("head")[0].appendChild(tag);
}
function NoRightClick_addEventHandler(event) {
	NoRightClick_addEventHandlerBody("onmousedown",   NoRightClick_mouseDown);
	NoRightClick_addEventHandlerBody("onmousemove",   NoRightClick_mouseMove);
	NoRightClick_addEventHandlerBody("oncontextmenu", NoRightClick_noEvent);
	NoRightClick_addEventHandlerBody("onselectstart", NoRightClick_noEvent);
}
function NoRightClick_addEventHandlerBody(name, func) {
	var bodyObj = document.getElementByName("body")[0];
	var oldfunc = body[name];
	if (oldfunc) {
		body[name] = new function() {
			oldfunc();
			func(event);
		}
	} else {
		body[name] = NoRightClick_addEventHandler;
	}
}
/*********************************************************************
 * テキストの選択範囲をリセットする。
 * IEではonselectstart用イベントハンドラで事足りる。
 *--------------------------------------------------------------------
 * [引数] event : イベント
 * [戻り] なし
 *********************************************************************/
function NoRightClick_resetSelection(event) {
	if (event.button != NoRightClick_MOUSE_CODE.LEFT) return;
	var type = NoRightClick_getSourceElementName(event);
	if (type && NoRightClick_IGNORE_ELEMENT[type]) return;
	if (window.getSelection) {
		window.getSelection().removeAllRanges();
	} else if (document.selection) { //IEはここに来ないがいちおう
		document.selection.empty();
	}
}
/*********************************************************************
 * MouseMove用イベントハンドラ。テキストの選択範囲リセットのため。
 * IE以外で使用
 *--------------------------------------------------------------------
 * [引数] event : イベント
 * [戻り] なし
 *********************************************************************/
function NoRightClick_mouseMove(event) {
	NoRightClick_resetSelection(event);
}
/*********************************************************************
 * MouseDown用イベントハンドラ。テキストの選択範囲リセットのためと、
 * Operaなど、contextmenuをサポートしていないブラウザのため。IE以外で使用。
 *--------------------------------------------------------------------
 * [引数] event : イベント
 * [戻り] なし
 *********************************************************************/
function NoRightClick_mouseDown(event) {
	NoRightClick_resetSelection(event);
	if (event.button != NoRightClick_MOUSE_CODE.RIGHT) return true;
	return NoRightClick_noEvent(event);
}
/*********************************************************************
 * あらかじめ指定されている除外エレメントでないなら、イベントを無効にする。
 *--------------------------------------------------------------------
 * [引数] event : イベント
 * [戻り] なし
 *********************************************************************/
function NoRightClick_noEvent(event) {
	var type = NoRightClick_getSourceElementName(event);
	if (type && NoRightClick_IGNORE_ELEMENT[type]) return true;

	if (event.preventDefault) {
		event.preventDefault();
	} else if (document.attachEvent) {
		event.cancelBubble = true;
		event.returnValue = false;
	}
	return false;
}
/*********************************************************************
 * イベントが発生したオブジェクトの名称を返す。
 *--------------------------------------------------------------------
 * [引数] event : イベント
 * [戻り] イベントが発生したオブジェクトの名称
 *********************************************************************/
function NoRightClick_getSourceElementName(event) {
	var type = null;
	if (event.srcElement) {
		type = (event.srcElement.type ? event.srcElement.type : event.srcElement.tagName);
	} else if (event.target) {
		type = (event.target.type ? event.target.type : event.target.tagName);
	} else {
		type = "";
	}
	return type.toLowerCase();
}

