sside.net

Safari Content-Blocking Rules Reference 日本語訳

この文書について

これはdeveloper.apple.com内にあるSafari Content-Blocking Rules Referenceを日本語に翻訳したものです。原文著作者の許諾は受けていません。権利者からの申し出があった場合、この文書は削除などの対応を行うことがあります。

翻訳にあたって、原文は尊重しますが完全な翻訳を保証するものではありません。誤読、誤訳があることを理解してください。

Introduction to Safari Content-Blocking Rules (はじめに、Safariでのコンテントブロッキングルールについて)

コンテントブロッカーApp拡張は、SafariとSafari Viewコントローラにおける、コンテンツの取り扱いをカスタマイズします。拡張はSafariのリクエストから要素の不可視化、読み込みのブロック、Cookieの除去を行うことが出来ます。あなたのApp拡張で、どのようにSafariがコンテンツを操作するか、コンテントブロッキングルールを与えます。

コンテントブロッキングルールは、実際にブロッキングを行う際、拡張が提供するコードは事前に構造化フォーマットに変換されます。WebKitはルールセットを実行時効率を考慮したバイトコードに変換し、ページリクエストが生成されて実行される前のレイテンシ低減を行います。Safariは希望しないコンテントへのリクエストを行いません。不要なダウンロードを回避することで、Safariはメモリ消費を低減し、パフォーマンスを改善します。

macOS、iOS上のSafariではコンテントブロッキングルールのフォーマットは同一で、これはJSONオブジェクトの配列です。全てのルールはtrigger辞書とaction辞書を含みます。triggerは何に対してルールを適用するか、actionはマッチした対象があればSafariが何を行うかを指定します。

コンテントブロッキングルール作成は、まずWeb Inspectorを使ってWebページ上のリソースを調べます。ブロックしたい要素を見つけたら、続いてターゲットの要素のみにマッチするtriggerを作成し、actionで振る舞いを指定します。

あなたのApp拡張へのルール追加を容易にするために、Xcodeではcontent blockerテンプレートを提供します。XcodeでのApp拡張についてのドキュメントはApp Extension Programming Guideを参照してください。

Note: iOS版SafariへのコンテントブロッキングApp拡張は64bitデバイスへのみ提供可能です。

コンテントブロッキングについてより多くの情報が必要なら、WWDC 2015のSafari Extensibility: Content Blocking and Shared Linksセッションを視聴してください。

Creating Safari Content-Blocking Rules (Safariコンテントブロッキングルールの作成)

Safariコンテントブロッキングルールをリスト1で示しています。ルール辞書の最上層オブジェクトが配列になっていることが見て取れます。全てのルール辞書はtrigger辞書とaction辞書を含んでいます。

リスト1. コンテントブロッキングルールの配列

[
    {
        "trigger": {
            ...
        },
        "action": {
            ...
        }
    },
    {
        "trigger": {
            ...
        },
        "action": {
            ...
        }
    }
]

Creating a Trigger Dictionary (trigger辞書の作成)

trigger辞書には必ず、URLに対するマッチングを指定する uri-filter キーを含む必要があります。それ以外のキーはtriggerの動作を変更するオプションです。例を挙げると、特定のドメインでのみ動作させる、または特定のドメインでは動作を制限するなどです。

リスト2では画像とスタイルシートのリソースを対象にして、特定のドメインを除外したtriggerを示します。

リスト2. 画像とスタイルシートを対象にしたトリガ

"trigger": {
        "url-filter": ".*",
        "resource-type": ["image", "style-sheet"],
        "unless-domain": ["your-content-server.com", "trusted-content-server.com"]
}

使用可能なtriggerフィールドを以下に記します。

url-filter

このキーは文字列型に関連付けされています。このキーはtrigger辞書における唯一の必須項目です。値の文字列を使い、URLに対してマッチングを行います。マッチングは完全なURL、またはURL内に対するパターンに対して行います。

url-filterの文字列はJavaScriptの正規表現に対して厳密なサブセットを用います。正規表現のリストは表1に示します。JavaScriptの正規表現はパーサにおいてはサブセットに制限しています。サポートされない表現はパースエラーとなります。

表1. JavaScriptの正規表現でサポートしている機能

Syntax Description
.* ドットを含む任意の文字が0回以上登場する文字列とマッチします。このシンタックスを使うと全てのURLにマッチします。
. 任意の文字とマッチします。
\. 明示的にドット文字とマッチします。
[a-b] 指定した範囲のアルファベット文字とマッチします。
(abc) 指定した文字列グループとマッチします。
+ 直前の文字の1階以上の繰り返しにマッチします。
* 直前の文字の0回以上の繰り返しにマッチします。
? 直前の文字の0回、または1回の繰り返しにマッチします。

url-filter-is-case-sensitive

このキーはboolean型に関連付けされています。デフォルト値はfalseです。

if-domain または unless-domain

このキーは文字列型の配列に関連付けされています。文字列はURL内のドメイン名とマッチングを行います。if-domainフィールドはactionの処理をリスト内のドメインに制限します。unless-domainフィールドは、リスト内のドメインを除外します。特定のtrigger辞書はif-domainunless-domainの両方を含めることは出来ません。ドメイン名は小文字のASCII文字で指定する必要があります。non-ASCIIな文字はpunycodeでエンコードします。

