Ad Blocking with ArkWeb in HarmonyOS Next
Overview
ArkWeb provides an ad-blocking feature for applications, supporting both cloud-pushed default easylist rules and custom rule files set via interfaces. It intercepts ad resource downloads at the network layer or injects CSS rules into web pages to hide specific ad elements.
Easylist Syntax Rules
The current configuration file format follows easylist syntax rules. Here are some commonly used easylist syntax rules:
Rule Category | Description | Example |
---|---|---|
URL Interception Rule | Blocks subresource requests where the URL matches "example.com/js/*_tv.js" across all websites. Used for defining domain filtering rules to match specific domains and all their subdomains. | ` |
URL Interception Rule | Blocks third-party resources where the URL matches "alimama.cn" on websites not belonging to alimama.com or taobao.com. {% raw %}$third_party is an options syntax indicating a match for third-party resources; using ~ before a domain name excludes that domain. |
` |
Exception Rule | Disables ad blocking on the example.com webpage. {% raw %}@@ is the syntax keyword for exception rules, indicating no filtering. |
`@@ |
Exception Rule | On web pages with the domain litv.tv, does not filter subresources matching ".adserver.". | {% raw %}@@.adserver.$domain=litv.tv
|
Element Hiding Rule | Hides elements with class="i528" on domains myabandonware.com and myware.com. ## is used to indicate element hiding. |
myabandonware.com, myware.com##.i528 |
Element Hiding Exception Rule | Does not hide elements with id="ad_1" on the sdf-event.sakura.ne.jp website. | sdf-event.sakura.ne.jp#@##ad_1 |
Exception rules are typically used in conjunction with regular rules to disable regular rules in specific scenarios. Using exception rules alone does not make sense.
Constraints and Limitations
- The
WebviewController
class includes theenableAdsBlock()
interface to enable/disable the ad-blocking feature at the Web instance level. - A new
AdsBlockManager
global singleton class is introduced, providing capabilities for custom ad-blocking configurations and controlling site-level feature switches. - The
Web
instance offers theonAdsBlocked()
callback notification method to inform the upper-layer application of interception information. - The
AdsBlockManager
interface'ssetAdsBlockRules()
can only set one custom configuration, which will be persisted. There is no need to reconfigure on cold start, avoiding the recompilation and parsing of ad-blocking configurations on each cold start. - Data operated by
AdsBlockManager
interfaces such asaddAdsBlockDisallowedList()
,removeAdsBlockDisallowedList()
,clearAdsBlockDisallowedList()
,addAdsBlockAllowedList()
,removeAdsBlockAllowedList()
, andclearAdsBlockAllowedList()
will not be persisted and need to be reset on cold start. - If a Web instance enables the ad-blocking feature but does not call
AdsBlockManager
interfaces to configure disallowlist and allowlist data, ad blocking will be enabled for all websites by default. - When allowlist and disallowlist data are used together, the allowlist has higher priority than the disallowlist. If a match is found in the allowlist, the disallowlist will not be used, and ad blocking will be enabled for that website.
- If the application does not enable the ad-blocking feature, ensure that the Web component does not request the default built-in easylist configuration file from the server.
- Disallowlist and allowlist data use suffix matching. For example, if the application sets the domain "xxyy.com", it can match the website with the URL "wwsstt.xxyy.com".
Use Cases
Enabling Ad Blocking
Applications can use the setAdsBlockRules()
interface provided by AdsBlockManager
to set custom easylist filtering rules and enable the ad-blocking feature via the enableAdsBlock()
interface of the Web component.
In the following example, an application selects an easylist rule file using a file picker and enables the ad-blocking feature.
// xxx.ets
import { webview } from '@kit.ArkWeb';
import { picker, fileUri } from '@kit.CoreFileKit';
// Demonstrate clicking a button to open an easylist rule file via filepicker and set it in the Web component
@Entry
@Component
struct WebComponent {
main_url: string = 'https://www.example.com';
controller: webview.WebviewController = new webview.WebviewController();
@State input_text: string = 'https://www.example.com';
build() {
Column() {
Row() {
Flex() {
Button({type: ButtonType.Capsule}) {
Text("setAdsBlockRules")
}
.onClick(() => {
try {
let documentSelectionOptions: ESObject = new picker.DocumentSelectOptions();
let documentPicker: ESObject = new picker.DocumentViewPicker();
documentPicker.select(documentSelectionOptions).then((documentSelectResult: ESObject) => {
if (documentSelectResult && documentSelectResult.length > 0) {
let fileRealPath = new fileUri.FileUri(documentSelectResult[0]);
console.info('DocumentViewPicker.select successfully, uri: ' + fileRealPath);
webview.AdsBlockManager.setAdsBlockRules(fileRealPath.path, true);
}
})
} catch (err) {
console.error('DocumentViewPicker.select failed with err:' + err);
}
})
}
}
Web({ src: this.main_url, controller: this.controller })
.onControllerAttached(() => {
this.controller.enableAdsBlock(true);
})
}
}
}
If there is a built-in easylist rule file, the replace
parameter of the setAdsBlockRules()
interface can be used to set the rule file usage strategy. replace=true
indicates not using the built-in easylist rule file, while replace=false
means custom rules and built-in rules will work simultaneously. If there is a conflict between built-in and custom rules, use replace=true
to disable the built-in rule effect.
The custom rule file set will take effect for all Web components within the application process, acting as a global application-level configuration file. It will be persisted and continue to work after application restarts.
Disabling Ad Blocking for Specific Domain Pages
After enabling the ad-blocking switch for the Web component, applications may sometimes want to disable ad blocking for specific pages. In addition to using custom easylist rules, AdsBlockManager
also provides the addAdsBlockDisallowedList()
interface to achieve this.
// xxx.ets
import { webview } from '@kit.ArkWeb';
// Demonstrate setting ad-blocking domain policy for the Web component via a button click
@Entry
@Component
struct WebComponent {
main_url: string = 'https://www.example.com';
text_input_controller: TextInputController = new TextInputController();
controller: webview.WebviewController = new webview.WebviewController();
@State input_text: string = 'https://www.example.com';
build() {
Column() {
Row() {
Flex() {
TextInput({ text: this.input_text, placeholder: this.main_url, controller: this.text_input_controller })
.id("input_url")
.height(40)
.margin(5)
.borderColor(Color.Blue)
.onChange((value: string) => {
this.input_text = value;
})
Button({type: ButtonType.Capsule}) { Text("Go") }
.onClick(() => {
this.controller.loadUrl(this.input_text);
})
Button({type: ButtonType.Capsule}) { Text("addAdsBlockDisallowedList") }
.onClick(() => {
let arrDomainSuffixes = new Array<string>();
arrDomainSuffixes.push('example.com');
arrDomainSuffixes.push('abcdefg.cn');
webview.AdsBlockManager.addAdsBlockDisallowedList(arrDomainSuffixes);
})
}
}
Web({ src: this.main_url, controller: this.controller })
.onControllerAttached(() => {
this.controller.enableAdsBlock(true);
})
}
}
}
Top comments (0)