Skip to content

Commit c601fd4

Browse files
committed
Custom scriptlet support
1 parent 4ab4576 commit c601fd4

9 files changed

Lines changed: 868 additions & 11 deletions

File tree

Cargo.lock

Lines changed: 158 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ anyhow = "1"
1313
fs2 = "0.4"
1414
tempfile = "3"
1515
ctrlc = "3"
16+
rusty-leveldb = "4"
17+
base64 = "0.22"

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,19 @@ brave-shields-cli filters bisect rules.txt
101101

102102
The `bisect` command performs an interactive binary search to find which filter rule in a file is causing a site issue. It loads all rules, then iteratively exceptions out half the candidates with `@@` prefixes, asking at each step whether the issue persists. A working file (`bisect-filters.txt`) and state file (`bisect-state.json`) are written to the current directory. Original filters are restored when bisect completes. If interrupted or quit mid-session, the state is preserved and can be resumed with `--resume bisect-state.json`.
103103

104+
#### scriptlets
105+
106+
Manage custom scriptlets (user-defined JavaScript for adblock injection). These are stored in a LevelDB database at `Default/AdBlock Custom Resources/` and are shared across profiles.
107+
108+
```bash
109+
brave-shields-cli scriptlets list
110+
brave-shields-cli scriptlets get user-my-script.js
111+
brave-shields-cli scriptlets add user-my-script.js script.js
112+
brave-shields-cli scriptlets remove user-my-script.js
113+
```
114+
115+
Scriptlet names must start with `user-` and end with `.js`. Once added, reference them in custom filters with `example.com##+js(user-my-script.js)`.
116+
104117
#### profiles
105118

106119
List available browser profiles.

src/commands/bisect.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -240,12 +240,12 @@ fn make_exception(rule: &str) -> String {
240240
if rule.starts_with("@@") || rule.starts_with("#@#") {
241241
return rule.to_string();
242242
}
243-
// Cosmetic filter: contains ## (but not scriptlet ###+js)
243+
// Cosmetic or scriptlet filter: contains ##
244+
// Both cosmetic (##.ad) and scriptlet (##+js(...)) use #@# for exceptions.
245+
// The @@ prefix is only for network rules.
244246
if let Some(pos) = rule.find("##") {
245-
if !rule[pos..].starts_with("###+") {
246-
let (domain, selector) = rule.split_at(pos);
247-
return format!("{}#@#{}", domain, &selector[2..]);
248-
}
247+
let (domain, selector) = rule.split_at(pos);
248+
return format!("{}#@#{}", domain, &selector[2..]);
249249
}
250250
format!("@@{}", rule)
251251
}
@@ -682,10 +682,20 @@ mod tests {
682682

683683
#[test]
684684
fn test_make_exception_scriptlet() {
685-
// Scriptlet injection: ###+js(...) should get @@ prefix, not #@#
685+
// Scriptlet injection uses ##+js(...) syntax (two hashes, not three).
686+
// Exception replaces ## with #@#.
687+
assert_eq!(
688+
make_exception("example.com##+js(abort-on-property-read, foo)"),
689+
"example.com#@#+js(abort-on-property-read, foo)"
690+
);
691+
}
692+
693+
#[test]
694+
fn test_make_exception_scriptlet_no_domain() {
695+
// Global scriptlet: ##+js(...) with no domain
686696
assert_eq!(
687-
make_exception("example.com###+js(abort-on-property-read, foo)"),
688-
"@@example.com###+js(abort-on-property-read, foo)"
697+
make_exception("##+js(abort-on-property-read, foo)"),
698+
"#@#+js(abort-on-property-read, foo)"
689699
);
690700
}
691701

src/commands/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub mod bisect;
22
pub mod filters;
3+
pub mod scriptlets;
34
pub mod get;
45
pub mod list;
56
pub mod profiles;

0 commit comments

Comments
 (0)