@duckduckgo/autoconsent 15.0.0 → 16.0.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.
Files changed (90) hide show
  1. package/.github/dependabot.yml +0 -3
  2. package/.github/workflows/release.yml +0 -4
  3. package/AGENTS.md +3 -3
  4. package/CHANGELOG.md +32 -0
  5. package/build.sh +3 -2
  6. package/dist/addon-firefox/background.bundle.js +8 -24
  7. package/dist/addon-firefox/compact-rules.json +1 -1
  8. package/dist/addon-firefox/content.bundle.js +184 -686
  9. package/dist/addon-firefox/manifest.json +1 -1
  10. package/dist/addon-firefox/popup.bundle.js +196 -25
  11. package/dist/addon-firefox/popup.html +98 -5
  12. package/dist/addon-firefox/rule-index.json +1 -0
  13. package/dist/addon-firefox/rules.json +1 -1
  14. package/dist/addon-mv3/background.bundle.js +8 -24
  15. package/dist/addon-mv3/compact-rules.json +1 -1
  16. package/dist/addon-mv3/content.bundle.js +184 -686
  17. package/dist/addon-mv3/manifest.json +1 -1
  18. package/dist/addon-mv3/popup.bundle.js +196 -25
  19. package/dist/addon-mv3/popup.html +98 -5
  20. package/dist/addon-mv3/rule-index.json +1 -0
  21. package/dist/addon-mv3/rules.json +1 -1
  22. package/dist/autoconsent.cjs.js +184 -685
  23. package/dist/autoconsent.esm.js +184 -685
  24. package/dist/autoconsent.playwright.js +185 -689
  25. package/dist/autoconsent.standalone.js +3625 -0
  26. package/dist/types/cmps/base.d.ts +3 -3
  27. package/dist/types/cmps/trustarc-top.d.ts +1 -1
  28. package/dist/types/eval-handler.d.ts +3 -3
  29. package/dist/types/heuristics.d.ts +2 -2
  30. package/dist/types/types.d.ts +10 -23
  31. package/dist/types/web.d.ts +0 -9
  32. package/docs/api.md +1 -8
  33. package/docs/puppeteer.md +1 -3
  34. package/docs/rule-syntax.md +0 -17
  35. package/eslint.config.mjs +1 -1
  36. package/lib/cmps/base.ts +5 -6
  37. package/lib/cmps/conversant.ts +7 -4
  38. package/lib/cmps/trustarc-top.ts +1 -1
  39. package/lib/cmps/uniconsent.ts +4 -4
  40. package/lib/eval-handler.ts +6 -3
  41. package/lib/heuristics.ts +15 -15
  42. package/lib/types.ts +9 -21
  43. package/lib/utils.ts +13 -9
  44. package/lib/web.ts +3 -53
  45. package/package.json +4 -17
  46. package/playwright/content.ts +1 -2
  47. package/readme.md +3 -6
  48. package/rules/autoconsent/dreamlab-cmp.json +13 -0
  49. package/rules/build.ts +4 -23
  50. package/rules/compact-rules.json +1 -1
  51. package/rules/rule-index-builder.ts +58 -0
  52. package/rules/rule-index.json +1 -0
  53. package/rules/rules.json +1 -1
  54. package/standalone/content.ts +101 -0
  55. package/tests/dreamlab-cmp.spec.ts +3 -0
  56. package/tests/quantcast.spec.ts +0 -6
  57. package/tests-wtr/heuristics/get-actionable-popups.ts +13 -13
  58. package/tests-wtr/heuristics/heuristic-cmp.ts +32 -33
  59. package/tests-wtr/lifecycle/find-cmp.ts +5 -8
  60. package/tests-wtr/web/do-opt-in.test.ts +0 -1
  61. package/tests-wtr/web/do-opt-out.test.ts +0 -1
  62. package/tests-wtr/web/do-self-test.test.ts +0 -1
  63. package/tests-wtr/web/filter-cmps.test.ts +0 -1
  64. package/tests-wtr/web/receive-message-callback.test.ts +1 -2
  65. package/tests-wtr/web/update-state.test.ts +1 -3
  66. package/tsconfig.build.json +1 -1
  67. package/.github/workflows/update-filterlist.yml +0 -42
  68. package/dist/autoconsent.extra.cjs.js +0 -15709
  69. package/dist/autoconsent.extra.esm.js +0 -15641
  70. package/dist/types/cmps/consentomatic.d.ts +0 -34
  71. package/dist/types/consentomatic/index.d.ts +0 -2
  72. package/dist/types/consentomatic/tools.d.ts +0 -10
  73. package/dist/types/filterlist-engine.d.ts +0 -2
  74. package/dist/types/filterlist-utils.d.ts +0 -4
  75. package/dist/types/web-extra.d.ts +0 -11
  76. package/lib/cmps/consentomatic.ts +0 -97
  77. package/lib/consentomatic/index.ts +0 -252
  78. package/lib/consentomatic/tools.ts +0 -199
  79. package/lib/filterlist-engine.ts +0 -5
  80. package/lib/filterlist-utils.ts +0 -45
  81. package/lib/web-extra.ts +0 -116
  82. package/rules/consentomatic.json +0 -1
  83. package/rules/filterlist.txt +0 -18440
  84. package/rules/filterlists/overrides.txt +0 -4
  85. package/scripts/compile-filterlist.mjs +0 -63
  86. package/scripts/fetch-easylist.sh +0 -25
  87. package/scripts/rebuild-filterlist.mjs +0 -216
  88. package/tests/oil.spec.ts +0 -7
  89. package/tests/springer.spec.ts +0 -7
  90. package/tests/wordpressgdpr.spec.ts +0 -6
@@ -36,412 +36,8 @@ __export(web_exports, {
36
36
  });
37
37
  module.exports = __toCommonJS(web_exports);
