@duckduckgo/autoconsent 14.97.0 → 15.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.
- package/CHANGELOG.md +18 -0
- package/dist/addon-firefox/background.bundle.js +10 -1
- package/dist/addon-firefox/compact-rules.json +1 -1
- package/dist/addon-firefox/content.bundle.js +142 -33
- package/dist/addon-firefox/manifest.json +1 -1
- package/dist/addon-firefox/popup.bundle.js +10 -1
- package/dist/addon-firefox/rules.json +1 -1
- package/dist/addon-mv3/background.bundle.js +10 -1
- package/dist/addon-mv3/compact-rules.json +1 -1
- package/dist/addon-mv3/content.bundle.js +142 -33
- package/dist/addon-mv3/manifest.json +1 -1
- package/dist/addon-mv3/popup.bundle.js +10 -1
- package/dist/addon-mv3/rules.json +1 -1
- package/dist/autoconsent.cjs.js +142 -33
- package/dist/autoconsent.esm.js +142 -33
- package/dist/autoconsent.extra.cjs.js +142 -33
- package/dist/autoconsent.extra.esm.js +142 -33
- package/dist/autoconsent.playwright.js +142 -33
- package/dist/types/cmps/base.d.ts +4 -2
- package/dist/types/heuristic-patterns.d.ts +3 -0
- package/dist/types/heuristics.d.ts +4 -7
- package/dist/types/types.d.ts +18 -2
- package/lib/cmps/base.ts +20 -7
- package/lib/heuristic-patterns.ts +68 -1
- package/lib/heuristics.ts +76 -27
- package/lib/types.ts +20 -2
- package/lib/utils.ts +2 -1
- package/lib/web.ts +3 -1
- package/package.json +1 -1
- package/rules/autoconsent/twitch.json +1 -1
- package/rules/compact-rules.json +1 -1
- package/rules/rules.json +1 -1
- package/tests-wtr/heuristics/get-actionable-popups.html +16 -0
- package/tests-wtr/heuristics/get-actionable-popups.ts +85 -6
- package/tests-wtr/heuristics/heuristic-cmp.html +69 -0
- package/tests-wtr/heuristics/heuristic-cmp.ts +178 -0
- package/tests-wtr/heuristics/heuristics-utils.test.ts +96 -28
- package/tests-wtr/lifecycle/find-cmp.html +14 -0
- package/tests-wtr/lifecycle/find-cmp.ts +44 -2
|
@@ -11483,6 +11483,14 @@ function extractFeaturesFromDOM(roots = [document.documentElement]) {
|
|
|
11483
11483
|
// lib/filterlist-utils.ts
|
|
11484
11484
|
var import_tldts_experimental3 = __toESM(require_cjs());
|
|
11485
11485
|
|
|
11486
|
+
// lib/types.ts
|
|
11487
|
+
var PopupHandlingModes = {
|
|
11488
|
+
None: -1,
|
|
11489
|
+
Reject: 0,
|
|
11490
|
+
Tier1: 1,
|
|
11491
|
+
Tier2: 2
|
|
11492
|
+
};
|
|
11493
|
+
|
|
11486
11494
|
// lib/utils.ts
|
|
11487
11495
|
function getStyleElement(styleOverrideElementId = "autoconsent-css-rules") {
|
|
11488
11496
|
const styleSelector = `style#${styleOverrideElementId}`;
|
|
@@ -11567,7 +11575,8 @@ function normalizeConfig(providedConfig) {
|
|
|
11567
11575
|
waits: false
|
|
11568
11576
|
},
|
|
11569
11577
|
performanceLoggingEnabled: false,
|
|
11570
|
-
heuristicPopupSearchTimeout: 100
|
|
11578
|
+
heuristicPopupSearchTimeout: 100,
|
|
11579
|
+
heuristicMode: PopupHandlingModes.Reject
|
|
11571
11580
|
};
|
|
11572
11581
|
const updatedConfig = copyObject(defaultConfig);
|
|
11573
11582
|
for (const key of Object.keys(defaultConfig)) {
|
|
@@ -12401,12 +12410,17 @@ var REJECT_PATTERNS_ENGLISH = [
|
|
|
12401
12410
|
/^\s*(use|accept|allow|continue\s+with)?\s*only\s*(strictly)?\s*(necessary|essentials?|required)?\s*(cookies)?\s*$/is,
|
|
12402
12411
|
// e.g. "do not sell or share my personal information", "do not sell my personal information"
|
|
12403
12412
|
// often used in CCPA
|
|
12404
|
-
/^\s*do\s+not\s+sell(\s+or\s+share)?\s*my\s*personal\s*
|
|
12413
|
+
/^\s*do\s+not\s+sell(\s+or\s+share)?\s*my\s*personal\s*info(rmation)?\s*$/is,
|
|
12405
12414
|
"allow selection",
|
|
12406
|
-
"disagree and close"
|
|
12415
|
+
"disagree and close",
|
|
12407
12416
|
// These are impactful, but look error-prone
|
|
12417
|
+
// // e.g. "disagree"
|
|
12418
|
+
/^(i)?\s*disagree\s*(and\s+close)?$/i,
|
|
12408
12419
|
// // e.g. "i do not agree"
|
|
12409
12420
|
// /^\s*(i\s+)?do\s+not\s+agree\s*$/i,
|
|
12421
|
+
"no",
|
|
12422
|
+
/^no,? thanks$/is,
|
|
12423
|
+
/^opt[ -]out$/is
|
|
12410
12424
|
];
|
|
12411
12425
|
var REJECT_PATTERNS_DUTCH = [
|
|
12412
12426
|
"weigeren",
|
|
@@ -12982,6 +12996,64 @@ var NEVER_MATCH_PATTERNS = [
|
|
|
12982
12996
|
/sostienici/is,
|
|
12983
12997
|
/suscribir/is
|
|
12984
12998
|
];
|
|
12999
|
+
var SETTINGS_PATTERNS = [
|
|
13000
|
+
"settings",
|
|
13001
|
+
"preferences",
|
|
13002
|
+
/customi(s|z)e/is,
|
|
13003
|
+
"show details",
|
|
13004
|
+
"more options",
|
|
13005
|
+
/(manage|configure) (my|your) (preferences|choices|cookies)/is,
|
|
13006
|
+
"manage choices",
|
|
13007
|
+
/(cookie )?preference center/is,
|
|
13008
|
+
"change settings",
|
|
13009
|
+
"configure",
|
|
13010
|
+
"change my preferences",
|
|
13011
|
+
"cookie manager",
|
|
13012
|
+
"cookie preference",
|
|
13013
|
+
"let me choose",
|
|
13014
|
+
"cookieconsent preferences",
|
|
13015
|
+
/privacy choices/is,
|
|
13016
|
+
/(privacy|cookie|custom) settings/is,
|
|
13017
|
+
/cookies? (settings|preferences|setting)/is,
|
|
13018
|
+
/(manage|customize|customise|opt-out|edit).*(cookies|preferences|settings|options)/is,
|
|
13019
|
+
"cookie consent options",
|
|
13020
|
+
"privacy controls",
|
|
13021
|
+
"show purposes",
|
|
13022
|
+
// German
|
|
13023
|
+
"einstellungen"
|
|
13024
|
+
];
|
|
13025
|
+
var ACCEPT_PATTERNS = [
|
|
13026
|
+
/^(accept|allow)( all)?( cookies)?$/is,
|
|
13027
|
+
/i (accept|allow)( all)?/is,
|
|
13028
|
+
"yes",
|
|
13029
|
+
/^(i )?agree$/is,
|
|
13030
|
+
"continue with all",
|
|
13031
|
+
"accept and continue",
|
|
13032
|
+
/accept all above/is,
|
|
13033
|
+
/^(accept|agree) and close/is,
|
|
13034
|
+
"accept continue",
|
|
13035
|
+
"agree proceed",
|
|
13036
|
+
"allow and continue",
|
|
13037
|
+
"close and accept",
|
|
13038
|
+
/accept all$/is,
|
|
13039
|
+
"im ok with that",
|
|
13040
|
+
"accept optional cookies",
|
|
13041
|
+
/^alle (cookies )?akzeptieren$/is
|
|
13042
|
+
];
|
|
13043
|
+
var ACKNOWLEDGE_PATTERNS = [
|
|
13044
|
+
"ok",
|
|
13045
|
+
"close",
|
|
13046
|
+
"continue",
|
|
13047
|
+
"x",
|
|
13048
|
+
/^got it!?$/,
|
|
13049
|
+
"i understand",
|
|
13050
|
+
"dismiss",
|
|
13051
|
+
"okay",
|
|
13052
|
+
"acknowledge",
|
|
13053
|
+
/^close (banner|cookie notification)$/is,
|
|
13054
|
+
/understood$/is,
|
|
13055
|
+
"confirm my choices"
|
|
13056
|
+
];
|
|
12985
13057
|
|
|
12986
13058
|
// lib/heuristics.ts
|
|
12987
13059
|
var BUTTON_LIKE_ELEMENT_SELECTOR = 'button, input[type="button"], input[type="submit"], a, [role="button"], [class*="button"]';
|
|
@@ -13000,48 +13072,61 @@ function checkHeuristicPatterns(allText, detectPatterns = DETECT_PATTERNS) {
|
|
|
13000
13072
|
}
|
|
13001
13073
|
return { patterns, snippets: snippets2 };
|
|
13002
13074
|
}
|
|
13003
|
-
function getActionablePopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
13075
|
+
function getActionablePopups(mode = PopupHandlingModes.Reject, timeout = POPUP_SEARCH_MAX_TIME) {
|
|
13004
13076
|
const popups = getPotentialPopups(timeout);
|
|
13005
13077
|
const result = popups.reduce((acc, popup) => {
|
|
13006
13078
|
const popupText = popup.text?.trim();
|
|
13007
13079
|
if (popupText) {
|
|
13008
13080
|
const { patterns } = checkHeuristicPatterns(popupText);
|
|
13009
13081
|
if (patterns.length > 0) {
|
|
13010
|
-
|
|
13011
|
-
|
|
13012
|
-
|
|
13013
|
-
|
|
13014
|
-
|
|
13015
|
-
otherButtons
|
|
13016
|
-
});
|
|
13017
|
-
}
|
|
13082
|
+
classifyButtons(popup.buttons);
|
|
13083
|
+
popup.regexClassification = classifyPopup(popup.buttons);
|
|
13084
|
+
acc.push({
|
|
13085
|
+
...popup
|
|
13086
|
+
});
|
|
13018
13087
|
}
|
|
13019
13088
|
}
|
|
13020
13089
|
return acc;
|
|
13021
13090
|
}, []);
|
|
13022
|
-
return result
|
|
13091
|
+
return result.filter(
|
|
13092
|
+
(popup) => popup.regexClassification !== void 0 && popup.regexClassification !== PopupHandlingModes.None && popup.regexClassification <= mode
|
|
13093
|
+
).sort((a, b) => (a.regexClassification ?? 0) - (b.regexClassification ?? 0));
|
|
13023
13094
|
}
|
|
13024
13095
|
function classifyButtons(buttons) {
|
|
13025
|
-
const rejectButtons = [];
|
|
13026
|
-
const otherButtons = [];
|
|
13027
13096
|
for (const button of buttons) {
|
|
13028
|
-
|
|
13029
|
-
rejectButtons.push(button);
|
|
13030
|
-
} else {
|
|
13031
|
-
otherButtons.push(button);
|
|
13032
|
-
}
|
|
13097
|
+
button.regexClassification = classifyButtonTextRegex(button.text);
|
|
13033
13098
|
}
|
|
13034
|
-
return {
|
|
13035
|
-
rejectButtons,
|
|
13036
|
-
otherButtons
|
|
13037
|
-
};
|
|
13038
13099
|
}
|
|
13039
|
-
function
|
|
13100
|
+
function classifyPopup(buttons) {
|
|
13101
|
+
const { reject, settings, accept, acknowledge } = buttons.reduce(
|
|
13102
|
+
(acc, button) => {
|
|
13103
|
+
if (button.regexClassification && button.regexClassification !== "other") {
|
|
13104
|
+
acc[button.regexClassification]++;
|
|
13105
|
+
}
|
|
13106
|
+
return acc;
|
|
13107
|
+
},
|
|
13108
|
+
{ reject: 0, settings: 0, accept: 0, acknowledge: 0 }
|
|
13109
|
+
);
|
|
13110
|
+
if (reject > 0) {
|
|
13111
|
+
return PopupHandlingModes.Reject;
|
|
13112
|
+
}
|
|
13113
|
+
if (settings > 0) {
|
|
13114
|
+
return PopupHandlingModes.None;
|
|
13115
|
+
}
|
|
13116
|
+
if (acknowledge > 0) {
|
|
13117
|
+
return PopupHandlingModes.Tier1;
|
|
13118
|
+
}
|
|
13119
|
+
if (accept > 0) {
|
|
13120
|
+
return accept === 1 ? PopupHandlingModes.Tier2 : PopupHandlingModes.None;
|
|
13121
|
+
}
|
|
13122
|
+
return PopupHandlingModes.None;
|
|
13123
|
+
}
|
|
13124
|
+
function testButtonMatches(buttonText, matchPatterns, neverMatchPatterns) {
|
|
13040
13125
|
if (!buttonText) {
|
|
13041
13126
|
return false;
|
|
13042
13127
|
}
|
|
13043
13128
|
const cleanedButtonText = cleanButtonText(buttonText);
|
|
13044
|
-
return !neverMatchPatterns.some((p) => p.test(cleanedButtonText)) &&
|
|
13129
|
+
return !neverMatchPatterns.some((p) => p instanceof RegExp && p.test(cleanedButtonText) || p === cleanedButtonText) && matchPatterns.some((p) => p instanceof RegExp && p.test(cleanedButtonText) || p === cleanedButtonText);
|
|
13045
13130
|
}
|
|
13046
13131
|
function cleanButtonText(buttonText) {
|
|
13047
13132
|
let result = buttonText.toLowerCase();
|
|
@@ -13055,6 +13140,21 @@ function cleanButtonText(buttonText) {
|
|
|
13055
13140
|
result = result.trim();
|
|
13056
13141
|
return result;
|
|
13057
13142
|
}
|
|
13143
|
+
function classifyButtonTextRegex(buttonText) {
|
|
13144
|
+
if (testButtonMatches(buttonText, REJECT_PATTERNS, NEVER_MATCH_PATTERNS)) {
|
|
13145
|
+
return "reject";
|
|
13146
|
+
}
|
|
13147
|
+
if (testButtonMatches(buttonText, SETTINGS_PATTERNS, NEVER_MATCH_PATTERNS)) {
|
|
13148
|
+
return "settings";
|
|
13149
|
+
}
|
|
13150
|
+
if (testButtonMatches(buttonText, ACCEPT_PATTERNS, NEVER_MATCH_PATTERNS)) {
|
|
13151
|
+
return "accept";
|
|
13152
|
+
}
|
|
13153
|
+
if (testButtonMatches(buttonText, ACKNOWLEDGE_PATTERNS, NEVER_MATCH_PATTERNS)) {
|
|
13154
|
+
return "acknowledge";
|
|
13155
|
+
}
|
|
13156
|
+
return "other";
|
|
13157
|
+
}
|
|
13058
13158
|
function getPotentialPopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
13059
13159
|
const isFramed = !isTopFrame();
|
|
13060
13160
|
if (isFramed && window.parent && window.parent !== window.top) {
|
|
@@ -13500,7 +13600,7 @@ var AutoConsentCMP = class extends AutoConsentCMPBase {
|
|
|
13500
13600
|
}
|
|
13501
13601
|
};
|
|
13502
13602
|
var AutoConsentHeuristicCMP = class extends AutoConsentCMPBase {
|
|
13503
|
-
constructor(autoconsentInstance) {
|
|
13603
|
+
constructor(autoconsentInstance, mode = PopupHandlingModes.Reject) {
|
|
13504
13604
|
super(autoconsentInstance);
|
|
13505
13605
|
this.popups = [];
|
|
13506
13606
|
this.name = "HEURISTIC";
|
|
@@ -13509,6 +13609,7 @@ var AutoConsentHeuristicCMP = class extends AutoConsentCMPBase {
|
|
|
13509
13609
|
frame: false
|
|
13510
13610
|
// do not run in iframes for security reasons
|
|
13511
13611
|
};
|
|
13612
|
+
this.mode = mode;
|
|
13512
13613
|
}
|
|
13513
13614
|
get hasSelfTest() {
|
|
13514
13615
|
return true;
|
|
@@ -13522,25 +13623,33 @@ var AutoConsentHeuristicCMP = class extends AutoConsentCMPBase {
|
|
|
13522
13623
|
async detectCmp() {
|
|
13523
13624
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
13524
13625
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorStart");
|
|
13525
|
-
this.popups = getActionablePopups(this.autoconsent.config.heuristicPopupSearchTimeout);
|
|
13626
|
+
this.popups = getActionablePopups(this.mode, this.autoconsent.config.heuristicPopupSearchTimeout);
|
|
13526
13627
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorEnd");
|
|
13527
13628
|
this.autoconsent.config.performanceLoggingEnabled && performance.measure("heuristicDetector", "heuristicDetectorStart", "heuristicDetectorEnd");
|
|
13528
13629
|
if (this.popups.length > 0) {
|
|
13630
|
+
this.name = `HEURISTIC-TIER${this.popups[0].regexClassification}`;
|
|
13529
13631
|
return Promise.resolve(true);
|
|
13530
13632
|
}
|
|
13531
13633
|
return Promise.resolve(false);
|
|
13532
13634
|
}
|
|
13533
13635
|
async detectPopup() {
|
|
13534
13636
|
if (this.popups.length > 0) {
|
|
13535
|
-
if (this.popups.length > 1
|
|
13536
|
-
this.autoconsent.config.logs.errors && console.warn("Heuristic found multiple
|
|
13637
|
+
if (this.popups.length > 1) {
|
|
13638
|
+
this.autoconsent.config.logs.errors && console.warn("Heuristic found multiple popups");
|
|
13537
13639
|
}
|
|
13538
13640
|
return true;
|
|
13539
13641
|
}
|
|
13540
13642
|
return false;
|
|
13541
13643
|
}
|
|
13644
|
+
getTargetButton() {
|
|
13645
|
+
const popup = this.popups[0];
|
|
13646
|
+
const level = popup.regexClassification;
|
|
13647
|
+
const buttons = popup.buttons;
|
|
13648
|
+
const targetButtonType = level === PopupHandlingModes.Reject ? "reject" : level === PopupHandlingModes.Tier1 ? "acknowledge" : "accept";
|
|
13649
|
+
return buttons.find((button) => button.regexClassification === targetButtonType);
|
|
13650
|
+
}
|
|
13542
13651
|
optOut() {
|
|
13543
|
-
const button = this.
|
|
13652
|
+
const button = this.getTargetButton();
|
|
13544
13653
|
if (button) {
|
|
13545
13654
|
return this.clickElement(button.element);
|
|
13546
13655
|
}
|
|
@@ -13553,7 +13662,7 @@ var AutoConsentHeuristicCMP = class extends AutoConsentCMPBase {
|
|
|
13553
13662
|
throw new Error("Not Implemented");
|
|
13554
13663
|
}
|
|
13555
13664
|
async test() {
|
|
13556
|
-
const button = this.
|
|
13665
|
+
const button = this.getTargetButton();
|
|
13557
13666
|
if (button) {
|
|
13558
13667
|
await this.wait(500);
|
|
13559
13668
|
return !isElementVisible(button.element);
|
|
@@ -15023,7 +15132,7 @@ var AutoConsent = class {
|
|
|
15023
15132
|
}
|
|
15024
15133
|
}
|
|
15025
15134
|
});
|
|
15026
|
-
const heuristicRules = isTop && this.config.enableHeuristicAction && this.state.findCmpAttempts % 2 === 0 ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
15135
|
+
const heuristicRules = isTop && this.config.enableHeuristicAction && this.state.findCmpAttempts % 2 === 0 ? [new AutoConsentHeuristicCMP(this, this.config.heuristicMode)] : [];
|
|
15027
15136
|
const rulesPriorityStages = [
|
|
15028
15137
|
["site-specific", siteSpecificRules],
|
|
15029
15138
|
["generic", genericRules],
|
|
@@ -11412,6 +11412,14 @@ function extractFeaturesFromDOM(roots = [document.documentElement]) {
|
|
|
11412
11412
|
};
|
|
11413
11413
|
}
|
|
11414
11414
|
|
|
11415
|
+
// lib/types.ts
|
|
11416
|
+
var PopupHandlingModes = {
|
|
11417
|
+
None: -1,
|
|
11418
|
+
Reject: 0,
|
|
11419
|
+
Tier1: 1,
|
|
11420
|
+
Tier2: 2
|
|
11421
|
+
};
|
|
11422
|
+
|
|
11415
11423
|
// lib/utils.ts
|
|
11416
11424
|
function getStyleElement(styleOverrideElementId = "autoconsent-css-rules") {
|
|
11417
11425
|
const styleSelector = `style#${styleOverrideElementId}`;
|
|
@@ -11496,7 +11504,8 @@ function normalizeConfig(providedConfig) {
|
|
|
11496
11504
|
waits: false
|
|
11497
11505
|
},
|
|
11498
11506
|
performanceLoggingEnabled: false,
|
|
11499
|
-
heuristicPopupSearchTimeout: 100
|
|
11507
|
+
heuristicPopupSearchTimeout: 100,
|
|
11508
|
+
heuristicMode: PopupHandlingModes.Reject
|
|
11500
11509
|
};
|
|
11501
11510
|
const updatedConfig = copyObject(defaultConfig);
|
|
11502
11511
|
for (const key of Object.keys(defaultConfig)) {
|
|
@@ -12330,12 +12339,17 @@ var REJECT_PATTERNS_ENGLISH = [
|
|
|
12330
12339
|
/^\s*(use|accept|allow|continue\s+with)?\s*only\s*(strictly)?\s*(necessary|essentials?|required)?\s*(cookies)?\s*$/is,
|
|
12331
12340
|
// e.g. "do not sell or share my personal information", "do not sell my personal information"
|
|
12332
12341
|
// often used in CCPA
|
|
12333
|
-
/^\s*do\s+not\s+sell(\s+or\s+share)?\s*my\s*personal\s*
|
|
12342
|
+
/^\s*do\s+not\s+sell(\s+or\s+share)?\s*my\s*personal\s*info(rmation)?\s*$/is,
|
|
12334
12343
|
"allow selection",
|
|
12335
|
-
"disagree and close"
|
|
12344
|
+
"disagree and close",
|
|
12336
12345
|
// These are impactful, but look error-prone
|
|
12346
|
+
// // e.g. "disagree"
|
|
12347
|
+
/^(i)?\s*disagree\s*(and\s+close)?$/i,
|
|
12337
12348
|
// // e.g. "i do not agree"
|
|
12338
12349
|
// /^\s*(i\s+)?do\s+not\s+agree\s*$/i,
|
|
12350
|
+
"no",
|
|
12351
|
+
/^no,? thanks$/is,
|
|
12352
|
+
/^opt[ -]out$/is
|
|
12339
12353
|
];
|
|
12340
12354
|
var REJECT_PATTERNS_DUTCH = [
|
|
12341
12355
|
"weigeren",
|
|
@@ -12911,6 +12925,64 @@ var NEVER_MATCH_PATTERNS = [
|
|
|
12911
12925
|
/sostienici/is,
|
|
12912
12926
|
/suscribir/is
|
|
12913
12927
|
];
|
|
12928
|
+
var SETTINGS_PATTERNS = [
|
|
12929
|
+
"settings",
|
|
12930
|
+
"preferences",
|
|
12931
|
+
/customi(s|z)e/is,
|
|
12932
|
+
"show details",
|
|
12933
|
+
"more options",
|
|
12934
|
+
/(manage|configure) (my|your) (preferences|choices|cookies)/is,
|
|
12935
|
+
"manage choices",
|
|
12936
|
+
/(cookie )?preference center/is,
|
|
12937
|
+
"change settings",
|
|
12938
|
+
"configure",
|
|
12939
|
+
"change my preferences",
|
|
12940
|
+
"cookie manager",
|
|
12941
|
+
"cookie preference",
|
|
12942
|
+
"let me choose",
|
|
12943
|
+
"cookieconsent preferences",
|
|
12944
|
+
/privacy choices/is,
|
|
12945
|
+
/(privacy|cookie|custom) settings/is,
|
|
12946
|
+
/cookies? (settings|preferences|setting)/is,
|
|
12947
|
+
/(manage|customize|customise|opt-out|edit).*(cookies|preferences|settings|options)/is,
|
|
12948
|
+
"cookie consent options",
|
|
12949
|
+
"privacy controls",
|
|
12950
|
+
"show purposes",
|
|
12951
|
+
// German
|
|
12952
|
+
"einstellungen"
|
|
12953
|
+
];
|
|
12954
|
+
var ACCEPT_PATTERNS = [
|
|
12955
|
+
/^(accept|allow)( all)?( cookies)?$/is,
|
|
12956
|
+
/i (accept|allow)( all)?/is,
|
|
12957
|
+
"yes",
|
|
12958
|
+
/^(i )?agree$/is,
|
|
12959
|
+
"continue with all",
|
|
12960
|
+
"accept and continue",
|
|
12961
|
+
/accept all above/is,
|
|
12962
|
+
/^(accept|agree) and close/is,
|
|
12963
|
+
"accept continue",
|
|
12964
|
+
"agree proceed",
|
|
12965
|
+
"allow and continue",
|
|
12966
|
+
"close and accept",
|
|
12967
|
+
/accept all$/is,
|
|
12968
|
+
"im ok with that",
|
|
12969
|
+
"accept optional cookies",
|
|
12970
|
+
/^alle (cookies )?akzeptieren$/is
|
|
12971
|
+
];
|
|
12972
|
+
var ACKNOWLEDGE_PATTERNS = [
|
|
12973
|
+
"ok",
|
|
12974
|
+
"close",
|
|
12975
|
+
"continue",
|
|
12976
|
+
"x",
|
|
12977
|
+
/^got it!?$/,
|
|
12978
|
+
"i understand",
|
|
12979
|
+
"dismiss",
|
|
12980
|
+
"okay",
|
|
12981
|
+
"acknowledge",
|
|
12982
|
+
/^close (banner|cookie notification)$/is,
|
|
12983
|
+
/understood$/is,
|
|
12984
|
+
"confirm my choices"
|
|
12985
|
+
];
|
|
12914
12986
|
|
|
12915
12987
|
// lib/heuristics.ts
|
|
12916
12988
|
var BUTTON_LIKE_ELEMENT_SELECTOR = 'button, input[type="button"], input[type="submit"], a, [role="button"], [class*="button"]';
|
|
@@ -12929,48 +13001,61 @@ function checkHeuristicPatterns(allText, detectPatterns = DETECT_PATTERNS) {
|
|
|
12929
13001
|
}
|
|
12930
13002
|
return { patterns, snippets: snippets2 };
|
|
12931
13003
|
}
|
|
12932
|
-
function getActionablePopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
13004
|
+
function getActionablePopups(mode = PopupHandlingModes.Reject, timeout = POPUP_SEARCH_MAX_TIME) {
|
|
12933
13005
|
const popups = getPotentialPopups(timeout);
|
|
12934
13006
|
const result = popups.reduce((acc, popup) => {
|
|
12935
13007
|
const popupText = popup.text?.trim();
|
|
12936
13008
|
if (popupText) {
|
|
12937
13009
|
const { patterns } = checkHeuristicPatterns(popupText);
|
|
12938
13010
|
if (patterns.length > 0) {
|
|
12939
|
-
|
|
12940
|
-
|
|
12941
|
-
|
|
12942
|
-
|
|
12943
|
-
|
|
12944
|
-
otherButtons
|
|
12945
|
-
});
|
|
12946
|
-
}
|
|
13011
|
+
classifyButtons(popup.buttons);
|
|
13012
|
+
popup.regexClassification = classifyPopup(popup.buttons);
|
|
13013
|
+
acc.push({
|
|
13014
|
+
...popup
|
|
13015
|
+
});
|
|
12947
13016
|
}
|
|
12948
13017
|
}
|
|
12949
13018
|
return acc;
|
|
12950
13019
|
}, []);
|
|
12951
|
-
return result
|
|
13020
|
+
return result.filter(
|
|
13021
|
+
(popup) => popup.regexClassification !== void 0 && popup.regexClassification !== PopupHandlingModes.None && popup.regexClassification <= mode
|
|
13022
|
+
).sort((a, b) => (a.regexClassification ?? 0) - (b.regexClassification ?? 0));
|
|
12952
13023
|
}
|
|
12953
13024
|
function classifyButtons(buttons) {
|
|
12954
|
-
const rejectButtons = [];
|
|
12955
|
-
const otherButtons = [];
|
|
12956
13025
|
for (const button of buttons) {
|
|
12957
|
-
|
|
12958
|
-
rejectButtons.push(button);
|
|
12959
|
-
} else {
|
|
12960
|
-
otherButtons.push(button);
|
|
12961
|
-
}
|
|
13026
|
+
button.regexClassification = classifyButtonTextRegex(button.text);
|
|
12962
13027
|
}
|
|
12963
|
-
return {
|
|
12964
|
-
rejectButtons,
|
|
12965
|
-
otherButtons
|
|
12966
|
-
};
|
|
12967
13028
|
}
|
|
12968
|
-
function
|
|
13029
|
+
function classifyPopup(buttons) {
|
|
13030
|
+
const { reject, settings, accept, acknowledge } = buttons.reduce(
|
|
13031
|
+
(acc, button) => {
|
|
13032
|
+
if (button.regexClassification && button.regexClassification !== "other") {
|
|
13033
|
+
acc[button.regexClassification]++;
|
|
13034
|
+
}
|
|
13035
|
+
return acc;
|
|
13036
|
+
},
|
|
13037
|
+
{ reject: 0, settings: 0, accept: 0, acknowledge: 0 }
|
|
13038
|
+
);
|
|
13039
|
+
if (reject > 0) {
|
|
13040
|
+
return PopupHandlingModes.Reject;
|
|
13041
|
+
}
|
|
13042
|
+
if (settings > 0) {
|
|
13043
|
+
return PopupHandlingModes.None;
|
|
13044
|
+
}
|
|
13045
|
+
if (acknowledge > 0) {
|
|
13046
|
+
return PopupHandlingModes.Tier1;
|
|
13047
|
+
}
|
|
13048
|
+
if (accept > 0) {
|
|
13049
|
+
return accept === 1 ? PopupHandlingModes.Tier2 : PopupHandlingModes.None;
|
|
13050
|
+
}
|
|
13051
|
+
return PopupHandlingModes.None;
|
|
13052
|
+
}
|
|
13053
|
+
function testButtonMatches(buttonText, matchPatterns, neverMatchPatterns) {
|
|
12969
13054
|
if (!buttonText) {
|
|
12970
13055
|
return false;
|
|
12971
13056
|
}
|
|
12972
13057
|
const cleanedButtonText = cleanButtonText(buttonText);
|
|
12973
|
-
return !neverMatchPatterns.some((p) => p.test(cleanedButtonText)) &&
|
|
13058
|
+
return !neverMatchPatterns.some((p) => p instanceof RegExp && p.test(cleanedButtonText) || p === cleanedButtonText) && matchPatterns.some((p) => p instanceof RegExp && p.test(cleanedButtonText) || p === cleanedButtonText);
|
|
12974
13059
|
}
|
|
12975
13060
|
function cleanButtonText(buttonText) {
|
|
12976
13061
|
let result = buttonText.toLowerCase();
|
|
@@ -12984,6 +13069,21 @@ function cleanButtonText(buttonText) {
|
|
|
12984
13069
|
result = result.trim();
|
|
12985
13070
|
return result;
|
|
12986
13071
|
}
|
|
13072
|
+
function classifyButtonTextRegex(buttonText) {
|
|
13073
|
+
if (testButtonMatches(buttonText, REJECT_PATTERNS, NEVER_MATCH_PATTERNS)) {
|
|
13074
|
+
return "reject";
|
|
13075
|
+
}
|
|
13076
|
+
if (testButtonMatches(buttonText, SETTINGS_PATTERNS, NEVER_MATCH_PATTERNS)) {
|
|
13077
|
+
return "settings";
|
|
13078
|
+
}
|
|
13079
|
+
if (testButtonMatches(buttonText, ACCEPT_PATTERNS, NEVER_MATCH_PATTERNS)) {
|
|
13080
|
+
return "accept";
|
|
13081
|
+
}
|
|
13082
|
+
if (testButtonMatches(buttonText, ACKNOWLEDGE_PATTERNS, NEVER_MATCH_PATTERNS)) {
|
|
13083
|
+
return "acknowledge";
|
|
13084
|
+
}
|
|
13085
|
+
return "other";
|
|
13086
|
+
}
|
|
12987
13087
|
function getPotentialPopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
12988
13088
|
const isFramed = !isTopFrame();
|
|
12989
13089
|
if (isFramed && window.parent && window.parent !== window.top) {
|
|
@@ -13429,7 +13529,7 @@ var AutoConsentCMP = class extends AutoConsentCMPBase {
|
|
|
13429
13529
|
}
|
|
13430
13530
|
};
|
|
13431
13531
|
var AutoConsentHeuristicCMP = class extends AutoConsentCMPBase {
|
|
13432
|
-
constructor(autoconsentInstance) {
|
|
13532
|
+
constructor(autoconsentInstance, mode = PopupHandlingModes.Reject) {
|
|
13433
13533
|
super(autoconsentInstance);
|
|
13434
13534
|
this.popups = [];
|
|
13435
13535
|
this.name = "HEURISTIC";
|
|
@@ -13438,6 +13538,7 @@ var AutoConsentHeuristicCMP = class extends AutoConsentCMPBase {
|
|
|
13438
13538
|
frame: false
|
|
13439
13539
|
// do not run in iframes for security reasons
|
|
13440
13540
|
};
|
|
13541
|
+
this.mode = mode;
|
|
13441
13542
|
}
|
|
13442
13543
|
get hasSelfTest() {
|
|
13443
13544
|
return true;
|
|
@@ -13451,25 +13552,33 @@ var AutoConsentHeuristicCMP = class extends AutoConsentCMPBase {
|
|
|
13451
13552
|
async detectCmp() {
|
|
13452
13553
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
13453
13554
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorStart");
|
|
13454
|
-
this.popups = getActionablePopups(this.autoconsent.config.heuristicPopupSearchTimeout);
|
|
13555
|
+
this.popups = getActionablePopups(this.mode, this.autoconsent.config.heuristicPopupSearchTimeout);
|
|
13455
13556
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorEnd");
|
|
13456
13557
|
this.autoconsent.config.performanceLoggingEnabled && performance.measure("heuristicDetector", "heuristicDetectorStart", "heuristicDetectorEnd");
|
|
13457
13558
|
if (this.popups.length > 0) {
|
|
13559
|
+
this.name = `HEURISTIC-TIER${this.popups[0].regexClassification}`;
|
|
13458
13560
|
return Promise.resolve(true);
|
|
13459
13561
|
}
|
|
13460
13562
|
return Promise.resolve(false);
|
|
13461
13563
|
}
|
|
13462
13564
|
async detectPopup() {
|
|
13463
13565
|
if (this.popups.length > 0) {
|
|
13464
|
-
if (this.popups.length > 1
|
|
13465
|
-
this.autoconsent.config.logs.errors && console.warn("Heuristic found multiple
|
|
13566
|
+
if (this.popups.length > 1) {
|
|
13567
|
+
this.autoconsent.config.logs.errors && console.warn("Heuristic found multiple popups");
|
|
13466
13568
|
}
|
|
13467
13569
|
return true;
|
|
13468
13570
|
}
|
|
13469
13571
|
return false;
|
|
13470
13572
|
}
|
|
13573
|
+
getTargetButton() {
|
|
13574
|
+
const popup = this.popups[0];
|
|
13575
|
+
const level = popup.regexClassification;
|
|
13576
|
+
const buttons = popup.buttons;
|
|
13577
|
+
const targetButtonType = level === PopupHandlingModes.Reject ? "reject" : level === PopupHandlingModes.Tier1 ? "acknowledge" : "accept";
|
|
13578
|
+
return buttons.find((button) => button.regexClassification === targetButtonType);
|
|
13579
|
+
}
|
|
13471
13580
|
optOut() {
|
|
13472
|
-
const button = this.
|
|
13581
|
+
const button = this.getTargetButton();
|
|
13473
13582
|
if (button) {
|
|
13474
13583
|
return this.clickElement(button.element);
|
|
13475
13584
|
}
|
|
@@ -13482,7 +13591,7 @@ var AutoConsentHeuristicCMP = class extends AutoConsentCMPBase {
|
|
|
13482
13591
|
throw new Error("Not Implemented");
|
|
13483
13592
|
}
|
|
13484
13593
|
async test() {
|
|
13485
|
-
const button = this.
|
|
13594
|
+
const button = this.getTargetButton();
|
|
13486
13595
|
if (button) {
|
|
13487
13596
|
await this.wait(500);
|
|
13488
13597
|
return !isElementVisible(button.element);
|
|
@@ -14952,7 +15061,7 @@ var AutoConsent = class {
|
|
|
14952
15061
|
}
|
|
14953
15062
|
}
|
|
14954
15063
|
});
|
|
14955
|
-
const heuristicRules = isTop && this.config.enableHeuristicAction && this.state.findCmpAttempts % 2 === 0 ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
15064
|
+
const heuristicRules = isTop && this.config.enableHeuristicAction && this.state.findCmpAttempts % 2 === 0 ? [new AutoConsentHeuristicCMP(this, this.config.heuristicMode)] : [];
|
|
14956
15065
|
const rulesPriorityStages = [
|
|
14957
15066
|
["site-specific", siteSpecificRules],
|
|
14958
15067
|
["generic", genericRules],
|