[ * ]文字をドメイン名の前に指定することで、任意のサブドメインとドメイン名双方にマッチさせることが出来ます。例を挙げると、*.webkit.orgを指定した場合、bugs.webkit.orgwebkit.org双方にマッチします。

resource-type

このキーは文字列型の配列に関連付けされ、マッチさせたいリソースタイプを表します。指定しない場合は、全てのリソースタイプとマッチングを行います。この文字列はブラウザの解釈するリソースに対して指定され、必ずしもリソースの種類と一致するするわけではありません。例を挙げると、<img src="something.css">はimageと識別されます。resource-typeに指定できる値は以下になります。

  • document
  • image
  • style-sheet
  • script
  • font
  • raw (Any untyped load, such as XMLHttpRequest)
  • svg-document
  • media
  • popup

load-type

このキーは文字列型の配列に関連付けられています。指定できる2つの値のうち、どちらかしか指定できません。指定しない場合は、全てのload typesにマッチします。

  • first-party

このルールは表示中のページと同じスキーム、同じドメイン、同じポートのリソースに対してのみ働きます。

  • third-party

このルールは表示中のページと異なるドメインのリソースに対して働きます。

if-top-url or unless-top-url

このキーは文字列型の配列に関連付けられています。指定した文字列は表示中のURLとマッチングを行います。if-top-urlフィールドはURLパターンのリストでactionを行うURLの制限を行います。unless-top-urlはURLパターンのリストにマッチしないページをactionの対象にします。1つのtriggerにはif-top-urlunless-top-urlを同時に含めることは出来ません。URLの文字列は小文字のASCII文字で指定する必要があります。非ASCII文字はpunycodeでエンコードします。

Creating an Action Dictionary (action辞書の作成)

triggerがリソースに対してマッチしたとき、ブラウザは関連付けられたactionの実行をキューします。全てのtriggerが評価された後、順番にactionが実行されます。triggerがマッチしたとき、既にtriggerされたルールと同じ結果を齎すactionはスキップされます。これは、パフォーマンス上の要請からフィルタ作成者に対し、同じactionのフィルタはルールのグループ化を促すものです。例を挙げると、最初のルールがコンテントの読み込み、後続のルールがcookieのブロックである場合、等々、actionが異なればtriggerの評価は継続して行われます。

actionにおいては、2つのフィールドのみ定義されています。typeselectorです。type actionは必須です。もしtypecss-display-noneの場合selectorも必要です。それ以外ではselectorはオプショナルです。

actionフィールドのリストは以下になります。

type

typeフィールドは必須のフィールドです。以下のactionから一つ選択します。

  • block

ブラウザのエンジンに読み込みをブロックするリソース種別を伝えます。もしリソースがキャッシュ済みの場合、キャッシュの読み込みも無視します。

  • block-cookies

サーバへのリクエストを行う前に、ブラウザエンジンによりヘッダから全てのcookieを除きます。これはSafari自体のプライバシーポリシーより低順位に置かれ、プライバシーポリシーでブロックできるものを容認しないためのものです。このためblock-cookiesignore-previous-rulesを組み合わせたものは、プライバシーポリシーを上書きしません。

  • css-display-none

ページ上のCSSセレクタによって、要素を非表示にします。2つ目のactionフィールドselectorは非表示にする要素のリストを含みます。selectorにマッチした要素はdisplayプロパティnoneに設定され、非表示化されます。

  • ignore-previous-rules

直前にtriggerされたactionを機能しなくします。

  • make-https

httpでサーバにリクエストするURLをhttpsに書き換えます。明示的にポート指定(httpのデフォルトポート80以外)されたものと、http以外のプロトコルが指定されたリンクに対しては機能しません。

selector

セレクタのリストを定義する文字列です。この値はcss-display-none actionでのみ必須です。actionのtypeがcss-display-noneでない場合、selectorフィールドは無視されます。カンマ区切りで、独立したCSSセレクタを記述できます。Safari、WebKitでサポートされる全てのセレクタは、Safariコンテントブロッキングルールでもサポートされます。以下の表3で示すような、W3C Selectors Level 4 draftで定義された合体セレクタも、またサポートしています。

リスト3. 合体セレクタ(complex selectors)を用いて要素を非表示化する

"action": {
        "type": "css-display-none",
        "selector": "#newsletter, :matches(.main-page, .article) .news-overlay"
}

翻訳に際して & 最後に

個人的に必要なのでやりました。iOSなSafariのコンテンツブロッカのフォーマットと機能を把握したかった。ので個人的に翻訳して一通り訳し終わったらこのBlogにでも上げるかと思い、8割方終えた段階で平然と2か月以上放置していたのですが、明日就職の面接に行く際に「お前の英語レベルはどれくらいだ」というのがあり、元々「頑張ればドキュメントが読めるくらい(ドロップダウンリストに頑張ればというのはない)」とpaizaのプロファイルにも記載していたのに…というのはありましたが、いい機会なので残り2割を訳してここに置いておきます。

あと、当然誤訳がないとは1%も言う気はないので、誤訳を見つけた親切な人はTwitterあたりで教えてください。未許諾なので勝手に直します。