38
38
 
39
- // lib/consentomatic/tools.ts
40
- var _Tools = class _Tools {
41
- static setBase(base) {
42
- _Tools.base = base;
43
- }
44
- static findElement(options, parent = null, multiple = false) {
45
- let possibleTargets = null;
46
- if (parent != null) {
47
- possibleTargets = Array.from(parent.querySelectorAll(options.selector));
48
- } else {
49
- if (_Tools.base != null) {
50
- possibleTargets = Array.from(
51
- _Tools.base.querySelectorAll(options.selector)
52
- );
53
- } else {
54
- possibleTargets = Array.from(
55
- document.querySelectorAll(options.selector)
56
- );
57
- }
58
- }
59
- if (options.textFilter != null) {
60
- possibleTargets = possibleTargets.filter((possibleTarget) => {
61
- const textContent = possibleTarget.textContent.toLowerCase();
62
- if (Array.isArray(options.textFilter)) {
63
- let foundText = false;
64
- for (const text of options.textFilter) {
65
- if (textContent.indexOf(text.toLowerCase()) !== -1) {
66
- foundText = true;
67
- break;
68
- }
69
- }
70
- return foundText;
71
- } else if (options.textFilter != null) {
72
- return textContent.indexOf(options.textFilter.toLowerCase()) !== -1;
73
- }
74
- return false;
75
- });
76
- }
77
- if (options.styleFilters != null) {
78
- possibleTargets = possibleTargets.filter((possibleTarget) => {
79
- const styles = window.getComputedStyle(possibleTarget);
80
- let keep = true;
81
- for (const styleFilter of options.styleFilters) {
82
- const option = styles[styleFilter.option];
83
- if (styleFilter.negated) {
84
- keep = keep && option !== styleFilter.value;
85
- } else {
86
- keep = keep && option === styleFilter.value;
87
- }
88
- }
89
- return keep;
90
- });
91
- }
92
- if (options.displayFilter != null) {
93
- possibleTargets = possibleTargets.filter((possibleTarget) => {
94
- if (options.displayFilter) {
95
- return possibleTarget.offsetHeight !== 0;
96
- } else {
97
- return possibleTarget.offsetHeight === 0;
98
- }
99
- });
100
- }
101
- if (options.iframeFilter != null) {
102
- possibleTargets = possibleTargets.filter(() => {
103
- if (options.iframeFilter) {
104
- return window.location !== window.parent.location;
105
- } else {
106
- return window.location === window.parent.location;
107
- }
108
- });
109
- }
110
- if (options.childFilter != null) {
111
- possibleTargets = possibleTargets.filter((possibleTarget) => {
112
- const oldBase = _Tools.base;
113
- _Tools.setBase(possibleTarget);
114
- const childResults = _Tools.find(options.childFilter);
115
- _Tools.setBase(oldBase);
116
- return childResults.target != null;
117
- });
118
- }
119
- if (multiple) {
120
- return possibleTargets;
121
- } else {
122
- if (possibleTargets.length > 1) {
123
- console.warn(
124
- "Multiple possible targets: ",
125
- possibleTargets,
126
- options,
127
- parent
128
- );
129
- }
130
- return possibleTargets[0];
131
- }
132
- }
133
- static find(options, multiple = false) {
134
- const results = [];
135
- if (options.parent != null) {
136
- const parent = _Tools.findElement(options.parent, null, multiple);
137
- if (parent != null) {
138
- if (parent instanceof Array) {
139
- parent.forEach((p) => {
140
- const targets = _Tools.findElement(options.target, p, multiple);
141
- if (targets instanceof Array) {
142
- targets.forEach((target) => {
143
- results.push({
144
- parent: p,
145
- target
146
- });
147
- });
148
- } else {
149
- results.push({
150
- parent: p,
151
- target: targets
152
- });
153
- }
154
- });
155
- return results;
156
- } else {
157
- const targets = _Tools.findElement(options.target, parent, multiple);
158
- if (targets instanceof Array) {
159
- targets.forEach((target) => {
160
- results.push({
161
- parent,
162
- target
163
- });
164
- });
165
- } else {
166
- results.push({
167
- parent,
168
- target: targets
169
- });
170
- }
171
- }
172
- }
173
- } else {
174
- const targets = _Tools.findElement(options.target, null, multiple);
175
- if (targets instanceof Array) {
176
- targets.forEach((target) => {
177
- results.push({
178
- parent: null,
179
- target
180
- });
181
- });
182
- } else {
183
- results.push({
184
- parent: null,
185
- target: targets
186
- });
187
- }
188
- }
189
- if (results.length === 0) {
190
- results.push({
191
- parent: null,
192
- target: null
193
- });
194
- }
195
- if (multiple) {
196
- return results;
197
- } else {
198
- if (results.length !== 1) {
199
- console.warn(
200
- "Multiple results found, even though multiple false",
201
- results
202
- );
203
- }
204
- return results[0];
205
- }
206
- }
207
- };
208
- _Tools.base = null;
209
- var Tools = _Tools;
210
-
211
- // lib/consentomatic/index.ts
212
- function matches(config) {
213
- const result = Tools.find(config);
214
- if (config.type === "css") {
215
- return !!result.target;
216
- } else if (config.type === "checkbox") {
217
- return !!result.target && result.target.checked;
218
- }
219
- }
220
- async function executeAction(config, param) {
221
- switch (config.type) {
222
- case "click":
223
- return clickAction(config);
224
- case "list":
225
- return listAction(config, param);
226
- case "consent":
227
- return consentAction(config, param);
228
- case "ifcss":
229
- return ifCssAction(config, param);
230
- case "waitcss":
231
- return waitCssAction(config);
232
- case "foreach":
233
- return forEachAction(config, param);
234
- case "hide":
235
- return hideAction(config);
236
- case "slide":
237
- return slideAction(config);
238
- case "close":
239
- return closeAction();
240
- case "wait":
241
- return waitAction(config);
242
- case "eval":
243
- return evalAction(config);
244
- default:
245
- throw new Error("Unknown action type: " + config.type);
246
- }
247
- }
248
- var STEP_TIMEOUT = 0;
249
- function waitTimeout(timeout) {
250
- return new Promise((resolve) => {
251
- setTimeout(() => {
252
- resolve();
253
- }, timeout);
254
- });
255
- }
256
- async function clickAction(config) {
257
- const result = Tools.find(config);
258
- if (result.target != null) {
259
- result.target.click();
260
- }
261
- return waitTimeout(STEP_TIMEOUT);
262
- }
263
- async function listAction(config, param) {
264
- for (const action of config.actions) {
265
- await executeAction(action, param);
266
- }
267
- }
268
- async function consentAction(config, consentTypes) {
269
- for (const consentConfig of config.consents) {
270
- const shouldEnable = consentTypes.indexOf(consentConfig.type) !== -1;
271
- if (consentConfig.matcher && consentConfig.toggleAction) {
272
- const isEnabled = matches(consentConfig.matcher);
273
- if (isEnabled !== shouldEnable) {
274
- await executeAction(consentConfig.toggleAction);
275
- }
276
- } else {
277
- if (shouldEnable) {
278
- await executeAction(consentConfig.trueAction);
279
- } else {
280
- await executeAction(consentConfig.falseAction);
281
- }
282
- }
283
- }
284
- }
285
- async function ifCssAction(config, param) {
286
- const result = Tools.find(config);
287
- if (!result.target) {
288
- if (config.trueAction) {
289
- await executeAction(config.trueAction, param);
290
- }
291
- } else {
292
- if (config.falseAction) {
293
- await executeAction(config.falseAction, param);
294
- }
295
- }
296
- }
297
- async function waitCssAction(config) {
298
- await new Promise((resolve) => {
299
- let numRetries = config.retries || 10;
300
- const waitTime = config.waitTime || 250;
301
- const checkCss = () => {
302
- const result = Tools.find(config);
303
- if (config.negated && result.target || !config.negated && !result.target) {
304
- if (numRetries > 0) {
305
- numRetries -= 1;
306
- setTimeout(checkCss, waitTime);
307
- } else {
308
- resolve();
309
- }
310
- } else {
311
- resolve();
312
- }
313
- };
314
- checkCss();
315
- });
316
- }
317
- async function forEachAction(config, param) {
318
- const results = Tools.find(config, true);
319
- const oldBase = Tools.base;
320
- for (const result of results) {
321
- if (result.target) {
322
- Tools.setBase(result.target);
323
- await executeAction(config.action, param);
324
- }
325
- }
326
- Tools.setBase(oldBase);
327
- }
328
- async function hideAction(config) {
329
- const result = Tools.find(config);
330
- if (result.target) {
331
- result.target.classList.add("Autoconsent-Hidden");
332
- }
333
- }
334
- async function slideAction(config) {
335
- const result = Tools.find(config);
336
- const dragResult = Tools.find(config.dragTarget);
337
- if (result.target) {
338
- const targetBounds = result.target.getBoundingClientRect();
339
- const dragTargetBounds = dragResult.target.getBoundingClientRect();
340
- let yDiff = dragTargetBounds.top - targetBounds.top;
341
- let xDiff = dragTargetBounds.left - targetBounds.left;
342
- if (this.config.axis.toLowerCase() === "y") {
343
- xDiff = 0;
344
- }
345
- if (this.config.axis.toLowerCase() === "x") {
346
- yDiff = 0;
347
- }
348
- const screenX = window.screenX + targetBounds.left + targetBounds.width / 2;
349
- const screenY = window.screenY + targetBounds.top + targetBounds.height / 2;
350
- const clientX = targetBounds.left + targetBounds.width / 2;
351
- const clientY = targetBounds.top + targetBounds.height / 2;
352
- const mouseDown = document.createEvent("MouseEvents");
353
- mouseDown.initMouseEvent(
354
- "mousedown",
355
- true,
356
- true,
357
- window,
358
- 0,
359
- screenX,
360
- screenY,
361
- clientX,
362
- clientY,
363
- false,
364
- false,
365
- false,
366
- false,
367
- 0,
368
- result.target
369
- );
370
- const mouseMove = document.createEvent("MouseEvents");
371
- mouseMove.initMouseEvent(
372
- "mousemove",
373
- true,
374
- true,
375
- window,
376
- 0,
377
- screenX + xDiff,
378
- screenY + yDiff,
379
- clientX + xDiff,
380
- clientY + yDiff,
381
- false,
382
- false,
383
- false,
384
- false,
385
- 0,
386
- result.target
387
- );
388
- const mouseUp = document.createEvent("MouseEvents");
389
- mouseUp.initMouseEvent(
390
- "mouseup",
391
- true,
392
- true,
393
- window,
394
- 0,
395
- screenX + xDiff,
396
- screenY + yDiff,
397
- clientX + xDiff,
398
- clientY + yDiff,
399
- false,
400
- false,
401
- false,
402
- false,
403
- 0,
404
- result.target
405
- );
406
- result.target.dispatchEvent(mouseDown);
407
- await this.waitTimeout(10);
408
- result.target.dispatchEvent(mouseMove);
409
- await this.waitTimeout(10);
410
- result.target.dispatchEvent(mouseUp);
411
- }
412
- }
413
- async function waitAction(config) {
414
- await waitTimeout(config.waitTime);
415
- }
416
- async function closeAction() {
417
- window.close();
418
- }
419
- async function evalAction(config) {
420
- console.log("eval!", config.code);
421
- return new Promise((resolve) => {
422
- try {
423
- if (config.async) {
424
- window.eval(config.code);
425
- setTimeout(() => {
426
- resolve(window.eval("window.__consentCheckResult"));
427
- }, config.timeout || 250);
428
- } else {
429
- resolve(window.eval(config.code));
430
- }
431
- } catch (e) {
432
- console.warn("eval error", e, config.code);
433
- resolve(false);
434
- }
435
- });
436
- }
437
-
438
- // lib/types.ts
439
- var PopupHandlingModes = {
440
- None: -1,
441
- Reject: 0,
442
- Tier1: 1,
443
- Tier2: 2
444
- };
39
+ // lib/rules.ts
40
+ var SUPPORTED_RULE_STEP_VERSION = 2;
445
41
 
