@duckduckgo/autoconsent 14.65.0 → 14.66.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md ADDED
@@ -0,0 +1,332 @@
1
+ # Autoconsent Agent Guide
2
+
3
+ A library for automatically handling cookie consent popups on websites. Used in DuckDuckGo browser apps. Rules detect Consent Management Providers (CMPs) and automate opt-out/opt-in flows.
4
+
5
+ ## Project Layout
6
+
7
+ ```
8
+ lib/ TypeScript source for the autoconsent engine
9
+ lib/cmps/ Code-based CMP rule classes (sourcepoint, onetrust, etc.)
10
+ lib/rules.ts Type definitions for AutoConsentCMPRule and rule steps
11
+ lib/eval-snippets.ts Eval snippets for main-world JS execution
12
+ rules/autoconsent/ Hand-maintained JSON rules
13
+ rules/generated/ Auto-generated JSON rules (auto_XX_domain_hash.json)
14
+ rules/build.ts Merges all rules into rules.json, consentomatic.json, compact-rules.json
15
+ tests/ Playwright E2E test specs (one per CMP)
16
+ tests-wtr/ Web Test Runner unit tests for DOM actions and rule logic
17
+ playwright/runner.ts Test harness: generateCMPTests(name, urls, options)
18
+ addon/ Browser extension (MV3 + Firefox)
19
+ scripts/ Build and validation scripts
20
+ docs/ Reference documentation (rule syntax, internal API)
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ```bash
26
+ npm ci
27
+ npm run prepublish # full build: compile filterlist, build rules, bundle
28
+ npm run watch # auto-rebuild on changes to lib/, addon/, rules/
29
+ ```
30
+
31
+ | Command | Purpose |
32
+ |---------|---------|
33
+ | `npm run watch` | Auto-rebuild on changes to `lib/`, `addon/`, `rules/` (runs `prepublish` on each change) |
34
+ | `npm run lint` | ESLint + Prettier + JSON rule schema validation |
35
+ | `npm run lint-fix` | Auto-fix lint and formatting issues |
36
+ | `npm run rule-syntax-check` | Validate `rules/autoconsent/*.json` against the TypeScript schema |
37
+ | `npm run test:lib` | Unit tests (Web Test Runner) |
38
+ | `npm run test` | All Playwright E2E tests |
39
+ | `npm run test:webkit` | Playwright tests in WebKit only |
40
+ | `npm run test:chrome` | Playwright tests in Chrome only |
41
+ | `npm run build-rules` | Rebuild `rules.json`, `consentomatic.json`, `compact-rules.json` |
42
+ | `npm run create-rule` | Scaffold a new JSON rule + test spec |
43
+
44
+ ## Working with Rules
45
+
46
+ ### JSON Rules
47
+
48
+ JSON rules live in `rules/autoconsent/` (hand-maintained) and `rules/generated/` (auto-generated). Each file defines one CMP rule following the `AutoConsentCMPRule` type in `lib/rules.ts`.
49
+
50
+ ```json
51
+ {
52
+ "name": "example-cmp",
53
+ "prehideSelectors": ["#cookie-banner"],
54
+ "detectCmp": [{ "exists": "#cookie-banner" }],
55
+ "detectPopup": [{ "visible": "#cookie-banner" }],
56
+ "optIn": [{ "waitForThenClick": "#accept-all" }],
57
+ "optOut": [{ "waitForThenClick": "#reject-all" }],
58
+ "test": [{ "cookieContains": "consent=rejected" }]
59
+ }
60
+ ```
61
+
62
+ For the complete rule syntax reference (all step types, element selectors, conditionals, etc.), see [docs/rule-syntax.md](docs/rule-syntax.md).
63
+
64
+ ### prehideSelectors
65
+
66
+ `prehideSelectors` inject CSS early (before the CMP is even detected) to prevent the cookie popup from flickering on screen. They use `opacity: 0` (not `display: none`) so the popup still occupies layout space and detection via `visible` checks still works. If opt-out doesn't start within 2 seconds, the elements are automatically unhidden to avoid permanently hiding page content.
67
+
68
+ Keep prehideSelectors **narrow** — they are applied across all matching rules simultaneously, so an overly broad selector (e.g. `body`) could hide the entire page during the 2-second window.
69
+
70
+ ### Code-Based Rules
71
+
72
+ For CMPs requiring complex non-linear logic, CMP API interaction, or complex multi-path flows, use a TypeScript class extending `AutoConsentCMPBase` in `lib/cmps/`. Examples: `sourcepoint-frame.ts`, `onetrust.ts`, `cookiebot.ts`, `consentmanager.ts`.
73
+
74
+ Code-based rules implement the `AutoCMP` interface: `detectCmp()`, `detectPopup()`, `optOut()`, `optIn()`, and optionally `test()`. They have access to DOM helpers like `this.click()`, `this.waitForElement()`, `this.waitForVisible()`, and `this.elementExists()`.
75
+
76
+ ### When to Use Code vs JSON
77
+
78
+ - **JSON:** Linear consent flows, DOM-based detection, single-path opt-out. JSON rules are preferable because they can be shipped in DuckDuckGo apps without a full app release.
79
+ - **Code:** Multi-path branching, CMP JavaScript API calls, `Promise.race()` for competing UI states, complex state machines (e.g., Sourcepoint serving GDPR/CCPA/US National variants on different URL paths).
80
+
81
+ ### Selector Strategy
82
+
83
+ Prefer selectors in this order (most stable first):
84
+
85
+ 1. **Stable data attributes:** `[data-testid="cookie-reject"]`, `[data-action="sp-cc"]`, `[data-qa="allow-all-cookies"]`
86
+ 2. **Stable IDs:** `#sp-cc-accept`, `#cookie-banner` — but avoid dynamic IDs from React Aria (`#react-aria*`), Radix (`#radix-\:*\:`), or CSS Modules (`.sd-cmp-3cRQ2`), which change between builds/sessions.
87
+ 3. **Semantic class substrings:** `[class*="cookie-banner"]`, `[class*="reject"]` — avoid full body class lists (`body.home.wp-singular.page-template...`) which break across pages.
88
+ 4. **Structural CSS:** `#banner button.secondary` — avoid deep `nth-child` chains from generated rules.
89
+ 5. **XPath text matching (fallback):** `xpath///button[contains(., 'Reject')]` — use as a last resort since button text is language-specific and breaks across locales. Same caution applies to `aria-label` attributes, which are often localized.
90
+ 6. **Array selectors** for shadow DOM / iframe piercing: `["host-element", "button"]` finds `button` inside the shadow root of `host-element`. Each string in the array narrows the search scope — if an intermediate element has an open `shadowRoot`, the next selector runs inside it; if it's a same-origin iframe, the next selector runs inside its `contentDocument`. Use when a CMP renders inside shadow DOM or a same-origin iframe.
91
+
92
+ When writing or reviewing selectors, also watch out for:
93
+ - **Hardcoded attribute values** that are site-specific — use generic selectors in code-based rules.
94
+ - **Over-qualified selectors** from generated rules — e.g. `div[id][name][role][aria-modal][tabindex][lang]` requiring every attribute to exist, or redundant `:nth-child(2)#some-id` where the ID alone suffices.
95
+
96
+ ## Debugging and Fixing Rules
97
+
98
+ ### Identifying Broken Rules
99
+
100
+ 1. **Playwright test failures** are the primary signal. Run the specific test:
101
+ ```bash
102
+ npx playwright test tests/sirdata.spec.ts --project webkit
103
+ ```
104
+ 2. **Check test output** for which stage failed: `cmpDetected`, `popupFound`, `autoconsentDone`, `optOutResult`, `selfTestResult`.
105
+ 3. **Use the test extension** (`dist/addon-mv3/`) for manual debugging. Load it in Chrome, visit the site, and check the devtools panel for step-by-step logs.
106
+
107
+ ### Common Failure Modes
108
+
109
+ **Race conditions:** Consent popups load asynchronously. Use `waitFor` / `waitForThenClick` / `waitForVisible` instead of bare `exists` / `click`. Add `{ "wait": 500 }` before critical actions when the CMP has known async initialization. In code-based rules, use `Promise.race()` for multiple possible UI states.
110
+
111
+ **Incorrect consent action selectors:** Generated rules sometimes target a privacy policy link instead of the reject button. Ensure `optOut` steps target an actual reject/decline button.
112
+
113
+ **Region-dependent behavior:** Many CMPs show different dialogs by region (GDPR in EU, CCPA in US). See [Regional Differences](#regional-differences) below.
114
+
115
+ ### Fixing JSON Rules
116
+
117
+ 1. Read the existing rule to understand its current selectors and flow.
118
+ 2. Identify the broken step from test output or by inspecting the site.
119
+ 3. Edit the JSON file — apply the fix to every occurrence of the selector within the file (`detectCmp`, `detectPopup`, `optOut`, and `test` often use similar selectors).
120
+ 4. For generated rules, the same CMP may appear across multiple region files (`auto_CH_*.json`, `auto_DE_*.json`, etc.). Apply the fix to all affected files.
121
+ 5. Run `npm run lint` to validate.
122
+
123
+ ### Fixing Code-Based Rules
124
+
125
+ 1. Read the CMP class in `lib/cmps/` and trace the failing code path.
126
+ 2. Avoid hardcoded attribute values that are site-specific.
127
+ 3. Add path/state detection for new CMP variants. Check `location.pathname`, button presence, or URL parameters.
128
+ 4. Add fallback paths when variants may not have the expected buttons.
129
+
130
+ ### Adding Fallback Paths
131
+
132
+ Use `if`/`then`/`else` for region-dependent or variant-dependent flows:
133
+
134
+ ```json
135
+ {
136
+ "if": { "exists": "#reject-button" },
137
+ "then": [{ "waitForThenClick": "#reject-button" }],
138
+ "else": [{
139
+ "if": { "exists": "#manage-cookies" },
140
+ "then": [
141
+ { "waitForThenClick": "#manage-cookies" },
142
+ { "waitForThenClick": "#reject-all" }
143
+ ],
144
+ "else": [
145
+ { "waitForThenClick": "[role='button'][title='Close']" }
146
+ ]
147
+ }]
148
+ }
149
+ ```
150
+
151
+ ## Adding New Rules
152
+
153
+ 1. Run `npm run create-rule` to scaffold the JSON + test spec.
154
+ 2. Fill in `detectCmp`, `detectPopup`, `optOut`, `optIn` with stable selectors.
155
+ 3. Add a `test` array — prefer `cookieContains` when the CMP stores consent in cookies.
156
+ - JSON rules can also use `{ "eval": "SNIPPET_NAME" }` steps to execute predefined JavaScript snippets from `lib/eval-snippets.ts`. Useful for calling CMP APIs (e.g., `window.Cookiebot`, `__cmp('getCMPData')`) in detection, opt-out, or test phases. Each snippet is a named function that returns a boolean. New snippets must be added to `lib/eval-snippets.ts` and referenced by name in the rule JSON.
157
+ 4. Run `npm run lint` and `npm run test:lib`.
158
+ 5. Test with Playwright: `npx playwright test tests/my-cmp.spec.ts --project webkit`.
159
+
160
+ ### When Generated Rules Need Fixes
161
+
162
+ Generated rules (`rules/generated/auto_XX_domain_hash.json`) are created by a crawler and often have:
163
+ - Deep `nth-child` chains that break on layout changes
164
+ - Dynamic IDs from UI frameworks
165
+ - Long body class lists
166
+ - Over-qualified selectors requiring many attributes simultaneously
167
+
168
+ Fixes typically need to be applied across all region variants of the same domain (e.g., `auto_CH_kitbag.com_*.json`, `auto_DE_kitbag.com_*.json`). Search for the domain to find all related files.
169
+
170
+ ## Cosmetic Rules
171
+
172
+ Cosmetic rules hide the cookie popup via CSS rather than clicking a reject button. They are marked with `"cosmetic": true` and use `hide` steps in their `optOut` array. Use cosmetic rules when a popup has no reject/decline button — only an "Accept" or "Close" option.
173
+
174
+ ### When to Use Cosmetic vs Click-Based Rules
175
+
176
+ A popup should use a **click-based rule** (the default) if it has a reject/decline button. This includes buttons with text like "Reject all", "Only necessary cookies", "Decline", and equivalents in other languages. If the popup only has "Accept" / "OK" / "Close" / "Got it" and no way to reject, use a **cosmetic rule** to hide it.
177
+
178
+ ### Common Breakage Patterns
179
+
180
+ Hiding a popup can break the page if the CMP also locks scrolling or adds overlays. Watch for:
181
+
182
+ **Scroll lock via CSS class:** `body` or `html` gets a class like `no-scroll`, `modal-open`, `overflow-hidden`. Fix with:
183
+ ```json
184
+ { "removeClass": "no-scroll", "selector": "body" }
185
+ ```
186
+
187
+ **Scroll lock via inline style:** `body.style.overflow = "hidden"`. Fix with:
188
+ ```json
189
+ { "addStyle": "overflow: auto !important", "selector": "body" }
190
+ ```
191
+
192
+ **Overlay preventing clicks:** A `position: fixed` div with high z-index covers the page. Fix by hiding it:
193
+ ```json
194
+ { "hide": "#overlay-selector" }
195
+ ```
196
+
197
+ **Body position lock:** `body.style.position = "fixed"` with `top: -XXpx`. Fix with:
198
+ ```json
199
+ { "setStyle": "", "selector": "body" }
200
+ ```
201
+
202
+ ### Cosmetic Rule Structure
203
+
204
+ ```json
205
+ {
206
+ "name": "example-cosmetic",
207
+ "cosmetic": true,
208
+ "prehideSelectors": ["#cookie-banner"],
209
+ "detectCmp": [{ "exists": "#cookie-banner" }],
210
+ "detectPopup": [{ "visible": "#cookie-banner" }],
211
+ "optOut": [
212
+ { "hide": "#cookie-banner" },
213
+ { "removeClass": "no-scroll", "selector": "body", "optional": true }
214
+ ],
215
+ "optIn": [{ "waitForThenClick": "#accept-button" }]
216
+ }
217
+ ```
218
+
219
+ Add breakage fix steps AFTER the `hide` step in `optOut`. Mark breakage fixes as `"optional": true` since they may not always apply.
220
+
221
+ ## Triaging Broken Sites
222
+
223
+ When investigating a site where cookie popup handling is broken or missing:
224
+
225
+ ### Step 1: Check Current State
226
+
227
+ Load the bundled extension in Chrome (`dist/addon-mv3/` after `npm run prepublish`), visit the site, and check the devtools panel for autoconsent logs. Determine whether:
228
+ - An existing rule matched but failed (which stage? `detectCmp`, `detectPopup`, `optOut`?)
229
+ - No rule matched at all
230
+
231
+ ### Step 2: Diagnose
232
+
233
+ If an **existing rule matched but failed**: identify the broken step from the logs, inspect the site to understand what changed (new selectors, different layout, region variant), and fix the rule.
234
+
235
+ If **no rule matched**: determine the CMP type. Check if the popup is from a known CMP (OneTrust, Sourcepoint, Cookiebot, etc.) by inspecting the banner's HTML, class names, and script sources. If it's a known CMP, the existing rule may need updated detection selectors. If it's unknown, create a new rule.
236
+
237
+ ### Step 3: Determine Rule Type
238
+
239
+ - If the popup has a **reject/decline button** → create or fix a click-based rule
240
+ - If the popup has **no reject option** (only accept/close) → create a cosmetic rule
241
+ - If the CMP requires **complex logic** (API calls, multiple UI states, iframe communication) → use a code-based CMP class
242
+
243
+ ### Step 4: Implement and Test
244
+
245
+ 1. Create or edit the rule file
246
+ 2. Add or update the test spec in `tests/`
247
+ 3. Run `npm run lint` to validate
248
+ 4. Test locally: `npx playwright test tests/<cmp>.spec.ts --project webkit`
249
+ 5. Test in multiple regions if the CMP is region-dependent (requires both `REGION` and `PROXY_SERVER` — see [Testing Across Regions](#testing-across-regions))
250
+ 6. For cosmetic rules, verify no breakage (scrolling works, page is interactable)
251
+
252
+ ## Regional Differences
253
+
254
+ CMPs behave differently depending on the user's region due to different privacy regulations:
255
+
256
+ - **EU/EEA (GDPR):** Full consent dialog with explicit reject/accept options. Most rules target this variant.
257
+ - **US (CCPA/state laws):** Often a simpler notice with just a "Close" button, or a "Do Not Sell" link. Some CMPs show nothing at all in the US.
258
+ - **Other regions:** May show GDPR-like dialogs, simplified notices, or nothing.
259
+
260
+ ### Handling Regional Variants in Rules
261
+
262
+ Use `if`/`then`/`else` conditionals to handle different UIs within a single rule. For code-based rules, add path detection (e.g., Sourcepoint's `/privacy-manager/index.html` vs `/us_pm/index.html`).
263
+
264
+ ### Testing Across Regions
265
+
266
+ Two things are needed to test from a specific region:
267
+
268
+ 1. **`REGION` env var** — filters which test URLs to run (from `data/coverage.json`). This only controls test selection, it does **not** change where requests come from.
269
+ 2. **`PROXY_SERVER` env var** — routes browser traffic through a geographic proxy so sites see the correct region. Without a proxy, the site sees your real location regardless of `REGION`.
270
+
271
+ ```bash
272
+ # Local: only filters tests, requests come from your real location
273
+ REGION=DE npx playwright test tests/sirdata.spec.ts --project webkit
274
+
275
+ # With proxy: tests are filtered AND requests are routed through the proxy
276
+ REGION=DE PROXY_SERVER=socks5://proxy.example:1080 npx playwright test tests/sirdata.spec.ts --project webkit
277
+ ```
278
+
279
+ In CI, Jenkins loads region-specific `.env` files that set both `REGION` and `PROXY_SERVER` together.
280
+
281
+ Test specs support `skipRegions` and `onlyRegions` to control when tests run:
282
+
283
+ ```typescript
284
+ generateCMPTests('Sirdata', ['https://gizmodo.com/'], {
285
+ skipRegions: ['US'], // skip test in these regions
286
+ onlyRegions: [], // only run in these regions
287
+ });
288
+ ```
289
+
290
+ ## PR Review Checklist
291
+
292
+ ### CI Pipeline
293
+
294
+ Two CI systems run on PRs:
295
+
296
+ 1. **GitHub Actions** (`.github/workflows/checks.yml`): runs `npm run lint` and `npm run test:lib` on every push/PR. These must pass.
297
+ 2. **Jenkins**: runs Playwright E2E tests in 9 regions (US, GB, AU, CA, DE, FR, NL, CH, NO). Only tests for modified rule files and their corresponding test specs are run. Jenkins posts a PR comment with an artifact ZIP link and a link to the [review tool](https://zok.pw/autoconsent-review-tool/) for inspecting screenshots.
298
+
299
+ ### Reviewing New Rule PRs
300
+
301
+ - [ ] `npm run lint` passes (ESLint + Prettier + schema validation)
302
+ - [ ] JSON rule validates against schema (`npm run rule-syntax-check`)
303
+ - [ ] A corresponding test spec exists in `tests/`
304
+ - [ ] Test URLs are reachable and relevant
305
+ - [ ] Selectors are stable (no dynamic IDs, no full body class lists, no CSS module hashes)
306
+ - [ ] `optOut` targets an actual reject/decline button, not a privacy policy link
307
+ - [ ] For generated rule fixes: all region variants are updated consistently
308
+
309
+ ### Reviewing Code-Based Rule PRs
310
+
311
+ - [ ] Lint and unit tests pass
312
+ - [ ] No hardcoded site-specific attribute values
313
+ - [ ] Fallback paths exist for regional variants
314
+ - [ ] Uses existing DOM helpers (`this.click()`, `this.waitForElement()`, etc.)
315
+
316
+ ### Handling Flaky E2E Tests
317
+
318
+ E2E tests hit live sites and are inherently flaky due to site changes, regional differences, and network conditions. Before concluding a test is broken:
319
+
320
+ - Check Jenkins screenshots in the review tool
321
+ - If a test fails only in certain regions, consider adding `skipRegions`
322
+ - Playwright is configured with retries (2 retries in CI)
323
+ - Verify the site still has the same cookie consent popup by visiting it manually
324
+
325
+ ## Verification
326
+
327
+ | Step | Command |
328
+ |------|---------|
329
+ | Schema + formatting | `npm run lint` |
330
+ | Unit tests | `npm run test:lib` |
331
+ | Single CMP E2E test | `npx playwright test tests/<cmp>.spec.ts --project webkit` |
332
+ | Full E2E suite | `npm run test` |
package/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ # v14.66.0 (Sat Mar 28 2026)
2
+
3
+ #### 🚀 Enhancement
4
+
5
+ - Bump the adblocker group with 2 updates [#1099](https://github.com/duckduckgo/autoconsent/pull/1099) ([@dependabot[bot]](https://github.com/dependabot[bot]) [@muodov](https://github.com/muodov))
6
+ - Update EasyList Cookie to 3d7c4396813e269c757e5e9851d80b7b5db622a0 [#1216](https://github.com/duckduckgo/autoconsent/pull/1216) ([@sammacbeth](https://github.com/sammacbeth) [@github-actions[bot]](https://github.com/github-actions[bot]))
7
+ - Add more "reject" patterns [#1218](https://github.com/duckduckgo/autoconsent/pull/1218) ([@muodov](https://github.com/muodov))
8
+
9
+ #### 📝 Documentation
10
+
11
+ - Reorganize docs, add AGENTS.md [#1217](https://github.com/duckduckgo/autoconsent/pull/1217) ([@cursoragent](https://github.com/cursoragent) [@muodov](https://github.com/muodov))
12
+
13
+ #### Authors: 5
14
+
15
+ - [@dependabot[bot]](https://github.com/dependabot[bot])
16
+ - [@github-actions[bot]](https://github.com/github-actions[bot])
17
+ - Cursor Agent ([@cursoragent](https://github.com/cursoragent))
18
+ - Maxim Tsoy ([@muodov](https://github.com/muodov))
19
+ - Sam Macbeth ([@sammacbeth](https://github.com/sammacbeth))
20
+
21
+ ---
22
+
1
23
  # v14.65.0 (Fri Mar 27 2026)
2
24
 
3
25
  #### 🚀 Enhancement
@@ -860,10 +860,10 @@
860
860
  /^\s*(use|accept|allow|continue\s+with)?\s*only\s*(strictly)?\s*(necessary|essentials?|required)?\s*(cookies)?\s*$/is,
861
861
  // e.g. "do not sell or share my personal information", "do not sell my personal information"
862
862
  // often used in CCPA
863
- /^\s*do\s+not\s+sell(\s+or\s+share)?\s*my\s*personal\s*information\s*$/is
863
+ /^\s*do\s+not\s+sell(\s+or\s+share)?\s*my\s*personal\s*information\s*$/is,
864
+ "allow selection",
865
+ "disagree and close"
864
866
  // These are impactful, but look error-prone
865
- // // e.g. "disagree"
866
- // /^\s*(i)?\s*disagree\s*(and\s+close)?\s*$/i,
867
867
  // // e.g. "i do not agree"
868
868
  // /^\s*(i\s+)?do\s+not\s+agree\s*$/i,
869
869
  ];
@@ -877,6 +877,7 @@
877
877
  "alleen noodzakelijk",
878
878
  "weiger",
879
879
  "weiger cookies",
880
+ "selectie toestaan",
880
881
  "doorgaan zonder te accepteren",
881
882
  "alleen functionele cookies",
882
883
  "alleen functioneel",
@@ -979,6 +980,8 @@
979
980
  "tout refuser",
980
981
  "refuser",
981
982
  "refuser tous les cookies",
983
+ "non merci",
984
+ "interdire tous les cookies",
982
985
  "je refuse",
983
986
  "refuser tout",
984
987
  "tout rejeter",
@@ -1066,6 +1069,8 @@
1066
1069
  "nur notwendige cookies",
1067
1070
  "nur essenzielle cookies akzeptieren",
1068
1071
  "nur notwendige cookies verwenden",
1072
+ "nur technisch notwendige",
1073
+ "nur essentielle cookies akzeptieren",
1069
1074
  "alles ablehnen",
1070
1075
  "nur notwendige",
1071
1076
  "alle cookies ablehnen",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Autoconsent",
4
- "version": "2026.3.24",
4
+ "version": "2026.3.27",
5
5
  "background": {
6
6
  "scripts": [
7
7
  "background.bundle.js"
@@ -860,10 +860,10 @@
860
860
  /^\s*(use|accept|allow|continue\s+with)?\s*only\s*(strictly)?\s*(necessary|essentials?|required)?\s*(cookies)?\s*$/is,
861
861
  // e.g. "do not sell or share my personal information", "do not sell my personal information"
862
862
  // often used in CCPA
863
- /^\s*do\s+not\s+sell(\s+or\s+share)?\s*my\s*personal\s*information\s*$/is
863
+ /^\s*do\s+not\s+sell(\s+or\s+share)?\s*my\s*personal\s*information\s*$/is,
864
+ "allow selection",
865
+ "disagree and close"
864
866
  // These are impactful, but look error-prone
865
- // // e.g. "disagree"
866
- // /^\s*(i)?\s*disagree\s*(and\s+close)?\s*$/i,
867
867
  // // e.g. "i do not agree"
868
868
  // /^\s*(i\s+)?do\s+not\s+agree\s*$/i,
869
869
  ];
@@ -877,6 +877,7 @@
877
877
  "alleen noodzakelijk",
878
878
  "weiger",
879
879
  "weiger cookies",
880
+ "selectie toestaan",
880
881
  "doorgaan zonder te accepteren",
881
882
  "alleen functionele cookies",
882
883
  "alleen functioneel",
@@ -979,6 +980,8 @@
979
980
  "tout refuser",
980
981
  "refuser",
981
982
  "refuser tous les cookies",
983
+ "non merci",
984
+ "interdire tous les cookies",
982
985
  "je refuse",
983
986
  "refuser tout",
984
987
  "tout rejeter",
@@ -1066,6 +1069,8 @@
1066
1069
  "nur notwendige cookies",
1067
1070
  "nur essenzielle cookies akzeptieren",
1068
1071
  "nur notwendige cookies verwenden",
1072
+ "nur technisch notwendige",
1073
+ "nur essentielle cookies akzeptieren",
1069
1074
  "alles ablehnen",
1070
1075
  "nur notwendige",
1071
1076
  "alle cookies ablehnen",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Autoconsent",
4
- "version": "2026.3.24",
4
+ "version": "2026.3.27",
5
5
  "background": {
6
6
  "service_worker": "background.bundle.js"
7
7
  },
@@ -895,10 +895,10 @@ var REJECT_PATTERNS_ENGLISH = [
895
895
  /^\s*(use|accept|allow|continue\s+with)?\s*only\s*(strictly)?\s*(necessary|essentials?|required)?\s*(cookies)?\s*$/is,
896
896
  // e.g. "do not sell or share my personal information", "do not sell my personal information"
897
897
  // often used in CCPA
898
- /^\s*do\s+not\s+sell(\s+or\s+share)?\s*my\s*personal\s*information\s*$/is
898
+ /^\s*do\s+not\s+sell(\s+or\s+share)?\s*my\s*personal\s*information\s*$/is,
899
+ "allow selection",
900
+ "disagree and close"
899
901
  // These are impactful, but look error-prone
900
- // // e.g. "disagree"
901
- // /^\s*(i)?\s*disagree\s*(and\s+close)?\s*$/i,
902
902
  // // e.g. "i do not agree"
903
903
  // /^\s*(i\s+)?do\s+not\s+agree\s*$/i,
904
904
  ];
@@ -912,6 +912,7 @@ var REJECT_PATTERNS_DUTCH = [
912
912
  "alleen noodzakelijk",
913
913
  "weiger",
914
914
  "weiger cookies",
915
+ "selectie toestaan",
915
916
  "doorgaan zonder te accepteren",
916
917
  "alleen functionele cookies",
917
918
  "alleen functioneel",
@@ -1014,6 +1015,8 @@ var REJECT_PATTERNS_FRENCH = [
1014
1015
  "tout refuser",
1015
1016
  "refuser",
1016
1017
  "refuser tous les cookies",
1018
+ "non merci",
1019
+ "interdire tous les cookies",
1017
1020
  "je refuse",
1018
1021
  "refuser tout",
1019
1022
  "tout rejeter",
@@ -1101,6 +1104,8 @@ var REJECT_PATTERNS_GERMAN = [
1101
1104
  "nur notwendige cookies",
1102
1105
  "nur essenzielle cookies akzeptieren",
1103
1106
  "nur notwendige cookies verwenden",
1107
+ "nur technisch notwendige",
1108
+ "nur essentielle cookies akzeptieren",
1104
1109
  "alles ablehnen",
1105
1110
  "nur notwendige",
1106
1111
  "alle cookies ablehnen",
@@ -865,10 +865,10 @@ var REJECT_PATTERNS_ENGLISH = [
865
865
  /^\s*(use|accept|allow|continue\s+with)?\s*only\s*(strictly)?\s*(necessary|essentials?|required)?\s*(cookies)?\s*$/is,
866
866
  // e.g. "do not sell or share my personal information", "do not sell my personal information"
867
867
  // often used in CCPA
868
- /^\s*do\s+not\s+sell(\s+or\s+share)?\s*my\s*personal\s*information\s*$/is
868
+ /^\s*do\s+not\s+sell(\s+or\s+share)?\s*my\s*personal\s*information\s*$/is,
869
+ "allow selection",
870
+ "disagree and close"
869
871
  // These are impactful, but look error-prone
870
- // // e.g. "disagree"
871
- // /^\s*(i)?\s*disagree\s*(and\s+close)?\s*$/i,
872
872
  // // e.g. "i do not agree"
873
873
  // /^\s*(i\s+)?do\s+not\s+agree\s*$/i,
874
874
  ];
@@ -882,6 +882,7 @@ var REJECT_PATTERNS_DUTCH = [
882
882
  "alleen noodzakelijk",
883
883
  "weiger",
884
884
  "weiger cookies",
885
+ "selectie toestaan",
885
886
  "doorgaan zonder te accepteren",
886
887
  "alleen functionele cookies",
887
888
  "alleen functioneel",
@@ -984,6 +985,8 @@ var REJECT_PATTERNS_FRENCH = [
984
985
  "tout refuser",
985
986
  "refuser",
986
987
  "refuser tous les cookies",
988
+ "non merci",
989
+ "interdire tous les cookies",
987
990
  "je refuse",
988
991
  "refuser tout",
989
992
  "tout rejeter",
@@ -1071,6 +1074,8 @@ var REJECT_PATTERNS_GERMAN = [
1071
1074
  "nur notwendige cookies",
1072
1075
  "nur essenzielle cookies akzeptieren",
1073
1076
  "nur notwendige cookies verwenden",
1077
+ "nur technisch notwendige",
1078
+ "nur essentielle cookies akzeptieren",
1074
1079
  "alles ablehnen",
1075
1080
  "nur notwendige",
1076
1081
  "alle cookies ablehnen",