uBlock Origin(以降 uBO)を入れてから一年ちょい。
快適に使っているけれど、副作用というか誤爆も まあまあ ある。
気が付いたら その都度、Myフィルターにルールを追加して対応するのだけれど、たまにしかいじらないから文法とかぜんぜん頭に入ってないし、参考URL とかリンクを置いとくだけじゃダメだ。
というわけで、きちんと公式のページとか読んだ。
以下、未来の自分に向けてのメモ書き。
TL;DR
まずは、ブロックの種類から
https://github.com/gorhill/uBlock/wiki/Overview-of-uBlock's-network-filtering-engine
https://github.com/gorhill/uBlock/wiki/Overview-of-uBlock's-network-filtering-engine:-details
(1) | whitelist | ポップアップの青い電源ボタンで OFF にすると追加される |
(2) | url filtering rule | ログの 4列目をつついて表示されるところで指定するやつ |
(3) | local dynamic filtering rule | ポップアップの advanced user で表示される 2列目で指定するやつ(My ルールの一時的なルール) |
(4) | global dynamic filtering rule | My ルールで、一時的なルールをコミットして、恒久的なルールにしたやつ |
(5) | static filtering rule | 外部フィルター、My フィルター |
ざくっとした指定しかできないけど、その分 軽いから、先に判定されるようになってるのがホワイトリストとかダイナミックルールで、このサイトは一括で OK とか NG みたいなのは、こちらが推奨。
コードをいじるような使い方だったら、Static Filter だけ覚えておけば良い、という感じか。
Static Filter の文法
https://github.com/gorhill/uBlock/wiki/Static-filter-syntax
Network Filter と Cosmetic Filter の二種類。
Adblock Plus(以降 ABP)では、Filter と Element hiding と呼んでいたやつ。
基本は ABP の文法。
https://adblockplus.org/en/filter-cheatsheet
https://adblockplus.org/en/filters
Network Filter
- ブロック
対象のURL + $ + オプション
- 例外(ブロックの指定を打ち消す)
@@ + 対象のURL + $ + オプション
#灰色は省略可
対象のURL
ワイルドキャラクタなんかが使える URL のパターン、もしくは、正規表現
* | wildcard character |
| | start or end anchor |
|| | domain name anchor |
^ | separator |
セパレータは、正規表現の単語境界だと思ってると はまる。
_
-
.
%
は、境界として扱われない。
ドメインに含まれるピリオドが、実際に踏んだ地雷だったり。
start anchor や domain name anchor は、検索パラメータ中にドメインっぽい表現がある場合なんかを除外できる。
オプション
ブロックの適用を種類やドメインで限定したり、動作を決めたりできる。
ABP のチートシートに書いてないオプションもあるし、uBO で拡張されたやつもある。
覚えておけば良いのは、このくらいか。
script, image, object, xmlhttprequest, popup | リクエストの種類で限定 |
domain=, third-party | ページのドメインで限定 |
important | 例外指定に勝つブロック |
redirect= | リクエストを置き換える |
inline-script | inline script を消しちゃうのかな |
domain= に指定するドメインは、
|
で区切って複数指定できる~
を頭につけて、「それ以外」を表現できる
Cosmetic Filter
- 非表示
- 例外(非表示の指定を打ち消す)
#灰色は省略可
ドメイン
ドメインには
*
がワイルドカードで使える,
で区切って複数指定できる~
を頭につけて、except を表現できる
URL ではなく、ドメイン。
「このページのこの要素」って使い方もあるような気はするけれど、本来の目的が広告のブロックだから、基本は「どこにあっても」なのか。
特定のページのある要素を隠すなら Stylish とかを使ってね、ということかも。
セレクタ
セレクタには、CSS のセレクタと、uBO で拡張した書式が使える。
https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#procedural-cosmetic-filters
https://github.com/gorhill/uBlock/wiki/Procedural-cosmetic-filters
:has(...)
... な子要素を持つ親とか祖先を指定。-
:has-text(...)
... なテキストを含む子要素を持つ親とか祖先を指定。 広告な要素は目印がついてない可能性は大きいので、:has()
よりも強力か? -
:if(...)
:if-not(...)
:has()
の AND とかを表現できる(かな -
:matches-css(...)
:matches-css-before(...)
:matches-css-after(...)
style で要素を限定。
-before と -after は、:before と :after 疑似要素に対応 -
:xpath(...)
XPath じゃないと指定できない要素はあるかな? -
script:contains(...)
特定のインラインスクリプトを除外する(動作させない)ために使うはず。 -
script:inject(...)
assets/ublock/resources.txt で定義されたスクリプトを注入するということか。 -
:style(...)
非表示にするんじゃなくて、... なスタイルを適用する。
Stylish なんかでできるやつ
ABP のセレクタ拡張は、uBO に対応するものがあるので、使う必要がないはず。
:-abp-properties()
→:matches-css()
:-abp-has()
→:has()
ABP のセレクタ拡張を使うときには、##
の代わりに #?#
を使うみたい(覚えなくて良い)。
script:inject()
は、使いどころ悩む。
HASH が変わっちゃうから、普通の利用者は resources.txt を修正できないし、ほぼ開発者用。
extension-data/ublock0.sqlite の settings name=cache/ublock-resources が実体だからここを書き換えると追加できるかも。
いや、WebExtension に対応してから、置き場所が Indexed DB に変わってるんだ。
resources の文字が見当たらないなあ...
どこに保存されてるんだろう?
AdBlock Plus との違い
ABP にあって uBO にない
uBO では、例外ルールの document オプションが効かない。
Whitelist を使ってくれ、ということかな。
ABP にはなくて uBO にある
Cosmetic Filter には、結構 追加されている。
Network Filter の HOSTS files って何だ?
domain anchor や、wildcard を書かなくても、ホスト名っぽい表記だったら通すよ、ってことかな
ABP と決別したわけだから、ABP のページを参照しなくても済むように、GitHub の方に書いといて欲しい、という気はする。
Static Filter について整理
Network Filter は、指定されたリクエストをブロックする。
ページの URL が引っかかれば警告のページが表示されて、進むかどうかを聞いてくる。
ページ中の記述にある URL が引っかかれば、音なしで遮断。
「設定」の「ブロックされた要素の設置場所全てを非表示にする」にチェックを入れていると、大きさを持っている img や iframe なんかは display: none;
が指定されて、要素が存在してないことになる。
Cosmetic Filter は、指定された要素を見えなくする。
テキスト埋め込みの広告など、リクエストを出さない広告をブロックする。
リクエストを出すわけでもなく、もともと見えてないインラインスクリプト関連は、ちょっと異質。
Network Filter に inline-script
オプションが指定された場合は、対象の URL が「この URL のページで」という意味になって、Cosmetic Filter のドメインのような意味合いになっている。
Cosmetic Filter の ##
より後は影響を及ぼす要素の指定だけど、script:inject だけは動作の指定になっている。
script:contains()
の方は、「無効にする(動かない)」<script>
を限定するものだから、ある意味「セレクタ」と言っても良い。
script:contains()
というより、script
タグに :contains()
という疑似クラスと思えば、違和感はない。
My フィルタを書くにあたって
Static Filter の実例
uBlock filters から。
広告を見せない
外部フィルタの例外指定を打ち消す
Network Filter の redirect
画像を消しちゃうんじゃなくて、置き換える。
レイアウトを保ちたいときとかに使うのかなあ。
# fuckadblock defuser fuckadblock.js-3.2.0 application/javascript (function() { var noopfn = function() { ; }; // var Fab = function() {}; Fab.prototype.check = noopfn; Fab.prototype.clearEvent = noopfn; Fab.prototype.emitEvent = noopfn; Fab.prototype.on = function(a, b) { if ( !a ) { b(); } return this; }; Fab.prototype.onDetected = function() { return this; }; Fab.prototype.onNotDetected = function(a) { a(); return this; }; Fab.prototype.setOption = noopfn; var fab = new Fab(), getSetFab = { get: function() { return Fab; }, set: function() {} }, getsetfab = { get: function() { return fab; }, set: function() {} }; if ( window.hasOwnProperty('FuckAdBlock') ) { window.FuckAdBlock = Fab; } else { Object.defineProperty(window, 'FuckAdBlock', getSetFab); } if ( window.hasOwnProperty('BlockAdBlock') ) { window.BlockAdBlock = Fab; } else { Object.defineProperty(window, 'BlockAdBlock', getSetFab); } if ( window.hasOwnProperty('SniffAdBlock') ) { window.SniffAdBlock = Fab; } else { Object.defineProperty(window, 'SniffAdBlock', getSetFab); } if ( window.hasOwnProperty('fuckAdBlock') ) { window.fuckAdBlock = fab; } else { Object.defineProperty(window, 'fuckAdBlock', getsetfab); } if ( window.hasOwnProperty('blockAdBlock') ) { window.blockAdBlock = fab; } else { Object.defineProperty(window, 'blockAdBlock', getsetfab); } if ( window.hasOwnProperty('sniffAdBlock') ) { window.sniffAdBlock = fab; } else { Object.defineProperty(window, 'sniffAdBlock', getsetfab); } })();
redirect
は、処理を置き換えちゃう。Anti AdBlocker のクラス、または window のプロパティを置き換えることで、それ以降の処理がエラーにならない。
Cosmetic Filter の script:inject
javascript を注入する。Greasemonkey とかでできるやつ。
# https://github.com/uBlockOrigin/uAssets/issues/58 gpt-defuser.js application/javascript (function() { var noopfn = function() { ; }; var props = '_resetGPT resetGPT resetAndLoadGPTRecovery _resetAndLoadGPTRecovery setupGPT setupGPTuo'; props = props.split(/\s+/); while ( props.length ) { var prop = props.pop(); if ( typeof window[prop] === 'function' ) { window[prop] = noopfn; } else { Object.defineProperty(window, prop, { get: function() { return noopfn; }, set: noopfn }); } } })();
他にも eval を横取りしたり。
redirect や script:inject で、2次利用できそうなやつ
redirect
1x1-transparent.gif とか | 透明画像に置き換える |
nooptext noopcss noopjs noopframe noopmp3-0.1s |
空っぽ系 : MIME タイプごとにある noopmp3-0.1s は、無音の MP3 |
script:inject
antiAdBlock.js |
Anti AdBlock 対策 window.antiAdBlock() |
lesechos.fr.js |
Anti AdBlock 対策 window.checkAdBlock() |
ideal.es.js |
Anti AdBlock 対策 window.is_block_adb_enabled |
window.name-defuser | window.name を空にする |
alert-buster.js | alert を console.log に置き換える |
noeval.js silent-noeval.js noeval-if.js |
window.eval を殺す |
setTimeout-logger.js setInterval-logger.js |
メソッドの呼び出しをロギング |
csp.js |
meta http-equiv="Content-Security-Policy" を書き換える or 設定する |
|
addEventListener をフィルタリングする パラメータにマッチする Listener の登録をスキップする {{1}} : イベント {{2}} : コード |
|
setTimeout をフィルタリングする パラメータにマッチする setTimeout の登録をスキップする {{1}} : コード {{2}} : delay |
|
第一引数のプロパティがインラインスクリプトで使われたときにエラーにする(それ以降が処理されない)。 第二引数が指定されたときには、その表現が含まれるインラインスクリプトで使われた場合のみ有効になる。 |
abort-current-inline-script.js
は、メソッドもガードできる(メソッドの実体を取得するために getter が使われるから)。
エラーにしたときの window.onerror も、自分の分だけ握りつぶしているという芸の細かさ :-)
##script,redirect=noopjs
との違いは、普通は目印がない script タグで、特定のものだけ動かさないとか、途中まで実行させられることとか
redirect=noopjs
の意味
どちらも外部スクリプトのリクエストはブロックされるわけだし、中身を何もしない関数に置き換えている意味が分からなかった。
大きな違いは、onload のイベントが発火されるかどうか。
Anti AdBlock 系の処理では、script の onload をチェックしている奴がいるらしくて、そういうタイプを無効化するために利用されているみたいだ。
Cosmetic Filter の例外指定で
郵便局の郵便番号検索の結果ページがこんな感じになっている(deteil は、ぼくの typo ではない)。
<div class="adArea deteil"> ... </div>
こいつが、EasyList の以下の定義に引っかかる。
郵便局だから広告エリアはないだろうけれど、例外の指定は範囲を狭めておきたい。
というわけで、こういうふうにした。
これが、例外の指定が効いてない。
セレクタにクラスを複数指定するのがダメなのかと思ったけれど、そうではなく、例外の指定は、対象のブロックをする定義と同じになっていないと打ち消さない、ということみたい。
ちなみに、これを追記している途中(2017-11-16)に、.adArea が .bnrArea に変更された。
まさか、AdBlock を考慮したわけでもないだろうけれど。
インラインスクリプト系の制限?
分かっていないだけだろうけど、うまく制御できないケースがいくつか。
- Network Filter
- inline-script が効かない
- Cosmetic Filter
- script:inject が localhost に効かない
- script:contains が効かない
script の beforescriptexecute イベントを使ってるから、Firefox でしか動かないよ的な情報はちらほらあるんだけど、こちらは Firefox。
でも、inline-scrpt の指定が、Static Filter でも Dynamic Filter でも効かない。
script:contains が動かないって書いてる人、見つけた。
Other things worth noting are:
uBlock Origin for Firefox
- The new version is a hybrid extension right now. It will show up as legacy in about:addons
- script:contains filter do not work
- cosmetic filters are limited as the browser's user styles cannot be used for that anymore
- Users who are on the "legacy" dev channel will notice that the "dev channel will cease to work". These users need to install the new version manually
WebExtension になったのと、なんか関係あるんだろうか。
とりあえず、script の beforescriptexecute イベントは発火されるようだけれども。
My フィルタの実際
自分で追加するときには、フィルタの誤爆対処が一番多くって、次に広告じゃないけど見たくないやつ、そしてちょこざいなガード外し、という感じの頻度かな。
追加でブロック
あまり追加してないけど、こんな感じ。
! Internet Archive の寄付を募るやつ web.archive.org###donate-banner ! 「Google をホームページに」のポップアップ www.google.com,www.google.co.jp##div[role="dialog"]:has(a[title="No thanks"])
誤爆の対処
- 動的に作ってるようなページできちんと動いてない、もしくは、見えてるはずのものが見えてないことに気が付く
- UBO のリクエストログから、
- 動いてない → ピンクになってる行で、5列目が script か xhr を探す
- 見えない → 黄色になっている行で 5列目が dom か image を探す
- 3列目をクリックして、ブロックしているフィルタとルールを確認
- それを打ち消すルールを My フィルタに書く
ってな感じ。
これを書いている時点では、大体こんな感じになってる(そのまんまじゃない)。
! adlib さんのアイコン http://q.hatena.ne.jp/1468372807#a1257828 @@||www.*hatena.*^*^adlib^ ! http://candycrush.wikia.com の画像が見えなくなっちゃう @@||slot1.images.wikia.nocookie.net^*_ads_*$script ! こっちは必要なかった(というか、入れるとビデオ広告がうるさい) !@@||slot1.images.wikia.nocookie.net^*_analytics_*$script ! localhost のコンテンツは、ブロックする必要ない @@*$domain=localhost ! "amazon lambda" で検索すると、「ツール」が効かなくなってる (´・ω・`) ! ABP Japanese Filter ! amazon が地雷を踏む ! @@*$domain=www.google.com @@www.google.com/*^adinfo^$script,first-party ! 2ch で Bookmarklet が動かない(豆腐フィルタ) ! |http://$third-party,script,domain=2ch.net @@http://localhost$script,domain=2ch.net ! National Geographic for Web の動画 @@||uliza.jp^$domain=natgeo.nikkeibp.co.jp ! 人力検索の ASIN 記法の画像が無いと、やっぱり寂しい @@amazon.com/images$domain=q.hatena.ne.jp ! 人力検索の「関連する商品」 ! JPN: ABP Japanese filters (日本用フィルタ) の &affid= に引っかかる ! パラメータは、空なのに :-/ @@||q.hatena.ne.jp/api/products?keyword=$domain=q.hatena.ne.jp ! Google Search Console が動かない @@||www.google.com/webmasters/tools^*-analytics- ! Mozilla WebExtension Example には /popup/ に配置されたソースが結構ある @@||github.com/*^popup^$popup,first-party
コピペガード外し
某質問で、検索して見つけたこのページ。
内容はきちんとしているっぽいのだけれど、右クリックメニューに始まり、範囲選択の禁止などのコピーガードが癪に障る。果ては、ソース表示やインスペクタのキーボードショートカットまで殺してある。
まずは、イベントハンドラの確認。
ctrl + shift + i
や、ALT
でメニューバーを出す操作も殺されてる。
でも、アドレスバーにフォーカスが当たっている状態であれば、コンテンツのイベントハンドラは無効化できる。
インスペクタで、html のイベントを確認。
keydown
、contextmenu
、dragstart
が無効化されるイベントハンドラが登録されている。
document.body
の selectstart
も無効化されている。
My フィルタに以下の設定を追加して、再表示する。
www.kosodatedou.com##script:inject(addEventListener-defuser.js, /^(keydown|contextmenu|dragstart|selectstart)/)
addEventListener-defuser.js
は、addEventListener を Hook して、イベントハンドラの登録を阻止する。
キーは効くようになったけど、右クリックメニューや範囲選択ができない。
ctrl + u
で、ソースを確認。
<script type="text/javascript"> document.oncontextmenu = function(e) { var t = e || window.event; var n = t.target || t.srcElement; if (n.nodeName != "A") return false }; document.ondragstart = function() { return false }; </script>
こんな感じで、addEventListener
メソッドを使わずに oncontextmenu
プロパティに、直接 ハンドラを代入しているので、addEventListener の Hook が効かない。
My フィルタに以下の設定を追加して、再表示する。
www.kosodatedou.com##script:inject(abort-current-inline-script.js, document.oncontextmenu) www.kosodatedou.com##script:inject(abort-current-inline-script.js, document.ondragstart) www.kosodatedou.com##script:inject(abort-current-inline-script.js, document.body.onselectstart)
abort-current-inline-script.js
は、特定のプロパティの setter、getter を Hook して、その設定や参照を阻止する。
右クリックメニューは出るようになったけど、ドラッグや ctrl-a での範囲選択ができない。
document.body.onselectstart のイベントハンドラを無効化できていない様子。
onselectstart を阻害しているコードは、こんなの。
function disableSelection(e) { if (typeof e.onselectstart != "undefined") e.onselectstart = function() { return false }; else if (typeof e.style.MozUserSelect != "undefined") e.style.MozUserSelect = "none"; else e.onmousedown = function() { return false }; e.style.cursor = "default" } window.onload = function() { disableSelection(document.body) }
document.body.onselectstart
を置き換えるコードが onload で走っているので、Cosmetic Filter の script:inject が動くときには、未だ document.body.onselectstart
は null のままなんだ。
script:inject
は、レンダリング時に実行されて、実行された後には消される。
abort-current-inline-script.js
は、実行されたときに存在しているプロパティの getter / setter を書き換えているから、素直に使うと空振りしちゃう。
ちょっと悩んで、追加したのは この My フィルタ。
www.kosodatedou.com##script:inject(abort-current-inline-script.js, disableSelection)
global なスコープの関数は window のプロパティで、呼び出すときには、その getter が呼ばれている様子。
関数の getter を無効にすることで、その呼び出しを無効化できる。
最終的に追加した My フィルタは、こんな感じに。
www.kosodatedou.com##script:inject(addEventListener-defuser.js, /^keydown/) www.kosodatedou.com##script:inject(abort-current-inline-script.js, document.oncontextmenu) www.kosodatedou.com##script:inject(abort-current-inline-script.js, document.ondragstart) www.kosodatedou.com##script:inject(abort-current-inline-script.js, disableSelection)
アンチ AdBlocker 対策
Image Raiderという画像検索サイト。マッシュアップ(他人の褌)のくせに AdBlocker 検出をして「AD-BLOCKER 外してね」メッセージとともに YouTube の動画を流す。
うざったいのは、こんなコード。
jQuery(document).ready(function(){ if (jQuery('#myGContainer').height() == 0) { document.getElementById('myGContainer').innerHTML="<h1><strong>Ad-blocker Detected!</strong> ..."; usingAdBlock = true; ga('send', 'event', 'Adblock', 'Active'); } });
こいつも onload 的なタイミングで処理を仕込んでくるし、長めのインラインスクリプトの一部なので、微妙に手強い。
検索してみたら、こんなページがありました。
imageraider.com ・ Issue #2819 ・ AdguardTeam/AdguardFilters
Added to English filterimageraider.com#@#.adsbygoogle
なるほど。敢えて、Cosmetic Filter の例外を追加する、と。
広告を表示するためのスクリプトはブロックされているので、真っ白なスペースとして表示される。
あとは邪魔なスペースを小さくするだけ。
imageraider.com###myGContainer:style(height: 1px !important; overflow: hidden;)
リクエストログの画面の見方
https://github.com/gorhill/uBlock/wiki/The-logger
色
通ったリクエスト | |
ルールによってブロックされたリクエスト | |
ルールによってブロックの例外で通されたリクエスト | |
Cosmetic Filter で非表示にされたか、redirect= で置き換えられたイメージとか |
script:inject() は、ログに残らないのかな。
列
- 2列目
- クリックすると、そのページの uBlock ポップアップを表示する。
閉じられたウィンドウやタブのログ。ツールバーの×をクリックすると消える バックグラウンド通信(behind-the-schene) Note in the figure above the entry named "Behind the scene": selecting this entry allows to show only behind-the-scene network requests. Behind-the-scene network requests are requests which do not originate from any specific tab, and are denoted by the eye-slash icon in the second column. More about behind-the-scene network requests here.
https://github.com/gorhill/uBlock/wiki/The-logger#page-selector - 3列目
- 適用されたルール。
クリックすると、どのフィルターに含まれているかが分かる。 - 4列目
- 処理結果。
クリックすると、そのリクエストをルールに追加する画面になるーー ブロック or 非表示 ++ 許可(ブロックに対する例外設定がある) << リダイレクト - 5列目
- リクエストのタイプ。doc, inline-script, script, css, image, xhr, dom 。
fetch も xhr で記録される。 - 6列目
- 基本的に、
- Network Filter では、ブロックされた URL
- Cosmetic Filter の場合には、そのページの URL
その他
多分、忘れても良いことだけど、一応 残しておく。
Dynamic Filter
https://github.com/gorhill/uBlock/wiki/Dynamic-filtering:-quick-guide
https://github.com/gorhill/uBlock/wiki/Dynamic-filtering:-rule-syntax
https://github.com/gorhill/uBlock/wiki/Dynamic-URL-filtering
Dynamic の命名は、ルールをテキストで書くんじゃなくて、画面からポチポチやって設定するのを「動的(dynamic)」と言っているような気がする。
Dynamic Filter も、Dynamic URL Filter も定義は同じところに書かれる。
source のサイトを表示したときに、destination へのリクエストを、block / allow / noop するだけじゃないかな。
画面からの入力に制約があるので、そのうちのいくつかのパターンに名前を付けているという。
アイコンをクリックして出てくるポップアップで、上に寄せられているホスト名じゃない部分で、緑 / 灰 / 赤 が "Type based rule" 。
下のホスト名のところが、"Hostname based rule" 。
リクエストログの 4列目をクリックして出てくるポップアップで、ダイナミック... のタブの方で指定するのが Dynamic URL Filter 。
デフォルトの Whitelist
about-scheme behind-the-scene chrome-extension-scheme chrome-scheme moz-extension-scheme opera-scheme vivaldi-scheme
デフォルトの、この七つ。
多分、消しちゃいけないやつ。
Firefox の WebExtension だと、about-scheme とか関係ないような気がしなくもないけれど。
外部フィルタ
デフォルトでチェックが入ってるものに加えて、豆腐フィルタを使ってる。
http://tofukko.r.ribbon.to/abp.html
http://tofukko.r.ribbon.to/Adblock_Plus_list.txt
"EasyList" と "JPN: ABP Japanese filters (日本用フィルタ)" の誤爆がときどき気になるけど、現時点では外すほどではないかな。
script:inject は、どこに注入されるのか
DOM Inspector では、どこに注入されているか分からない。
js/contentscript.js を見ると、head の末尾に追加されるようだけれども。
if ( cfeDetails.scripts ) { // Have the injected script tag remove itself when execution completes: // to keep DOM as clean as possible. text = cfeDetails.scripts + "\n" + "(function() {\n" + " var c = document.currentScript,\n" + " p = c && c.parentNode;\n" + " if ( p ) {\n" + " p.removeChild(c);\n" + " }\n" + "})();";
ああ、消されるのか。
実行中の inline script が、どの script タグだ、って欲しくなるときがたまにあるけど、currentScript なんてプロパティがあるんだ。
フィルタに 8文字以上
http://cojocco.blog113.fc2.com/blog-entry-26.html
ここに書いてある「フィルタに8文字以上」は、どこソースだろう...
まあ、ABP の話だし、
は、矛盾した内容だから、話半分以下かな。
2010年4月の記載だし、気にしなくて良いかな。
https://adblockplus.org/forum/viewtopic.php?t=17056
2013年8月のやりとり
https://github.com/chrisaljoudi/uBlock/issues/161#issuecomment-58547364
2014年10月
これかな。
デフォルトで取り込む対象の外部フィルタとかもそのままでも、uBO の導入前に比べて確実に速くなってるんだから、ルールの記載とかは それほど気にしなくても良いような気がする(それほど広告の展開が遅い)。
遅いなあと感じたら、誤爆の多そうな外部フィルタを外していけば良いという感じかな。
script:inject には、パラメータを渡すことができる
resources.txt 中の、{{1}}
や{{2}}
というようなのがパラメータの指定。
setTimeout-defuser.js
setTimeout-defuser.js application/javascript (function() { var z = window.setTimeout, needle = '{{1}}', delay = parseInt('{{2}}', 10); if ( needle === '' || needle === '{{1}}' ) { needle = '.?'; } else if ( needle.slice(0,1) === '/' && needle.slice(-1) === '/' ) { needle = needle.slice(1,-1); ...
最初の {{1}}
しか置き換えないのかなあ。
じゃなければ、最初の if が不思議すぎる。
js/cosmetic-filtering.js
FilterContainer.prototype._fillupUserScript = function(content, args) { var i = 1, pos, arg; while ( args !== '' ) { pos = args.indexOf(','); if ( pos === -1 ) { pos = args.length; } arg = args.slice(0, pos).trim().replace(this._reEscapeScriptArg, '\\$&'); content = content.replace('{{' + i + '}}', arg); args = args.slice(pos + 1).trim(); i++; } return content; };
置き換えが一回だけなのは、そういう風に作ってるから良いとして、needle === '{{1}}'
という判定を入れなければならない理由が謎。
不思議な if は、こんなのを想定しているんだ。
パラメータの置き換えは、フィルターに指定された引数のループ。
引数自体を省略すると、'{{1}}'
は、置換されずに そのまま残る。
カンマを続けて書いて、空の引数にすると、'{{1}}'
が空文字列で置換される。
# ここまで