2012-01-02 2011年に読んだ本
2012-01-01 2011年に読んだ本
2011-11-21 AutoPagerize側あれこれ
■AutoPagerizeもwindow共有不可の問題にはやっぱり影響受けてて、そのあたりちょっと考えてみましたよ
社長が訊く
任天堂のサイトにあるゲーム製作の舞台裏紹介ページ「社長が訊く」。現行のAutoPagerizeだとscriptタグで追加されるムービーへのリンクが変なことになるので、それをどうにかするスクリプトを書いた。
おそらくgreasemonkey版のAutoPagerizeでないと動かないので悪しからず。しかも以下に示す対策も必要。
AutoPagerizeにもsharedObjectを処方
ユーザースクリプト間のwindowの共有が問題となって、minibufferやLDRizeの動作に差し障りが出るのは既出の通り。対策もまた既出。他にもReblogCommandのような双方に依存するスクリプトがあれば、記事(id:aiwendi:20111115:1321338264) tでリブログ復活 - aiwendilの日記 のようにすれば解決する。
ということで、sharedObjectが用意できている環境ならば、windowの共有自体は下のようにすれば済む。行のオフセットが5000とかやたらアホみたいな数値になっているのは、ローカルにごりごり書いたSITEINFOの分なのでお気になさらぬよう。
@@ -5255,8 +5002,6 @@ if (typeof(window.AutoPagerize) == 'undefined') { } window.AutoPagerize.launchAutoPager = launchAutoPager + sharedObject.AutoPagerize = window.AutoPagerize + var ev = document.createEvent('Event') ev.initEvent('GM_AutoPagerizeLoaded', true, false) document.dispatchEvent(ev)
window.AutoPagerizeを全部sharedObject.AutoPagerizeに書き換えなくても、AutoPagerize側の準備が出来た時点(つまり、GM_AutoPagerizeLoadedイベントの発火直前)で、sharedObjectにもコピーを作ってやればいい、というわけ。
AutoPagerizeのAPI(自分用メモを兼ねて)
で、AutoPagerizeとスクリプトの連携に話は移るわけだが、今回書いたスクリプトはAutoPagerizeのAPI(AutoPagerize Wiki: APIs (ja))を利用している。
APIs
Filters
別のGreasemonkey Scriptから、AutoPagerizeの動作の途中に処理を挟むことができる。
Filter 実行タイミング 引数 用途 addDocumentFilter 次のページを読み込んで Document 作成した完了直後で、 Document からpageElement を切り出す前であり、「さらに次のページ」の URL 取得前 htmlDoc ( GM_xmlhttpRequest で取得したソースを元に作成した Document オブジェクト), this.requestURL (次のページとして取得した URL ), this.info (使用している SITEINFO ) nextLink, pageElement の取得の補助、 SITEINFO の動的な変更など addFilter 次のページの pageElement を挿入後 pageElement ( htmlDoc から getElementsByXPath ( this.info.pageElement , htmlDoc で切り出した) 要素の配列。要素自身だと間違われやすいがあくまで配列) 継ぎ足しした部分を他の Script から操作したい場合など addRequestFilter 次ページ取得のリクエストを送信する直前 GM_XHR用リクエストオプション リクエストのURLやオプションを変更する addResponseFilter 次ページ取得のレスポンス取得時 レスポンス、URL レスポンスの内容を変更する launchAutoPager
AutoPagerizeにsitoinfoを渡して実行させることができる。
引数はsitoinfoを格納した配列。
http://autopagerize.jottit.com/apis_%28ja%29
window.AutoPagerize下にあるAPIなので、現状、どうしてもwindowの共有が必須になる。今回スクリプトを書くのに参考にしたls SITEINFO for Greasemonkeyにしても、sharedObject.AutoPagerizeを使うように書き換えて動かしているので。
まあ、windowの共有の代替策が見つかったところで、実のところまだ問題は残っているが。
■イベントの抜け道
windowの共有の次は、スクリプト間のイベント伝播だ。GM_AutoPagerizeLoaded、GM_MinibufferLoadedのような専用イベントを用意しても、スクリプト間では伝播されないようになったので(同じスクリプト内ならイベントも伝播する。MinibufferとLDRizeを同じスクリプトにつっこんだら動く、というのもそういうことだ)、どうにかしてこれを伝播可能にしたい。
似たような事例というのは案外転がっているもので、ググっていたらこういうの(XPCNativeWrapperとunsafeWindowの間でデータを送受信する | へびにっき)に行き当たった。
XPCNativeWrapperの外側でスクリプトを評価する関数。Firebugも同じことをしている。unsafeWindowを触らないので安全。
function evalInPage(fun) { location.href = "javascript:void (" + fun + ")()"; }
これは面白い!Function.prototype.toString が関数のソースコードを返すことを利用した、巧妙にして簡潔なハック。
次のように引数を渡せるように改良すればさらに強力になる(引数に渡せるのはJSON化可能な値のみ)。
function evalInPage(func, args) { var argStr = JSON.stringify(args || []); location.href = "javascript:void "+ func +".apply(null,"+ argStr +")"; }
GM_xmlhttpRequest を使って別ドメインから得たデータを、unsafeWindow 上のライブラリを使って表示する、といったコードが安全かつ自然に書けるようになる。
http://wp.serpere.info/archives/1107
つまり、スクリプトから実行してうまくいかないんなら、ページ側で実行してもらいましょう、という話。今回のスクリプトにしても、元ページの初期化関数にタダ乗りするようにしたのは、このページを見たおかげ。
課題とか
こいつを上手くMinibufferあたりに組み込んでやると、イベントの発火は可能になる。ページ側での実行になるのでLDRize等の他のスクリプトからイベントを参照することも可能だ、というところまでは確認した。イベントの授受は元々非同期前提の動作なので、そのへんも問題ない。
残る問題はAutoPagerizeのほう。普通に動かすだけなら今でも問題ないが、イベント伝播も元通りにしようとするといささか困った点が出てくる。GM_AutoPagerizeLoadedとGM_AutoPagerizeNextPageLoadedのふたつのイベントはごく普通のイベントなので問題はない。
今回APIを使ったのもそのあたりが原因で、MutationイベントであるAutoPagerize_DOMNodeInsertedをページ側で実行してもらおうとしたとき、発火対象ノードを一意に定める必要が出てくる。このイベントは実質AutoPagerizeのAPIみたいなもんで、これに対してaddEventListnerを設定することで新しく追加されたノードをいじれて、非常に使いやすい。
ノードそのものはJSON化不可なので、引数にしたところで意味がない。思いつく範囲では、ページ側に渡すスクリプトに、セレクタを利用するquerySelectorや、XPathを使うevaluateなどを用いたノード特定用の部品を組み込めばいいのだろうが……。少なくとも、テキストノードを選択することがうまく出来ないquerySelectorのほうは、選択肢から除外して良さそうだ。
■書いてるうちに思いついたこと(暫定解決策)
pageElementがそもそも追加ノード、追加予定ノードの情報を全部持ってるんだから、こいつを上手くバラしてやればいいんだ、ということで、多分ページ側でAutoPagerizeの持つ全イベントのエミュレートは可能、だと思う。
おそらく、
pageElement: '//hoge/fuga|//hage/piyo',
に対して、
pageElementN: '(//hoge/fuga|//hage/piyo)[N]',
という感じでN番目のノードを指定してやれば、うまいこといくはず。
ところでウチのページに引用した箇所の見え方がひどい。CSSいじくったほうがいいのかね……。
2011-11-12 こっちは朝7時、向こうは深夜1時過ぎ。実に6時間弱の遅れ。
■Re:LDRizeをFirefox8+greasemonkey0.9.12以降で動かす
tyoroさん(id:tyoro1210 はてなが本拠じゃなさそうなのでこの呼称はどうか)がこっちの記事(id:t_f_m:20111111:1320962283)の6時間前にもっと有意義な記事を上げておられました。
Greasemonkey0.9.12以降でMinibufferとLDRizeが動かない理由とか - tyoro.exe
こっちの対策のほうが色々できて確実だと思われます。相変わらずイベントが伝わらないので、AutoPagerize依存だったり、minibufffer、LDRize依存のスクリプトは上手く動きませんが。AutoPagerizeもアドオン版に変えれば依存スクリプトが動くんだろうけど、自前のSITEINFOを手軽に書けるから抜け出せないんだよなあ。
一点つっこんでおくと、vimperator向けのパッチの
if (Cc.injectScripts.toSource().search('sharedWindow') == -1) {
は、
if (Cc.injectScripts.toSource().search('sharedObject') == -1) {
だと思われます。追記済みかどうかの判定なので。
2011-11-11 話題になってる内容を記事にしてみる
■LDRizeをFirefox8+greasemonkey0.9.12以降で動かす
g:vimperator:id:yutamoty:20111109:1320826826
firefox 8 で LDRize 動いたっぽい - yutamoty.vimp - vimperatorグループ
動かす方法は既にあるが、greasemonkey0.9.11以下が必要で、かつFirefox4.0以降+greasemonkey0.9.1以降用の対策も必要。
軽く確認したところ、動かない原因はLDRizeを起動させるGM_Minibuffer_Loadedイベントが伝わっていないことだったので、手抜きの解決。
minibufferの末尾にLDRizeの中身をコピペしてやればいい。
なお、greasemonkey自体のGM_openInTab関数の動作が直っているので、window.openに頼らなくて済む。
2011-10-12 要望:Tumblrにトラックバック機能が欲しい。
■Re:Re:XPathの動作にまつわる試行錯誤
以前書いた記事(id:t_f_m:20110321:1301004931 XPathの動作にまつわる試行錯誤 - 近江在住)の内容を検証・仕様確認してくださった方がいらっしゃったので、この記事はそれへの返答となります。
tumblr:xkansanさんありがとうございます。
検証の要点
問題となったXPath、サイト構造とほぼ同様のテスト環境によるテスト。
この結果を見て疑問に思ったことは、
- id(“target-ul”)/li[2][substring-before(self::li/a/@href, “p”) = substring-before(preceding-sibling::li/a/@href, “n”)]/a という XPath で 「記事を読む」 の a ノードが選択されるのはなぜか
- id(“target-ul”)/li[3][substring-before(self::li/a/@href, “p”) = substring-before(preceding-sibling::li/a/@href, “n”)]/a という XPath でなにも選択されないのはなぜか
という2点。
xK.memo - Re: XPathの動作にまつわる試行錯誤
問題の切り分け。それぞれの解題は以下。
空文字問題
1. について
これは、 li[2] の述語で空文字同士の比較が行われているため。 以下の2つの XPath とその結果を見比べればわかると思う。
分かってしまえば、こちらは至極単純。
substring-before(self::li/a/@href, "p")
を実行した結果も
substring-before(preceding-sibling::li/a/@href, "n")
を実行した結果も、共に空文字となり、空文字同士の比較は真。当然である。
仮にこれを[1][2]のような文字付加に依らず回避するならば、
id("target-ul")/li[substring-before(self::li/a/@href, "p")][substring-before(self::li/a/@href, "p") = substring-before(preceding-sibling::li/a/@href,"n")]/a
のように空文字そのものの真偽を判定してやれば良いだろうか。かなり冗長だが。
ノードと文字列
2. について
(中略)
これまでは substring-before の中でノードセットが文字列に変換される際には1つのノードしかノードセットに含まれなかったのでノードセットの文字列化について特に触れなかったのだけれど、この場合のように複数のノードを含むノードセットはどのように文字列化されるのか。
これは http://www.w3.org/TR/xpath/#section-String-Functions に書いてある。
A node-set is converted to a string by returning the string-value of the node in the node-set that is first in document order.文書順で一番最初のノードの文字列値がノードセットの文字列値になるとある。 この場合にあてはめると
つまり、仕様に従ってノードから文字列(正しくはノードセット、ノード集合から文字列)に変換しているだけなので、別にバグというわけではない。何となく、文字列セットのようなものに変換されて、全て比較に回されるのではないかと思っていたのだが、世の中そんなに甘くなかった。
これを回避するための方策は
なのでノードセットを文字列化するときには、そのノードセットに1つのノードのみが含まれているようにするのがよいのでは。
とあるし、実際そうするしかない。
id("target-ul")/li[substring-before(self::li/a/@href, "p") = substring-before(preceding-sibling::li/a/@href,"n")]/a
の中の
preceding-sibling::li/a/@href
の部分が唯一のノードを返せばよい。少し冗長になるが、
preceding-sibling::li[contains(a/@href,"n")]/a/@href
として、一意に存在するノードを拾い上げれば良い。
対策
というわけで t_f_m さんが書こうとしていた XPath は、 id(“MainContent”)/div[@class=”pager”]/div/ul/li[substring-before(substring-after(self::li/a/@href,”/photos/”),”-p”) = substring-before(substring-after(preceding-sibling::li [1] /a/@href,”/news/”),”-n”) and substring-before(substring-after(self::li/a/@href,”/photos/”),”-p”) != “” ]/a みたいに書いたらいいのではないか、と思う。少し不格好かもしれないけれど。
あるいは、ページ構造によっては id(“MainContent”)/div[@class=”pager”]/div/ul/li [last()] [substring-before(substring-after(self::li/a/@href,”/photos/”),”-p”) = substring-before(substring-after(preceding-sibling::li [1] /a/@href,”/news/”),”-n”)]/a と書けるかもしれない。
『出来るだけマルチバイト文字をXPathとして使いたくない』という前提があるので、こういう書き方をせざるを得ないのだろうな、と思う。文字列も集合として取り扱えるのなら、ここまでトリッキーな書き方をしなくて済むのだろうけれど。まあ、この実装の利点も何となく分かるので、不満というほどでもない。
で、一意にノード同士を比較することが出来るなら元の問題もそこまで大きく騒がなくて済んだので、意味を失わない程度に書き換えるなら、自分はこうするかなあ、と。
id("MainContent")/div[@class="pager"]/div/ul/li[contains(a/@href,"photos")][substring-before(substring-after(a/@href,"/photos/"),"-p") = substring-before(substring-after(preceding-sibling::li[contains(a/@href,"news")]/a/@href,"/news/"),"-n")]/a
xkansanさんの書いてくれた例と大差はないが、自分なりのこだわりというヤツ。
締めに
元記事執筆以降も、何件か似たような失敗と、条件次第ではすべての要素が比較対象となるわけではないらしい、という事には薄々気付いていたものの、具体的な仕様についてはどこにまとまっているのかよく分からなかったので触れずにいた。今回、こうして仕様レベルの動作も含めた検証を見ることで、横着してばかりではいけないな、と痛感した。
実際のところ、動くSITEINFO自体は既に出来ているので、検証の確認と今後に役立てるべき反省材料という以上のものは無いのだが、XPathの仕様に触れることで推奨される手法、あるいは推奨されない手法、バッドノウハウなどを整理できる。他の仕様も、時間を見て確認していく予定。
2011-09-11 LDRizeもいじる。ところで誰にバグ修正を訴えればいいのだろう。
■LDRizeのindicator表示位置バグの修正
AutoPagerizeについてばかり書いているけれど、そりゃあ便利なgreasemonkeyって言ったらLDRizeも当然入れてる。
基本的にはSITEINFOいじって気が向いたら反映して、とその程度しか使わないのだけれど、それでもSITEINFOに対するmicroformatsの反映優先順位や、非対応ページでの強制実行の未実装など、不満はそこそこある。強制実行はAutoPagerizeでも実装して欲しいところ。他のスクリプトからLDRizeやAutoPagerizeの起動が出来るようになると相当選択肢が増えるしね。
ともかく、今回の件はローカルに書いた分ではだいぶ前に解決していたのだけれど、やっぱり記事にまとめて公開しておくことにする。
発端
pixiv関連のSITEINFOはLDRize、AutoPagerize共にローカルでは結構いじっていて、あと普段からタグ付けしない人間なのでブックマークを手抜きするためのSITEINFOをSkip Redirector用にも書いてたりする。
で、pixiv百科事典がどうもサイト構成をリニューアルしたようなので、それに合わせてAutoPagerize用とLDRize用のSITEINFOを書いた。
AutoPagerizeはAutoPagerizeで、Ajaxに対応し切れていないので、時々気持ち悪い動作になるのが不満点ではあるのだが、問題はLDRizeのほう。SITEINFOに由来する記述と動作には不満点は特にないのだが、ここにきてheightを指定した場合の動作が顕著に表れてきた。
実態
ここ( http://wedata.net/items/54763 )では、画面の下のほうにいくと強制的に画面上に現れるナビゲーションと選択中の要素とがかぶらないように、120というheight値を指定しているのだが、indicator(LDRize実行中に現れる赤い三角形)が変な場所に表示される。以前からheight値を設定した際には微妙に表示位置がズレていることには気付いていたが、120という極端な値では無視できないほどのズレとなる。
原因はindicatorのtop位置を指定するstyleの計算がズレていたこと。
こんな感じ。
@@ -437,7 +437,7 @@ LDRize.prototype = { if(!p)return; var i=this.img.indicator; i.style.display = 'block'; - i.style.top = (p.y+this.getScrollHeight()-DEFAULT_HEIGHT) + 'px'; + i.style.top = (p.y+this.scrollHeight) + 'px'; i.style.left = Math.max((p.x-this.indicatorMargin), 0) + 'px'; },
パッチは以下のgistにある。
■LDRizeの#gm_ldrize_pinlistの横幅を制限
ついでに自分用の使いやすくする設定。これもLDRizeに直接ぶち込んでる。
ピンを立てた時のバルーンが、ものによってはものすごく横に長くなってしまい、画面中央付近までかぶさって見づらくなる状況を回避する。
@@ -345,6 +345,7 @@ LDRize.prototype = { if(CSS_HIGHLIGHT_LINK) css += "\n.gm_ldrize_link {" + CSS_HIGHLIGHT_LINK + "}"; if(CSS_HIGHLIGHT_PINNED) css += "\n.gm_ldrize_pinned {" + CSS_HIGHLIGHT_PINNED + "}"; css += ".gm_ldrize_iframe { min-height:200px; position:fixed; bottom:0px; left:0px; right:0px; }"; + css += "#gm_ldrize_pinlist { max-width:300px; }"; return css; }, initPinList: function(){
モノはココ。
2011-06-11 実は腐向けだろうがR-18Gだろうがどんとこい! のフィルター不要派
■hide_pixiv_image_with_keyword.user.js
きっかけとか
数日前のことだが、@tailtameさんのいくつかの発言が目に入った。
#pixiv 仕様変更でブログ書き換えのためにNGワード探しっと。虎兎入ってて吹いた。なら動くな : Greasemonkey使ってフィルタかけちゃえ: 膳ブログ URL
2011-06-07 16:43:20 via web
#pixiv 追記をキメた : ねこまぐろBlog :: pixivとTINAMIのタイトルからサムネイルを非表示にするユーザCSS*Firefox+Stylish URL
2011-06-07 16:53:34 via web
テキストから選択できりゃいいんだけどなぁCSSじゃ無理か。ぐりもんなら出来るのかなぁ <a>ここから引っ張れればいいのだが</a> うーん。1閲覧数を与えるからねw
2011-06-07 16:54:29 via web
中々面白そうだったので2番目の発言で言及されている本人のブログ(ねこまぐろBlog :: pixivとTINAMIのタイトルからサムネイルを非表示にするユーザCSS*Firefox+Stylish)を確認してみた。pixivでの住み分けについての話らしい。
pixivの仕様変更のため、今まではユーザースタイルシートの指定に使っていたalt属性がなくなり、タイトルに特定の語句を含む画像のサムネイルを非表示にすることが出来なくなったとのこと。
テキストから選択できりゃいいんだけどなぁCSSじゃ無理か。ぐりもんなら出来るのかなぁ <a>ここから引っ張れればいいのだが</a> うーん。1閲覧数を与えるからねw
2011-06-07 16:54:29 via web
@tailtame サムネimgタグにaltが入ってなくても、タイトルのaタグには目的の文字が入ってるんですよね? なら閲覧数をプラスさせなくてもグリモンで対策できますよ。
2011-06-07 17:05:00 via Movatter to @tailtame
@tomahawque aの中身からもいけるんですね!今は「<a><p><img></p><h1>Title</h1></a>」と謎構成になってます
2011-06-07 17:15:47 via web to @tmhwq
@tailtame document.evaluate('//a[p/img and h1[contains(.,"腐")/p/img',document,null,7,null).snapshotItem(0).style.display="none"; ですかね。
2011-06-07 17:36:47 via Movatter to @tailtame
@tomahawque ありがとうございますーと最初の1タイトルしか無理なようです。残念(`・ω・´)
2011-06-07 17:42:55 via web to @tmhwq
@tomahawque ありがとうございますー、と思ったら今度は動かない何故JS難しいですね(´・ω・`;)
2011-06-07 19:47:01 via web to @tomahawque
上みたいなやり取りもあって、完成したスクリプトは以下。実はあのときtypoってたので(×snapshotLength() ○snapshotLength)動きませんでした。ゴメンなさい。
かんせいばん
完成版ではキーワードの指定がやりやすいようにしてあります。
正規表現も使えます。
インストールはこちらからどうぞ。
var HIDE_KEYWORD = [ "腐", ]; var SAFE_KEYWORD= [ "豆腐", ]; function hide(node){ var titles=document.evaluate('.//a[p/img and h1]/h1',node,null,7,null); var hooked=[]; var hideKey=HIDE_KEYWORD.join("|"); var safeKey=SAFE_KEYWORD.join("|"); for(var i=0, l=titles.snapshotLength;i<l;i++){ var title=titles.snapshotItem(i); if(!title.textContent.match(safeKey) && title.textContent.match(hideKey)){ hooked.push(title); } } hooked.forEach(function(f){ f.previousElementSibling.style.display="none"; } ); } function boot(){ window.addEventListener("AutoPagerize_DOMNodeInserted",function(evt){ hide(evt.target) }, false ); } hide(document); if(window.AutoPagerize){ boot(); }else{ window.addEventListener("GM_AutoPagerizeLoaded",boot,false); }
つかいかた
上のリンクからgreasemonkeyにさくっとインストール。AutoPagerize対応アリ。
初期状態では
var HIDE_KEYWORD = [ "腐", ]; var SAFE_KEYWORD= [ "豆腐", ];
に設定してあるので、HIDE_KEYWORDに気に入らないキーワードをぶち込んで非表示にしてください。キーワードが短すぎて他の語句も拾うのがイヤなときはSAFE_KEYWORDを。普通に表示します。
優先順位はSAFE_KEYWORDのほうが高いので悪しからず。レスポンス次第で改良します。気が向けば。
■その他思ったこと
id:fublog さんのところのXPathからセレクタへの移植は簡単なお仕事です - fublogとかCSSセレクタでSITEINFO実践編 IT-PLUS - fublogを思い出して、CSSセレクターで強引に何とかする荒行が出来ないかと思ったら、text()要素はどうにもならないんですね。そりゃあユーザースタイルシートじゃダメで、ユーザースクリプトが必要になるわけだ。alt属性重要。
2011-05-22 トラックバック・はてなスターなんかがあると、結構嬉しいことに気付
■A_smart_dashboard_is_reblogged_mine
自分の記事(id:t_f_m:20101002:1286035229)にトラックバックが来て気付いたのだが、A_smart_dashboard_is_reblogged_mineがそれなりに需要を満たしているようで結構嬉しい。
トラックバック元の余りにも扇情的なので当該ブログに一切リンクしない今週の俺概況 - はてなダイアリー - KLaxon - O.P. on HATENAだけでなく、tumblr上(Firefoxでtumblr 2011)でも布教してもらっているようで、本当にありがたい話です。
記事時点から時間も経って、tumblrで日本語サービスが始まったりFirefox4が一般化したりの細々とした変化があるので、ちょっとばかり更新しました。あと、以前の状態だとインストールが面倒くさかったのでgithubにアップしました。以下からダウンロードできます。
a_smart_dashboard_is_reblogged_mine
Google Chrome+(AutoPatchWork or AutoPagerize)+NinjaKit環境でも動くバージョンもあるので、そっちが欲しい人はgithubから適当に持っていってください。
追記
自分がvimperatorで対策パッチ当ててるからすっかり忘れてましたが、Firefox 4.0b8〜b9 でLDRize (Minibufferの修正) - wltの日記にあるように、デフォルトのFirefox4+Greasemonkeyだとユーザースクリプト間の連携がうまく動かないのでアドオン版を使うか、vimperatorやtomblooを使った対策を取るか、Greasemonkey自体に手を加える対策を取るかしてください。
shimaken
初めてコメントさせていただきます、KLaxon / Emotional Factorsをほそぼそとやっております、しまけんと申します。トラックバックありがとうございました。
reblogメインでtumbler使っていて、followerが多いと、Dashboard上から明らかに重複したpostが無くなるだけでさかのぼるのが相当速くなるのでとてもありがたく使わせていただいております。
このスクリプト、もっとメジャーになっても良いと思うのですが……tumblrそのものがまだまだマイナーなのでしょうか……。
t_f_m
コメントありがとうございます、t_f_mです。
tumblr使っていて強く思うのは、一度reblogしたからって気にせず二度三度とreblogする人の多いこと多いこと。
reblogついでにコメントの応酬(maybowjingさん関連なんか特に http://himmelkei.tumblr.com/post/5160520263 http://maybowjing.tumblr.com/post/5574503335)でコミュニケーションを取る人もいます。
隠さなくても構わない人と隠されると困る人は、確かにこのスクリプトは不要だろうなーと思います。



ありがたい。
injectScriptsの中身眺めてて思ったのですが、script.textContentやscriptSrcで直接スクリプト自体に触れることも出来るので、その気になればスクリプト自体に手を加えなくても対策できるのかも知れませんね。