diff --git a/packages/tsurlfilter/src/rules/declarative-converter/README.md b/packages/tsurlfilter/src/rules/declarative-converter/README.md index 69fb54407..f75531cb7 100644 --- a/packages/tsurlfilter/src/rules/declarative-converter/README.md +++ b/packages/tsurlfilter/src/rules/declarative-converter/README.md @@ -3,17 +3,19 @@ 1. [MV3 specific limitations](#mv3_specific_limitations) 1. [allowrules](#mv3_specific_limitations__allowrules) 1. [$document](#mv3_specific_limitations__$document) - 1. [$removeparam](#mv3_specific_limitations__$removeparam) - 1. [$removeheader](#mv3_specific_limitations__$removeheader) - 1. [$csp](#mv3_specific_limitations__$csp) + 1. [$removeparam, $removeheader, $csp](#mv3_specific_limitations__$removeparam__$removeheader__$csp) 1. [$redirect-rule](#mv3_specific_limitations__$redirect-rule) 1. [Basic examples](#basic_examples) 1. [Basic modifiers](#basic_modifiers) + 1. [$denyallow](#basic_modifiers__$denyallow) 1. [$domain](#basic_modifiers__$domain) - 1. [$third-party](#basic_modifiers__$third-party) - 1. [$popup](#basic_modifiers__$popup) - 1. [$match-case](#basic_modifiers__$match-case) 1. [$header](#basic_modifiers__$header) + 1. [$important](#basic_modifiers__$important) + 1. [$match-case](#basic_modifiers__$match-case) + 1. [$method](#basic_modifiers__$method) + 1. [$popup](#basic_modifiers__$popup) + 1. [$third-party](#basic_modifiers__$third-party) + 1. [$to](#basic_modifiers__$to) 1. [Content type modifiers](#content_type_modifiers) 1. [$document](#content_type_modifiers__$document) 1. [$image](#content_type_modifiers__$image) @@ -29,29 +31,29 @@ 1. [$webrtc](#content_type_modifiers__$webrtc) 1. [$other](#content_type_modifiers__$other) 1. [Exception rules modifiers](#exception_rules_modifiers) - 1. [$elemhide](#exception_rules_modifiers__$elemhide) 1. [$content](#exception_rules_modifiers__$content) + 1. [$elemhide](#exception_rules_modifiers__$elemhide) 1. [$jsinject](#exception_rules_modifiers__$jsinject) - 1. [$urlblock](#exception_rules_modifiers__$urlblock) 1. [$stealth](#exception_rules_modifiers__$stealth) - 1. [$generichide](#exception_rules_modifiers__$generichide) + 1. [$urlblock](#exception_rules_modifiers__$urlblock) 1. [$genericblock](#exception_rules_modifiers__$genericblock) + 1. [$generichide](#exception_rules_modifiers__$generichide) 1. [$specifichide](#exception_rules_modifiers__$specifichide) 1. [Advanced capabilities](#advanced_capabilities) - 1. [$important](#advanced_capabilities__$important) - 1. [$badfilter](#advanced_capabilities__$badfilter) - 1. [$replace](#advanced_capabilities__$replace) - 1. [$csp](#advanced_capabilities__$csp) 1. [$all](#advanced_capabilities__$all) + 1. [$badfilter](#advanced_capabilities__$badfilter) 1. [$cookie](#advanced_capabilities__$cookie) + 1. [$csp](#advanced_capabilities__$csp) + 1. [$permissions](#advanced_capabilities__$permissions) 1. [$redirect](#advanced_capabilities__$redirect) 1. [$redirect-rule](#advanced_capabilities__$redirect-rule) + 1. [$referrerpolicy](#advanced_capabilities__$referrerpolicy) + 1. [$removeheader](#advanced_capabilities__$removeheader) + 1. [$removeparam](#advanced_capabilities__$removeparam) + 1. [$replace](#advanced_capabilities__$replace) 1. [noop](#advanced_capabilities__noop) 1. [$empty](#advanced_capabilities__$empty) - 1. [$denyallow](#advanced_capabilities__$denyallow) 1. [$mp4](#advanced_capabilities__$mp4) - 1. [$removeparam](#advanced_capabilities__$removeparam) - 1. [$removeheader](#advanced_capabilities__$removeheader) 1. [Not supported in extension](#not_supported_in_extension) 1. [$hls (not supported in extension)](#not_supported_in_extension__$hls_(not_supported_in_extension)) 1. [$jsonprune (not supported in extension)](#not_supported_in_extension__$jsonprune_(not_supported_in_extension)) @@ -62,6 +64,7 @@ # Description This file contains examples of converting filter rules to new MV3 declarative rules and describes some MV3-specific limitations of the converted rules. +For a full description of each modifier, see the knowledgebase https://adguard.com/kb/general/ad-filtering/create-own-filters.

@@ -70,7 +73,7 @@ rules and describes some MV3-specific limitations of the converted rules. ## allowrules Allowrules currently are not supported for these modifiers: -1. some specific exceptions: '$genericblock', '$jsinject', '$urlblock', '$content', '$stealth'. +1. some specific exceptions: `$genericblock`, `$jsinject`, `$urlblock`, `$content`, `$stealth`. 1. `$redirect` 1. `$removeparam` 1. `$removeheader` @@ -78,33 +81,24 @@ Allowrules currently are not supported for these modifiers: ## $document -During convertion process $document modificator is expanded into -$elemhide, $content, $urlblock, $jsinject, -of which: -- $content - not supported in the MV3; -- $elemhide, $jsinject - not implemented yet; -- $urlblock - converted not correctly (allow all requests not on the specified -url, but FROM specified url and also disables cosmetic rules). -So we still convert the $document-rules, but not 100% correctly. - - -## $removeparam -Groups of $removeparam rules with the same conditions are combined into one -rule only within one filter. +During convertion process exception with $document modificator is expanded +into `$elemhide,content,urlblock,jsinject` of which: +- `$content` - not supported in the MV3, +- `$elemhide` - supported, +- `$jsinject` - not implemented yet, +- `$urlblock` - not implemented yet. - -## $removeheader -Groups of $removeheader rules with the same conditions are combined into one -rule only within one filter. +So we still convert rules with `$document`, but not 100% correctly. - -## $csp -Groups of $csp rules with the same conditions are combined into one -rule only within one filter. + +## $removeparam, $removeheader, $csp +Rules with `$removeparam` or `$removeheader` or `$csp` which contains the same +conditions are combined into one rule only within one filter but not across +different filters. Because of that, rules from different filter can conflict. ## $redirect-rule -Works as $redirect +Works as `$redirect`.

@@ -257,6 +251,46 @@ example.org##.banner # Basic modifiers + +## $denyallow +Status: supported +
+Examples: +
+ +```adblock +*$script,domain=a.com|b.com,denyallow=x.com|y.com +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[ + { + "id": 1, + "action": { + "type": "block" + }, + "condition": { + "urlFilter": "*", + "initiatorDomains": [ + "a.com", + "b.com" + ], + "excludedRequestDomains": [ + "x.com", + "y.com" + ], + "resourceTypes": [ + "script" + ], + "isUrlFilterCaseSensitive": false + }, + "priority": 252 + } +] + +``` ## $domain Status: partial supported @@ -633,113 +667,6 @@ page$domain=targetdomain.com|~example.org } ] -``` - -## $third-party -Status: supported -
-Examples: -
-example 1 - -```adblock -||domain.com^$third-party -``` - -↓↓↓↓ converted to ↓↓↓↓ - -```json -[ - { - "id": 1, - "action": { - "type": "block" - }, - "condition": { - "urlFilter": "||domain.com^", - "domainType": "thirdParty", - "isUrlFilterCaseSensitive": false - }, - "priority": 2 - } -] - -``` -example 2 - -```adblock -||domain.com$~third-party -``` - -↓↓↓↓ converted to ↓↓↓↓ - -```json -[ - { - "id": 1, - "action": { - "type": "block" - }, - "condition": { - "urlFilter": "||domain.com", - "domainType": "firstParty", - "isUrlFilterCaseSensitive": false - }, - "priority": 2 - } -] - -``` - -## $popup -Status: partial support -
-MV3 limitations: -
-Cannot be converted to MV3 Declarative Rule, but maybe can be implemented on -the content-script side -
-Examples: -
- -```adblock -||domain.com^$popup -``` - -↓↓↓↓ converted to ↓↓↓↓ - -```json -[] - -``` - -## $match-case -Status: supported -
-Examples: -
- -```adblock -*/BannerAd.gif$match-case -``` - -↓↓↓↓ converted to ↓↓↓↓ - -```json -[ - { - "id": 1, - "action": { - "type": "block" - }, - "condition": { - "urlFilter": "*/BannerAd.gif", - "isUrlFilterCaseSensitive": true - }, - "priority": 2 - } -] - ``` ## $header @@ -799,20 +726,19 @@ example 4 [] ``` -
-
- - -# Content type modifiers -Status: all content type modifiers supported, except deprecated $webrtc -and $object-subrequest + +## $important +Status: supported
Examples:
-example 1 +example 1. +
+blocking rule will block all requests despite of the exception rule ```adblock -||example.org^$image +||example.org^$important +@@||example.org^ ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -826,20 +752,32 @@ example 1 }, "condition": { "urlFilter": "||example.org^", - "resourceTypes": [ - "image" - ], "isUrlFilterCaseSensitive": false }, - "priority": 101 + "priority": 1000001 + }, + { + "id": 2, + "action": { + "type": "allow" + }, + "condition": { + "urlFilter": "||example.org^", + "isUrlFilterCaseSensitive": false + }, + "priority": 100001 } ] ``` -example 2 +example 2. +
+if the exception rule also has `$important` modifier it will prevail, +so no requests will not be blocked ```adblock -||example.org^$script,stylesheet +||example.org^$important +@@||example.org^$important ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -853,21 +791,34 @@ example 2 }, "condition": { "urlFilter": "||example.org^", - "resourceTypes": [ - "stylesheet", - "script" - ], "isUrlFilterCaseSensitive": false }, - "priority": 76 + "priority": 1000001 + }, + { + "id": 2, + "action": { + "type": "allow" + }, + "condition": { + "urlFilter": "||example.org^", + "isUrlFilterCaseSensitive": false + }, + "priority": 1100001 } ] ``` -example 3 +example 3. +
+if a document-level exception rule is applied to the document, +the `$important` modifier will be ignored; +so if a request to `example.org` is sent from the `test.org` domain, +the blocking rule will not be applied despite it has the `$important` modifier ```adblock -||example.org^$~image,~script,~stylesheet +||example.org^$important +@@||test.org^$document ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -881,24 +832,36 @@ example 3 }, "condition": { "urlFilter": "||example.org^", - "excludedResourceTypes": [ - "stylesheet", - "script", - "image" + "isUrlFilterCaseSensitive": false + }, + "priority": 1000001 + }, + { + "id": 2, + "action": { + "type": "allowAllRequests" + }, + "condition": { + "urlFilter": "||test.org^", + "resourceTypes": [ + "main_frame" ], "isUrlFilterCaseSensitive": false }, - "priority": 2 + "priority": 140101 } ] ``` - -## $document -example 1 + +## $match-case +Status: supported +
+Examples: +
```adblock -@@||example.com^$document +*/BannerAd.gif$match-case ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -908,24 +871,27 @@ example 1 { "id": 1, "action": { - "type": "allowAllRequests" + "type": "block" }, "condition": { - "urlFilter": "||example.com^", - "resourceTypes": [ - "main_frame" - ], - "isUrlFilterCaseSensitive": false + "urlFilter": "*/BannerAd.gif", + "isUrlFilterCaseSensitive": true }, - "priority": 140101 + "priority": 2 } ] ``` -example 2 + +## $method +Status: not implemented yet +
+Examples: +
+example 1 ```adblock -@@||example.com^$document,~extension +||evil.com^$method=get|head ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -935,24 +901,21 @@ example 2 { "id": 1, "action": { - "type": "allowAllRequests" + "type": "block" }, "condition": { - "urlFilter": "||example.com^", - "resourceTypes": [ - "main_frame" - ], + "urlFilter": "||evil.com^", "isUrlFilterCaseSensitive": false }, - "priority": 140101 + "priority": 76 } ] ``` -example 3 +example 2 ```adblock -||example.com^$document +||evil.com^$method=~post|~put ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -965,21 +928,18 @@ example 3 "type": "block" }, "condition": { - "urlFilter": "||example.com^", - "resourceTypes": [ - "main_frame" - ], + "urlFilter": "||evil.com^", "isUrlFilterCaseSensitive": false }, - "priority": 101 + "priority": 2 } ] ``` -example 4 +example 3 ```adblock -||example.com^$document,redirect=noopframe +@@||evil.com$method=get ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -989,27 +949,21 @@ example 4 { "id": 1, "action": { - "type": "redirect", - "redirect": { - "extensionPath": "/path/to/resources/noopframe.html" - } + "type": "allow" }, "condition": { - "urlFilter": "||example.com^", - "resourceTypes": [ - "main_frame" - ], + "urlFilter": "||evil.com", "isUrlFilterCaseSensitive": false }, - "priority": 1101 + "priority": 100101 } ] ``` -example 5 +example 4 ```adblock -||example.com^$document,removeparam=test +@@||evil.com$method=~post ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1019,33 +973,31 @@ example 5 { "id": 1, "action": { - "type": "redirect", - "redirect": { - "transform": { - "queryTransform": { - "removeParams": [ - "test" - ] - } - } - } + "type": "allow" }, "condition": { - "urlFilter": "||example.com^", - "resourceTypes": [ - "main_frame" - ], + "urlFilter": "||evil.com", "isUrlFilterCaseSensitive": false }, - "priority": 101 + "priority": 100002 } ] ``` -example 6 + +## $popup +Status: not implemented yet +
+MV3 limitations: +
+Cannot be converted to MV3 Declarative Rule, but maybe can be implemented on +the content-script side +
+Examples: +
```adblock -||example.com^$document,replace=/test1/test2/ +||domain.com^$popup ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1054,11 +1006,16 @@ example 6 [] ``` - -## $image + +## $third-party +Status: supported +
+Examples: +
+example 1 ```adblock -||example.org^$image +||domain.com^$third-party ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1071,22 +1028,19 @@ example 6 "type": "block" }, "condition": { - "urlFilter": "||example.org^", - "resourceTypes": [ - "image" - ], + "urlFilter": "||domain.com^", + "domainType": "thirdParty", "isUrlFilterCaseSensitive": false }, - "priority": 101 + "priority": 2 } ] ``` - -## $stylesheet +example 2 ```adblock -||example.org^$stylesheet +||domain.com$~third-party ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1099,22 +1053,25 @@ example 6 "type": "block" }, "condition": { - "urlFilter": "||example.org^", - "resourceTypes": [ - "stylesheet" - ], + "urlFilter": "||domain.com", + "domainType": "firstParty", "isUrlFilterCaseSensitive": false }, - "priority": 101 + "priority": 2 } ] ``` - -## $script + +## $to +Status: not implemented yet +
+Examples: +
+example 1 ```adblock -||example.org^$script +/ads$to=evil.com|evil.org ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1127,22 +1084,18 @@ example 6 "type": "block" }, "condition": { - "urlFilter": "||example.org^", - "resourceTypes": [ - "script" - ], + "urlFilter": "/ads", "isUrlFilterCaseSensitive": false }, - "priority": 101 + "priority": 2 } ] ``` - -## $object +example 2 ```adblock -||example.org^$object +/ads$to=~not.evil.com|evil.com ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1155,22 +1108,18 @@ example 6 "type": "block" }, "condition": { - "urlFilter": "||example.org^", - "resourceTypes": [ - "object" - ], + "urlFilter": "/ads", "isUrlFilterCaseSensitive": false }, - "priority": 101 + "priority": 2 } ] ``` - -## $font +example 3 ```adblock -||example.org^$font +/ads$to=~good.com|~good.org ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1183,22 +1132,27 @@ example 6 "type": "block" }, "condition": { - "urlFilter": "||example.org^", - "resourceTypes": [ - "font" - ], + "urlFilter": "/ads", "isUrlFilterCaseSensitive": false }, - "priority": 101 + "priority": 2 } ] ``` - -## $media +
+
+ + +# Content type modifiers +Status: all content type modifiers supported, except deprecated $webrtc and $object-subrequest. +
+Examples: +
+example 1 ```adblock -||example.org^$media +||example.org^$image ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1213,7 +1167,7 @@ example 6 "condition": { "urlFilter": "||example.org^", "resourceTypes": [ - "media" + "image" ], "isUrlFilterCaseSensitive": false }, @@ -1222,12 +1176,10 @@ example 6 ] ``` - -## $subdocument -example 1 +example 2 ```adblock -||example.com^$subdocument +||example.org^$script,stylesheet ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1240,21 +1192,22 @@ example 1 "type": "block" }, "condition": { - "urlFilter": "||example.com^", + "urlFilter": "||example.org^", "resourceTypes": [ - "sub_frame" + "stylesheet", + "script" ], "isUrlFilterCaseSensitive": false }, - "priority": 101 + "priority": 76 } ] ``` -example 2 +example 3 ```adblock -||example.com^$subdocument,domain=domain.com +||example.org^$~image,~script,~stylesheet ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1267,25 +1220,25 @@ example 2 "type": "block" }, "condition": { - "urlFilter": "||example.com^", - "initiatorDomains": [ - "domain.com" - ], - "resourceTypes": [ - "sub_frame" + "urlFilter": "||example.org^", + "excludedResourceTypes": [ + "stylesheet", + "script", + "image" ], "isUrlFilterCaseSensitive": false }, - "priority": 301 + "priority": 2 } ] ``` - -## $ping + +## $document +example 1 ```adblock -||example.org^$ping +@@||example.com^$document ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1295,25 +1248,24 @@ example 2 { "id": 1, "action": { - "type": "block" + "type": "allowAllRequests" }, "condition": { - "urlFilter": "||example.org^", + "urlFilter": "||example.com^", "resourceTypes": [ - "ping" + "main_frame" ], "isUrlFilterCaseSensitive": false }, - "priority": 101 + "priority": 140101 } ] ``` - -## $xmlhttprequest +example 2 ```adblock -||example.org^$xmlhttprequest +@@||example.com^$document,~extension ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1323,25 +1275,24 @@ example 2 { "id": 1, "action": { - "type": "block" + "type": "allowAllRequests" }, "condition": { - "urlFilter": "||example.org^", + "urlFilter": "||example.com^", "resourceTypes": [ - "xmlhttprequest" + "main_frame" ], "isUrlFilterCaseSensitive": false }, - "priority": 101 + "priority": 140101 } ] ``` - -## $websocket +example 3 ```adblock -||example.org^$websocket +||example.com^$document ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1354,9 +1305,9 @@ example 2 "type": "block" }, "condition": { - "urlFilter": "||example.org^", + "urlFilter": "||example.com^", "resourceTypes": [ - "websocket" + "main_frame" ], "isUrlFilterCaseSensitive": false }, @@ -1365,28 +1316,417 @@ example 2 ] ``` - -## $webrtc -Status: not supported -
-example 1 +example 4 ```adblock -||example.com^$webrtc,domain=example.org +||example.com^$document,redirect=noopframe ``` ↓↓↓↓ converted to ↓↓↓↓ ```json -[] - -``` -example 2 - -```adblock -@@*$webrtc,domain=example.org -``` - +[ + { + "id": 1, + "action": { + "type": "redirect", + "redirect": { + "extensionPath": "/path/to/resources/noopframe.html" + } + }, + "condition": { + "urlFilter": "||example.com^", + "resourceTypes": [ + "main_frame" + ], + "isUrlFilterCaseSensitive": false + }, + "priority": 1101 + } +] + +``` +example 5 + +```adblock +||example.com^$document,removeparam=test +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[ + { + "id": 1, + "action": { + "type": "redirect", + "redirect": { + "transform": { + "queryTransform": { + "removeParams": [ + "test" + ] + } + } + } + }, + "condition": { + "urlFilter": "||example.com^", + "resourceTypes": [ + "main_frame" + ], + "isUrlFilterCaseSensitive": false + }, + "priority": 101 + } +] + +``` +example 6 + +```adblock +||example.com^$document,replace=/test1/test2/ +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[] + +``` + +## $image + +```adblock +||example.org^$image +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[ + { + "id": 1, + "action": { + "type": "block" + }, + "condition": { + "urlFilter": "||example.org^", + "resourceTypes": [ + "image" + ], + "isUrlFilterCaseSensitive": false + }, + "priority": 101 + } +] + +``` + +## $stylesheet + +```adblock +||example.org^$stylesheet +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[ + { + "id": 1, + "action": { + "type": "block" + }, + "condition": { + "urlFilter": "||example.org^", + "resourceTypes": [ + "stylesheet" + ], + "isUrlFilterCaseSensitive": false + }, + "priority": 101 + } +] + +``` + +## $script + +```adblock +||example.org^$script +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[ + { + "id": 1, + "action": { + "type": "block" + }, + "condition": { + "urlFilter": "||example.org^", + "resourceTypes": [ + "script" + ], + "isUrlFilterCaseSensitive": false + }, + "priority": 101 + } +] + +``` + +## $object + +```adblock +||example.org^$object +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[ + { + "id": 1, + "action": { + "type": "block" + }, + "condition": { + "urlFilter": "||example.org^", + "resourceTypes": [ + "object" + ], + "isUrlFilterCaseSensitive": false + }, + "priority": 101 + } +] + +``` + +## $font + +```adblock +||example.org^$font +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[ + { + "id": 1, + "action": { + "type": "block" + }, + "condition": { + "urlFilter": "||example.org^", + "resourceTypes": [ + "font" + ], + "isUrlFilterCaseSensitive": false + }, + "priority": 101 + } +] + +``` + +## $media + +```adblock +||example.org^$media +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[ + { + "id": 1, + "action": { + "type": "block" + }, + "condition": { + "urlFilter": "||example.org^", + "resourceTypes": [ + "media" + ], + "isUrlFilterCaseSensitive": false + }, + "priority": 101 + } +] + +``` + +## $subdocument +example 1 + +```adblock +||example.com^$subdocument +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[ + { + "id": 1, + "action": { + "type": "block" + }, + "condition": { + "urlFilter": "||example.com^", + "resourceTypes": [ + "sub_frame" + ], + "isUrlFilterCaseSensitive": false + }, + "priority": 101 + } +] + +``` +example 2 + +```adblock +||example.com^$subdocument,domain=domain.com +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[ + { + "id": 1, + "action": { + "type": "block" + }, + "condition": { + "urlFilter": "||example.com^", + "initiatorDomains": [ + "domain.com" + ], + "resourceTypes": [ + "sub_frame" + ], + "isUrlFilterCaseSensitive": false + }, + "priority": 301 + } +] + +``` + +## $ping + +```adblock +||example.org^$ping +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[ + { + "id": 1, + "action": { + "type": "block" + }, + "condition": { + "urlFilter": "||example.org^", + "resourceTypes": [ + "ping" + ], + "isUrlFilterCaseSensitive": false + }, + "priority": 101 + } +] + +``` + +## $xmlhttprequest + +```adblock +||example.org^$xmlhttprequest +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[ + { + "id": 1, + "action": { + "type": "block" + }, + "condition": { + "urlFilter": "||example.org^", + "resourceTypes": [ + "xmlhttprequest" + ], + "isUrlFilterCaseSensitive": false + }, + "priority": 101 + } +] + +``` + +## $websocket + +```adblock +||example.org^$websocket +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[ + { + "id": 1, + "action": { + "type": "block" + }, + "condition": { + "urlFilter": "||example.org^", + "resourceTypes": [ + "websocket" + ], + "isUrlFilterCaseSensitive": false + }, + "priority": 101 + } +] + +``` + +## $webrtc +Status: not supported +
+example 1 + +```adblock +||example.com^$webrtc,domain=example.org +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[] + +``` +example 2 + +```adblock +@@*$webrtc,domain=example.org +``` + ↓↓↓↓ converted to ↓↓↓↓ ```json @@ -1426,19 +1766,15 @@ example 2 # Exception rules modifiers - -## $elemhide -Status: is supported but not converted. -
-MV3 limitations: -
-Not convertible to DNR in MV3, but in MV3 [tswebextension](https://github.com/AdguardTeam/tsurlfilter/tree/master/packages/tswebextension) uses content-script to request cosmetic rules from tsurlfilter's with [MatchingResult.getCosmeticOption](https://github.com/AdguardTeam/tsurlfilter/blob/master/packages/tsurlfilter/src/engine/matching-result.ts#L235), where $elemhide, $specifichide and $generichide will be applied. + +## $content +Status: not supported in MV3
Examples:
```adblock -@@||example.com^$elemhide +@@||example.com^$content ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1447,19 +1783,19 @@ Not convertible to DNR in MV3, but in MV3 [tswebextension](https://github.com/Ad [] ``` - -## $content -Status: not implemented yet + +## $elemhide +Status: supported but not converted.
MV3 limitations:
-Bug: currently converted to allowAllRequests rules +Not convertible to DNR in MV3, but in MV3 [tswebextension](https://github.com/AdguardTeam/tsurlfilter/tree/master/packages/tswebextension) uses content-script to request cosmetic rules from tsurlfilter's with [MatchingResult.getCosmeticOption](https://github.com/AdguardTeam/tsurlfilter/blob/master/packages/tsurlfilter/src/engine/matching-result.ts#L235), where $elemhide, $specifichide and $generichide will be applied.
Examples:
```adblock -@@||example.com^$content +@@||example.com^$elemhide ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1484,31 +1820,6 @@ Bug: currently converted to allowAllRequests rules ```json [] -``` - -## $urlblock -Status: not implemented yet -
-MV3 limitations: -
-Bug: uses urlFilter instead of initiatorDomains -
-Bug: incorrect priority -
-Bug: disables cosmetic rules -
-Examples: -
- -```adblock -@@||example.com^$urlblock -``` - -↓↓↓↓ converted to ↓↓↓↓ - -```json -[] - ``` ## $stealth @@ -1540,19 +1851,15 @@ example 2 [] ``` - -## $generichide -Status: is supported but not converted. -
-MV3 limitations: -
-Not convertible to DNR in MV3, but in MV3 [tswebextension](https://github.com/AdguardTeam/tsurlfilter/tree/master/packages/tswebextension) uses content-script to request cosmetic rules from tsurlfilter's with [MatchingResult.getCosmeticOption](https://github.com/AdguardTeam/tsurlfilter/blob/master/packages/tsurlfilter/src/engine/matching-result.ts#L235), where $elemhide, $specifichide and $generichide will be applied. + +## $urlblock +Status: not implemented yet
Examples:
```adblock -@@||example.com^$generichide +@@||example.com^$urlblock ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1578,9 +1885,9 @@ Not convertible to DNR in MV3, but in MV3 [tswebextension](https://github.com/Ad [] ``` - -## $specifichide -Status: is supported but not converted. + +## $generichide +Status: supported but not converted.
MV3 limitations:
@@ -1590,7 +1897,7 @@ Not convertible to DNR in MV3, but in MV3 [tswebextension](https://github.com/Ad
```adblock -@@||example.org^$specifichide +@@||example.com^$generichide ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1599,101 +1906,41 @@ Not convertible to DNR in MV3, but in MV3 [tswebextension](https://github.com/Ad [] ``` -
-
- - -# Advanced capabilities - -## $important -Status: supported + +## $specifichide +Status: supported but not converted. +
+MV3 limitations: +
+Not convertible to DNR in MV3, but in MV3 [tswebextension](https://github.com/AdguardTeam/tsurlfilter/tree/master/packages/tswebextension) uses content-script to request cosmetic rules from tsurlfilter's with [MatchingResult.getCosmeticOption](https://github.com/AdguardTeam/tsurlfilter/blob/master/packages/tsurlfilter/src/engine/matching-result.ts#L235), where $elemhide, $specifichide and $generichide will be applied.
Examples:
-example 1. -blocking rule will block all requests despite of the exception rule - -```adblock -||example.org^$important -@@||example.org^ -``` - -↓↓↓↓ converted to ↓↓↓↓ - -```json -[ - { - "id": 1, - "action": { - "type": "block" - }, - "condition": { - "urlFilter": "||example.org^", - "isUrlFilterCaseSensitive": false - }, - "priority": 1000001 - }, - { - "id": 2, - "action": { - "type": "allow" - }, - "condition": { - "urlFilter": "||example.org^", - "isUrlFilterCaseSensitive": false - }, - "priority": 100001 - } -] - -``` -example 2. -if the exception rule also has `$important` modifier it will prevail, -so no requests will not be blocked ```adblock -||example.org^$important -@@||example.org^$important +@@||example.org^$specifichide ``` ↓↓↓↓ converted to ↓↓↓↓ ```json -[ - { - "id": 1, - "action": { - "type": "block" - }, - "condition": { - "urlFilter": "||example.org^", - "isUrlFilterCaseSensitive": false - }, - "priority": 1000001 - }, - { - "id": 2, - "action": { - "type": "allow" - }, - "condition": { - "urlFilter": "||example.org^", - "isUrlFilterCaseSensitive": false - }, - "priority": 1100001 - } -] +[] ``` -example 3. -if a document-level exception rule is applied to the document, -the `$important` modifier will be ignored; -so if a request to `example.org` is sent from the `test.org` domain, -the blocking rule will not be applied despite it has the `$important` modifier +
+
+ + +# Advanced capabilities + +## $all +Status: supported +
+Examples: +
```adblock -||example.org^$important -@@||test.org^$document +||example.org^$all ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1707,23 +1954,23 @@ the blocking rule will not be applied despite it has the `$important` modifier }, "condition": { "urlFilter": "||example.org^", - "isUrlFilterCaseSensitive": false - }, - "priority": 1000001 - }, - { - "id": 2, - "action": { - "type": "allowAllRequests" - }, - "condition": { - "urlFilter": "||test.org^", "resourceTypes": [ - "main_frame" + "main_frame", + "sub_frame", + "stylesheet", + "script", + "image", + "font", + "object", + "xmlhttprequest", + "ping", + "media", + "websocket", + "other" ], "isUrlFilterCaseSensitive": false }, - "priority": 140101 + "priority": 56 } ] @@ -1930,16 +2177,16 @@ example 10 ] ``` - -## $replace -Status: not supported + +## $cookie +Status: implemented in `release/v2.2` branch
Examples:
example 1 ```adblock -||example.org^$replace=/()[\s\S]*<\/VAST>/\$1<\/VAST>/i +||example.org^$cookie=NAME;maxAge=3600;sameSite=lax ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1951,7 +2198,7 @@ example 1 example 2 ```adblock -||example.org^$replace=/X/Y/ +||example.org^$cookie ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1963,7 +2210,7 @@ example 2 example 3 ```adblock -||example.org^$replace=/Z/Y/ +||example.org^$cookie=NAME ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1975,7 +2222,67 @@ example 3 example 4 ```adblock -@@||example.org/page/*$replace=/Z/Y/ +||example.org^$cookie=/regexp/ +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[] + +``` +example 5 + +```adblock +@@||example.org^$cookie +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[] + +``` +example 6 + +```adblock +@@||example.org^$cookie=NAME +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[] + +``` +example 7 + +```adblock +@@||example.org^$cookie=/regexp/ +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[] + +``` +example 8 + +```adblock +$cookie=__cfduid +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[] + +``` +example 9 + +```adblock +$cookie=/__utm[a-z]/ ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -1983,6 +2290,31 @@ example 4 ```json [] +``` +example 10 + +```adblock +||facebook.com^$third-party,cookie=c_user +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[ + { + "id": 1, + "action": { + "type": "block" + }, + "condition": { + "urlFilter": "||facebook.com^", + "domainType": "thirdParty", + "isUrlFilterCaseSensitive": false + }, + "priority": 2 + } +] + ``` ## $csp @@ -2170,51 +2502,8 @@ example 5 ] ``` - -## $all -Status: not implemented yet -
-Examples: -
- -```adblock -||example.org^$all -``` - -↓↓↓↓ converted to ↓↓↓↓ - -```json -[ - { - "id": 1, - "action": { - "type": "block" - }, - "condition": { - "urlFilter": "||example.org^", - "resourceTypes": [ - "main_frame", - "sub_frame", - "stylesheet", - "script", - "image", - "font", - "object", - "xmlhttprequest", - "ping", - "media", - "websocket", - "other" - ], - "isUrlFilterCaseSensitive": false - }, - "priority": 56 - } -] - -``` - -## $cookie + +## $permissions Status: not implemented yet
Examples: @@ -2222,7 +2511,7 @@ example 5 example 1 ```adblock -||example.org^$cookie=NAME;maxAge=3600;sameSite=lax +||example.org^$permissions=sync-xhr=() ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -2234,7 +2523,7 @@ example 1 example 2 ```adblock -||example.org^$cookie +@@||example.org/page/*$permissions=sync-xhr=() ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -2246,7 +2535,7 @@ example 2 example 3 ```adblock -||example.org^$cookie=NAME +@@||example.org/page/*$permissions ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -2258,7 +2547,7 @@ example 3 example 4 ```adblock -||example.org^$cookie=/regexp/ +$domain=example.org|example.com,permissions=oversized-images=()\, sync-script=()\, unsized-media=() ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -2270,67 +2559,8 @@ example 4 example 5 ```adblock -@@||example.org^$cookie -``` - -↓↓↓↓ converted to ↓↓↓↓ - -```json -[] - -``` -example 6 - -```adblock -@@||example.org^$cookie=NAME -``` - -↓↓↓↓ converted to ↓↓↓↓ - -```json -[] - -``` -example 7 - -```adblock -@@||example.org^$cookie=/regexp/ -``` - -↓↓↓↓ converted to ↓↓↓↓ - -```json -[] - -``` -example 8 - -```adblock -$cookie=__cfduid -``` - -↓↓↓↓ converted to ↓↓↓↓ - -```json -[] - -``` -example 9 - -```adblock -$cookie=/__utm[a-z]/ -``` - -↓↓↓↓ converted to ↓↓↓↓ - -```json -[] - -``` -example 10 - -```adblock -||facebook.com^$third-party,cookie=c_user +||example.org^$permissions=sync-xhr=() +@@||example.org^$document ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -2338,16 +2568,18 @@ example 10 ```json [ { - "id": 1, + "id": 2, "action": { - "type": "block" + "type": "allowAllRequests" }, "condition": { - "urlFilter": "||facebook.com^", - "domainType": "thirdParty", + "urlFilter": "||example.org^", + "resourceTypes": [ + "main_frame" + ], "isUrlFilterCaseSensitive": false }, - "priority": 2 + "priority": 140101 } ] @@ -2728,16 +2960,64 @@ Converting as $redirect rules ] ``` - -## noop + +## $referrerpolicy +Status: not implemented yet +
+Examples: +
+example 1 + +```adblock +||example.com^$referrerpolicy=unsafe-urlblock +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[] + +``` +example 2 + +```adblock +@@||example.com^$referrerpolicy=unsafe-urlblock +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[] + +``` +example 3 + +```adblock +@@||example.com/abcd.html^$referrerpolicy +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[] + +``` + +## $removeheader Status: supported
+Allowlist rules are not supported +
+Rules with the same matching condition are combined into one, but only within +the scope of one static filter or within the scope of all dynamic rules +(custom filters and user rules). +
Examples:
+example 1 ```adblock -||example.com$_,removeparam=/^ss\\$/,_,image -||example.com$domain=example.org,___,~third-party +||example.org^$removeheader=header-name ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -2745,38 +3025,43 @@ Converting as $redirect rules ```json [ { - "id": 2, + "id": 1, "action": { - "type": "block" + "type": "modifyHeaders", + "responseHeaders": [ + { + "header": "header-name", + "operation": "remove" + } + ] }, "condition": { - "urlFilter": "||example.com", - "domainType": "firstParty", - "initiatorDomains": [ - "example.org" - ], - "isUrlFilterCaseSensitive": false + "urlFilter": "||example.org^", + "isUrlFilterCaseSensitive": false, + "resourceTypes": [ + "main_frame", + "sub_frame", + "stylesheet", + "script", + "image", + "font", + "object", + "xmlhttprequest", + "ping", + "media", + "websocket", + "other" + ] }, - "priority": 202 + "priority": 1 } ] ``` - -## $empty -Status: implemented not correct, deprecated -
-MV3 limitations: -
-Converted as simple blocking rule. -
-Examples: -
-example 1. -returns an empty response to all requests to example.org and all subdomains. +example 2 ```adblock -||example.org^$empty +||example.org^$removeheader=request:header-name ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -2786,29 +3071,65 @@ returns an empty response to all requests to example.org and all subdomains. { "id": 1, "action": { - "type": "redirect", - "redirect": { - "extensionPath": "/path/to/resources/nooptext.js" - } + "type": "modifyHeaders", + "requestHeaders": [ + { + "header": "header-name", + "operation": "remove" + } + ] }, "condition": { "urlFilter": "||example.org^", - "isUrlFilterCaseSensitive": false + "isUrlFilterCaseSensitive": false, + "resourceTypes": [ + "main_frame", + "sub_frame", + "stylesheet", + "script", + "image", + "font", + "object", + "xmlhttprequest", + "ping", + "media", + "websocket", + "other" + ] }, - "priority": 1001 + "priority": 1 } ] ``` - -## $denyallow -Status: supported -
-Examples: -
+example 3 ```adblock -*$script,domain=a.com|b.com,denyallow=x.com|y.com +@@||example.org^$removeheader +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[] + +``` +example 4 (with limitations) + +```adblock +@@||example.org^$removeheader=header +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[] + +``` +example 5 + +```adblock +||example.org^$removeheader=refresh ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -2818,39 +3139,85 @@ returns an empty response to all requests to example.org and all subdomains. { "id": 1, "action": { - "type": "block" + "type": "modifyHeaders", + "responseHeaders": [ + { + "header": "refresh", + "operation": "remove" + } + ] }, "condition": { - "urlFilter": "*", - "initiatorDomains": [ - "a.com", - "b.com" - ], - "excludedRequestDomains": [ - "x.com", - "y.com" - ], + "urlFilter": "||example.org^", + "isUrlFilterCaseSensitive": false, "resourceTypes": [ - "script" - ], - "isUrlFilterCaseSensitive": false + "main_frame", + "sub_frame", + "stylesheet", + "script", + "image", + "font", + "object", + "xmlhttprequest", + "ping", + "media", + "websocket", + "other" + ] }, - "priority": 252 + "priority": 1 } ] ``` - -## $mp4 -Status: not implemented yet, deprecated -
-Examples: -
-example 1. -block a video downloads from ||example.com/videos/* and changes the response to a video placeholder. +example 6 + +```adblock +||example.org^$removeheader=request:x-client-data +``` + +↓↓↓↓ converted to ↓↓↓↓ + +```json +[ + { + "id": 1, + "action": { + "type": "modifyHeaders", + "requestHeaders": [ + { + "header": "x-client-data", + "operation": "remove" + } + ] + }, + "condition": { + "urlFilter": "||example.org^", + "isUrlFilterCaseSensitive": false, + "resourceTypes": [ + "main_frame", + "sub_frame", + "stylesheet", + "script", + "image", + "font", + "object", + "xmlhttprequest", + "ping", + "media", + "websocket", + "other" + ] + }, + "priority": 1 + } +] + +``` +example 8 ```adblock -||example.com/videos/$mp4 +$removeheader=location,domain=example.com ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -2860,26 +3227,42 @@ block a video downloads from ||example.com/videos/* and changes the response to { "id": 1, "action": { - "type": "redirect", - "redirect": { - "extensionPath": "/path/to/resources/noopmp4.mp4" - } + "type": "modifyHeaders", + "responseHeaders": [ + { + "header": "location", + "operation": "remove" + } + ] }, "condition": { - "urlFilter": "||example.com/videos/", - "resourceTypes": [ - "media" + "initiatorDomains": [ + "example.com" ], - "isUrlFilterCaseSensitive": false + "isUrlFilterCaseSensitive": false, + "resourceTypes": [ + "main_frame", + "sub_frame", + "stylesheet", + "script", + "image", + "font", + "object", + "xmlhttprequest", + "ping", + "media", + "websocket", + "other" + ] }, - "priority": 1101 + "priority": 201 } ] ``` ## $removeparam -Status: partial support +Status: partial supported
MV3 limitations:
@@ -3040,6 +3423,7 @@ $removeparam=/^(utm_content|utm_campaign|utm_referrer)=/ ``` example 10 +
Group of similar remove param rules will be combined into one ```adblock @@ -3103,110 +3487,40 @@ $xmlhttprequest,removeparam=p1case2 ] ``` - -## $removeheader -Status: supported -
-Allowlist rules are not supported -
-Rules with the same matching condition are combined into one, but only within -the scope of one static filter or within the scope of all dynamic rules -(custom filters and user rules). + +## $replace +Status: not supported
Examples:
example 1 ```adblock -||example.org^$removeheader=header-name +||example.org^$replace=/()[\s\S]*<\/VAST>/\$1<\/VAST>/i ``` ↓↓↓↓ converted to ↓↓↓↓ ```json -[ - { - "id": 1, - "action": { - "type": "modifyHeaders", - "responseHeaders": [ - { - "header": "header-name", - "operation": "remove" - } - ] - }, - "condition": { - "urlFilter": "||example.org^", - "isUrlFilterCaseSensitive": false, - "resourceTypes": [ - "main_frame", - "sub_frame", - "stylesheet", - "script", - "image", - "font", - "object", - "xmlhttprequest", - "ping", - "media", - "websocket", - "other" - ] - }, - "priority": 1 - } -] +[] ``` example 2 ```adblock -||example.org^$removeheader=request:header-name +||example.org^$replace=/X/Y/ ``` ↓↓↓↓ converted to ↓↓↓↓ ```json -[ - { - "id": 1, - "action": { - "type": "modifyHeaders", - "requestHeaders": [ - { - "header": "header-name", - "operation": "remove" - } - ] - }, - "condition": { - "urlFilter": "||example.org^", - "isUrlFilterCaseSensitive": false, - "resourceTypes": [ - "main_frame", - "sub_frame", - "stylesheet", - "script", - "image", - "font", - "object", - "xmlhttprequest", - "ping", - "media", - "websocket", - "other" - ] - }, - "priority": 1 - } -] +[] ``` example 3 ```adblock -@@||example.org^$removeheader +||example.org^$replace=/Z/Y/ ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -3215,10 +3529,10 @@ example 3 [] ``` -example 4 (with limitations) +example 4 ```adblock -@@||example.org^$removeheader=header +@@||example.org/page/*$replace=/Z/Y/ ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -3227,10 +3541,16 @@ example 4 (with limitations) [] ``` -example 5 + +## noop +Status: supported +
+Examples: +
```adblock -||example.org^$removeheader=refresh +||example.com$_,removeparam=/^ss\\$/,_,image +||example.com$domain=example.org,___,~third-party ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -3238,43 +3558,33 @@ example 5 ```json [ { - "id": 1, + "id": 2, "action": { - "type": "modifyHeaders", - "responseHeaders": [ - { - "header": "refresh", - "operation": "remove" - } - ] + "type": "block" }, "condition": { - "urlFilter": "||example.org^", - "isUrlFilterCaseSensitive": false, - "resourceTypes": [ - "main_frame", - "sub_frame", - "stylesheet", - "script", - "image", - "font", - "object", - "xmlhttprequest", - "ping", - "media", - "websocket", - "other" - ] + "urlFilter": "||example.com", + "domainType": "firstParty", + "initiatorDomains": [ + "example.org" + ], + "isUrlFilterCaseSensitive": false }, - "priority": 1 + "priority": 202 } ] ``` -example 6 + +## $empty +Status: supported +
+Examples: +
+example 1. ```adblock -||example.org^$removeheader=request:x-client-data +||example.org^$empty ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -3284,41 +3594,30 @@ example 6 { "id": 1, "action": { - "type": "modifyHeaders", - "requestHeaders": [ - { - "header": "x-client-data", - "operation": "remove" - } - ] + "type": "redirect", + "redirect": { + "extensionPath": "/path/to/resources/nooptext.js" + } }, "condition": { "urlFilter": "||example.org^", - "isUrlFilterCaseSensitive": false, - "resourceTypes": [ - "main_frame", - "sub_frame", - "stylesheet", - "script", - "image", - "font", - "object", - "xmlhttprequest", - "ping", - "media", - "websocket", - "other" - ] + "isUrlFilterCaseSensitive": false }, - "priority": 1 + "priority": 1001 } ] ``` -example 8 + +## $mp4 +Status: supported, deprecated +
+Examples: +
+example 1. ```adblock -$removeheader=location,domain=example.com +||example.com/videos/$mp4 ``` ↓↓↓↓ converted to ↓↓↓↓ @@ -3328,35 +3627,19 @@ $removeheader=location,domain=example.com { "id": 1, "action": { - "type": "modifyHeaders", - "responseHeaders": [ - { - "header": "location", - "operation": "remove" - } - ] + "type": "redirect", + "redirect": { + "extensionPath": "/path/to/resources/noopmp4.mp4" + } }, "condition": { - "initiatorDomains": [ - "example.com" - ], - "isUrlFilterCaseSensitive": false, + "urlFilter": "||example.com/videos/", "resourceTypes": [ - "main_frame", - "sub_frame", - "stylesheet", - "script", - "image", - "font", - "object", - "xmlhttprequest", - "ping", - "media", - "websocket", - "other" - ] + "media" + ], + "isUrlFilterCaseSensitive": false }, - "priority": 201 + "priority": 1101 } ] @@ -3372,4 +3655,4 @@ $removeheader=location,domain=example.com ## $app (not supported in extension) -## $extension (not supported in extension) \ No newline at end of file +## $extension (not supported in extension) diff --git a/packages/tsurlfilter/src/rules/declarative-converter/grouped-rules-converters/abstract-rule-converter.ts b/packages/tsurlfilter/src/rules/declarative-converter/grouped-rules-converters/abstract-rule-converter.ts index 762059dfe..98c5ac14a 100644 --- a/packages/tsurlfilter/src/rules/declarative-converter/grouped-rules-converters/abstract-rule-converter.ts +++ b/packages/tsurlfilter/src/rules/declarative-converter/grouped-rules-converters/abstract-rule-converter.ts @@ -682,6 +682,8 @@ export abstract class DeclarativeRuleConverter { { option: NetworkRuleOption.Extension, name: '$extension' }, { option: NetworkRuleOption.Stealth, name: '$stealth' }, /* Specific exceptions */ + { option: NetworkRuleOption.Method, name: '$method' }, + { option: NetworkRuleOption.To, name: '$to' }, { option: NetworkRuleOption.Popup, name: '$popup', diff --git a/packages/tsurlfilter/src/rules/declarative-converter/readme.txt b/packages/tsurlfilter/src/rules/declarative-converter/readme.txt index d1adde49f..39d817943 100644 --- a/packages/tsurlfilter/src/rules/declarative-converter/readme.txt +++ b/packages/tsurlfilter/src/rules/declarative-converter/readme.txt @@ -1,6 +1,7 @@ ! # Description ! This file contains examples of converting filter rules to new MV3 declarative ! rules and describes some MV3-specific limitations of the converted rules. +! For a full description of each modifier, see the knowledgebase https://adguard.com/kb/general/ad-filtering/create-own-filters. !
!
@@ -8,36 +9,29 @@ ! # MV3 specific limitations ! ## allowrules ! Allowrules currently are not supported for these modifiers: -! 1. some specific exceptions: '$genericblock', '$jsinject', '$urlblock', '$content', '$stealth'. +! 1. some specific exceptions: `$genericblock`, `$jsinject`, `$urlblock`, `$content`, `$stealth`. ! 1. `$redirect` ! 1. `$removeparam` ! 1. `$removeheader` ! 1. `$csp` ! ! ## $document -! During convertion process $document modificator is expanded into -! $elemhide, $content, $urlblock, $jsinject, -! of which: -! - $content - not supported in the MV3; -! - $elemhide, $jsinject - not implemented yet; -! - $urlblock - converted not correctly (allow all requests not on the specified -! url, but FROM specified url and also disables cosmetic rules). -! So we still convert the $document-rules, but not 100% correctly. +! During convertion process exception with $document modificator is expanded +! into `$elemhide,content,urlblock,jsinject` of which: +! - `$content` - not supported in the MV3, +! - `$elemhide` - supported, +! - `$jsinject` - not implemented yet, +! - `$urlblock` - not implemented yet. ! -! ## $removeparam -! Groups of $removeparam rules with the same conditions are combined into one -! rule only within one filter. +! So we still convert rules with `$document`, but not 100% correctly. ! -! ## $removeheader -! Groups of $removeheader rules with the same conditions are combined into one -! rule only within one filter. -! -! ## $csp -! Groups of $csp rules with the same conditions are combined into one -! rule only within one filter. +! ## $removeparam, $removeheader, $csp +! Rules with `$removeparam` or `$removeheader` or `$csp` which contains the same +! conditions are combined into one rule only within one filter but not across +! different filters. Because of that, rules from different filter can conflict. ! ! ## $redirect-rule -! Works as $redirect +! Works as `$redirect`. !
!
@@ -66,6 +60,13 @@ example.org##.banner ! ! # Basic modifiers +! ## $denyallow +! Status: supported +!
+! Examples: +!
+*$script,domain=a.com|b.com,denyallow=x.com|y.com + ! ## $domain ! Status: partial supported !
@@ -104,18 +105,73 @@ page$domain=targetdomain.com ! example 14 page$domain=targetdomain.com|~example.org -! ## $third-party +! ## $header +! Status: not supported +!
+! MV3 limitations: +!
+! Cannot be converted to MV3 Declarative Rule +!
+! Examples: +!
+! example 1 +||example.com^$header=set-cookie:foo +! example 2 +||example.com^$header=set-cookie +! example 3 +@@||example.com^$header=set-cookie:/foo\, bar\$/ +! example 4 +@@||example.com^$header=set-cookie + + +! ## $important ! Status: supported !
! Examples: !
+! example 1. +!
+! blocking rule will block all requests despite of the exception rule +||example.org^$important +@@||example.org^ +! example 2. +!
+! if the exception rule also has `$important` modifier it will prevail, +! so no requests will not be blocked +||example.org^$important +@@||example.org^$important +! example 3. +!
+! if a document-level exception rule is applied to the document, +! the `$important` modifier will be ignored; +! so if a request to `example.org` is sent from the `test.org` domain, +! the blocking rule will not be applied despite it has the `$important` modifier +||example.org^$important +@@||test.org^$document + +! ## $match-case +! Status: supported +!
+! Examples: +!
+*/BannerAd.gif$match-case + +! ## $method +! Status: not implemented yet +!
+! Examples: +!
! example 1 -||domain.com^$third-party +||evil.com^$method=get|head ! example 2 -||domain.com$~third-party +||evil.com^$method=~post|~put +! example 3 +@@||evil.com$method=get +! example 4 +@@||evil.com$method=~post ! ## $popup -! Status: partial support +! Status: not implemented yet !
! MV3 limitations: !
@@ -126,37 +182,33 @@ page$domain=targetdomain.com|~example.org !
||domain.com^$popup -! ## $match-case +! ## $third-party ! Status: supported !
! Examples: !
-*/BannerAd.gif$match-case +! example 1 +||domain.com^$third-party +! example 2 +||domain.com$~third-party -! ## $header -! Status: not supported -!
-! MV3 limitations: -!
-! Cannot be converted to MV3 Declarative Rule +! ## $to +! Status: not implemented yet !
! Examples: !
! example 1 -||example.com^$header=set-cookie:foo +/ads$to=evil.com|evil.org ! example 2 -||example.com^$header=set-cookie +/ads$to=~not.evil.com|evil.com ! example 3 -@@||example.com^$header=set-cookie:/foo\, bar\$/ -! example 4 -@@||example.com^$header=set-cookie +/ads$to=~good.com|~good.org !
!
! ! # Content type modifiers -! Status: all content type modifiers supported, except deprecated $webrtc -! and $object-subrequest +! Status: all content type modifiers supported, except deprecated $webrtc and $object-subrequest. !
! Examples: !
@@ -230,8 +282,15 @@ page$domain=targetdomain.com|~example.org ! ! # Exception rules modifiers +! ## $content +! Status: not supported in MV3 +!
+! Examples: +!
+@@||example.com^$content + ! ## $elemhide -! Status: is supported but not converted. +! Status: supported but not converted. !
! MV3 limitations: !
@@ -241,51 +300,39 @@ page$domain=targetdomain.com|~example.org !
@@||example.com^$elemhide -! ## $content +! ## $jsinject ! Status: not implemented yet !
-! MV3 limitations: -!
-! Bug: currently converted to allowAllRequests rules -!
! Examples: !
-@@||example.com^$content +@@||example.com^$jsinject -! ## $jsinject +! ## $stealth ! Status: not implemented yet !
! Examples: !
-@@||example.com^$jsinject +! example 1 +@@||example.com^$stealth +! example 2 +@@||domain.com^$script,stealth,domain=example.com ! ## $urlblock ! Status: not implemented yet !
-! MV3 limitations: -!
-! Bug: uses urlFilter instead of initiatorDomains -!
-! Bug: incorrect priority -!
-! Bug: disables cosmetic rules -!
! Examples: !
@@||example.com^$urlblock -! ## $stealth +! ## $genericblock ! Status: not implemented yet !
! Examples: !
-! example 1 -@@||example.com^$stealth -! example 2 -@@||domain.com^$script,stealth,domain=example.com +@@||example.com^$genericblock ! ## $generichide -! Status: is supported but not converted. +! Status: supported but not converted. !
! MV3 limitations: !
@@ -295,15 +342,8 @@ page$domain=targetdomain.com|~example.org !
@@||example.com^$generichide -! ## $genericblock -! Status: not implemented yet -!
-! Examples: -!
-@@||example.com^$genericblock - ! ## $specifichide -! Status: is supported but not converted. +! Status: supported but not converted. !
! MV3 limitations: !
@@ -318,27 +358,12 @@ page$domain=targetdomain.com|~example.org ! ! # Advanced capabilities -! ## $important +! ## $all ! Status: supported !
! Examples: !
-! example 1. -! blocking rule will block all requests despite of the exception rule -||example.org^$important -@@||example.org^ -! example 2. -! if the exception rule also has `$important` modifier it will prevail, -! so no requests will not be blocked -||example.org^$important -@@||example.org^$important -! example 3. -! if a document-level exception rule is applied to the document, -! the `$important` modifier will be ignored; -! so if a request to `example.org` is sent from the `test.org` domain, -! the blocking rule will not be applied despite it has the `$important` modifier -||example.org^$important -@@||test.org^$document +||example.org^$all ! ## $badfilter ! Status: partial support @@ -381,19 +406,31 @@ page$domain=targetdomain.com|~example.org /some$domain=example.com|example.org|example.io /some$domain=example.com|~example.org,badfilter -! ## $replace -! Status: not supported +! ## $cookie +! Status: not implemented yet !
! Examples: !
! example 1 -||example.org^$replace=/()[\s\S]*<\/VAST>/\$1<\/VAST>/i +||example.org^$cookie=NAME;maxAge=3600;sameSite=lax ! example 2 -||example.org^$replace=/X/Y/ +||example.org^$cookie ! example 3 -||example.org^$replace=/Z/Y/ +||example.org^$cookie=NAME ! example 4 -@@||example.org/page/*$replace=/Z/Y/ +||example.org^$cookie=/regexp/ +! example 5 +@@||example.org^$cookie +! example 6 +@@||example.org^$cookie=NAME +! example 7 +@@||example.org^$cookie=/regexp/ +! example 8 +$cookie=__cfduid +! example 9 +$cookie=/__utm[a-z]/ +! example 10 +||facebook.com^$third-party,cookie=c_user ! ## $csp ! Status: supported @@ -418,38 +455,22 @@ page$domain=targetdomain.com|~example.org ||example.org^$csp=script-src 'self' 'unsafe-eval' http: https: @@||example.org^$document -! ## $all -! Status: not implemented yet -!
-! Examples: -!
-||example.org^$all - -! ## $cookie +! ## $permissions ! Status: not implemented yet !
! Examples: !
! example 1 -||example.org^$cookie=NAME;maxAge=3600;sameSite=lax +||example.org^$permissions=sync-xhr=() ! example 2 -||example.org^$cookie +@@||example.org/page/*$permissions=sync-xhr=() ! example 3 -||example.org^$cookie=NAME +@@||example.org/page/*$permissions ! example 4 -||example.org^$cookie=/regexp/ +$domain=example.org|example.com,permissions=oversized-images=()\, sync-script=()\, unsized-media=() ! example 5 -@@||example.org^$cookie -! example 6 -@@||example.org^$cookie=NAME -! example 7 -@@||example.org^$cookie=/regexp/ -! example 8 -$cookie=__cfduid -! example 9 -$cookie=/__utm[a-z]/ -! example 10 -||facebook.com^$third-party,cookie=c_user +||example.org^$permissions=sync-xhr=() +@@||example.org^$document ! ## $redirect ! Status: partial support @@ -497,45 +518,46 @@ $cookie=/__utm[a-z]/ ||example.org/script.js ||example.org^$redirect-rule=noopjs -! ## noop -! Status: supported -!
-! Examples: -!
-||example.com$_,removeparam=/^ss\\$/,_,image -||example.com$domain=example.org,___,~third-party - -! ## $empty -! Status: implemented not correct, deprecated -!
-! MV3 limitations: -!
-! Converted as simple blocking rule. +! ## $referrerpolicy +! Status: not implemented yet !
! Examples: !
-! example 1. -! returns an empty response to all requests to example.org and all subdomains. -||example.org^$empty +! example 1 +||example.com^$referrerpolicy=unsafe-urlblock +! example 2 +@@||example.com^$referrerpolicy=unsafe-urlblock +! example 3 +@@||example.com/abcd.html^$referrerpolicy -! ## $denyallow +! ## $removeheader ! Status: supported !
-! Examples: +! Allowlist rules are not supported !
-*$script,domain=a.com|b.com,denyallow=x.com|y.com - -! ## $mp4 -! Status: not implemented yet, deprecated +! Rules with the same matching condition are combined into one, but only within +! the scope of one static filter or within the scope of all dynamic rules +! (custom filters and user rules). !
! Examples: !
-! example 1. -! block a video downloads from ||example.com/videos/* and changes the response to a video placeholder. -||example.com/videos/$mp4 +! example 1 +||example.org^$removeheader=header-name +! example 2 +||example.org^$removeheader=request:header-name +! example 3 +@@||example.org^$removeheader +! example 4 (with limitations) +@@||example.org^$removeheader=header +! example 5 +||example.org^$removeheader=refresh +! example 6 +||example.org^$removeheader=request:x-client-data +! example 8 +$removeheader=location,domain=example.com ! ## $removeparam -! Status: partial support +! Status: partial supported !
! MV3 limitations: !
@@ -569,37 +591,50 @@ $removeparam=/^(utm_source|utm_medium|utm_term)=/ ! example 9 $removeparam=/^(utm_content|utm_campaign|utm_referrer)=/ ! example 10 +!
! Group of similar remove param rules will be combined into one ||testcases.adguard.com$xmlhttprequest,removeparam=p1case1 ||testcases.adguard.com$xmlhttprequest,removeparam=p2case1 ||testcases.adguard.com$xmlhttprequest,removeparam=P3Case1 $xmlhttprequest,removeparam=p1case2 -! ## $removeheader -! Status: supported -!
-! Allowlist rules are not supported -!
-! Rules with the same matching condition are combined into one, but only within -! the scope of one static filter or within the scope of all dynamic rules -! (custom filters and user rules). +! ## $replace +! Status: not supported !
! Examples: !
! example 1 -||example.org^$removeheader=header-name +||example.org^$replace=/()[\s\S]*<\/VAST>/\$1<\/VAST>/i ! example 2 -||example.org^$removeheader=request:header-name +||example.org^$replace=/X/Y/ ! example 3 -@@||example.org^$removeheader -! example 4 (with limitations) -@@||example.org^$removeheader=header -! example 5 -||example.org^$removeheader=refresh -! example 6 -||example.org^$removeheader=request:x-client-data -! example 8 -$removeheader=location,domain=example.com +||example.org^$replace=/Z/Y/ +! example 4 +@@||example.org/page/*$replace=/Z/Y/ + +! ## noop +! Status: supported +!
+! Examples: +!
+||example.com$_,removeparam=/^ss\\$/,_,image +||example.com$domain=example.org,___,~third-party + +! ## $empty +! Status: supported +!
+! Examples: +!
+! example 1. +||example.org^$empty + +! ## $mp4 +! Status: supported, deprecated +!
+! Examples: +!
+! example 1. +||example.com/videos/$mp4 ! # Not supported in extension diff --git a/packages/tsurlfilter/tasks/generate-examples.ts b/packages/tsurlfilter/tasks/generate-examples.ts index c8be0cfa0..6d22d95a2 100644 --- a/packages/tsurlfilter/tasks/generate-examples.ts +++ b/packages/tsurlfilter/tasks/generate-examples.ts @@ -108,7 +108,11 @@ const parseRowAndLinkFromText = ( const hash = parentLink ? `${parentLink}__` : ''; // Gen link - const linkName = txt.slice(levelInTable).trim().toLocaleLowerCase().replace(/\s/g, '_'); + const linkName = txt + .slice(levelInTable) + .trim() + .toLocaleLowerCase() + .replace(/[\s,]/g, '_'); const idLinkWithHash = `${hash}${linkName}`; const htmlLink = ``; diff --git a/packages/tswebextension/src/lib/mv3/background/scriptlets.ts b/packages/tswebextension/src/lib/mv3/background/scriptlets.ts index cd233a42e..a36eb99b5 100644 --- a/packages/tswebextension/src/lib/mv3/background/scriptlets.ts +++ b/packages/tswebextension/src/lib/mv3/background/scriptlets.ts @@ -11,6 +11,7 @@ import { tabsApi } from './tabs-api'; * @see {@link engineApi.getScriptsStringForUrl} */ const getScripts = async (url: string): Promise => { + // TODO: Extract cosmetic option from matching result (AG-24586) return engineApi.getScriptsStringForUrl(url, CosmeticOption.CosmeticOptionAll); }; @@ -19,6 +20,7 @@ const getScripts = async (url: string): Promise => { * @see {@link engineApi.getScriptletsDataForUrl} */ const getScriptletsDataList = async (url: string): Promise => { + // TODO: Extract cosmetic option from matching result (AG-24586) return engineApi.getScriptletsDataForUrl(url, CosmeticOption.CosmeticOptionAll); };