直すと言って放置していたスクリプトを修正した

[追記 2015 Mar. 10th 01:00頃]
on Google の方は一部動かなくなったみたいなので暫定の対処法書きました。
http://d.hatena.ne.jp/barrackdo/20150309/1425916907
たぶん大丈夫な……はず。
ろくにテストしてないけどw
[追記終了]

おひさー

2013年も既に1月が過ぎ2月に突入してますね。
ここ数カ月ばかり鬱モードに入っていて、しばらく精神的にアウトプットが無理な状態でした。*1


で、消息を絶つ前に Google 検索が変わって動かなくなっていたスクリプトを改修するとお約束していたのですが、2〜3ヶ月ほど放置状態になってしまっていて、それに関しては非常に申し訳なく思っています。


というわけで、遅きに失した感はあるものの復帰第1段はこの約束を果たすこととします。

Googleの検索結果に他の検索エンジンへのリンクを挿入するやつ

前バージョン: http://d.hatena.ne.jp/barrackdo/20120301/1330611582
前々バージョン: http://d.hatena.ne.jp/barrackdo/20110514/1305402951
前々々バージョン: http://d.hatena.ne.jp/barrackdo/20110428/1304022996

そういえば、前のままだと Google+ 向けのスクリプトっぽいので名前変えました。

今回動作を確認しているのは Sleipnir 2.9.15(+ IE9)、Furefox Portable 18.0.2(+ Greasemonkey 1.7.1)、SRWare Iron Portable 24.0.1350.0(176001)*2です。

例のごとく Sleinpir は文字コード Shift_JIS で、Iron 含む Chrome 系は文字コード UTF-8 で、Firefox はどちらでも可で保存しまして突っ込んでください。

今回は再びダウナーな状態と重なってしまうという不幸への対策として、挿入位置と検索ワードの取得方法をユーザ側で変更できるようにしました。
スクリプト中の以下の場所の数字を書き換えればおkです。

var insPos = 0;
var getWordType = 0;

基本的には、それぞれ数字が大きい方がデザインの変更に強いはずです。
設定できる数値の幅なんかはスクリプト中に書いてあるのでここでは特に書きません。

また、検索エンジンの増減、変更方法などは前回のものと変わっていないのでこれまた割愛。

あと、すっかり忘れていた Sleipnir サーチの方にも対応させておきました。

// ==UserScript==
// @name          Other Search Engine Link on Google
// @namespace     http://d.hatena.ne.jp/barrackdo/
// @include       http*://*google.co*/search?*q=*
// @include       http*://www.google.com/webhp?*#*q=*
// @include       http*://www.google.co.jp/*#*q=*
// @include       http://search.fenrir-inc.com/?*
// ==/UserScript==

