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);
};