2009年02月25日
Google検索後のページで検索ワードをハイライト表示するGreasemonkeyスクリプト
Google検索でキャッシュを見ると色が変わるアレと同じことを通常の検索時にもするスクリプトです。
インストールはこちらから⇒インストールする
以下、蛇足。
ワードに一致した部分に前から機械的にspanタグをつけていくだけなので、「Java JavaScript」のように先にあるワードが後にあるワードに含まれるような場合などは後のワードがハイライトされなくなります(逆順なら大丈夫なんですが)。これは仕様ということで。
"hoge and hoge"というテキストのhogeの部分をspanタグで囲った状態のノードツリーがほしいときに、空のelementを生成してそのinnerHTMLに"<span>hoge</span> and <span>hoge</span>"というテキストを放り込んだ後にchildNodesを取得するというかなり強引な方法を使っているんですけど、これをもっとエレガントにやる方法ってないもんでしょうか。一ノードずつcreateしていくのは面倒だし…。innerHTMLの内部でやっている変換処理と同様のことをするネイティブな関数とかがあると嬉しいのに。
過剰にコメントつけて作ってたのでソースも一応張っときます。
// ==UserScript== // @name search word highlighter // @namespace http://inasphere.net/ // @description Google検索結果から遷移したページで検索ワードをハイライト表示する // @include * // @author inamenai // @license MIT License // @version 0.2 // ==/UserScript== // 配布場所 // http://d.hatena.ne.jp/inamenai/20090225/p1 // 変更履歴 // 2009/02/26 0.2 エスケープされていた文字がHTMLタグに戻ってしまう現象を修正 // 2009/02/25 0.1 リリース (function() { // リファラがgoogleでありかつ現在ページがgoogleでない場合のみ動作させる var GOOGLE_URL_REG_EXP = /http:\/\/.*google\.co\.jp\//; if (!GOOGLE_URL_REG_EXP.test(document.referrer) || GOOGLE_URL_REG_EXP.test(document.location.href)) { return; } // リファラから検索クエリが正常に取得できなかったら終了 var SEARCH_QUERY_REG_EXP = /q=[A-Za-z0-9%\+]+/; var queryArray = SEARCH_QUERY_REG_EXP.exec(document.referrer); if (queryArray == null || queryArray[0] == null || queryArray[0] == "") { return; } // 検索ワードごとの配列に分解 var query = decodeURIComponent(queryArray[0].substring(2)); var wordArray = query.split(/[\s\+]/); // ハイライトの対象としないHTMLタグの定義 var IGNORE_TAG_REG_EXP = /textarea|option|style|script/i; // 全検索ワードごとにループ for (var i = 0; i < wordArray.length; i++) { // body以下の全エレメントノードを取得してエレメントノードごとにループ // ハイライト用の<span>タグ追加によってツリー構造は変化するのでループのたびに再取得する var elementNodeArray = Array.slice(document.getElementsByTagName("body")[0].getElementsByTagName("*")); for (var j = 0; j < elementNodeArray.length; j++) { // エレメントノードの持つ子ノードごとにループ var childNodeArray = Array.slice(elementNodeArray[j].childNodes); for (var k = 0; k < childNodeArray.length; k++) { var targetNode = childNodeArray[k]; // 処理対象はテキストノードのみ if (targetNode.nodeType != 3) { continue; } // 親ノードがハイライト対象外のタグの場合は除外 if (IGNORE_TAG_REG_EXP.test(targetNode.parentNode.tagName)) { continue; } // テキスト内容を取得 var text = targetNode.nodeValue; // ソース上でエスケープされていた部分が特殊文字に戻った状態で取得されるので再エスケープ text = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); // 検索ワードが見つからなければ何もしない var wordRegExp = new RegExp(wordArray[i], "gi"); if (!wordRegExp.test(text)) { continue; } // 適当なエレメントノードを作ってinnerHTMLにタグ混じりのテキストを放り込む // 自動的にノードツリーに変換されるのでそれを取得 var tmpNode = document.createElement("span"); tmpNode.innerHTML = text.replace(wordRegExp, "<span class=\"swh_word" + (i % 10 + 1) + "\">$&</span>"); var childrenArray = Array.slice(tmpNode.childNodes); // 作成された子ノードごとにループ for (var l = 0; l < childrenArray.length; l++) { // 子ノードを元のノードの位置にinsert targetNode.parentNode.insertBefore(childrenArray[l], targetNode); } // 元のノードを削除 targetNode.parentNode.removeChild(targetNode); } } } // ハイライト用スタイルを追加 GM_addStyle( "span.swh_word1 {font-weight: bold; color: #000000; background-color: #ffff66;} " + "span.swh_word2 {font-weight: bold; color: #000000; background-color: #a0ffff;} " + "span.swh_word3 {font-weight: bold; color: #000000; background-color: #99ff99;} " + "span.swh_word4 {font-weight: bold; color: #000000; background-color: #ff9999;} " + "span.swh_word5 {font-weight: bold; color: #000000; background-color: #ff66ff;} " + "span.swh_word6 {font-weight: bold; color: #ffffff; background-color: #880000;} " + "span.swh_word7 {font-weight: bold; color: #ffffff; background-color: #00aa00;} " + "span.swh_word8 {font-weight: bold; color: #ffffff; background-color: #886800;} " + "span.swh_word9 {font-weight: bold; color: #ffffff; background-color: #004699;} " + "span.swh_word10 {font-weight: bold; color: #ffffff; background-color: #990099;}" ); })();
2009/02/26 追記
ソース上でエスケープされていた文字がHTMLタグに戻ってしまう問題を修正しました。id:rikuoさんありがとうございました!
トラックバック - http://d.hatena.ne.jp/inamenai/20090225/p1
リンク元
- 130 http://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4GGIH_jaJP281JP281&q=google 検索 ハイライト
- 59 http://clip.nifty.com/entry/d8454656d84f425493b1ca42c6da3a682f83d432/714078
- 54 http://www.google.co.jp/search?hl=ja&client=firefox-a&rls=org.mozilla:ja:official&hs=MVt&q=現在のページ+ハイライト 画像&btnG=検索&lr=lang_
- 48 http://www.google.co.jp/search?q=検索ワード javascript&lr=lang_ja&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:ja:official&client=firefox-a
- 37 http://www.google.co.jp/search?hl=ja&q=google+検索 ハイライト&sourceid=navclient-ff&rlz=1B3GGGL_jaJP302JP302&ie=UTF-8
- 28 http://search.yahoo.co.jp/search?p=検索ワードを取得して表示&ei=UTF-8&fr=moz2&x=wrt
- 28 http://www.google.co.jp/search?q=GOOGLE+検索+ワード&sourceid=navclient-ff&ie=UTF-8&rlz=1B3GGGL_jaJP264JP265
- 26 http://ezsch.ezweb.ne.jp/search/ezGoogleMain.php?query=google+検索ワード&sr=0002
- 25 http://www.google.co.jp/search?hl=ja&q=ハイライト表示+google&lr=
- 22 http://www.google.co.jp/search?hl=ja&q=検索ワード 表示&lr=
