守护脚本和重定向资源
AdGuard的脚本和再定向资源库提供了内容阻塞的扩展能力.
说明: 此软件包开发于 辅助软件Limited/ext-scripletes。 。 。 . 这个 守护小组/脚本 寄存器是一个公共镜像.
脚本
Scriptlet是一种JavaScript函数,可以在AdGuard过滤规则中以声明方式使用.
AdGuard支持许多不同的脚本. 请注意,为了实现交叉阻塞相容性,我们也支持uBO和ABP的语法.
语法
封锁规则
[domains]#%#//scriptlet(name[, arguments])
domains- 可选,应适用该规则的领域清单;name需要,AdGuard脚本库的脚本名称;arguments——可选,列表string参数(不支持其他类型的参数).
备注
论据的意义取决于脚本.
脚本参数中的特殊字符必须适当逃脱:
- 无效 :
'prop["nested"]'"prop['nested']"'prop[\'nested\']'"prop[\"nested\"]"- 无效 :
'prop['nested']'"prop["nested"]"脚本
name和每个arguments应该用引号包起来. 您可以为脚本名称和参数使用单引出或双引出. 建议采用单一引文,但如果使用该引文会使可读性更差,则不予采用, 譬如说.".css('display','block');"比较喜欢'.css(\'display\',\'block\');'。 。 。 .
例外规则
[domains]#@%#//scriptlet([name[, arguments]])
domains- 可选,应适用该规则的领域清单;name- 可选的,除申请外的脚本名称; 如果不设定,则不会应用全部脚本;arguments——可选,列表string参数来匹配相同的阻塞规则并禁用它.
实例
-
应用
abort-on-property-read所有页面的脚本example.org及其子域, 并传递一个论据alert:example.org#%#//scriptlet('abort-on-property-read', 'alert') -
删除
branding从所有类别div[class^="inner"]要素 在所有页面上example.org及其子域 :example.org#%#//scriptlet('remove-class', 'branding', 'div[class^="inner"]') -
应用
set-constant财务报告和审定财务报表set-cookie在任何网页上, 但因为特定的脚本例外规则 仅限set-constant脚本将应用在example.org及其子域 :#%#//scriptlet('set-constant', 'adList', 'emptyArr') #%#//scriptlet('set-cookie', 'accepted', 'true') example.org#@%#//scriptlet('set-cookie') -
应用
adjust-setInterval在任何网页上, 财务报告和审定财务报表set-local-storage-item在所有页面上example.com及其子域, 但也有多个脚本例外规则, 因此不应用脚本规则example.com及其子域 :#%#//scriptlet('adjust-setInterval', 'count', '*', '0.001') example.com#%#//scriptlet('set-local-storage-item', 'ALLOW_COOKIES', 'false') example.com#@%#//scriptlet()
限制
允许的脚本来源有:
- 由AdGuard 团队创建的过滤器;
- 自定义已安装为
Trusted· ; - 用户规则.
信任的脚本
信任的脚本是具有扩展功能的脚本.
他们的名字前缀为 trusted-,例如 trusted-click-element, (中文(简体) ),
很容易与普通脚本区分开来.
限制
信任的脚本无法与其它阻塞器兼容 .
重新定向资源
AdGuard能够将网络请求重定向到本地的"资源".
语法
AdGuard 使用的过滤规则语法与 uBlock 来源。 。 。 .
另外,它与ABP兼容 $rewrite=abp-resource 修饰相.
$redirect 是用于修改 基本过滤规则
因此,使用这个修改符的规则支持所有其他基本修改符,例如: $domain, (中文(简体) ), $third-party, (中文(简体) ), $script等 (中文(简体) ).
其价值 $redirect 修改符必须是用于重定向的资源的名称.
见 资源。 。 。 .
优先权
$redirect规则在 知识库。 。 。 .
实例
||example.org/script.js$script,redirect=noopjs——将所有请求重定向到script.js转到命名的资源noopjs。 。 。 .||example.org/test.mp4$media,redirect=noopmp4-1s- 要求example.org/test.mp4将重新定向 转到命名的资源noopmp4-1s。 。 。 .
uBlock 来源指定了额外的资源名称
none可以禁用其他重定向规则. AdGuard 不支持, 使用$badfilter以禁用特定规则.
发展
如何建设
安装依赖性 :
pnpm install
构建 :
pnpm build
在tsurlfilter目录安装和链接依赖,链接脚本, 移动到软件包并构建,并创建tsurlfilter链接.
lerna bootstrap
pnpm link --global "@adguard/scriptlets"
cd ./packages/tsurlfilter
pnpm build
pnpm link --global
在扩展目录中安装依赖性、链接软件包并构建
pnpm install
pnpm link --global "@adguard/scriptlets"
# run build script
如何测试
有些测试在QUnit进行,有些在Vitest进行.
运行所有测试 :
pnpm test
-
QUnit用于测试脚本、重定向和助手:
pnpm test:qunit [scriptlets | redirects | helpers]对于脚本和重定向测试运行可以更具体:
// node test run pnpm test:qunit scriptlets --name set-cookie pnpm test:qunit redirects --name ati-smarttag // gui test run pnpm test:qunit scriptlets --name set-cookie --gui pnpm test:qunit redirects --name ati-smarttag --gui为了在Gui模式下进行测试后调试, 您可以更改脚本/ 重定向代码, 而不停止服务器 在新终端运行 :
pnpm test:qunit scriptlets --name set-cookie --build -
运行所有滑稽测试 :
pnpm test:vitest或限制试验——
include可在vitest.config.ts或指定 测试名称 在命令行中,例如:pnpm test:vitest -t isValidScriptletRule
运行测试 jest 应当命名 .spec.js,因此它们不会被列入 QUnit 测试.
调试
使用 debugger; 需要时,请运行
pnpm test
打开所需的 HTML 文件 tests/dist 在您的浏览器中, 带有devtools
如何链接软件包
脚本库依赖于外部软件包,例如 @adguard/agtree。 。 。 .
在开发过程中,您可能需要使用 pnpm link。 。 。 .
如何更新wiki
维基文库中相关的原始文献: 有2个要更新的脚本:
pnpm wiki:build-table——检查相容性数据更新并更新相容性表. 在准备发行时应该手动运行.pnpm wiki:build-docs——更新维基页面about-scriptlets.md财务报告和审定财务报表about-redirects.md。 。 。 . 正在从 JSDoc 类型对相应脚本的注释生成,并重定向源文件 应付@scriptlet编号 :@redirect财务报告和审定财务报表@description标签。 发行时自动运行.
使用量
核心文件夹
对于 核心文件夹 您应该使用 dist/scriptlets.corelibs.json 财务报告和审定财务报表 dist/redirects.json。 。 。 .
文件示例 :
{
"version": "1.0.0",
"scriptlets": [
{
"names": [
"abort-on-property-read",
"ubo-abort-on-property-read.js",
"abp-abort-on-property-read"
],
"scriptlet": "function() { ...code... }"
}
]
}
司马:
{
"type": "object",
"properties": {
"version": {
"type": "string"
},
"scriptlets": {
"type": "array",
"items": {
"type": "object",
"properties": {
"names": {
"type": "array",
"items": {
"type": "string"
}
},
"scriptlet": {
"type": "string"
}
}
}
}
}
}
国家预防机制模块
安装
您可以使用
- 雅伦数字 :
yarn add @adguard/scriptlets - 国家预防机制数字 :
npm install @adguard/scriptlets - 菲律宾数字 :
pnpm add @adguard/scriptlets
API 描述
脚本 API
欢迎您使用脚本作为CJS模块或无害环境管理模块:
const { scriptlets } = require('@adguard/scriptlets');
// or
import { scriptlets } from '@adguard/scriptlets';
invoke()
/**
* Returns scriptlet code by `source`.
*
* @param source Scriptlet properties.
*
* @returns Scriptlet code.
* @throws An error on unknown scriptlet name.
*/
declare function getScriptletCode(source: Source): string;
declare const scriptlets: {
invoke: typeof getScriptletCode;
};
地点 Source 为:
interface Source {
/**
* Scriptlet name
*/
name: string;
/**
* Arguments for scriptlet function
*/
args: string[];
/**
* {'extension'|'corelibs'} engine Defines the final form of scriptlet string presentation
*/
engine: string;
/**
* Version
*/
version: string;
/**
* flag to enable printing to console debug information
*/
verbose: boolean;
/**
* Source rule text is used for debugging purposes.
*
* @deprecated since it is not used in the code anymore.
*/
ruleText?: string;
/**
* Domain name, used to improve logging
*/
domainName?: string;
/**
* Optional unique identifier for a scriptlet instance.
*
* This identifier is used to prevent multiple executions of the same scriptlet on the page.
* If provided, this `uniqueId` will be combined with the scriptlet's `name` and `args`
* to create a unique identifier for the scriptlet call. This identifier is
* stored in the `Window.prototype.toString` object to ensure the scriptlet
* is not executed more than once in the same context.
*
* By avoiding multiple executions, it helps in reducing redundant operations and
* potential side effects that might occur if the same scriptlet is called multiple times.
*
* If `uniqueId` is not specified, no such unique identifier is created, and the
* scriptlet can be called multiple times.
*/
uniqueId?: string;
/**
* Instance of content script provided API.
*
* Property optional because:
* - for backwards compatibility.
* - currently only CoreLibs provides this API.
*/
api?: ContentScriptApi;
}
另见 ContentScriptApi 更多细节.
getScriptletFunction()
/**
* Returns scriptlet function by `name`.
*
* @param {string} name Scriptlet name
*
* @returns {Function} — Scriptlet function.
*/
declare function getScriptletFunction(name: any): string;
declare const scriptlets: {
getScriptletFunction: typeof getScriptletFunction;
};
属性
SCRIPTLETS_VERSION
类型 : string
当前版本的脚本库.
ContentScriptApi
API 提供 核心文件夹 内容脚本.
此 API 用于为脚本提供一套公用设施和共享状态 在网页上运行。 它特别包括:
export interface ContentScriptApi {
/**
* Trusted Types Policy API utilities.
*/
readonly policy: PolicyApi;
/**
* Shared state between different script and scriptlet rules.
*
* This object acts as a centralized repository for shared data.
* - Keys represent the unique identifiers or names of the shared data.
* - Values can be of any type and should correspond to the specific data shared across script rules.
*
* Example:.
* ```adguard
* ! Modify in one script rule
* #%#api.shared.testKey = 'testValue'
*
* ! Access in another (logs 'testValue')
* #%#console.log(api.shared.testKey)
* ```
*/
readonly shared: Record<string, unknown>;
}
PolicyApi
信任类型 API 工具 .
此界面扩展本地 TrustedTypePolicy 财务报告和审定财务报表 TrustedTypePolicyFactory
提供更方便用户的API,用于与信任类型合作。 如果出现
环境不支持信任类型 API, 它提供了多填充方法
和属性以确保兼容性.
export interface PolicyApi extends TrustedTypePolicy, TrustedTypePolicyFactory {
/**
* Is Trusted Types API supported.
*/
isSupported: boolean;
/**
* TrustedType enum attached to PolicyApi.
*
* Reason why we attach it to instance because inside
* of script and scriptlet we can't import and to not
* pollute global env with custom variables.
*
* @example
* api.policy.TrustedType.HTML // "TrustedHTML"
*/
TrustedType: typeof TrustedType;
/**
* Creates Trusted Type depending on `type`:
* - `TrustedHTML`
* - `TrustedScript`
* - `TrustedScriptURL`
* - or returns back `input` if none of them applicable.
*
* @example
* divElement.innerHTML = api.policy.create(api.policy.TrustedType.HTML, '<div></div>');
*
* @param type Trusted Type.
* @param input Input from which creates Trusted Type.
* @returns Created value.
*/
create(type: TrustedType, input: string): string;
/**
* Converts `value` of `attribute` into one of the Trusted Types:
* - `TrustedHTML`
* - `TrustedScript`
* - `TrustedScriptURL`
* - or returns back `value` if none of them applicable (`null`).
*
* @example
* const trustedScriptURL = api.policy.convertAttributeToTrusted("script", "src", 'SOME_URL');
* scriptElement.setAttribute("src", trustedScriptURL);
*
* @param tagName Name of an HTML tag.
* @param attribute Attribute.
* @param value Value of attribute that needs to be converted.
* @param elementNS Element namespace, if empty defaults to the HTML namespace.
* @param attrNS Attribute namespace, if empty defaults to null.
* @returns Converted value.
*/
convertAttributeToTrusted(
tagName: string,
attribute: string,
value: string,
elementNS?: string,
attrNS?: string,
): string;
/**
* Converts `value` of `property` into one of the Trusted Types:
* - `TrustedHTML`
* - `TrustedScript`
* - `TrustedScriptURL`
* - or returns back `value` if none of them applicable (`null`).
*
* @example
* divElement.innerHTML = api.policy.convertPropertyToTrusted("div", "innerHTML", "<div></div>");
*
* @param tagName Name of an HTML tag.
* @param property Property.
* @param value Value or property.
* @param elementNS Element namespace, if empty defaults to the HTML namespace.
* @returns Converted value.
*/
convertPropertyToTrusted(
tagName: string,
property: string,
value: string,
elementNS?: string,
): string;
}
- 信任的类型政策 接口
- 信任的Type 政策事实 接口
重定向 API
欢迎您使用重定向器作为CJS模块或无害环境管理模块:
const { Redirects } = require('@adguard/scriptlets/redirects');
// or
import { Redirects, getRedirectFilename } from '@adguard/scriptlets/redirects';
重定向类
import { Redirects } from '@adguard/scriptlets';
/**
* Converts rawYaml into JS object with sources titles used as keys
*/
const redirects = new Redirects(rawYaml)
地点 rawYaml 有 YAML 内容的字符串位于 dist/redirects.yml。 。 。 .
getRedirect()
/**
* Returns redirect source object by title
*/
const redirect = redirects.getRedirect('noopjs');
/**
* Redirect is an object with following props:
* {
* title: 1x1-transparent.gif
* comment: http://probablyprogramming.com/2009/03/15/the-tiniest-gif-ever
* contentType: image/gif;base64
* content: R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
* }
*/
isBlocking()
/**
* Check if redirect is blocking, e.g. click2load.html
*/
const isBlocking = redirect.isBlocking('click2load.html');
getRedirectFilename()
import { getRedirectFilename } from '@adguard/scriptlets/redirects';
/**
* For a given name or alias of redirect returns the corresponding filename
* @param name Name or alias of redirect
* @returns Redirect's filename with extension
*/
declare function getRedirectFilename(name: string): string;
验证器 API
isValidScriptletName()
import { isValidScriptletName } from '@adguard/scriptlets/validators';
/**
* Checks whether the `name` is valid scriptlet name.
* Uses cache for better performance.
*
* @param name Scriptlet name.
* @returns True if scriptlet name is a valid one or an empty string,
* otherwise false.
*/
declare function isValidScriptletName(name: string | null): boolean;
isValidScriptletRule()
/**
* 1. For ADG scriptlet checks whether the scriptlet syntax and name are valid.
* 2. For UBO and ABP scriptlet first checks their compatibility with ADG
* by converting them into ADG syntax, and after that checks the name.
*
* ADG or UBO rules are "single-scriptlet", but ABP rule may contain more than one snippet
* so if at least one of them is not valid — whole `ruleText` rule is not valid too.
*
* @param rule Any scriptlet rule — ADG or UBO or ABP.
*
* @returns True if scriptlet name is valid in rule.
*/
declare function isValidScriptletRule(rule: string | ScriptletInjectionRule): boolean;
isAdgScriptletRule(), (中文(简体) ), isUboScriptletRule(), (中文(简体) ), isAbpSnippetRule()
/**
* Checks if the `rule` is AdGuard scriptlet rule
*
* @param rule - rule text
* @returns true if given rule is adg rule
*/
declare function isAdgScriptletRule(rule: string): boolean;
/**
* Checks if the `rule` is uBO scriptlet rule
*
* @param rule rule text
* @returns true if given rule is ubo rule
*/
declare function isUboScriptletRule(rule: string): boolean;
/**
* Checks if the `rule` is AdBlock Plus snippet
*
* @param rule rule text
* @returns true if given rule is abp rule
*/
declare function isAbpSnippetRule(rule: string): boolean;
isValidAdgRedirectRule()
/**
* Checks if the `rule` is **valid** AdGuard redirect resource rule
*
* @param rule - rule text
* @returns true if given rule is valid adg redirect
*/
declare function isValidAdgRedirectRule(rule: string): boolean
isRedirectResourceCompatibleWithAdg()
/**
* Checks if the specified redirect resource is compatible with AdGuard
*
* @param redirectName - Redirect resource name to check
* @returns - true if the redirect resource is compatible with AdGuard
*/
declare function isRedirectResourceCompatibleWithAdg(redirectName: string): boolean;
转换器 API
import {
convertUboToAdg,
convertAbpToAdg,
convertScriptletToAdg,
convertAdgToUbo
} from '@adguard/scriptlets/converters';
convertUboToAdg()
/**
* Converts string of UBO scriptlet rule to AdGuard scriptlet rule
*
* @param rule UBO scriptlet rule
* @returns array with one AdGuard scriptlet rule
*
* @deprecated
*/
declare function convertUboToAdg(rule: string | ScriptletInjectionRule): string[];
注意UBO规则中的参数应该由逗号+空格来分隔. 否则,该规则无效.
convertAbpToAdg()
/**
* Convert string of ABP snippet rule to AdGuard scriptlet rule
*
* @param rule ABP snippet rule
* @returns array of AdGuard scriptlet rules, one or few items depends on Abp-rule
*/
declare function convertAbpToAdg(rule: string | ScriptletInjectionRule): string[];
convertScriptletToAdg()
/**
* Converts any scriptlet rule into AdGuard syntax rule.
* Comments and non-scriptlet rules are returned without changes.
*
* @param rule Rule.
*
* @returns Array of AdGuard scriptlet rules: one array item for ADG and UBO or few items for ABP.
* For the ADG `rule` validates its syntax, and returns an empty array if it is invalid.
*/
declare function convertScriptletToAdg(rule: string | ScriptletInjectionRule): string[];
convertAdgToUbo()
/**
* Converts AdGuard scriptlet rule to UBO syntax.
*
* @param rule AdGuard scriptlet rule
* @returns UBO scriptlet rule
* or undefined if `rule` is not valid AdGuard scriptlet rule.
*/
declare function convertAdgToUbo(rule: string | ScriptletInjectionRule): string | undefined;
convertAdgRedirectToUbo()
/**
* Converts Adg redirect rule to Ubo one
* 1. Checks if there is Ubo analog for Adg rule
* 2. Parses the rule and checks if there are any source type modifiers which are required by Ubo
* and if there are no one we add it manually to the end.
* Source types are chosen according to redirect name
* e.g. ||ad.com^$redirect=<name>,important ->> ||ad.com^$redirect=<name>,important,script
* 3. Replaces Adg redirect name by Ubo analog
*
* Note: if adg redirect uses UBO's priority syntax, it will be lost on conversion, e.g:
* ||example.com$redirect=noopjs:99 => ||example.com$redirect=noop.js
*
* @param rule adg rule
* @returns converted ubo rule
* @throws on incompatible rule
*/
declare function convertAdgRedirectToUbo(rule: string): string;
浏览器兼容性
| 浏览器 | 版本 |
|---|---|
| 颜色 | ✅55 |
| 火花 | 第52条 |
| 边缘 | 第15条 |
| 歌剧 | 第42条 |
| 萨法里 | ✅ 13 |
| Internet 浏览器 | ❌ |