1# Enabling Ads Blocking
2ArkWeb provides the ads blocking capability for applications, supporting default Easylist rules pushed by the cloud and custom rule files set by applications through APIs. It can intercept the advertisement resource download at the network layer or inject CSS rules into the web page to hide specific advertisement elements.
3
4The current configuration file uses the EasyList syntax.
5
6## Common Easylist Syntax
7
8| Type    | Description  | Example|
9| ---------- | ------ | ---- |
10| URL blocking rule| Blocks all sub-resource requests whose URLs match **example.com/js/*_tv.js**. This rule is used to block a specified domain name and all its subdomain names.| \|\|example.com/js/*_tv.js   |
11| URL blocking rule| Blocks third-party resources whose URLs match **"alimama.cn"** from websites whose domain names are neither **alimama.com** nor **taobao.com**. **\$third\_party** is an options syntax used to match third-party resources. A tilde (~) before a domain name indicates that the domain name is not included.| \|\|alimama.cn^$third-party,domain\=~alimama.com\|\~taobao.com   |
12| Exception rule| Disables ads blocking on **example.com**. **@@** is the syntax keyword that indicates no blocking.| \@\@\|\|example.com^$document   |
13| Exception rule| Disables the blocking of subresources that match **".adserver"** in the web page whose domain name is **litv.tv**.| \@\@.adserver.$domain=litv.tv   |
14| Element hiding rule| Hides all elements whose class is **i528** in the web page whose domain name is **myabandonware.com** or **myware.com**. **##** is used to hide an element.| myabandonware.com, myware.com##.i528   |
15| Element hiding exception rule| Disables the hiding of elements whose IDs are **ad_1** in **sdf-event.sakura.ne.jp**.| sdf-event.sakura.ne.jp#@##ad_1   |
16
17Exception rules are usually used together with common rules so that common rules do not take effect in some scenarios.
18For example, if you configure a blocking rule **||abc.com/js/123.js** to block websites, but some websites are blocked by mistake or cannot be blocked, you can configure exception rules for these websites.
19
20## Constraints
21
22- In the [WebviewController](../reference/apis-arkweb/js-apis-webview.md#webviewcontroller) class, add [enableAdsBlock()](../reference/apis-arkweb/js-apis-webview.md#enableadsblock12) to support the enabling and disabling of the web instance-level feature.
23
24- Add the [AdsBlockManager](../reference/apis-arkweb/js-apis-webview.md#adsblockmanager12) global singleton class to provide the capabilities of customizing ads blocking configurations and controlling website-level features.
25
26- The web instance provides [onAdsBlocked()](../reference/apis-arkweb/ts-basic-components-web.md#onadsblocked12) callback to notify the upper-layer application of the interception information.
27
28- Only one custom configuration can be set by the [setAdsBlockRules()](../reference/apis-arkweb/js-apis-webview.md#setadsblockrules12) API of [AdsBlockManager](../reference/apis-arkweb/js-apis-webview.md#adsblockmanager12). The configuration is persistent and does not need to be reconfigured during cold start of the application. This prevents the compilation and parsing of the ads blocking rule from being triggered again.
29
30- The following APIs of [AdsBlockManager](../reference/apis-arkweb/js-apis-webview.md#adsblockmanager12) do not support data persistence: [addAdsBlockDisallowedList()](../reference/apis-arkweb/js-apis-webview.md#addadsblockdisallowedlist12), [removeAdsBlockDisallowedList()](../reference/apis-arkweb/js-apis-webview.md#removeadsblockdisallowedlist12), [clearAdsBlockDisallowedList()](../reference/apis-arkweb/js-apis-webview.md#clearadsblockdisallowedlist12), [addAdsBlockAllowedList()](../reference/apis-arkweb/js-apis-webview.md#addadsblockallowedlist12), [removeAdsBlockAllowedList()](../reference/apis-arkweb/js-apis-webview.md#removeadsblockallowedlist12), [clearAdsBlockAllowedList()](../reference/apis-arkweb/js-apis-webview.md#clearadsblockallowedlist12). You need to configure them again during the application cold start.
31
32- If the ads blocking feature is enabled for a **Web** instance, but the [AdsBlockManager](../reference/apis-arkweb/js-apis-webview.md#adsblockmanager12) APIs, [addAdsBlockDisallowedList()](../reference/apis-arkweb/js-apis-webview.md#addadsblockdisallowedlist12), [removeAdsBlockDisallowedList()](../reference/apis-arkweb/js-apis-webview.md#removeadsblockdisallowedlist12), [clearAdsBlockDisallowedList()](../reference/apis-arkweb/js-apis-webview.md#clearadsblockdisallowedlist12), [addAdsBlockAllowedList()](../reference/apis-arkweb/js-apis-webview.md#addadsblockallowedlist12), [removeAdsBlockAllowedList()](../reference/apis-arkweb/js-apis-webview.md#removeadsblockallowedlist12) and [clearAdsBlockAllowedList()](../reference/apis-arkweb/js-apis-webview.md#clearadsblockallowedlist12) are not called to configure disallowlist and allowlist data, ads blocking is enabled for all websites by default.
33
34- When both allowlist and disallowlist are used, allowlist has a higher priority than disallowlist. That is, allowlist is used for matching first. If the matching is successful, disallowlist is not used, and the ads blocking feature is enabled for the website.
35
36- If the ads blocking feature is not enabled for the application, ensure that the **Web** component does not request the default built-in EasyList configuration file from the server.
37
38- The disallowlist and allowlist use suffix matching. For example, if the domain name of an application is **xxyy.com**, the website whose URL is **wwsstt.xxyy.com** can be matched.
39
40## Application Scenarios
41
42### Enabling Ads Blocking
43You can use [setAdsBlockRules()](../reference/apis-arkweb/js-apis-webview.md#setadsblockrules12) provided by **AdsBlockManager** to set blocking rules in EasyList and use [enableAdsBlock()](../reference/apis-arkweb/js-apis-webview.md#enableadsblock12) of the **Web** component to enable the ads blocking.
44
45The following example shows how to select the EasyList rule file using the file picker and how to enable the ads blocking in an application.
46
47```ts
48// xxx.ets
49import { webview } from '@kit.ArkWeb';
50import { picker, fileUri } from '@kit.CoreFileKit';
51
52// This example demonstrates how to click a button to open the EasyList using file picker and set the file in the Web component.
53@Entry
54@Component
55struct WebComponent {
56  main_url: string = 'https://www.example.com';
57  controller: webview.WebviewController = new webview.WebviewController();
58
59  @State input_text: string = 'https://www.example.com';
60
61  build() {
62    Column() {
63      Row() {
64        Flex() {
65          Button({type: ButtonType.Capsule}) {
66            Text("setAdsBlockRules")
67          }
68          .onClick(() => {
69            try {
70              let documentSelectionOptions: ESObject = new picker.DocumentSelectOptions();
71              let documentPicker: ESObject = new picker.DocumentViewPicker();
72              documentPicker.select(documentSelectionOptions).then((documentSelectResult: ESObject) => {
73                if (documentSelectResult && documentSelectResult.length > 0) {
74                  let fileRealPath = new fileUri.FileUri(documentSelectResult[0]);
75                  console.info('DocumentViewPicker.select successfully, uri: ' + fileRealPath);
76                  webview.AdsBlockManager.setAdsBlockRules(fileRealPath.path, true);
77                }
78              })
79            } catch (err) {
80              console.error('DocumentViewPicker.select failed with err:' + err);
81            }
82          })
83        }
84      }
85      Web({ src: this.main_url, controller: this.controller })
86        .onControllerAttached(()=>{
87          this.controller.enableAdsBlock(true);
88        })
89    }
90  }
91}
92```
93
94When the component has a built-in EasyList, the **replace** parameter of [setAdsBlockRules()](../reference/apis-arkweb/js-apis-webview.md#setadsblockrules12) can be used to set the options of the built-in rule. If **replace** is set to **true**, the built-in EasyList is not used. Otherwise, the custom rule and built-in rule work at the same time. If the built-in rule conflicts with the custom rule, you can use set **replace** to **true** to disable the built-in rule.
95
96The custom rule is a global configuration rule for the application that it takes effect for all **Web** components in the application processes. In addition, the rule is persistent that it continues to work when the application is restarted.
97
98### Disabling Ads Blocking on Pages with Specific Domain Names
99When the ads blocking of a **Web** component is enabled, you may want to disable it for some specific pages. In addition to the custom EasyList, you can also use [addAdsBlockDisallowedList()](../reference/apis-arkweb/js-apis-webview.md#addadsblockdisallowedlist12) provided by **AdsBlockManager** to disable the blocking.
100
101```ts
102// xxx.ets
103import { webview } from '@kit.ArkWeb';
104
105// This example demonstrates how to click a button to add an array of domain names to the disallowed list.
106@Entry
107@Component
108struct WebComponent {
109  main_url: string = 'https://www.example.com';
110  text_input_controller: TextInputController = new TextInputController();
111  controller: webview.WebviewController = new webview.WebviewController();
112
113  @State input_text: string = 'https://www.example.com';
114
115  build() {
116    Column() {
117      Row() {
118        Flex() {
119          TextInput({ text: this.input_text, placeholder: this.main_url, controller: this.text_input_controller})
120            .id("input_url")
121            .height(40)
122            .margin(5)
123            .borderColor(Color.Blue)
124            .onChange((value: string) => {
125              this.input_text = value;
126            })
127
128          Button({type: ButtonType.Capsule}) { Text("Go") }
129          .onClick(() => {
130            this.controller.loadUrl(this.input_text);
131          })
132
133          Button({type: ButtonType.Capsule}) { Text("addAdsBlockDisallowedList") }
134          .onClick(() => {
135            let arrDomainSuffixes = new Array<string>();
136            arrDomainSuffixes.push('example.com');
137            arrDomainSuffixes.push('abcdefg.cn');
138            webview.AdsBlockManager.addAdsBlockDisallowedList(arrDomainSuffixes);
139          })
140        }
141      }
142      Web({ src: this.main_url, controller: this.controller })
143        .onControllerAttached(()=>{
144          this.controller.enableAdsBlock(true);
145        })
146    }
147  }
148}
149```
150
151Add the domain name to **DisallowedList** of **AdsBlockManager** through [addAdsBlockDisallowedList()](../reference/apis-arkweb/js-apis-webview.md#addadsblockdisallowedlist12). When the page is loaded, the system matches the suffix of the web page URL with the domain name in **DisallowedList**. If the matching is successful, the system does not block ads on the page. In addition, [addAdsBlockAllowedList()](../reference/apis-arkweb/js-apis-webview.md#addadsblockallowedlist12) is provided to be used with **DisallowedList()** to set domain names and determine whether to enable ads blocking.
152
153**AdsBlockManager** caches two lists of domain names, including **DisallowedList** and **AllowList**. **DisallowedList** is used to disable ads blocking on web pages, and **AllowList** is used to enable ads blocking disabled by **DisallowedList**. **AllowList** has a higher priority. When a web page is loaded, the system matches the web page URL with **AllowList**. If the matching is successful, the ads blocking is enabled. Otherwise, the system continues to match the web page URL with **DisallowedList**. If the matching is successful, the ads blocking is disabled. If the accessed web page is neither list in **AllowList** nor in **DisallowedList**, the ads blocking for this web page is enabled by default.
154
155For example, if you want to enable ads blocking for** news.example.com** and **sport.example.com** in an application, but need to disable ads blocking for other web pages under the **example.com** domain, you can use **addAdsBlockDisallowedList()** to add **example.com** to **DisallowedList**, and then use **addAdsBlockAllowedList()** to add **news.example.com** and **sport.example.com** to **AllowedList**.
156
157```ts
158// xxx.ets
159import { webview } from '@kit.ArkWeb';
160
161// In the following example, **addAdsBlockAllowedList()** and **addAdsBlockDisallowedList()** are used together to set the ads blocking for web pages.
162@Entry
163@Component
164struct WebComponent {
165  main_url: string = 'https://www.example.com';
166  text_input_controller: TextInputController = new TextInputController();
167  controller: webview.WebviewController = new webview.WebviewController();
168
169  @State input_text: string = 'https://www.example.com';
170
171  build() {
172    Column() {
173      Row() {
174        Flex() {
175          TextInput({ text: this.input_text, placeholder: this.main_url, controller: this.text_input_controller})
176            .id("input_url")
177            .height(40)
178            .margin(5)
179            .borderColor(Color.Blue)
180            .onChange((value: string) => {
181              this.input_text = value;
182            })
183
184          Button({type: ButtonType.Capsule}) { Text("Go") }
185          .onClick(() => {
186            this.controller.loadUrl(this.input_text);
187          })
188
189          Button({type: ButtonType.Capsule}) { Text("addAdsBlockAllowedList") }
190          .onClick(() => {
191            let arrDisallowDomainSuffixes = new Array<string>();
192            arrDisallowDomainSuffixes.push('example.com');
193            webview.AdsBlockManager.addAdsBlockDisallowedList(arrDisallowDomainSuffixes);
194
195            let arrAllowedDomainSuffixes = new Array<string>();
196            arrAllowedDomainSuffixes.push('news.example.com');
197            arrAllowedDomainSuffixes.push('sport.example.com');
198            webview.AdsBlockManager.addAdsBlockAllowedList(arrAllowedDomainSuffixes);
199          })
200        }
201      }
202      Web({ src: this.main_url, controller: this.controller })
203        .onControllerAttached(()=>{
204          this.controller.enableAdsBlock(true);
205        })
206    }
207  }
208}
209```
210
211Note that the **DisallowedList** and **AllowedList** of the **AdsBlockManager** are not persisted. Therefore, the lists are reset to empty when the application is restarted.
212If the ads blocking function of the **Web** component is not enabled through [enableAdsBlock()](../reference/apis-arkweb/js-apis-webview.md#enableadsblock12), the preceding APIs do not take effect in the Web component.
213
214### Collecting Ads Blocking Information
215When ads blocking is enabled on the **Web** component, if any ad is blocked on the accessed web page, the [onAdsBlocked()](../reference/apis-arkweb/ts-basic-components-web.md#onadsblocked12) callback of the **Web** component notifies the application. You can collect blocking information and statistics as needed.
216
217```ts
218// xxx.ets
219import { webview } from '@kit.ArkWeb';
220
221
222@Entry
223@Component
224struct WebComponent {
225  @State totalAdsBlockCounts: number = 0;
226  controller: webview.WebviewController = new webview.WebviewController();
227
228  build() {
229    Column() {
230      Web({ src: 'https://www.example.com', controller: this.controller })
231        .onAdsBlocked((details: AdsBlockedDetails) => {
232          if (details) {
233            console.log(' Blocked ' + details.adsBlocked.length + ' in ' + details.url);
234            let adList: Array<string> = Array.from(new Set(details.adsBlocked));
235            this.totalAdsBlockCounts += adList.length;
236            console.log('Total blocked counts :' + this.totalAdsBlockCounts);
237          }
238        })
239    }
240  }
241}
242```
243
244To reduce the frequency of notifications and minimize the impact on the page loading process, only the first notification is made when the page is fully loaded. Subsequent blocking events are reported at intervals of 1 second, and no notifications are sent if there is no ads blocked.
245