446
42
  // lib/random.ts
447
43
  function getRandomID() {
@@ -469,6 +65,9 @@ var evalState = {
469
65
  sendContentMessage: null
470
66
  };
471
67
  function requestEval(code, snippetId) {
68
+ if (!evalState.sendContentMessage) {
69
+ return Promise.reject(new Error("AutoConsent is not initialized yet"));
70
+ }
472
71
  const id = getRandomID();
473
72
  evalState.sendContentMessage({
474
73
  type: "eval",
@@ -491,6 +90,155 @@ function resolveEval(id, value) {
491
90
  }
492
91
  }
493
92
 
93
+ // lib/utils.ts
94
+ function getStyleElement(styleOverrideElementId = "autoconsent-css-rules") {
95
+ const styleSelector = `style#${styleOverrideElementId}`;
96
+ const existingElement = document.querySelector(styleSelector);
97
+ if (existingElement && existingElement instanceof HTMLStyleElement) {
98
+ return existingElement;
99
+ } else {
100
+ const parent = document.head || document.getElementsByTagName("head")[0] || document.documentElement;
101
+ const css = document.createElement("style");
102
+ css.id = styleOverrideElementId;
103
+ parent.appendChild(css);
104
+ return css;
105
+ }
106
+ }
107
+ function getHidingStyle(method) {
108
+ const hidingSnippet = method === "opacity" ? `opacity: 0` : `display: none`;
109
+ return `${hidingSnippet} !important; z-index: -1 !important; pointer-events: none !important;`;
110
+ }
111
+ function hideElements(styleEl, selector, method = "display") {
112
+ const rule = `${selector} { ${getHidingStyle(method)} } `;
113
+ if (styleEl instanceof HTMLStyleElement) {
114
+ styleEl.innerText += rule;
115
+ return selector.length > 0;
116
+ }
117
+ return false;
118
+ }
119
+ async function waitFor(predicate, maxTimes, interval) {
120
+ const result = await predicate();
121
+ if (!result && maxTimes > 0) {
122
+ return new Promise((resolve) => {
123
+ setTimeout(async () => {
124
+ resolve(waitFor(predicate, maxTimes - 1, interval));
125
+ }, interval);
126
+ });
127
+ }
128
+ return Promise.resolve(result);
129
+ }
130
+ function isElementVisible(elem) {
131
+ if (!elem) {
132
+ return false;
133
+ }
134
+ if (elem.offsetParent !== null) {
135
+ return true;
136
+ } else {
137
+ const css = window.getComputedStyle(elem);
138
+ if (css.position === "fixed" && css.display !== "none") {
139
+ return true;
140
+ }
141
+ }
142
+ return false;
143
+ }
144
+ function copyObject(data) {
145
+ if (globalThis.structuredClone) {
146
+ return structuredClone(data);
147
+ }
148
+ return JSON.parse(JSON.stringify(data));
149
+ }
150
+ function normalizeConfig(providedConfig) {
151
+ const defaultConfig = {
152
+ enabled: true,
153
+ autoAction: "optOut",
154
+ // if falsy, the extension will wait for an explicit user signal before opting in/out
155
+ disabledCmps: [],
156
+ enablePrehide: true,
157
+ enableCosmeticRules: true,
158
+ enableGeneratedRules: true,
159
+ enableHeuristicDetection: false,
160
+ enablePopupMutationObserver: false,
161
+ detectRetries: 20,
162
+ isMainWorld: false,
163
+ prehideTimeout: 2e3,
164
+ visualTest: false,
165
+ logs: {
166
+ lifecycle: false,
167
+ rulesteps: false,
168
+ detectionsteps: false,
169
+ evals: false,
170
+ errors: true,
171
+ messages: false,
172
+ waits: false
173
+ },
174
+ performanceLoggingEnabled: false,
175
+ heuristicPopupSearchTimeout: 100,
176
+ heuristicMode: "off"
177
+ // heuristic disabled by default
178
+ };
179
+ const updatedConfig = copyObject(defaultConfig);
180
+ for (const key of Object.keys(defaultConfig)) {
181
+ if (typeof providedConfig[key] !== "undefined") {
182
+ updatedConfig[key] = providedConfig[key];
183
+ }
184
+ }
185
+ return updatedConfig;
186
+ }
187
+ function scheduleWhenIdle(callback, timeout = 500) {
188
+ if (globalThis.requestIdleCallback) {
189
+ requestIdleCallback(callback, { timeout });
190
+ } else {
191
+ setTimeout(callback, 0);
192
+ }
193
+ }
194
+ function highlightNode(node) {
195
+ const highlightedNode = node;
196
+ if (!node.style) return;
197
+ if (highlightedNode.__oldStyles !== void 0) {
198
+ return;
199
+ }
200
+ if (node.hasAttribute("style")) {
201
+ highlightedNode.__oldStyles = node.style.cssText;
202
+ }
203
+ node.style.animation = "pulsate .5s infinite";
204
+ node.style.outline = "solid red";
205
+ let styleTag = document.querySelector("style#autoconsent-debug-styles");
206
+ if (!styleTag) {
207
+ styleTag = document.createElement("style");
208
+ styleTag.id = "autoconsent-debug-styles";
209
+ }
210
+ styleTag.textContent = `
211
+ @keyframes pulsate {
212
+ 0% {
213
+ outline-width: 8px;
214
+ outline-offset: -4px;
215
+ }
216
+ 50% {
217
+ outline-width: 4px;
218
+ outline-offset: -2px;
219
+ }
220
+ 100% {
221
+ outline-width: 8px;
222
+ outline-offset: -4px;
223
+ }
224
+ }
225
+ `;
226
+ document.head.appendChild(styleTag);
227
+ }
228
+ function unhighlightNode(node) {
229
+ const highlightedNode = node;
230
+ if (!node.style || !node.hasAttribute("style")) return;
231
+ if (highlightedNode.__oldStyles !== void 0) {
232
+ node.style.cssText = highlightedNode.__oldStyles;
233
+ delete highlightedNode.__oldStyles;
234
+ } else {
235
+ node.removeAttribute("style");
236
+ }
237
+ }
238
+ function isTopFrame() {
239
+ return window.top === window && (!globalThis.location.ancestorOrigins || globalThis.location.ancestorOrigins.length === 0);
240
+ }
241
+
494
242
  // lib/eval-snippets.ts
495
243
  var snippets = {
496
244
  // code-based rules
@@ -668,154 +416,6 @@ function getFunctionBody(snippetFunc) {
668
416
  return `(${snippetStr})()`;
669
417
  }
670
418
 
671
- // lib/utils.ts
672
- function getStyleElement(styleOverrideElementId = "autoconsent-css-rules") {
673
- const styleSelector = `style#${styleOverrideElementId}`;
674
- const existingElement = document.querySelector(styleSelector);
675
- if (existingElement && existingElement instanceof HTMLStyleElement) {
676
- return existingElement;
677
- } else {
678
- const parent = document.head || document.getElementsByTagName("head")[0] || document.documentElement;
679
- const css = document.createElement("style");
680
- css.id = styleOverrideElementId;
681
- parent.appendChild(css);
682
- return css;
683
- }
684
- }
685
- function getHidingStyle(method) {
686
- const hidingSnippet = method === "opacity" ? `opacity: 0` : `display: none`;
687
- return `${hidingSnippet} !important; z-index: -1 !important; pointer-events: none !important;`;
688
- }
689
- function hideElements(styleEl, selector, method = "display") {
690
- const rule = `${selector} { ${getHidingStyle(method)} } `;
691
- if (styleEl instanceof HTMLStyleElement) {
692
- styleEl.innerText += rule;
693
- return selector.length > 0;
694
- }
695
- return false;
696
- }
697
- async function waitFor(predicate, maxTimes, interval) {
698
- const result = await predicate();
699
- if (!result && maxTimes > 0) {
700
- return new Promise((resolve) => {
701
- setTimeout(async () => {
702
- resolve(waitFor(predicate, maxTimes - 1, interval));
703
- }, interval);
704
- });
705
- }
706
- return Promise.resolve(result);
707
- }
708
- function isElementVisible(elem) {
709
- if (!elem) {
710
- return false;
711
- }
712
- if (elem.offsetParent !== null) {
713
- return true;
714
- } else {
715
- const css = window.getComputedStyle(elem);
716
- if (css.position === "fixed" && css.display !== "none") {
717
- return true;
718
- }
719
- }
720
- return false;
721
- }
722
- function copyObject(data) {
723
- if (globalThis.structuredClone) {
724
- return structuredClone(data);
725
- }
726
- return JSON.parse(JSON.stringify(data));
727
- }
728
- function normalizeConfig(providedConfig) {
729
- const defaultConfig = {
730
- enabled: true,
731
- autoAction: "optOut",
732
- // if falsy, the extension will wait for an explicit user signal before opting in/out
733
- disabledCmps: [],
734
- enablePrehide: true,
735
- enableCosmeticRules: true,
736
- enableGeneratedRules: true,
737
- enableHeuristicDetection: false,
738
- enableHeuristicAction: false,
739
- enablePopupMutationObserver: false,
740
- detectRetries: 20,
741
- isMainWorld: false,
742
- prehideTimeout: 2e3,
743
- enableFilterList: false,
744
- visualTest: false,
745
- logs: {
746
- lifecycle: false,
747
- rulesteps: false,
748
- detectionsteps: false,
749
- evals: false,
750
- errors: true,
751
- messages: false,
752
- waits: false
753
- },
754
- performanceLoggingEnabled: false,
755
- heuristicPopupSearchTimeout: 100,
756
- heuristicMode: PopupHandlingModes.Reject
757
- };
758
- const updatedConfig = copyObject(defaultConfig);
759
- for (const key of Object.keys(defaultConfig)) {
760
- if (typeof providedConfig[key] !== "undefined") {
761
- updatedConfig[key] = providedConfig[key];
762
- }
763
- }
764
- return updatedConfig;
765
- }
766
- function scheduleWhenIdle(callback, timeout = 500) {
767
- if (globalThis.requestIdleCallback) {
768
- requestIdleCallback(callback, { timeout });
769
- } else {
770
- setTimeout(callback, 0);
771
- }
772
- }
773
- function highlightNode(node) {
774
- if (!node.style) return;
775
- if (node.__oldStyles !== void 0) {
776
- return;
777
- }
778
- if (node.hasAttribute("style")) {
779
- node.__oldStyles = node.style.cssText;
780
- }
781
- node.style.animation = "pulsate .5s infinite";
782
- node.style.outline = "solid red";
783
- let styleTag = document.querySelector("style#autoconsent-debug-styles");
784
- if (!styleTag) {
785
- styleTag = document.createElement("style");
786
- styleTag.id = "autoconsent-debug-styles";
787
- }
788
- styleTag.textContent = `
789
- @keyframes pulsate {
790
- 0% {
791
- outline-width: 8px;
792
- outline-offset: -4px;
793
- }
794
- 50% {
795
- outline-width: 4px;
796
- outline-offset: -2px;
797
- }
798
- 100% {
799
- outline-width: 8px;
800
- outline-offset: -4px;
801
- }
802
- }
803
- `;
804
- document.head.appendChild(styleTag);
805
- }
806
- function unhighlightNode(node) {
807
- if (!node.style || !node.hasAttribute("style")) return;
808
- if (node.__oldStyles !== void 0) {
809
- node.style.cssText = node.__oldStyles;
810
- delete node.__oldStyles;
811
- } else {
812
- node.removeAttribute("style");
813
- }
814
- }
815
- function isTopFrame() {
816
- return window.top === window && (!globalThis.location.ancestorOrigins || globalThis.location.ancestorOrigins.length === 0);
817
- }
818
-
819
419
  // lib/heuristic-patterns.ts
820
420
  var DETECT_PATTERNS = [
821
421
  /accept cookies/gi,
@@ -1574,15 +1174,19 @@ function checkHeuristicPatterns(allText, detectPatterns = DETECT_PATTERNS) {
1574
1174
  const patterns = [];
1575
1175
  const snippets2 = [];
1576
1176
  for (const p of detectPatterns) {
1577
- const matches2 = allText?.match(p);
1578
- if (matches2) {
1177
+ const matches = allText?.match(p);
1178
+ if (matches) {
1579
1179
  patterns.push(p.toString());
1580
- snippets2.push(...matches2.map((m) => m.substring(0, 200)));
1180
+ snippets2.push(...matches.map((m) => m.substring(0, 200)));
1581
1181
  }
1582
1182
  }
1583
1183
  return { patterns, snippets: snippets2 };
1584
1184
  }
1585
- function getActionablePopups(mode = PopupHandlingModes.Reject, timeout = POPUP_SEARCH_MAX_TIME) {
1185
+ function getActionablePopups(mode = "reject", timeout = POPUP_SEARCH_MAX_TIME) {
1186
+ const acceptedLevels = mode === "tier2" ? ["reject", "tier1", "tier2"] : mode === "tier1" ? ["reject", "tier1"] : ["reject"];
1187
+ if (acceptedLevels.length === 0) {
1188
+ return [];
1189
+ }
1586
1190
  const popups = getPotentialPopups(timeout);
1587
1191
  const result = popups.reduce((acc, popup) => {
1588
1192
  const popupText = popup.text?.trim();
@@ -1598,9 +1202,7 @@ function getActionablePopups(mode = PopupHandlingModes.Reject, timeout = POPUP_S
1598
1202
  }
1599
1203
  return acc;
1600
1204
  }, []);
1601
- return result.filter(
1602
- (popup) => popup.regexClassification !== void 0 && popup.regexClassification !== PopupHandlingModes.None && popup.regexClassification <= mode
1603
- ).sort((a, b) => (a.regexClassification ?? 0) - (b.regexClassification ?? 0));
1205
+ return result.filter((popup) => popup.regexClassification !== void 0 && acceptedLevels.includes(popup.regexClassification)).sort((a, b) => (a.regexClassification ?? "") > (b.regexClassification ?? "") ? 1 : -1);
1604
1206
  }
1605
1207
  function classifyButtons(buttons) {
1606
1208
  for (const button of buttons) {
@@ -1618,18 +1220,18 @@ function classifyPopup(buttons) {
1618
1220
  { reject: 0, settings: 0, accept: 0, acknowledge: 0 }
1619
1221
  );
1620
1222
  if (reject > 0) {
1621
- return PopupHandlingModes.Reject;
1223
+ return "reject";
1622
1224
  }
1623
1225
  if (settings > 0) {
1624
- return PopupHandlingModes.None;
1226
+ return "none";
1625
1227
  }
1626
1228
  if (acknowledge > 0) {
1627
- return PopupHandlingModes.Tier1;
1229
+ return "tier1";
1628
1230
  }
1629
1231
  if (accept > 0) {
1630
- return accept === 1 ? PopupHandlingModes.Tier2 : PopupHandlingModes.None;
1232
+ return accept === 1 ? "tier2" : "none";
1631
1233
  }
1632
- return PopupHandlingModes.None;
1234
+ return "none";
1633
1235
  }
1634
1236
  function testButtonMatches(buttonText, matchPatterns, neverMatchPatterns) {
1635
1237
  if (!buttonText) {
@@ -2110,7 +1712,7 @@ var AutoConsentCMP = class extends AutoConsentCMPBase {
2110
1712
  }
2111
1713
  };
2112
1714
  var AutoConsentHeuristicCMP = class extends AutoConsentCMPBase {
2113
- constructor(autoconsentInstance, mode = PopupHandlingModes.Reject) {
1715
+ constructor(autoconsentInstance, mode = "reject") {
2114
1716
  super(autoconsentInstance);
2115
1717
  this.popups = [];
2116
1718
  this.name = "HEURISTIC";
@@ -2137,7 +1739,7 @@ var AutoConsentHeuristicCMP = class extends AutoConsentCMPBase {
2137
1739
  this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorEnd");
2138
1740
  this.autoconsent.config.performanceLoggingEnabled && performance.measure("heuristicDetector", "heuristicDetectorStart", "heuristicDetectorEnd");
2139
1741
  if (this.popups.length > 0) {
2140
- this.name = `HEURISTIC-TIER${this.popups[0].regexClassification}`;
1742
+ this.name = `HEURISTIC-${this.popups[0].regexClassification?.toUpperCase()}`;
2141
1743
  return Promise.resolve(true);
2142
1744
  }
2143
1745
  return Promise.resolve(false);
@@ -2155,7 +1757,7 @@ var AutoConsentHeuristicCMP = class extends AutoConsentCMPBase {
2155
1757
  const popup = this.popups[0];
2156
1758
  const level = popup.regexClassification;
2157
1759
  const buttons = popup.buttons;
2158
- const targetButtonType = level === PopupHandlingModes.Reject ? "reject" : level === PopupHandlingModes.Tier1 ? "acknowledge" : "accept";
1760
+ const targetButtonType = level === "reject" ? "reject" : level === "tier1" ? "acknowledge" : "accept";
2159
1761
  return buttons.find((button) => button.regexClassification === targetButtonType);
2160
1762
  }
2161
1763
  optOut() {
@@ -2181,76 +1783,6 @@ var AutoConsentHeuristicCMP = class extends AutoConsentCMPBase {
2181
1783
  }
2182
1784
  };
2183
1785
 
2184
- // lib/cmps/consentomatic.ts
2185
- var ConsentOMaticCMP = class {
2186
- constructor(name, config) {
2187
- this.name = name;
2188
- this.config = config;
2189
- this.methods = /* @__PURE__ */ new Map();
2190
- this.runContext = defaultRunContext;
2191
- this.isCosmetic = false;
2192
- config.methods.forEach((methodConfig) => {
2193
- if (methodConfig.action) {
2194
- this.methods.set(methodConfig.name, methodConfig.action);
2195
- }
2196
- });
2197
- this.hasSelfTest = false;
2198
- }
2199
- get isIntermediate() {
2200
- return false;
2201
- }
2202
- checkRunContext() {
2203
- return true;
2204
- }
2205
- checkFrameContext(isTop) {
2206
- return true;
2207
- }
2208
- hasMatchingUrlPattern() {
2209
- return false;
2210
- }
2211
- async detectCmp() {
2212
- const matchResults = this.config.detectors.map((detectorConfig) => matches(detectorConfig.presentMatcher));
2213
- return matchResults.some((r) => !!r);
2214
- }
2215
- async detectPopup() {
2216
- const matchResults = this.config.detectors.map((detectorConfig) => matches(detectorConfig.showingMatcher));
2217
- return matchResults.some((r) => !!r);
2218
- }
2219
- async executeAction(method, param) {
2220
- if (this.methods.has(method)) {
2221
- return executeAction(this.methods.get(method), param);
2222
- }
2223
- return true;
2224
- }
2225
- async optOut() {
2226
- await this.executeAction("HIDE_CMP");
2227
- await this.executeAction("OPEN_OPTIONS");
2228
- await this.executeAction("HIDE_CMP");
2229
- await this.executeAction("DO_CONSENT", []);
2230
- await this.executeAction("SAVE_CONSENT");
2231
- return true;
2232
- }
2233
- async optIn() {
2234
- await this.executeAction("HIDE_CMP");
2235
- await this.executeAction("OPEN_OPTIONS");
2236
- await this.executeAction("HIDE_CMP");
2237
- await this.executeAction("DO_CONSENT", ["D", "A", "B", "E", "F", "X"]);
2238
- await this.executeAction("SAVE_CONSENT");
2239
- return true;
2240
- }
2241
- async openCmp() {
2242
- await this.executeAction("HIDE_CMP");
2243
- await this.executeAction("OPEN_OPTIONS");
2244
- return true;
2245
- }
2246
- async test() {
2247
- return true;
2248
- }
2249
- };
2250
-
2251
- // lib/rules.ts
2252
- var SUPPORTED_RULE_STEP_VERSION = 2;
2253
-
2254
1786
  // lib/cmps/trustarc-top.ts
2255
1787
  var cookieSettingsButton = "#truste-show-consent";
2256
1788
  var shortcutOptOut = "#truste-consent-required";
@@ -2853,7 +2385,7 @@ var Uniconsent = class extends AutoConsentCMPBase {
2853
2385
  async optOut() {
2854
2386
  await this.waitForElement(".unic button", 1e3);
2855
2387
  document.querySelectorAll(".unic button").forEach((button) => {
2856
- const text = button.textContent;
2388
+ const text = button.textContent || "";
2857
2389
  if (text.includes("Manage Options") || text.includes("Optionen verwalten")) {
2858
2390
  button.click();
2859
2391
  }
@@ -2866,7 +2398,7 @@ var Uniconsent = class extends AutoConsentCMPBase {
2866
2398
  }
2867
2399
  });
2868
2400
  for (const b of document.querySelectorAll(".unic button")) {
2869
- const text = b.textContent;
2401
+ const text = b.textContent || "";
2870
2402
  for (const pattern of ["Confirm Choices", "Save Choices", "Auswahl speichern"]) {
2871
2403
  if (text.includes(pattern)) {
2872
2404
  b.click();
@@ -2923,6 +2455,9 @@ var Conversant = class extends AutoConsentCMPBase {
2923
2455
  item.querySelector(".cmp-accordion-item-title").click();
2924
2456
  await waitFor(() => !!item.querySelector(".cmp-accordion-item-content.cmp-active"), 10, 50);
2925
2457
  const content = item.querySelector(".cmp-accordion-item-content.cmp-active");
2458
+ if (!content) {
2459
+ return false;
2460
+ }
2926
2461
  content.querySelectorAll(".cmp-toggle-actions .cmp-toggle-deny:not(.cmp-toggle-deny--active)").forEach((e) => e.click());
2927
2462
  content.querySelectorAll(".cmp-toggle-actions .cmp-toggle-checkbox:not(.cmp-toggle-checkbox--active)").forEach((e) => e.click());
2928
2463
  }
@@ -3275,15 +2810,15 @@ var DomActions = class {
3275
2810
  }
3276
2811
  querySelectorChain(selectors) {
3277
2812
  let parent = document;
3278
- let matches2 = [];
2813
+ let matches = [];
3279
2814
  for (const selector of selectors) {
3280
- matches2 = this.querySingleReplySelector(selector, parent);
3281
- if (matches2.length === 0) {
2815
+ matches = this.querySingleReplySelector(selector, parent);
2816
+ if (matches.length === 0) {
3282
2817
  return [];
3283
2818
  }
3284
- parent = matches2[0];
2819
+ parent = matches[0];
3285
2820
  }
3286
- return matches2;
2821
+ return matches;
3287
2822
  }
3288
2823
  elementSelector(selector) {
3289
2824
  if (typeof selector === "string") {
@@ -3662,8 +3197,6 @@ var AutoConsent = class {
3662
3197
  this.rules = [];
3663
3198
  __privateAdd(this, _config);
3664
3199
  this.state = {
3665
- cosmeticFiltersOn: false,
3666
- filterListReported: false,
3667
3200
  lifecycle: "loading",
3668
3201
  prehideOn: false,
3669
3202
  findCmpAttempts: 0,
@@ -3713,9 +3246,6 @@ var AutoConsent = class {
3713
3246
  if (declarativeRules) {
3714
3247
  this.parseDeclarativeRules(declarativeRules);
3715
3248
  }
3716
- if (config.enableFilterList) {
3717
- this.initializeFilterList();
3718
- }
3719
3249
  this.rules = filterCMPs(this.rules, normalizedConfig);
3720
3250
  if (this.shouldPrehide) {
3721
3251
  if (document.documentElement) {
@@ -3739,8 +3269,6 @@ var AutoConsent = class {
3739
3269
  }
3740
3270
  this.updateState({ lifecycle: "initialized" });
3741
3271
  }
3742
- initializeFilterList() {
3743
- }
3744
3272
  get shouldPrehide() {
3745
3273
  return this.config.enablePrehide && !this.config.visualTest;
3746
3274
  }
@@ -3769,11 +3297,6 @@ var AutoConsent = class {
3769
3297
  parseDeclarativeRules(declarativeRules) {
3770
3298
  const perfEnabled = __privateGet(this, _config)?.performanceLoggingEnabled;
3771
3299
  perfEnabled && performance.mark("parseDeclarativeRulesStart");
3772
- if (declarativeRules.consentomatic) {
3773
- for (const [name, rule] of Object.entries(declarativeRules.consentomatic)) {
3774
- this.addConsentomaticCMP(name, rule);
3775
- }
3776
- }
3777
3300
  if (declarativeRules.autoconsent) {
3778
3301
  declarativeRules.autoconsent.forEach((ruleset) => {
3779
3302
  this.addDeclarativeCMP(ruleset);
@@ -3795,9 +3318,6 @@ var AutoConsent = class {
3795
3318
  this.rules.push(new AutoConsentCMP(ruleset, this));
3796
3319
  }
3797
3320
  }
3798
- addConsentomaticCMP(name, config) {
3799
- this.rules.push(new ConsentOMaticCMP(`com_${name}`, config));
3800
- }
3801
3321
  // start the detection process, possibly with a delay
3802
3322
  start() {
3803
3323
  scheduleWhenIdle(() => this._start());
@@ -3816,7 +3336,8 @@ var AutoConsent = class {
3816
3336
  if (this.shouldPrehide) {
3817
3337
  this.undoPrehide();
3818
3338
  }
3819
- return this.filterListFallback();
3339
+ this.updateState({ lifecycle: "nothingDetected" });
3340
+ return false;
3820
3341
  }
3821
3342
  this.updateState({ lifecycle: "cmpDetected" });
3822
3343
  const staticCmps = [];
@@ -3874,7 +3395,7 @@ var AutoConsent = class {
3874
3395
  }
3875
3396
  }
3876
3397
  });
3877
- const heuristicRules = isTop && this.config.enableHeuristicAction && this.state.findCmpAttempts % 2 === 0 ? [new AutoConsentHeuristicCMP(this, this.config.heuristicMode)] : [];
3398
+ const heuristicRules = isTop && this.config.heuristicMode !== "off" && this.state.findCmpAttempts % 2 === 0 ? [new AutoConsentHeuristicCMP(this, this.config.heuristicMode)] : [];
3878
3399
  const rulesPriorityStages = [
3879
3400
  ["site-specific", siteSpecificRules],
3880
3401
  ["generic", genericRules],
@@ -3982,9 +3503,6 @@ var AutoConsent = class {
3982
3503
  if (this.shouldPrehide && !this.state.prehideOn) {
3983
3504
  this.prehideElements();
3984
3505
  }
3985
- if (this.state.cosmeticFiltersOn) {
3986
- this.undoCosmetics();
3987
- }
3988
3506
  this.foundCmp = cmp;
3989
3507
  if (this.config.autoAction === "optOut") {
3990
3508
  return await this.doOptOut();
@@ -4148,25 +3666,6 @@ var AutoConsent = class {
4148
3666
  this.updateState({ prehideOn: false });
4149
3667
  this.domActions.undoPrehide();
4150
3668
  }
4151
- undoCosmetics() {
4152
- }
4153
- reportFilterlist() {
4154
- this.sendContentMessage({
4155
- type: "cmpDetected",
4156
- url: location.href,
4157
- cmp: "filterList"
4158
- });
4159
- this.sendContentMessage({
4160
- type: "popupFound",
4161
- cmp: "filterList",
4162
- url: location.href
4163
- });
4164
- this.updateState({ filterListReported: true });
4165
- }
4166
- filterListFallback() {
4167
- this.updateState({ lifecycle: "nothingDetected" });
4168
- return false;
4169
- }
4170
3669
  updateState(change) {
4171
3670
  Object.assign(this.state, change);
4172
3671
  this.sendContentMessage({