(function(){
	// 挿入する場所。以下に数値を設定する
	// 0:検索ツールと検索結果の間(デフォルト)、1:入力欄と検索ツールの間、2:ヘッダバー、3:ページ最上部(スクロール追従)
	
	var insPos = 0;
	
	
	// 検索ワードの取得方法
	// 0:検索ボックスから(動的:検索ボックスの検索ワードを変更すると、その検索ワードに変わる)、1:URLのクエリ(静的:検索ボックスの検索ワードを変えても、最初に検索したワードを使う)
	
	var getWordType = 0;
	
	
	// 挿入するリンクの設定
	// "["と"]"で囲まれたの中がひと固まりで、各設定は",(カンマ)"で区切る
	// 1つ目は表示方法。「0」で表示しない、「1」でアイコンのみ、「2」でテキストのみ、「3」両方
	// 2つ目は検索エンジン名。1つ目で「2」または「3」の時に表示するテキスト
	// 3つ目はアイコン。使いたい検索エンジンのドメインが例えば「example.com」だった場合は大抵の場合「getFavicon("example.com")」または「"http://example.com/favicon.ico"」みたいな感じでおkなはず
	// 4つ目は検索エンジンのリクエスト文。「\{searchTerms\}」な部分が検索ワードに置換される。あと、GETメソッドのみ対応
	// 5つ目は検索ワードをエンコードするかどうか「true」か「false」の2値で前者の場合は UTF-8 でエンコードされる。Shift_JIS だとか EUC-JP でエンコードは出来ない。
	
	var lnks = [
		[1, "Twitter", getFavicon("twitter.com"), "http://search.twitter.com/search?q=\{searchTerms\}", true],
		[1, "Yahoo!J", getFavicon("www.yahoo.co.jp"), "http://search.yahoo.co.jp/search?ei=UTF-8&fr=yjdnqp&p=\{searchTerms\}", true],
		[1, "bing", getFavicon("www.bing.com"), "http://www.bing.com/search?q=\{searchTerms\}&go=&form=QBLH&qs=n&sk=", true],
		[1, "Wikipedia", getFavicon("ja.wikipedia.org"), "http://ja.wikipedia.org/w/wiki.phtml?search=\{searchTerms\}", true],
		[1, "amazon", getFavicon("www.amazon.co.jp"), "http://www.amazon.co.jp/exec/obidos/external-search/250-0880593-9671458?mode=blended&tag=sleipnir0a-22&field-keywords=\{searchTerms\}", true],
		[1, "YouTube", getFavicon("www.youtube.com"), "http://www.youtube.com/results?search_query=\{searchTerms\}&search_sort=video_date_uploaded", true],
		[1, "ニコ動", getFavicon("www.nicovideo.jp"), "http://www.nicovideo.jp/search/\{searchTerms\}", true]
	];
	
	
	
	
	
	var d = document, uri = location.hostname.match(/search\.fenrir-inc\.com/) ? 1 : 0;
	
	setInterval(function(){
		var dv, tmp_q, sw = [], osel = d.getElementById("osel"), tmp_a;
		
		if(!osel) {
			// 挿入位置
			dv = d.createElement("div");
			dv.id = "osel";
			dv.style.height = "22px";
			dv.style.color = "#999";
			dv.style.lineHeight = "bottom";
			if(insPos == 1) {
				dv.style.marginBottom = "10px";
				dv.style.borderBottom = "1px solid #eee";
				if(uri === 1) {
					// 180 : #sideMenu の width
					// 14 : #sideMenu の margin-right
					dv.style.paddingLeft = 180 + 14 + "px";
					d.getElementById("sform").getElementsByTagName("form")[0].appendChild(dv);
				}else {
					// 122 : #center_col の margin-left
					dv.style.paddingLeft = 122 + "px";
					d.getElementById("mngb").appendChild(dv);
				}
			}else if(insPos == 2) {
				dv.style.display = "inline";
				if(uri === 1) {
					d.getElementById("etc").appendChild(dv);
				}else {
					d.getElementById("gbzc").appendChild(dv);
				}
			}else if(insPos == 3) {
				dv.style.position = "fixed";
				dv.style.top = "8px";
				if(uri === 1) {
					dv.style.right = "160px";
					dv.style.zIndex = "9";
				}else {
					dv.style.right = "128px";
					dv.style.zIndex = "999";
				}
				d.body.appendChild(dv);
			}else {
				dv.style.marginBottom = "10px";
				dv.style.borderBottom = "1px solid #eee";
				if(uri === 1) {
					// 180 : #sideMenu の width
					// 14 : #sideMenu の margin-right
					dv.style.paddingLeft = 180 + 14 + "px";
					d.body.insertBefore(dv, d.getElementById("main"));
				}else {
					// 122 : #center_col の margin-left
					dv.style.paddingLeft = 122 + "px";
					d.getElementById("cnt").insertBefore(dv, d.getElementById("ucs"));
				}
			}
			
			setLink(dv);
		}else {
			tmp_a = osel.getElementsByTagName("a");
			if(getWordType === 1) {
				tmp_q = location.href.split("?")[1].split("&");
				for(var i = 0, len = tmp_q.length; i < len; i++) {
					if(tmp_q[i].match(/^q=/)) {
						sw.push(decodeURIComponent(tmp_q[i].split("=")[1]));
						sw.push(tmp_q[i].split("=")[1]);
						break;
					}
				}
			}else {
				tmp_q = uri === 1 ? d.forms.namedItem("gs").elements.namedItem("q").value : d.forms.namedItem("gbqf").elements.namedItem("q").value;
				sw.push(tmp_q);
				sw.push(encodeURIComponent(tmp_q));
			}
			
			for(var i = 0, len = lnks.length; i < len; i++) {
				if(lnks[i][4]) {
					tmp_a[i].href = lnks[i][3].replace("\{searchTerms\}", sw[1]);
				}else {
					tmp_a[i].href = lnks[i][3].replace("\{searchTerms\}", sw[0]);
				}
			}
		}
	}, 1000);
	
	
function setLink(elm) {
	var q = uri === 1 ? d.forms.namedItem("gs").elements.namedItem("q").value : d.forms.namedItem("gbqf").elements.namedItem("q").value, oselog = new Array(lnks.length), tmp_link = "";
	
	for(var i = 0; i < lnks.length; i++) {
		if(lnks[i][0] > 0) {
			oselog[i] = d.createElement("a");
			if(lnks[i][4]) {
				oselog[i].href = lnks[i][3].replace("\{searchTerms\}", encodeURIComponent(q));
			}else {
				oselog[i].href = lnks[i][3].replace("\{searchTerms\}", q);
			}
			
			if(lnks[i][0] % 2 === 1) {
				tmp_link += "<img src=\"" + lnks[i][2] + "\" width=\"16\" height=\"16\" style=\"border:none;\">";
			}
			if(lnks[i][0] / 2 >= 1) {
				tmp_link += lnks[i][1];
			}
			oselog[i].innerHTML = tmp_link;
			oselog[i].target = "_blank";
			oselog[i].style.marginLeft = "0.5em";
			oselog[i].style.outline = "none";
			elm.appendChild(oselog[i]);
			tmp_link = "";
		}
	}
}

function getFavicon(hst) {
	return "http://www.google.com/s2/favicons?domain=" + encodeURIComponent(hst);
}

})();

