Jimmy Walesがあまりに的確に出現するので調査した
Jimmy Walesが出現するChrome拡張に大ウケした。ニコ動とかITMediaとかいまいちなページもあるが、割と的確に挿入されるのがなんかすごい。
というわけで、さっそく解体してみた
chrome-extension://{ID}/ でChrome拡張はファイルにアクセスできるので chrome-extension://idkjdjficifbfjjkdkiimioljbloddpl/manifest.json を早速調べると、 sitenoticediv.js、 contentscript.js という二つのスクリプトで実現されていることがわかる。同様にそれぞれのファイルを覗く。
sitenoticediv.js
var getInnerHTML = function() { var d = Math.random(); var str; if (d < 1/3) { : // 中略 } return str; };
ランダムで三種類のHTMLを返すgetInnerHTMLという関数が定義されているだけで、挿入位置の決定はしていない。ハズレ。
contentscript.js
// XPathResult.ORDERED_NODE_SNAPSHOT_TYPE で取得されたノード配列を返す function getElementsByXPath(a, b) { b || (b = document); for (var g = [], c = document.evaluate(a, b, null, 7, null), e = 0; e < c.snapshotLength; e++) { g.push(c.snapshotItem(e)); } return g } var init = function () { if (!document.getElementById("siteNotice")) //< Wikipediaへの過剰挿入を避ける狙い { var a = getElementsByXPath("//div"); if (a.length != 0) //< div要素が無いページには挿入しない { for ( // getBoundingClientRect は要素の位置とサイズを返してくれるメソッド // jQuery.fn.offset の実質的な中身みたいなもの var b = document.body.getBoundingClientRect(), // 下で使っているが以下の正規表現に適合するID、クラスの要素を挿入の対象とする g = /(main|body|center|articles|columns|content)/i, c, e = 0, h = 0; h < a.length; h++ ) //< div要素の数だけループ { var f = a[h], d = f.getBoundingClientRect(), i = false; // 注目すべき要素であるか判定 if (f.id) if (g.test(f.id)) i = true; if (f.className) if (g.test(f.className)) i = true; // 注目すべき要素の中で、 // - bodyのサイズの中に収まっている // - 幅が500px以上 // - 上から800px以内に要素上部が存在 // - 今まで選択された条件の要素の中で最も面積が大きい // 要素が選択され格納される if (i) if (d.height * d.width > e && d.height < b.height && d.width < b.width && d.width > 500 && d.top < 800) { c = f; e = d.height * d.width; } } // 適当な要素がない場合はbody直下に挿入することに if (!c) { c = document.body; } // 要素の生成 a = document.createElement("div"); a.id = "siteNotice"; a.style.zIndex = "9999"; a.innerHTML = getInnerHTML(); // 要素の先頭に挿入。空ならappendChild。 b = c.childNodes; b.length > 0 ? c.insertBefore(a, b[0]) : c.appendChild(a) } } }; init();
コード整形とコメントを書き加えました。全部コメントに書いてしまったが、結局、ある程度幅があって、ある程度画面の上の方に存在する要素の中で、一番大きな要素を本文が存在する要素と見なして、挿入している感じとなる。
それにしても、これだけのコードなのに中々それっぽく挿入してくるのが悔しく思う。すごいな。