Yahoo! Japan の検索結果に他の検索エンジンへのリンクを挿入するやつ

イムリーなことに(?)、Yahoo!検索も5日にデザインが変わったみたいだったので、合わせて新しくしておきました。

上記のを書いた後にそれを流用して書いただけなので、動作確認環境などは同じです。
ただし、こちらは挿入位置だけ変更可能になっています。

// ==UserScript==
// @name          Other Search Engine Link on Yahoo
// @namespace     http://d.hatena.ne.jp/barrackdo/
// @include       http://search.yahoo.co.jp/search?*p=*
// ==/UserScript==

(function() {
	// 挿入する場所。以下に数値を設定する
	// 0:検索結果件数とウェブ検索結果表示の間(デフォルト)、1:入力欄直下、2:ヘッダバー、3:ページ最上部(スクロール追従)
	
	var insPos = 0;
	
	
	// 挿入するリンクの設定
	// "["と"]"で囲まれたの中がひと固まりで、各設定は",(カンマ)"で区切る
	// 1つ目は表示方法。「0」で表示しない、「1」でアイコンのみ、「2」でテキストのみ、「3」両方
	// 2つ目は検索エンジン名。1つ目で「2」または「3」の時に表示するテキスト
	// 3つ目はアイコン。使いたい検索エンジンのドメインが例えば「example.com」だった場合は大抵の場合「getFavicon("example.com")」または「"http://example.com/favicon.ico"」みたいな感じでおkなはず
	// 4つ目は検索エンジンのリクエスト文。「\{searchTerms\}」な部分が検索ワードに置換される。あと、GETメソッドのみ対応
	// 5つ目は検索ワードをエンコードするかどうか「true」か「false」の2値で前者の場合は UTF-8 でエンコードされる。Shift_JIS だとか EUC-JP でエンコードは出来ない。
	
	var lnks = [
		[1, "Twitter", "http://twitter.com/favicon.ico", "http://search.twitter.com/search?q=\{searchTerms\}", true],
		[1, "Google", "http://www.google.com/favicon.ico", "http://www.google.com/search?aq=f&hl=ja&ie=UTF-8&q=\{searchTerms\}", true],
		[1, "bing", "http://www.bing.com/favicon.ico", "http://www.bing.com/search?q=\{searchTerms\}&go=&form=QBLH&qs=n&sk=", true],
		[1, "Wikipedia", "http://ja.wikipedia.org/favicon.ico", "http://ja.wikipedia.org/w/wiki.phtml?search=\{searchTerms\}", true],
		[1, "amazon", "http://www.amazon.co.jp/favicon.ico", "http://www.amazon.co.jp/exec/obidos/external-search/250-0880593-9671458?mode=blended&tag=sleipnir0a-22&field-keywords=\{searchTerms\}", true],
		[1, "YouTube", "http://www.youtube.com/favicon.ico", "http://www.youtube.com/results?search_query=\{searchTerms\}&search_sort=video_date_uploaded", true],
		[1, "ニコ動", "http://www.nicovideo.jp/favicon.ico", "http://www.nicovideo.jp/search/\{searchTerms\}", true]
	];
	
	
	
	
	
	var d = document;
	
	setInterval(function(){
		var dv, tmp_q, sw = [], osel = d.getElementById("osel"), tmp_a;
		
		if(!osel) {
			// 挿入位置
			dv = d.createElement("div");
			dv.id = "osel";
			dv.style.height = "22px";
			dv.style.color = "#999";
			if(insPos == 1) {
				// 16 : favicon の height
				dv.style.marginTop = 16 + "px";
				d.getElementById("SaC").appendChild(dv);
			}else if(insPos == 2) {
				d.getElementById("SaA-dtl").appendChild(dv)
			}else if(insPos == 3) {
				dv.style.position = "fixed";
				dv.style.top = "32px";
				dv.style.right = "180px";
				dv.style.zIndex = "3333";
				d.body.appendChild(dv);
			}else {
				// 950 : #contents の width
				// 18 : #mIn の padding-left の 10 + div.bd の padding-left の 8
				// 16 : favicon の サイズ
				dv.style.width = 950 + "px";
				dv.style.margin = "0 auto";
				dv.style.paddingLeft = 18 + 16 + "px";
				d.getElementById("Sf").appendChild(dv);
			}
			
			setLink(dv);
		}else {
			tmp_a = osel.getElementsByTagName("a");
			tmp_q = d.forms.namedItem("sbn").elements.namedItem("p").value;
			sw.push(tmp_q);
			sw.push(encodeURIComponent(tmp_q));
			
			for(var i = 0, len = lnks.length; i < len; i++) {
				if(lnks[i][4]) {
					tmp_a[i].href = lnks[i][3].replace("\{searchTerms\}", sw[1]);
				}else {
					tmp_a[i].href = lnks[i][3].replace("\{searchTerms\}", sw[0]);
				}
			}
		}
	}, 1000);
	
	
function setLink(elm) {
	var q = d.forms.namedItem("sbn").elements.namedItem("p").value, oseloy = new Array(lnks.length), tmp_link = "";
	
	for(var i = 0; i < lnks.length; i++) {
		if(lnks[i][0] > 0) {
			oseloy[i] = d.createElement("a");
			if(lnks[i][4]) {
				oseloy[i].href = lnks[i][3].replace("\{searchTerms\}", encodeURIComponent(q));
			}else {
				oseloy[i].href = lnks[i][3].replace("\{searchTerms\}", q);
			}
			
			if(lnks[i][0] % 2 === 1) {
				tmp_link += "<img src=\"" + lnks[i][2] + "\" width=\"16\" height=\"16\" style=\"border:none;\">";
			}
			if(lnks[i][0] / 2 >= 1) {
				tmp_link += lnks[i][1];
			}
			oseloy[i].innerHTML = tmp_link;
			oseloy[i].target = "_blank";
			oseloy[i].style.marginLeft = "0.5em";
			oseloy[i].style.outline = "none";
			elm.appendChild(oseloy[i]);
			tmp_link = "";
		}
	}
}

function getFavicon(hst) {
	return "http://www.google.com/s2/favicons?domain=" + encodeURIComponent(hst);
}

})();

*1:インプットも同様に出来てなくて、ウラシマーな状態ですw

*2:SRWare 公式の方。PortableApps.com 版もある