@duckduckgo/autoconsent 14.92.0 → 14.94.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 +24 -0
- package/dist/addon-firefox/background.bundle.js +2 -1
- package/dist/addon-firefox/content.bundle.js +23 -26
- package/dist/addon-firefox/manifest.json +1 -1
- package/dist/addon-firefox/popup.bundle.js +2 -1
- package/dist/addon-mv3/background.bundle.js +2 -1
- package/dist/addon-mv3/content.bundle.js +23 -26
- package/dist/addon-mv3/manifest.json +1 -1
- package/dist/addon-mv3/popup.bundle.js +2 -1
- package/dist/autoconsent.cjs.js +23 -26
- package/dist/autoconsent.esm.js +23 -26
- package/dist/autoconsent.extra.cjs.js +23 -26
- package/dist/autoconsent.extra.esm.js +23 -26
- package/dist/autoconsent.playwright.js +23 -26
- package/dist/types/heuristics.d.ts +1 -1
- package/dist/types/types.d.ts +1 -0
- package/dist/types/web.d.ts +0 -1
- package/lib/cmps/base.ts +4 -2
- package/lib/heuristics.ts +13 -8
- package/lib/types.ts +1 -0
- package/lib/utils.ts +1 -0
- package/lib/web.ts +8 -22
- package/package.json +1 -1
- package/tests-wtr/lifecycle/find-cmp.ts +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
# v14.94.0 (Fri Jun 12 2026)
|
|
2
|
+
|
|
3
|
+
#### 🚀 Enhancement
|
|
4
|
+
|
|
5
|
+
- Improve heuristic detection performance [#1381](https://github.com/duckduckgo/autoconsent/pull/1381) ([@sammacbeth](https://github.com/sammacbeth))
|
|
6
|
+
|
|
7
|
+
#### Authors: 1
|
|
8
|
+
|
|
9
|
+
- Sam Macbeth ([@sammacbeth](https://github.com/sammacbeth))
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# v14.93.0 (Wed Jun 10 2026)
|
|
14
|
+
|
|
15
|
+
#### 🚀 Enhancement
|
|
16
|
+
|
|
17
|
+
- Disable per-rule performance measurement [#1389](https://github.com/duckduckgo/autoconsent/pull/1389) ([@sammacbeth](https://github.com/sammacbeth))
|
|
18
|
+
|
|
19
|
+
#### Authors: 1
|
|
20
|
+
|
|
21
|
+
- Sam Macbeth ([@sammacbeth](https://github.com/sammacbeth))
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
1
25
|
# v14.92.0 (Tue Jun 09 2026)
|
|
2
26
|
|
|
3
27
|
#### 🚀 Enhancement
|
|
@@ -712,7 +712,8 @@
|
|
|
712
712
|
messages: false,
|
|
713
713
|
waits: false
|
|
714
714
|
},
|
|
715
|
-
performanceLoggingEnabled: false
|
|
715
|
+
performanceLoggingEnabled: false,
|
|
716
|
+
heuristicPopupSearchTimeout: 100
|
|
716
717
|
};
|
|
717
718
|
const updatedConfig = copyObject(defaultConfig);
|
|
718
719
|
for (const key of Object.keys(defaultConfig)) {
|
|
@@ -708,7 +708,8 @@
|
|
|
708
708
|
messages: false,
|
|
709
709
|
waits: false
|
|
710
710
|
},
|
|
711
|
-
performanceLoggingEnabled: false
|
|
711
|
+
performanceLoggingEnabled: false,
|
|
712
|
+
heuristicPopupSearchTimeout: 100
|
|
712
713
|
};
|
|
713
714
|
const updatedConfig = copyObject(defaultConfig);
|
|
714
715
|
for (const key of Object.keys(defaultConfig)) {
|
|
@@ -1460,6 +1461,7 @@
|
|
|
1460
1461
|
// lib/heuristics.ts
|
|
1461
1462
|
var BUTTON_LIKE_ELEMENT_SELECTOR = 'button, input[type="button"], input[type="submit"], a, [role="button"], [class*="button"]';
|
|
1462
1463
|
var TEXT_LIMIT = 1e5;
|
|
1464
|
+
var POPUP_SEARCH_MAX_TIME = 100;
|
|
1463
1465
|
function checkHeuristicPatterns(allText, detectPatterns = DETECT_PATTERNS) {
|
|
1464
1466
|
allText = allText.slice(0, TEXT_LIMIT);
|
|
1465
1467
|
const patterns = [];
|
|
@@ -1473,8 +1475,8 @@
|
|
|
1473
1475
|
}
|
|
1474
1476
|
return { patterns, snippets: snippets2 };
|
|
1475
1477
|
}
|
|
1476
|
-
function getActionablePopups() {
|
|
1477
|
-
const popups = getPotentialPopups();
|
|
1478
|
+
function getActionablePopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1479
|
+
const popups = getPotentialPopups(timeout);
|
|
1478
1480
|
const result = popups.reduce((acc, popup) => {
|
|
1479
1481
|
const popupText = popup.text?.trim();
|
|
1480
1482
|
if (popupText) {
|
|
@@ -1528,17 +1530,17 @@
|
|
|
1528
1530
|
result = result.trim();
|
|
1529
1531
|
return result;
|
|
1530
1532
|
}
|
|
1531
|
-
function getPotentialPopups() {
|
|
1533
|
+
function getPotentialPopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1532
1534
|
const isFramed = !isTopFrame();
|
|
1533
1535
|
if (isFramed && window.parent && window.parent !== window.top) {
|
|
1534
1536
|
return [];
|
|
1535
1537
|
}
|
|
1536
|
-
return collectPotentialPopups(isFramed);
|
|
1538
|
+
return collectPotentialPopups(isFramed, timeout);
|
|
1537
1539
|
}
|
|
1538
|
-
function collectPotentialPopups(isFramed) {
|
|
1540
|
+
function collectPotentialPopups(isFramed, timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1539
1541
|
let elements = [];
|
|
1540
1542
|
if (!isFramed) {
|
|
1541
|
-
elements = getPopupLikeElements();
|
|
1543
|
+
elements = getPopupLikeElements(timeout);
|
|
1542
1544
|
} else {
|
|
1543
1545
|
const doc = document.body || document.documentElement;
|
|
1544
1546
|
if (doc && isElementVisible(doc) && doc.innerText) {
|
|
@@ -1566,7 +1568,8 @@
|
|
|
1566
1568
|
}
|
|
1567
1569
|
return false;
|
|
1568
1570
|
}
|
|
1569
|
-
function getPopupLikeElements() {
|
|
1571
|
+
function getPopupLikeElements(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1572
|
+
const startTime = performance.now();
|
|
1570
1573
|
const walker = document.createTreeWalker(
|
|
1571
1574
|
document.documentElement,
|
|
1572
1575
|
NodeFilter.SHOW_ELEMENT,
|
|
@@ -1585,6 +1588,9 @@
|
|
|
1585
1588
|
return NodeFilter.FILTER_ACCEPT;
|
|
1586
1589
|
}
|
|
1587
1590
|
}
|
|
1591
|
+
if (performance.now() - startTime > timeout) {
|
|
1592
|
+
return NodeFilter.FILTER_REJECT;
|
|
1593
|
+
}
|
|
1588
1594
|
return NodeFilter.FILTER_SKIP;
|
|
1589
1595
|
}
|
|
1590
1596
|
}
|
|
@@ -1988,9 +1994,10 @@
|
|
|
1988
1994
|
get isCosmetic() {
|
|
1989
1995
|
return false;
|
|
1990
1996
|
}
|
|
1991
|
-
detectCmp() {
|
|
1997
|
+
async detectCmp() {
|
|
1998
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1992
1999
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorStart");
|
|
1993
|
-
this.popups = getActionablePopups();
|
|
2000
|
+
this.popups = getActionablePopups(this.autoconsent.config.heuristicPopupSearchTimeout);
|
|
1994
2001
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorEnd");
|
|
1995
2002
|
this.autoconsent.config.performanceLoggingEnabled && performance.measure("heuristicDetector", "heuristicDetectorStart", "heuristicDetectorEnd");
|
|
1996
2003
|
if (this.popups.length > 0) {
|
|
@@ -3490,7 +3497,7 @@
|
|
|
3490
3497
|
}
|
|
3491
3498
|
}
|
|
3492
3499
|
});
|
|
3493
|
-
const heuristicRules = isTop && this.config.enableHeuristicAction ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
3500
|
+
const heuristicRules = isTop && this.config.enableHeuristicAction && this.state.findCmpAttempts % 2 === 0 ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
3494
3501
|
const rulesPriorityStages = [
|
|
3495
3502
|
["site-specific", siteSpecificRules],
|
|
3496
3503
|
["generic", genericRules],
|
|
@@ -3498,10 +3505,7 @@
|
|
|
3498
3505
|
];
|
|
3499
3506
|
const runDetectCmp = async (cmp) => {
|
|
3500
3507
|
try {
|
|
3501
|
-
this.config.performanceLoggingEnabled && performance.mark(`detectCmp_${cmp.name}`);
|
|
3502
3508
|
const result = await cmp.detectCmp();
|
|
3503
|
-
this.config.performanceLoggingEnabled && performance.mark(`detectCmpEnd_${cmp.name}`);
|
|
3504
|
-
this.config.performanceLoggingEnabled && performance.measure(`detectCmp_${cmp.name}`, `detectCmp_${cmp.name}`, `detectCmpEnd_${cmp.name}`);
|
|
3505
3509
|
if (result) {
|
|
3506
3510
|
logsConfig.lifecycle && console.log(`Found CMP: ${cmp.name} ${window.location.href}`);
|
|
3507
3511
|
this.sendContentMessage({
|
|
@@ -3533,8 +3537,12 @@
|
|
|
3533
3537
|
}
|
|
3534
3538
|
this.detectHeuristics();
|
|
3535
3539
|
if (foundCMPs.length === 0 && retries > 0) {
|
|
3540
|
+
const waitFor2 = [this.domActions.wait(500)];
|
|
3541
|
+
if (this.state.findCmpAttempts > 1) {
|
|
3542
|
+
waitFor2.push(mutationObserver);
|
|
3543
|
+
}
|
|
3536
3544
|
try {
|
|
3537
|
-
await Promise.all(
|
|
3545
|
+
await Promise.all(waitFor2);
|
|
3538
3546
|
} catch (e) {
|
|
3539
3547
|
return [];
|
|
3540
3548
|
}
|
|
@@ -3829,17 +3837,6 @@
|
|
|
3829
3837
|
parseDeclarativeRules: getRoundedPerformanceEntries("parseDeclarativeRules")
|
|
3830
3838
|
};
|
|
3831
3839
|
}
|
|
3832
|
-
measureDetailedRulePerformance() {
|
|
3833
|
-
const cmpPerformance = performance.getEntriesByType("measure").filter((m) => m.name.startsWith("detectCmp_")).reduce((acc, m) => {
|
|
3834
|
-
const k = m.name.slice(10);
|
|
3835
|
-
if (!acc[k]) {
|
|
3836
|
-
acc[k] = 0;
|
|
3837
|
-
}
|
|
3838
|
-
acc[k] += m.duration;
|
|
3839
|
-
return acc;
|
|
3840
|
-
}, /* @__PURE__ */ Object.create(null));
|
|
3841
|
-
return cmpPerformance;
|
|
3842
|
-
}
|
|
3843
3840
|
};
|
|
3844
3841
|
|
|
3845
3842
|
// addon/content.ts
|
|
@@ -539,7 +539,8 @@
|
|
|
539
539
|
messages: false,
|
|
540
540
|
waits: false
|
|
541
541
|
},
|
|
542
|
-
performanceLoggingEnabled: false
|
|
542
|
+
performanceLoggingEnabled: false,
|
|
543
|
+
heuristicPopupSearchTimeout: 100
|
|
543
544
|
};
|
|
544
545
|
const updatedConfig = copyObject(defaultConfig);
|
|
545
546
|
for (const key of Object.keys(defaultConfig)) {
|
|
@@ -712,7 +712,8 @@
|
|
|
712
712
|
messages: false,
|
|
713
713
|
waits: false
|
|
714
714
|
},
|
|
715
|
-
performanceLoggingEnabled: false
|
|
715
|
+
performanceLoggingEnabled: false,
|
|
716
|
+
heuristicPopupSearchTimeout: 100
|
|
716
717
|
};
|
|
717
718
|
const updatedConfig = copyObject(defaultConfig);
|
|
718
719
|
for (const key of Object.keys(defaultConfig)) {
|
|
@@ -708,7 +708,8 @@
|
|
|
708
708
|
messages: false,
|
|
709
709
|
waits: false
|
|
710
710
|
},
|
|
711
|
-
performanceLoggingEnabled: false
|
|
711
|
+
performanceLoggingEnabled: false,
|
|
712
|
+
heuristicPopupSearchTimeout: 100
|
|
712
713
|
};
|
|
713
714
|
const updatedConfig = copyObject(defaultConfig);
|
|
714
715
|
for (const key of Object.keys(defaultConfig)) {
|
|
@@ -1460,6 +1461,7 @@
|
|
|
1460
1461
|
// lib/heuristics.ts
|
|
1461
1462
|
var BUTTON_LIKE_ELEMENT_SELECTOR = 'button, input[type="button"], input[type="submit"], a, [role="button"], [class*="button"]';
|
|
1462
1463
|
var TEXT_LIMIT = 1e5;
|
|
1464
|
+
var POPUP_SEARCH_MAX_TIME = 100;
|
|
1463
1465
|
function checkHeuristicPatterns(allText, detectPatterns = DETECT_PATTERNS) {
|
|
1464
1466
|
allText = allText.slice(0, TEXT_LIMIT);
|
|
1465
1467
|
const patterns = [];
|
|
@@ -1473,8 +1475,8 @@
|
|
|
1473
1475
|
}
|
|
1474
1476
|
return { patterns, snippets: snippets2 };
|
|
1475
1477
|
}
|
|
1476
|
-
function getActionablePopups() {
|
|
1477
|
-
const popups = getPotentialPopups();
|
|
1478
|
+
function getActionablePopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1479
|
+
const popups = getPotentialPopups(timeout);
|
|
1478
1480
|
const result = popups.reduce((acc, popup) => {
|
|
1479
1481
|
const popupText = popup.text?.trim();
|
|
1480
1482
|
if (popupText) {
|
|
@@ -1528,17 +1530,17 @@
|
|
|
1528
1530
|
result = result.trim();
|
|
1529
1531
|
return result;
|
|
1530
1532
|
}
|
|
1531
|
-
function getPotentialPopups() {
|
|
1533
|
+
function getPotentialPopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1532
1534
|
const isFramed = !isTopFrame();
|
|
1533
1535
|
if (isFramed && window.parent && window.parent !== window.top) {
|
|
1534
1536
|
return [];
|
|
1535
1537
|
}
|
|
1536
|
-
return collectPotentialPopups(isFramed);
|
|
1538
|
+
return collectPotentialPopups(isFramed, timeout);
|
|
1537
1539
|
}
|
|
1538
|
-
function collectPotentialPopups(isFramed) {
|
|
1540
|
+
function collectPotentialPopups(isFramed, timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1539
1541
|
let elements = [];
|
|
1540
1542
|
if (!isFramed) {
|
|
1541
|
-
elements = getPopupLikeElements();
|
|
1543
|
+
elements = getPopupLikeElements(timeout);
|
|
1542
1544
|
} else {
|
|
1543
1545
|
const doc = document.body || document.documentElement;
|
|
1544
1546
|
if (doc && isElementVisible(doc) && doc.innerText) {
|
|
@@ -1566,7 +1568,8 @@
|
|
|
1566
1568
|
}
|
|
1567
1569
|
return false;
|
|
1568
1570
|
}
|
|
1569
|
-
function getPopupLikeElements() {
|
|
1571
|
+
function getPopupLikeElements(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1572
|
+
const startTime = performance.now();
|
|
1570
1573
|
const walker = document.createTreeWalker(
|
|
1571
1574
|
document.documentElement,
|
|
1572
1575
|
NodeFilter.SHOW_ELEMENT,
|
|
@@ -1585,6 +1588,9 @@
|
|
|
1585
1588
|
return NodeFilter.FILTER_ACCEPT;
|
|
1586
1589
|
}
|
|
1587
1590
|
}
|
|
1591
|
+
if (performance.now() - startTime > timeout) {
|
|
1592
|
+
return NodeFilter.FILTER_REJECT;
|
|
1593
|
+
}
|
|
1588
1594
|
return NodeFilter.FILTER_SKIP;
|
|
1589
1595
|
}
|
|
1590
1596
|
}
|
|
@@ -1988,9 +1994,10 @@
|
|
|
1988
1994
|
get isCosmetic() {
|
|
1989
1995
|
return false;
|
|
1990
1996
|
}
|
|
1991
|
-
detectCmp() {
|
|
1997
|
+
async detectCmp() {
|
|
1998
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1992
1999
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorStart");
|
|
1993
|
-
this.popups = getActionablePopups();
|
|
2000
|
+
this.popups = getActionablePopups(this.autoconsent.config.heuristicPopupSearchTimeout);
|
|
1994
2001
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorEnd");
|
|
1995
2002
|
this.autoconsent.config.performanceLoggingEnabled && performance.measure("heuristicDetector", "heuristicDetectorStart", "heuristicDetectorEnd");
|
|
1996
2003
|
if (this.popups.length > 0) {
|
|
@@ -3490,7 +3497,7 @@
|
|
|
3490
3497
|
}
|
|
3491
3498
|
}
|
|
3492
3499
|
});
|
|
3493
|
-
const heuristicRules = isTop && this.config.enableHeuristicAction ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
3500
|
+
const heuristicRules = isTop && this.config.enableHeuristicAction && this.state.findCmpAttempts % 2 === 0 ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
3494
3501
|
const rulesPriorityStages = [
|
|
3495
3502
|
["site-specific", siteSpecificRules],
|
|
3496
3503
|
["generic", genericRules],
|
|
@@ -3498,10 +3505,7 @@
|
|
|
3498
3505
|
];
|
|
3499
3506
|
const runDetectCmp = async (cmp) => {
|
|
3500
3507
|
try {
|
|
3501
|
-
this.config.performanceLoggingEnabled && performance.mark(`detectCmp_${cmp.name}`);
|
|
3502
3508
|
const result = await cmp.detectCmp();
|
|
3503
|
-
this.config.performanceLoggingEnabled && performance.mark(`detectCmpEnd_${cmp.name}`);
|
|
3504
|
-
this.config.performanceLoggingEnabled && performance.measure(`detectCmp_${cmp.name}`, `detectCmp_${cmp.name}`, `detectCmpEnd_${cmp.name}`);
|
|
3505
3509
|
if (result) {
|
|
3506
3510
|
logsConfig.lifecycle && console.log(`Found CMP: ${cmp.name} ${window.location.href}`);
|
|
3507
3511
|
this.sendContentMessage({
|
|
@@ -3533,8 +3537,12 @@
|
|
|
3533
3537
|
}
|
|
3534
3538
|
this.detectHeuristics();
|
|
3535
3539
|
if (foundCMPs.length === 0 && retries > 0) {
|
|
3540
|
+
const waitFor2 = [this.domActions.wait(500)];
|
|
3541
|
+
if (this.state.findCmpAttempts > 1) {
|
|
3542
|
+
waitFor2.push(mutationObserver);
|
|
3543
|
+
}
|
|
3536
3544
|
try {
|
|
3537
|
-
await Promise.all(
|
|
3545
|
+
await Promise.all(waitFor2);
|
|
3538
3546
|
} catch (e) {
|
|
3539
3547
|
return [];
|
|
3540
3548
|
}
|
|
@@ -3829,17 +3837,6 @@
|
|
|
3829
3837
|
parseDeclarativeRules: getRoundedPerformanceEntries("parseDeclarativeRules")
|
|
3830
3838
|
};
|
|
3831
3839
|
}
|
|
3832
|
-
measureDetailedRulePerformance() {
|
|
3833
|
-
const cmpPerformance = performance.getEntriesByType("measure").filter((m) => m.name.startsWith("detectCmp_")).reduce((acc, m) => {
|
|
3834
|
-
const k = m.name.slice(10);
|
|
3835
|
-
if (!acc[k]) {
|
|
3836
|
-
acc[k] = 0;
|
|
3837
|
-
}
|
|
3838
|
-
acc[k] += m.duration;
|
|
3839
|
-
return acc;
|
|
3840
|
-
}, /* @__PURE__ */ Object.create(null));
|
|
3841
|
-
return cmpPerformance;
|
|
3842
|
-
}
|
|
3843
3840
|
};
|
|
3844
3841
|
|
|
3845
3842
|
// addon/content.ts
|
|
@@ -539,7 +539,8 @@
|
|
|
539
539
|
messages: false,
|
|
540
540
|
waits: false
|
|
541
541
|
},
|
|
542
|
-
performanceLoggingEnabled: false
|
|
542
|
+
performanceLoggingEnabled: false,
|
|
543
|
+
heuristicPopupSearchTimeout: 100
|
|
543
544
|
};
|
|
544
545
|
const updatedConfig = copyObject(defaultConfig);
|
|
545
546
|
for (const key of Object.keys(defaultConfig)) {
|
package/dist/autoconsent.cjs.js
CHANGED
|
@@ -743,7 +743,8 @@ function normalizeConfig(providedConfig) {
|
|
|
743
743
|
messages: false,
|
|
744
744
|
waits: false
|
|
745
745
|
},
|
|
746
|
-
performanceLoggingEnabled: false
|
|
746
|
+
performanceLoggingEnabled: false,
|
|
747
|
+
heuristicPopupSearchTimeout: 100
|
|
747
748
|
};
|
|
748
749
|
const updatedConfig = copyObject(defaultConfig);
|
|
749
750
|
for (const key of Object.keys(defaultConfig)) {
|
|
@@ -1495,6 +1496,7 @@ var NEVER_MATCH_PATTERNS = [
|
|
|
1495
1496
|
// lib/heuristics.ts
|
|
1496
1497
|
var BUTTON_LIKE_ELEMENT_SELECTOR = 'button, input[type="button"], input[type="submit"], a, [role="button"], [class*="button"]';
|
|
1497
1498
|
var TEXT_LIMIT = 1e5;
|
|
1499
|
+
var POPUP_SEARCH_MAX_TIME = 100;
|
|
1498
1500
|
function checkHeuristicPatterns(allText, detectPatterns = DETECT_PATTERNS) {
|
|
1499
1501
|
allText = allText.slice(0, TEXT_LIMIT);
|
|
1500
1502
|
const patterns = [];
|
|
@@ -1508,8 +1510,8 @@ function checkHeuristicPatterns(allText, detectPatterns = DETECT_PATTERNS) {
|
|
|
1508
1510
|
}
|
|
1509
1511
|
return { patterns, snippets: snippets2 };
|
|
1510
1512
|
}
|
|
1511
|
-
function getActionablePopups() {
|
|
1512
|
-
const popups = getPotentialPopups();
|
|
1513
|
+
function getActionablePopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1514
|
+
const popups = getPotentialPopups(timeout);
|
|
1513
1515
|
const result = popups.reduce((acc, popup) => {
|
|
1514
1516
|
const popupText = popup.text?.trim();
|
|
1515
1517
|
if (popupText) {
|
|
@@ -1563,17 +1565,17 @@ function cleanButtonText(buttonText) {
|
|
|
1563
1565
|
result = result.trim();
|
|
1564
1566
|
return result;
|
|
1565
1567
|
}
|
|
1566
|
-
function getPotentialPopups() {
|
|
1568
|
+
function getPotentialPopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1567
1569
|
const isFramed = !isTopFrame();
|
|
1568
1570
|
if (isFramed && window.parent && window.parent !== window.top) {
|
|
1569
1571
|
return [];
|
|
1570
1572
|
}
|
|
1571
|
-
return collectPotentialPopups(isFramed);
|
|
1573
|
+
return collectPotentialPopups(isFramed, timeout);
|
|
1572
1574
|
}
|
|
1573
|
-
function collectPotentialPopups(isFramed) {
|
|
1575
|
+
function collectPotentialPopups(isFramed, timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1574
1576
|
let elements = [];
|
|
1575
1577
|
if (!isFramed) {
|
|
1576
|
-
elements = getPopupLikeElements();
|
|
1578
|
+
elements = getPopupLikeElements(timeout);
|
|
1577
1579
|
} else {
|
|
1578
1580
|
const doc = document.body || document.documentElement;
|
|
1579
1581
|
if (doc && isElementVisible(doc) && doc.innerText) {
|
|
@@ -1601,7 +1603,8 @@ function isDialogLikeElement(node) {
|
|
|
1601
1603
|
}
|
|
1602
1604
|
return false;
|
|
1603
1605
|
}
|
|
1604
|
-
function getPopupLikeElements() {
|
|
1606
|
+
function getPopupLikeElements(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1607
|
+
const startTime = performance.now();
|
|
1605
1608
|
const walker = document.createTreeWalker(
|
|
1606
1609
|
document.documentElement,
|
|
1607
1610
|
NodeFilter.SHOW_ELEMENT,
|
|
@@ -1620,6 +1623,9 @@ function getPopupLikeElements() {
|
|
|
1620
1623
|
return NodeFilter.FILTER_ACCEPT;
|
|
1621
1624
|
}
|
|
1622
1625
|
}
|
|
1626
|
+
if (performance.now() - startTime > timeout) {
|
|
1627
|
+
return NodeFilter.FILTER_REJECT;
|
|
1628
|
+
}
|
|
1623
1629
|
return NodeFilter.FILTER_SKIP;
|
|
1624
1630
|
}
|
|
1625
1631
|
}
|
|
@@ -2023,9 +2029,10 @@ var AutoConsentHeuristicCMP = class extends AutoConsentCMPBase {
|
|
|
2023
2029
|
get isCosmetic() {
|
|
2024
2030
|
return false;
|
|
2025
2031
|
}
|
|
2026
|
-
detectCmp() {
|
|
2032
|
+
async detectCmp() {
|
|
2033
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
2027
2034
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorStart");
|
|
2028
|
-
this.popups = getActionablePopups();
|
|
2035
|
+
this.popups = getActionablePopups(this.autoconsent.config.heuristicPopupSearchTimeout);
|
|
2029
2036
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorEnd");
|
|
2030
2037
|
this.autoconsent.config.performanceLoggingEnabled && performance.measure("heuristicDetector", "heuristicDetectorStart", "heuristicDetectorEnd");
|
|
2031
2038
|
if (this.popups.length > 0) {
|
|
@@ -3758,7 +3765,7 @@ var AutoConsent = class {
|
|
|
3758
3765
|
}
|
|
3759
3766
|
}
|
|
3760
3767
|
});
|
|
3761
|
-
const heuristicRules = isTop && this.config.enableHeuristicAction ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
3768
|
+
const heuristicRules = isTop && this.config.enableHeuristicAction && this.state.findCmpAttempts % 2 === 0 ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
3762
3769
|
const rulesPriorityStages = [
|
|
3763
3770
|
["site-specific", siteSpecificRules],
|
|
3764
3771
|
["generic", genericRules],
|
|
@@ -3766,10 +3773,7 @@ var AutoConsent = class {
|
|
|
3766
3773
|
];
|
|
3767
3774
|
const runDetectCmp = async (cmp) => {
|
|
3768
3775
|
try {
|
|
3769
|
-
this.config.performanceLoggingEnabled && performance.mark(`detectCmp_${cmp.name}`);
|
|
3770
3776
|
const result = await cmp.detectCmp();
|
|
3771
|
-
this.config.performanceLoggingEnabled && performance.mark(`detectCmpEnd_${cmp.name}`);
|
|
3772
|
-
this.config.performanceLoggingEnabled && performance.measure(`detectCmp_${cmp.name}`, `detectCmp_${cmp.name}`, `detectCmpEnd_${cmp.name}`);
|
|
3773
3777
|
if (result) {
|
|
3774
3778
|
logsConfig.lifecycle && console.log(`Found CMP: ${cmp.name} ${window.location.href}`);
|
|
3775
3779
|
this.sendContentMessage({
|
|
@@ -3801,8 +3805,12 @@ var AutoConsent = class {
|
|
|
3801
3805
|
}
|
|
3802
3806
|
this.detectHeuristics();
|
|
3803
3807
|
if (foundCMPs.length === 0 && retries > 0) {
|
|
3808
|
+
const waitFor2 = [this.domActions.wait(500)];
|
|
3809
|
+
if (this.state.findCmpAttempts > 1) {
|
|
3810
|
+
waitFor2.push(mutationObserver);
|
|
3811
|
+
}
|
|
3804
3812
|
try {
|
|
3805
|
-
await Promise.all(
|
|
3813
|
+
await Promise.all(waitFor2);
|
|
3806
3814
|
} catch (e) {
|
|
3807
3815
|
return [];
|
|
3808
3816
|
}
|
|
@@ -4097,17 +4105,6 @@ var AutoConsent = class {
|
|
|
4097
4105
|
parseDeclarativeRules: getRoundedPerformanceEntries("parseDeclarativeRules")
|
|
4098
4106
|
};
|
|
4099
4107
|
}
|
|
4100
|
-
measureDetailedRulePerformance() {
|
|
4101
|
-
const cmpPerformance = performance.getEntriesByType("measure").filter((m) => m.name.startsWith("detectCmp_")).reduce((acc, m) => {
|
|
4102
|
-
const k = m.name.slice(10);
|
|
4103
|
-
if (!acc[k]) {
|
|
4104
|
-
acc[k] = 0;
|
|
4105
|
-
}
|
|
4106
|
-
acc[k] += m.duration;
|
|
4107
|
-
return acc;
|
|
4108
|
-
}, /* @__PURE__ */ Object.create(null));
|
|
4109
|
-
return cmpPerformance;
|
|
4110
|
-
}
|
|
4111
4108
|
};
|
|
4112
4109
|
_config = new WeakMap();
|
|
4113
4110
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/autoconsent.esm.js
CHANGED
|
@@ -713,7 +713,8 @@ function normalizeConfig(providedConfig) {
|
|
|
713
713
|
messages: false,
|
|
714
714
|
waits: false
|
|
715
715
|
},
|
|
716
|
-
performanceLoggingEnabled: false
|
|
716
|
+
performanceLoggingEnabled: false,
|
|
717
|
+
heuristicPopupSearchTimeout: 100
|
|
717
718
|
};
|
|
718
719
|
const updatedConfig = copyObject(defaultConfig);
|
|
719
720
|
for (const key of Object.keys(defaultConfig)) {
|
|
@@ -1465,6 +1466,7 @@ var NEVER_MATCH_PATTERNS = [
|
|
|
1465
1466
|
// lib/heuristics.ts
|
|
1466
1467
|
var BUTTON_LIKE_ELEMENT_SELECTOR = 'button, input[type="button"], input[type="submit"], a, [role="button"], [class*="button"]';
|
|
1467
1468
|
var TEXT_LIMIT = 1e5;
|
|
1469
|
+
var POPUP_SEARCH_MAX_TIME = 100;
|
|
1468
1470
|
function checkHeuristicPatterns(allText, detectPatterns = DETECT_PATTERNS) {
|
|
1469
1471
|
allText = allText.slice(0, TEXT_LIMIT);
|
|
1470
1472
|
const patterns = [];
|
|
@@ -1478,8 +1480,8 @@ function checkHeuristicPatterns(allText, detectPatterns = DETECT_PATTERNS) {
|
|
|
1478
1480
|
}
|
|
1479
1481
|
return { patterns, snippets: snippets2 };
|
|
1480
1482
|
}
|
|
1481
|
-
function getActionablePopups() {
|
|
1482
|
-
const popups = getPotentialPopups();
|
|
1483
|
+
function getActionablePopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1484
|
+
const popups = getPotentialPopups(timeout);
|
|
1483
1485
|
const result = popups.reduce((acc, popup) => {
|
|
1484
1486
|
const popupText = popup.text?.trim();
|
|
1485
1487
|
if (popupText) {
|
|
@@ -1533,17 +1535,17 @@ function cleanButtonText(buttonText) {
|
|
|
1533
1535
|
result = result.trim();
|
|
1534
1536
|
return result;
|
|
1535
1537
|
}
|
|
1536
|
-
function getPotentialPopups() {
|
|
1538
|
+
function getPotentialPopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1537
1539
|
const isFramed = !isTopFrame();
|
|
1538
1540
|
if (isFramed && window.parent && window.parent !== window.top) {
|
|
1539
1541
|
return [];
|
|
1540
1542
|
}
|
|
1541
|
-
return collectPotentialPopups(isFramed);
|
|
1543
|
+
return collectPotentialPopups(isFramed, timeout);
|
|
1542
1544
|
}
|
|
1543
|
-
function collectPotentialPopups(isFramed) {
|
|
1545
|
+
function collectPotentialPopups(isFramed, timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1544
1546
|
let elements = [];
|
|
1545
1547
|
if (!isFramed) {
|
|
1546
|
-
elements = getPopupLikeElements();
|
|
1548
|
+
elements = getPopupLikeElements(timeout);
|
|
1547
1549
|
} else {
|
|
1548
1550
|
const doc = document.body || document.documentElement;
|
|
1549
1551
|
if (doc && isElementVisible(doc) && doc.innerText) {
|
|
@@ -1571,7 +1573,8 @@ function isDialogLikeElement(node) {
|
|
|
1571
1573
|
}
|
|
1572
1574
|
return false;
|
|
1573
1575
|
}
|
|
1574
|
-
function getPopupLikeElements() {
|
|
1576
|
+
function getPopupLikeElements(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1577
|
+
const startTime = performance.now();
|
|
1575
1578
|
const walker = document.createTreeWalker(
|
|
1576
1579
|
document.documentElement,
|
|
1577
1580
|
NodeFilter.SHOW_ELEMENT,
|
|
@@ -1590,6 +1593,9 @@ function getPopupLikeElements() {
|
|
|
1590
1593
|
return NodeFilter.FILTER_ACCEPT;
|
|
1591
1594
|
}
|
|
1592
1595
|
}
|
|
1596
|
+
if (performance.now() - startTime > timeout) {
|
|
1597
|
+
return NodeFilter.FILTER_REJECT;
|
|
1598
|
+
}
|
|
1593
1599
|
return NodeFilter.FILTER_SKIP;
|
|
1594
1600
|
}
|
|
1595
1601
|
}
|
|
@@ -1993,9 +1999,10 @@ var AutoConsentHeuristicCMP = class extends AutoConsentCMPBase {
|
|
|
1993
1999
|
get isCosmetic() {
|
|
1994
2000
|
return false;
|
|
1995
2001
|
}
|
|
1996
|
-
detectCmp() {
|
|
2002
|
+
async detectCmp() {
|
|
2003
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1997
2004
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorStart");
|
|
1998
|
-
this.popups = getActionablePopups();
|
|
2005
|
+
this.popups = getActionablePopups(this.autoconsent.config.heuristicPopupSearchTimeout);
|
|
1999
2006
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorEnd");
|
|
2000
2007
|
this.autoconsent.config.performanceLoggingEnabled && performance.measure("heuristicDetector", "heuristicDetectorStart", "heuristicDetectorEnd");
|
|
2001
2008
|
if (this.popups.length > 0) {
|
|
@@ -3728,7 +3735,7 @@ var AutoConsent = class {
|
|
|
3728
3735
|
}
|
|
3729
3736
|
}
|
|
3730
3737
|
});
|
|
3731
|
-
const heuristicRules = isTop && this.config.enableHeuristicAction ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
3738
|
+
const heuristicRules = isTop && this.config.enableHeuristicAction && this.state.findCmpAttempts % 2 === 0 ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
3732
3739
|
const rulesPriorityStages = [
|
|
3733
3740
|
["site-specific", siteSpecificRules],
|
|
3734
3741
|
["generic", genericRules],
|
|
@@ -3736,10 +3743,7 @@ var AutoConsent = class {
|
|
|
3736
3743
|
];
|
|
3737
3744
|
const runDetectCmp = async (cmp) => {
|
|
3738
3745
|
try {
|
|
3739
|
-
this.config.performanceLoggingEnabled && performance.mark(`detectCmp_${cmp.name}`);
|
|
3740
3746
|
const result = await cmp.detectCmp();
|
|
3741
|
-
this.config.performanceLoggingEnabled && performance.mark(`detectCmpEnd_${cmp.name}`);
|
|
3742
|
-
this.config.performanceLoggingEnabled && performance.measure(`detectCmp_${cmp.name}`, `detectCmp_${cmp.name}`, `detectCmpEnd_${cmp.name}`);
|
|
3743
3747
|
if (result) {
|
|
3744
3748
|
logsConfig.lifecycle && console.log(`Found CMP: ${cmp.name} ${window.location.href}`);
|
|
3745
3749
|
this.sendContentMessage({
|
|
@@ -3771,8 +3775,12 @@ var AutoConsent = class {
|
|
|
3771
3775
|
}
|
|
3772
3776
|
this.detectHeuristics();
|
|
3773
3777
|
if (foundCMPs.length === 0 && retries > 0) {
|
|
3778
|
+
const waitFor2 = [this.domActions.wait(500)];
|
|
3779
|
+
if (this.state.findCmpAttempts > 1) {
|
|
3780
|
+
waitFor2.push(mutationObserver);
|
|
3781
|
+
}
|
|
3774
3782
|
try {
|
|
3775
|
-
await Promise.all(
|
|
3783
|
+
await Promise.all(waitFor2);
|
|
3776
3784
|
} catch (e) {
|
|
3777
3785
|
return [];
|
|
3778
3786
|
}
|
|
@@ -4067,17 +4075,6 @@ var AutoConsent = class {
|
|
|
4067
4075
|
parseDeclarativeRules: getRoundedPerformanceEntries("parseDeclarativeRules")
|
|
4068
4076
|
};
|
|
4069
4077
|
}
|
|
4070
|
-
measureDetailedRulePerformance() {
|
|
4071
|
-
const cmpPerformance = performance.getEntriesByType("measure").filter((m) => m.name.startsWith("detectCmp_")).reduce((acc, m) => {
|
|
4072
|
-
const k = m.name.slice(10);
|
|
4073
|
-
if (!acc[k]) {
|
|
4074
|
-
acc[k] = 0;
|
|
4075
|
-
}
|
|
4076
|
-
acc[k] += m.duration;
|
|
4077
|
-
return acc;
|
|
4078
|
-
}, /* @__PURE__ */ Object.create(null));
|
|
4079
|
-
return cmpPerformance;
|
|
4080
|
-
}
|
|
4081
4078
|
};
|
|
4082
4079
|
_config = new WeakMap();
|
|
4083
4080
|
export {
|
|
@@ -11306,7 +11306,8 @@ function normalizeConfig(providedConfig) {
|
|
|
11306
11306
|
messages: false,
|
|
11307
11307
|
waits: false
|
|
11308
11308
|
},
|
|
11309
|
-
performanceLoggingEnabled: false
|
|
11309
|
+
performanceLoggingEnabled: false,
|
|
11310
|
+
heuristicPopupSearchTimeout: 100
|
|
11310
11311
|
};
|
|
11311
11312
|
const updatedConfig = copyObject(defaultConfig);
|
|
11312
11313
|
for (const key of Object.keys(defaultConfig)) {
|
|
@@ -12725,6 +12726,7 @@ var NEVER_MATCH_PATTERNS = [
|
|
|
12725
12726
|
// lib/heuristics.ts
|
|
12726
12727
|
var BUTTON_LIKE_ELEMENT_SELECTOR = 'button, input[type="button"], input[type="submit"], a, [role="button"], [class*="button"]';
|
|
12727
12728
|
var TEXT_LIMIT = 1e5;
|
|
12729
|
+
var POPUP_SEARCH_MAX_TIME = 100;
|
|
12728
12730
|
function checkHeuristicPatterns(allText, detectPatterns = DETECT_PATTERNS) {
|
|
12729
12731
|
allText = allText.slice(0, TEXT_LIMIT);
|
|
12730
12732
|
const patterns = [];
|
|
@@ -12738,8 +12740,8 @@ function checkHeuristicPatterns(allText, detectPatterns = DETECT_PATTERNS) {
|
|
|
12738
12740
|
}
|
|
12739
12741
|
return { patterns, snippets: snippets2 };
|
|
12740
12742
|
}
|
|
12741
|
-
function getActionablePopups() {
|
|
12742
|
-
const popups = getPotentialPopups();
|
|
12743
|
+
function getActionablePopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
12744
|
+
const popups = getPotentialPopups(timeout);
|
|
12743
12745
|
const result = popups.reduce((acc, popup) => {
|
|
12744
12746
|
const popupText = popup.text?.trim();
|
|
12745
12747
|
if (popupText) {
|
|
@@ -12793,17 +12795,17 @@ function cleanButtonText(buttonText) {
|
|
|
12793
12795
|
result = result.trim();
|
|
12794
12796
|
return result;
|
|
12795
12797
|
}
|
|
12796
|
-
function getPotentialPopups() {
|
|
12798
|
+
function getPotentialPopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
12797
12799
|
const isFramed = !isTopFrame();
|
|
12798
12800
|
if (isFramed && window.parent && window.parent !== window.top) {
|
|
12799
12801
|
return [];
|
|
12800
12802
|
}
|
|
12801
|
-
return collectPotentialPopups(isFramed);
|
|
12803
|
+
return collectPotentialPopups(isFramed, timeout);
|
|
12802
12804
|
}
|
|
12803
|
-
function collectPotentialPopups(isFramed) {
|
|
12805
|
+
function collectPotentialPopups(isFramed, timeout = POPUP_SEARCH_MAX_TIME) {
|
|
12804
12806
|
let elements = [];
|
|
12805
12807
|
if (!isFramed) {
|
|
12806
|
-
elements = getPopupLikeElements();
|
|
12808
|
+
elements = getPopupLikeElements(timeout);
|
|
12807
12809
|
} else {
|
|
12808
12810
|
const doc = document.body || document.documentElement;
|
|
12809
12811
|
if (doc && isElementVisible(doc) && doc.innerText) {
|
|
@@ -12831,7 +12833,8 @@ function isDialogLikeElement(node) {
|
|
|
12831
12833
|
}
|
|
12832
12834
|
return false;
|
|
12833
12835
|
}
|
|
12834
|
-
function getPopupLikeElements() {
|
|
12836
|
+
function getPopupLikeElements(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
12837
|
+
const startTime = performance.now();
|
|
12835
12838
|
const walker = document.createTreeWalker(
|
|
12836
12839
|
document.documentElement,
|
|
12837
12840
|
NodeFilter.SHOW_ELEMENT,
|
|
@@ -12850,6 +12853,9 @@ function getPopupLikeElements() {
|
|
|
12850
12853
|
return NodeFilter.FILTER_ACCEPT;
|
|
12851
12854
|
}
|
|
12852
12855
|
}
|
|
12856
|
+
if (performance.now() - startTime > timeout) {
|
|
12857
|
+
return NodeFilter.FILTER_REJECT;
|
|
12858
|
+
}
|
|
12853
12859
|
return NodeFilter.FILTER_SKIP;
|
|
12854
12860
|
}
|
|
12855
12861
|
}
|
|
@@ -13253,9 +13259,10 @@ var AutoConsentHeuristicCMP = class extends AutoConsentCMPBase {
|
|
|
13253
13259
|
get isCosmetic() {
|
|
13254
13260
|
return false;
|
|
13255
13261
|
}
|
|
13256
|
-
detectCmp() {
|
|
13262
|
+
async detectCmp() {
|
|
13263
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
13257
13264
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorStart");
|
|
13258
|
-
this.popups = getActionablePopups();
|
|
13265
|
+
this.popups = getActionablePopups(this.autoconsent.config.heuristicPopupSearchTimeout);
|
|
13259
13266
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorEnd");
|
|
13260
13267
|
this.autoconsent.config.performanceLoggingEnabled && performance.measure("heuristicDetector", "heuristicDetectorStart", "heuristicDetectorEnd");
|
|
13261
13268
|
if (this.popups.length > 0) {
|
|
@@ -14756,7 +14763,7 @@ var AutoConsent = class {
|
|
|
14756
14763
|
}
|
|
14757
14764
|
}
|
|
14758
14765
|
});
|
|
14759
|
-
const heuristicRules = isTop && this.config.enableHeuristicAction ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
14766
|
+
const heuristicRules = isTop && this.config.enableHeuristicAction && this.state.findCmpAttempts % 2 === 0 ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
14760
14767
|
const rulesPriorityStages = [
|
|
14761
14768
|
["site-specific", siteSpecificRules],
|
|
14762
14769
|
["generic", genericRules],
|
|
@@ -14764,10 +14771,7 @@ var AutoConsent = class {
|
|
|
14764
14771
|
];
|
|
14765
14772
|
const runDetectCmp = async (cmp) => {
|
|
14766
14773
|
try {
|
|
14767
|
-
this.config.performanceLoggingEnabled && performance.mark(`detectCmp_${cmp.name}`);
|
|
14768
14774
|
const result = await cmp.detectCmp();
|
|
14769
|
-
this.config.performanceLoggingEnabled && performance.mark(`detectCmpEnd_${cmp.name}`);
|
|
14770
|
-
this.config.performanceLoggingEnabled && performance.measure(`detectCmp_${cmp.name}`, `detectCmp_${cmp.name}`, `detectCmpEnd_${cmp.name}`);
|
|
14771
14775
|
if (result) {
|
|
14772
14776
|
logsConfig.lifecycle && console.log(`Found CMP: ${cmp.name} ${window.location.href}`);
|
|
14773
14777
|
this.sendContentMessage({
|
|
@@ -14799,8 +14803,12 @@ var AutoConsent = class {
|
|
|
14799
14803
|
}
|
|
14800
14804
|
this.detectHeuristics();
|
|
14801
14805
|
if (foundCMPs.length === 0 && retries > 0) {
|
|
14806
|
+
const waitFor2 = [this.domActions.wait(500)];
|
|
14807
|
+
if (this.state.findCmpAttempts > 1) {
|
|
14808
|
+
waitFor2.push(mutationObserver);
|
|
14809
|
+
}
|
|
14802
14810
|
try {
|
|
14803
|
-
await Promise.all(
|
|
14811
|
+
await Promise.all(waitFor2);
|
|
14804
14812
|
} catch (e) {
|
|
14805
14813
|
return [];
|
|
14806
14814
|
}
|
|
@@ -15095,17 +15103,6 @@ var AutoConsent = class {
|
|
|
15095
15103
|
parseDeclarativeRules: getRoundedPerformanceEntries("parseDeclarativeRules")
|
|
15096
15104
|
};
|
|
15097
15105
|
}
|
|
15098
|
-
measureDetailedRulePerformance() {
|
|
15099
|
-
const cmpPerformance = performance.getEntriesByType("measure").filter((m) => m.name.startsWith("detectCmp_")).reduce((acc, m) => {
|
|
15100
|
-
const k = m.name.slice(10);
|
|
15101
|
-
if (!acc[k]) {
|
|
15102
|
-
acc[k] = 0;
|
|
15103
|
-
}
|
|
15104
|
-
acc[k] += m.duration;
|
|
15105
|
-
return acc;
|
|
15106
|
-
}, /* @__PURE__ */ Object.create(null));
|
|
15107
|
-
return cmpPerformance;
|
|
15108
|
-
}
|
|
15109
15106
|
};
|
|
15110
15107
|
_config = new WeakMap();
|
|
15111
15108
|
|
|
@@ -11240,7 +11240,8 @@ function normalizeConfig(providedConfig) {
|
|
|
11240
11240
|
messages: false,
|
|
11241
11241
|
waits: false
|
|
11242
11242
|
},
|
|
11243
|
-
performanceLoggingEnabled: false
|
|
11243
|
+
performanceLoggingEnabled: false,
|
|
11244
|
+
heuristicPopupSearchTimeout: 100
|
|
11244
11245
|
};
|
|
11245
11246
|
const updatedConfig = copyObject(defaultConfig);
|
|
11246
11247
|
for (const key of Object.keys(defaultConfig)) {
|
|
@@ -12659,6 +12660,7 @@ var NEVER_MATCH_PATTERNS = [
|
|
|
12659
12660
|
// lib/heuristics.ts
|
|
12660
12661
|
var BUTTON_LIKE_ELEMENT_SELECTOR = 'button, input[type="button"], input[type="submit"], a, [role="button"], [class*="button"]';
|
|
12661
12662
|
var TEXT_LIMIT = 1e5;
|
|
12663
|
+
var POPUP_SEARCH_MAX_TIME = 100;
|
|
12662
12664
|
function checkHeuristicPatterns(allText, detectPatterns = DETECT_PATTERNS) {
|
|
12663
12665
|
allText = allText.slice(0, TEXT_LIMIT);
|
|
12664
12666
|
const patterns = [];
|
|
@@ -12672,8 +12674,8 @@ function checkHeuristicPatterns(allText, detectPatterns = DETECT_PATTERNS) {
|
|
|
12672
12674
|
}
|
|
12673
12675
|
return { patterns, snippets: snippets2 };
|
|
12674
12676
|
}
|
|
12675
|
-
function getActionablePopups() {
|
|
12676
|
-
const popups = getPotentialPopups();
|
|
12677
|
+
function getActionablePopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
12678
|
+
const popups = getPotentialPopups(timeout);
|
|
12677
12679
|
const result = popups.reduce((acc, popup) => {
|
|
12678
12680
|
const popupText = popup.text?.trim();
|
|
12679
12681
|
if (popupText) {
|
|
@@ -12727,17 +12729,17 @@ function cleanButtonText(buttonText) {
|
|
|
12727
12729
|
result = result.trim();
|
|
12728
12730
|
return result;
|
|
12729
12731
|
}
|
|
12730
|
-
function getPotentialPopups() {
|
|
12732
|
+
function getPotentialPopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
12731
12733
|
const isFramed = !isTopFrame();
|
|
12732
12734
|
if (isFramed && window.parent && window.parent !== window.top) {
|
|
12733
12735
|
return [];
|
|
12734
12736
|
}
|
|
12735
|
-
return collectPotentialPopups(isFramed);
|
|
12737
|
+
return collectPotentialPopups(isFramed, timeout);
|
|
12736
12738
|
}
|
|
12737
|
-
function collectPotentialPopups(isFramed) {
|
|
12739
|
+
function collectPotentialPopups(isFramed, timeout = POPUP_SEARCH_MAX_TIME) {
|
|
12738
12740
|
let elements = [];
|
|
12739
12741
|
if (!isFramed) {
|
|
12740
|
-
elements = getPopupLikeElements();
|
|
12742
|
+
elements = getPopupLikeElements(timeout);
|
|
12741
12743
|
} else {
|
|
12742
12744
|
const doc = document.body || document.documentElement;
|
|
12743
12745
|
if (doc && isElementVisible(doc) && doc.innerText) {
|
|
@@ -12765,7 +12767,8 @@ function isDialogLikeElement(node) {
|
|
|
12765
12767
|
}
|
|
12766
12768
|
return false;
|
|
12767
12769
|
}
|
|
12768
|
-
function getPopupLikeElements() {
|
|
12770
|
+
function getPopupLikeElements(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
12771
|
+
const startTime = performance.now();
|
|
12769
12772
|
const walker = document.createTreeWalker(
|
|
12770
12773
|
document.documentElement,
|
|
12771
12774
|
NodeFilter.SHOW_ELEMENT,
|
|
@@ -12784,6 +12787,9 @@ function getPopupLikeElements() {
|
|
|
12784
12787
|
return NodeFilter.FILTER_ACCEPT;
|
|
12785
12788
|
}
|
|
12786
12789
|
}
|
|
12790
|
+
if (performance.now() - startTime > timeout) {
|
|
12791
|
+
return NodeFilter.FILTER_REJECT;
|
|
12792
|
+
}
|
|
12787
12793
|
return NodeFilter.FILTER_SKIP;
|
|
12788
12794
|
}
|
|
12789
12795
|
}
|
|
@@ -13187,9 +13193,10 @@ var AutoConsentHeuristicCMP = class extends AutoConsentCMPBase {
|
|
|
13187
13193
|
get isCosmetic() {
|
|
13188
13194
|
return false;
|
|
13189
13195
|
}
|
|
13190
|
-
detectCmp() {
|
|
13196
|
+
async detectCmp() {
|
|
13197
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
13191
13198
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorStart");
|
|
13192
|
-
this.popups = getActionablePopups();
|
|
13199
|
+
this.popups = getActionablePopups(this.autoconsent.config.heuristicPopupSearchTimeout);
|
|
13193
13200
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorEnd");
|
|
13194
13201
|
this.autoconsent.config.performanceLoggingEnabled && performance.measure("heuristicDetector", "heuristicDetectorStart", "heuristicDetectorEnd");
|
|
13195
13202
|
if (this.popups.length > 0) {
|
|
@@ -14690,7 +14697,7 @@ var AutoConsent = class {
|
|
|
14690
14697
|
}
|
|
14691
14698
|
}
|
|
14692
14699
|
});
|
|
14693
|
-
const heuristicRules = isTop && this.config.enableHeuristicAction ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
14700
|
+
const heuristicRules = isTop && this.config.enableHeuristicAction && this.state.findCmpAttempts % 2 === 0 ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
14694
14701
|
const rulesPriorityStages = [
|
|
14695
14702
|
["site-specific", siteSpecificRules],
|
|
14696
14703
|
["generic", genericRules],
|
|
@@ -14698,10 +14705,7 @@ var AutoConsent = class {
|
|
|
14698
14705
|
];
|
|
14699
14706
|
const runDetectCmp = async (cmp) => {
|
|
14700
14707
|
try {
|
|
14701
|
-
this.config.performanceLoggingEnabled && performance.mark(`detectCmp_${cmp.name}`);
|
|
14702
14708
|
const result = await cmp.detectCmp();
|
|
14703
|
-
this.config.performanceLoggingEnabled && performance.mark(`detectCmpEnd_${cmp.name}`);
|
|
14704
|
-
this.config.performanceLoggingEnabled && performance.measure(`detectCmp_${cmp.name}`, `detectCmp_${cmp.name}`, `detectCmpEnd_${cmp.name}`);
|
|
14705
14709
|
if (result) {
|
|
14706
14710
|
logsConfig.lifecycle && console.log(`Found CMP: ${cmp.name} ${window.location.href}`);
|
|
14707
14711
|
this.sendContentMessage({
|
|
@@ -14733,8 +14737,12 @@ var AutoConsent = class {
|
|
|
14733
14737
|
}
|
|
14734
14738
|
this.detectHeuristics();
|
|
14735
14739
|
if (foundCMPs.length === 0 && retries > 0) {
|
|
14740
|
+
const waitFor2 = [this.domActions.wait(500)];
|
|
14741
|
+
if (this.state.findCmpAttempts > 1) {
|
|
14742
|
+
waitFor2.push(mutationObserver);
|
|
14743
|
+
}
|
|
14736
14744
|
try {
|
|
14737
|
-
await Promise.all(
|
|
14745
|
+
await Promise.all(waitFor2);
|
|
14738
14746
|
} catch (e) {
|
|
14739
14747
|
return [];
|
|
14740
14748
|
}
|
|
@@ -15029,17 +15037,6 @@ var AutoConsent = class {
|
|
|
15029
15037
|
parseDeclarativeRules: getRoundedPerformanceEntries("parseDeclarativeRules")
|
|
15030
15038
|
};
|
|
15031
15039
|
}
|
|
15032
|
-
measureDetailedRulePerformance() {
|
|
15033
|
-
const cmpPerformance = performance.getEntriesByType("measure").filter((m) => m.name.startsWith("detectCmp_")).reduce((acc, m) => {
|
|
15034
|
-
const k = m.name.slice(10);
|
|
15035
|
-
if (!acc[k]) {
|
|
15036
|
-
acc[k] = 0;
|
|
15037
|
-
}
|
|
15038
|
-
acc[k] += m.duration;
|
|
15039
|
-
return acc;
|
|
15040
|
-
}, /* @__PURE__ */ Object.create(null));
|
|
15041
|
-
return cmpPerformance;
|
|
15042
|
-
}
|
|
15043
15040
|
};
|
|
15044
15041
|
_config = new WeakMap();
|
|
15045
15042
|
|
|
@@ -715,7 +715,8 @@
|
|
|
715
715
|
messages: false,
|
|
716
716
|
waits: false
|
|
717
717
|
},
|
|
718
|
-
performanceLoggingEnabled: false
|
|
718
|
+
performanceLoggingEnabled: false,
|
|
719
|
+
heuristicPopupSearchTimeout: 100
|
|
719
720
|
};
|
|
720
721
|
const updatedConfig = copyObject(defaultConfig);
|
|
721
722
|
for (const key of Object.keys(defaultConfig)) {
|
|
@@ -1467,6 +1468,7 @@
|
|
|
1467
1468
|
// lib/heuristics.ts
|
|
1468
1469
|
var BUTTON_LIKE_ELEMENT_SELECTOR = 'button, input[type="button"], input[type="submit"], a, [role="button"], [class*="button"]';
|
|
1469
1470
|
var TEXT_LIMIT = 1e5;
|
|
1471
|
+
var POPUP_SEARCH_MAX_TIME = 100;
|
|
1470
1472
|
function checkHeuristicPatterns(allText, detectPatterns = DETECT_PATTERNS) {
|
|
1471
1473
|
allText = allText.slice(0, TEXT_LIMIT);
|
|
1472
1474
|
const patterns = [];
|
|
@@ -1480,8 +1482,8 @@
|
|
|
1480
1482
|
}
|
|
1481
1483
|
return { patterns, snippets: snippets2 };
|
|
1482
1484
|
}
|
|
1483
|
-
function getActionablePopups() {
|
|
1484
|
-
const popups = getPotentialPopups();
|
|
1485
|
+
function getActionablePopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1486
|
+
const popups = getPotentialPopups(timeout);
|
|
1485
1487
|
const result = popups.reduce((acc, popup) => {
|
|
1486
1488
|
const popupText = popup.text?.trim();
|
|
1487
1489
|
if (popupText) {
|
|
@@ -1535,17 +1537,17 @@
|
|
|
1535
1537
|
result = result.trim();
|
|
1536
1538
|
return result;
|
|
1537
1539
|
}
|
|
1538
|
-
function getPotentialPopups() {
|
|
1540
|
+
function getPotentialPopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1539
1541
|
const isFramed = !isTopFrame();
|
|
1540
1542
|
if (isFramed && window.parent && window.parent !== window.top) {
|
|
1541
1543
|
return [];
|
|
1542
1544
|
}
|
|
1543
|
-
return collectPotentialPopups(isFramed);
|
|
1545
|
+
return collectPotentialPopups(isFramed, timeout);
|
|
1544
1546
|
}
|
|
1545
|
-
function collectPotentialPopups(isFramed) {
|
|
1547
|
+
function collectPotentialPopups(isFramed, timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1546
1548
|
let elements = [];
|
|
1547
1549
|
if (!isFramed) {
|
|
1548
|
-
elements = getPopupLikeElements();
|
|
1550
|
+
elements = getPopupLikeElements(timeout);
|
|
1549
1551
|
} else {
|
|
1550
1552
|
const doc = document.body || document.documentElement;
|
|
1551
1553
|
if (doc && isElementVisible(doc) && doc.innerText) {
|
|
@@ -1573,7 +1575,8 @@
|
|
|
1573
1575
|
}
|
|
1574
1576
|
return false;
|
|
1575
1577
|
}
|
|
1576
|
-
function getPopupLikeElements() {
|
|
1578
|
+
function getPopupLikeElements(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
1579
|
+
const startTime = performance.now();
|
|
1577
1580
|
const walker = document.createTreeWalker(
|
|
1578
1581
|
document.documentElement,
|
|
1579
1582
|
NodeFilter.SHOW_ELEMENT,
|
|
@@ -1592,6 +1595,9 @@
|
|
|
1592
1595
|
return NodeFilter.FILTER_ACCEPT;
|
|
1593
1596
|
}
|
|
1594
1597
|
}
|
|
1598
|
+
if (performance.now() - startTime > timeout) {
|
|
1599
|
+
return NodeFilter.FILTER_REJECT;
|
|
1600
|
+
}
|
|
1595
1601
|
return NodeFilter.FILTER_SKIP;
|
|
1596
1602
|
}
|
|
1597
1603
|
}
|
|
@@ -1995,9 +2001,10 @@
|
|
|
1995
2001
|
get isCosmetic() {
|
|
1996
2002
|
return false;
|
|
1997
2003
|
}
|
|
1998
|
-
detectCmp() {
|
|
2004
|
+
async detectCmp() {
|
|
2005
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1999
2006
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorStart");
|
|
2000
|
-
this.popups = getActionablePopups();
|
|
2007
|
+
this.popups = getActionablePopups(this.autoconsent.config.heuristicPopupSearchTimeout);
|
|
2001
2008
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark("heuristicDetectorEnd");
|
|
2002
2009
|
this.autoconsent.config.performanceLoggingEnabled && performance.measure("heuristicDetector", "heuristicDetectorStart", "heuristicDetectorEnd");
|
|
2003
2010
|
if (this.popups.length > 0) {
|
|
@@ -3498,7 +3505,7 @@
|
|
|
3498
3505
|
}
|
|
3499
3506
|
}
|
|
3500
3507
|
});
|
|
3501
|
-
const heuristicRules = isTop && this.config.enableHeuristicAction ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
3508
|
+
const heuristicRules = isTop && this.config.enableHeuristicAction && this.state.findCmpAttempts % 2 === 0 ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
3502
3509
|
const rulesPriorityStages = [
|
|
3503
3510
|
["site-specific", siteSpecificRules],
|
|
3504
3511
|
["generic", genericRules],
|
|
@@ -3506,10 +3513,7 @@
|
|
|
3506
3513
|
];
|
|
3507
3514
|
const runDetectCmp = async (cmp) => {
|
|
3508
3515
|
try {
|
|
3509
|
-
this.config.performanceLoggingEnabled && performance.mark(`detectCmp_${cmp.name}`);
|
|
3510
3516
|
const result = await cmp.detectCmp();
|
|
3511
|
-
this.config.performanceLoggingEnabled && performance.mark(`detectCmpEnd_${cmp.name}`);
|
|
3512
|
-
this.config.performanceLoggingEnabled && performance.measure(`detectCmp_${cmp.name}`, `detectCmp_${cmp.name}`, `detectCmpEnd_${cmp.name}`);
|
|
3513
3517
|
if (result) {
|
|
3514
3518
|
logsConfig.lifecycle && console.log(`Found CMP: ${cmp.name} ${window.location.href}`);
|
|
3515
3519
|
this.sendContentMessage({
|
|
@@ -3541,8 +3545,12 @@
|
|
|
3541
3545
|
}
|
|
3542
3546
|
this.detectHeuristics();
|
|
3543
3547
|
if (foundCMPs.length === 0 && retries > 0) {
|
|
3548
|
+
const waitFor2 = [this.domActions.wait(500)];
|
|
3549
|
+
if (this.state.findCmpAttempts > 1) {
|
|
3550
|
+
waitFor2.push(mutationObserver);
|
|
3551
|
+
}
|
|
3544
3552
|
try {
|
|
3545
|
-
await Promise.all(
|
|
3553
|
+
await Promise.all(waitFor2);
|
|
3546
3554
|
} catch (e) {
|
|
3547
3555
|
return [];
|
|
3548
3556
|
}
|
|
@@ -3837,17 +3845,6 @@
|
|
|
3837
3845
|
parseDeclarativeRules: getRoundedPerformanceEntries("parseDeclarativeRules")
|
|
3838
3846
|
};
|
|
3839
3847
|
}
|
|
3840
|
-
measureDetailedRulePerformance() {
|
|
3841
|
-
const cmpPerformance = performance.getEntriesByType("measure").filter((m) => m.name.startsWith("detectCmp_")).reduce((acc, m) => {
|
|
3842
|
-
const k = m.name.slice(10);
|
|
3843
|
-
if (!acc[k]) {
|
|
3844
|
-
acc[k] = 0;
|
|
3845
|
-
}
|
|
3846
|
-
acc[k] += m.duration;
|
|
3847
|
-
return acc;
|
|
3848
|
-
}, /* @__PURE__ */ Object.create(null));
|
|
3849
|
-
return cmpPerformance;
|
|
3850
|
-
}
|
|
3851
3848
|
};
|
|
3852
3849
|
_config = new WeakMap();
|
|
3853
3850
|
|
|
@@ -3,7 +3,7 @@ export declare function checkHeuristicPatterns(allText: string, detectPatterns?:
|
|
|
3
3
|
patterns: string[];
|
|
4
4
|
snippets: string[];
|
|
5
5
|
};
|
|
6
|
-
export declare function getActionablePopups(): PopupData[];
|
|
6
|
+
export declare function getActionablePopups(timeout?: number): PopupData[];
|
|
7
7
|
export declare function classifyButtons(buttons: ButtonData[]): {
|
|
8
8
|
rejectButtons: ButtonData[];
|
|
9
9
|
otherButtons: ButtonData[];
|
package/dist/types/types.d.ts
CHANGED
|
@@ -73,6 +73,7 @@ export type Config = {
|
|
|
73
73
|
waits: boolean;
|
|
74
74
|
};
|
|
75
75
|
performanceLoggingEnabled: boolean;
|
|
76
|
+
heuristicPopupSearchTimeout: number;
|
|
76
77
|
};
|
|
77
78
|
export type LifecycleState = 'loading' | 'initialized' | 'waitingForInitResponse' | 'started' | 'nothingDetected' | 'cosmeticFiltersDetected' | 'cmpDetected' | 'openPopupDetected' | 'runningOptOut' | 'runningOptIn' | 'optOutSucceeded' | 'optOutFailed' | 'optInSucceeded' | 'optInFailed' | 'done';
|
|
78
79
|
export type ConsentState = {
|
package/dist/types/web.d.ts
CHANGED
package/lib/cmps/base.ts
CHANGED
|
@@ -441,9 +441,11 @@ export class AutoConsentHeuristicCMP extends AutoConsentCMPBase {
|
|
|
441
441
|
return false;
|
|
442
442
|
}
|
|
443
443
|
|
|
444
|
-
detectCmp(): Promise<boolean> {
|
|
444
|
+
async detectCmp(): Promise<boolean> {
|
|
445
|
+
// wait for one tick to deprioritize heavy DOM operations
|
|
446
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
445
447
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark('heuristicDetectorStart');
|
|
446
|
-
this.popups = getActionablePopups();
|
|
448
|
+
this.popups = getActionablePopups(this.autoconsent.config.heuristicPopupSearchTimeout);
|
|
447
449
|
this.autoconsent.config.performanceLoggingEnabled && performance.mark('heuristicDetectorEnd');
|
|
448
450
|
this.autoconsent.config.performanceLoggingEnabled &&
|
|
449
451
|
performance.measure('heuristicDetector', 'heuristicDetectorStart', 'heuristicDetectorEnd');
|
package/lib/heuristics.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { isElementVisible, isTopFrame } from './utils';
|
|
|
4
4
|
|
|
5
5
|
const BUTTON_LIKE_ELEMENT_SELECTOR = 'button, input[type="button"], input[type="submit"], a, [role="button"], [class*="button"]';
|
|
6
6
|
const TEXT_LIMIT = 100000;
|
|
7
|
+
const POPUP_SEARCH_MAX_TIME = 100;
|
|
7
8
|
|
|
8
9
|
export function checkHeuristicPatterns(allText: string, detectPatterns = DETECT_PATTERNS) {
|
|
9
10
|
allText = allText.slice(0, TEXT_LIMIT);
|
|
@@ -20,8 +21,8 @@ export function checkHeuristicPatterns(allText: string, detectPatterns = DETECT_
|
|
|
20
21
|
return { patterns, snippets };
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
export function getActionablePopups(): PopupData[] {
|
|
24
|
-
const popups = getPotentialPopups();
|
|
24
|
+
export function getActionablePopups(timeout = POPUP_SEARCH_MAX_TIME): PopupData[] {
|
|
25
|
+
const popups = getPotentialPopups(timeout);
|
|
25
26
|
const result = popups.reduce((acc, popup) => {
|
|
26
27
|
const popupText = popup.text?.trim();
|
|
27
28
|
if (popupText) {
|
|
@@ -88,20 +89,20 @@ export function cleanButtonText(buttonText: string): string {
|
|
|
88
89
|
return result;
|
|
89
90
|
}
|
|
90
91
|
|
|
91
|
-
function getPotentialPopups() {
|
|
92
|
+
function getPotentialPopups(timeout = POPUP_SEARCH_MAX_TIME) {
|
|
92
93
|
const isFramed = !isTopFrame();
|
|
93
94
|
// do not inspect frames that are more than one level deep
|
|
94
95
|
if (isFramed && window.parent && window.parent !== window.top) {
|
|
95
96
|
return [];
|
|
96
97
|
}
|
|
97
98
|
|
|
98
|
-
return collectPotentialPopups(isFramed);
|
|
99
|
+
return collectPotentialPopups(isFramed, timeout);
|
|
99
100
|
}
|
|
100
101
|
|
|
101
|
-
function collectPotentialPopups(isFramed: boolean): PopupData[] {
|
|
102
|
+
function collectPotentialPopups(isFramed: boolean, timeout = POPUP_SEARCH_MAX_TIME): PopupData[] {
|
|
102
103
|
let elements = [];
|
|
103
104
|
if (!isFramed) {
|
|
104
|
-
elements = getPopupLikeElements();
|
|
105
|
+
elements = getPopupLikeElements(timeout);
|
|
105
106
|
} else {
|
|
106
107
|
// for iframes, just take the whole document
|
|
107
108
|
const doc = document.body || document.documentElement;
|
|
@@ -140,7 +141,8 @@ export function isDialogLikeElement(node: HTMLElement): boolean {
|
|
|
140
141
|
* Heuristic to get all elements that look like "popups"
|
|
141
142
|
* TODO: this heuristic is too strict, not all popups are actually sticky/fixed
|
|
142
143
|
*/
|
|
143
|
-
function getPopupLikeElements(): HTMLElement[] {
|
|
144
|
+
function getPopupLikeElements(timeout = POPUP_SEARCH_MAX_TIME): HTMLElement[] {
|
|
145
|
+
const startTime = performance.now();
|
|
144
146
|
const walker = document.createTreeWalker(
|
|
145
147
|
document.documentElement,
|
|
146
148
|
NodeFilter.SHOW_ELEMENT, // visit only element nodes
|
|
@@ -158,11 +160,14 @@ function getPopupLikeElements(): HTMLElement[] {
|
|
|
158
160
|
return NodeFilter.FILTER_ACCEPT;
|
|
159
161
|
}
|
|
160
162
|
}
|
|
163
|
+
// start rejecting after POPUP_SEARCH_MAX_TIME to avoid blocking the main thread
|
|
164
|
+
if (performance.now() - startTime > timeout) {
|
|
165
|
+
return NodeFilter.FILTER_REJECT;
|
|
166
|
+
}
|
|
161
167
|
return NodeFilter.FILTER_SKIP;
|
|
162
168
|
},
|
|
163
169
|
},
|
|
164
170
|
);
|
|
165
|
-
|
|
166
171
|
const found = [];
|
|
167
172
|
for (let node = walker.nextNode(); node; node = walker.nextNode()) {
|
|
168
173
|
found.push(node as HTMLElement);
|
package/lib/types.ts
CHANGED
package/lib/utils.ts
CHANGED
|
@@ -94,6 +94,7 @@ export function normalizeConfig(providedConfig: any): Config {
|
|
|
94
94
|
waits: false,
|
|
95
95
|
},
|
|
96
96
|
performanceLoggingEnabled: false,
|
|
97
|
+
heuristicPopupSearchTimeout: 100,
|
|
97
98
|
};
|
|
98
99
|
const updatedConfig: Config = copyObject(defaultConfig);
|
|
99
100
|
// filter out any unknown entries
|
package/lib/web.ts
CHANGED
|
@@ -294,8 +294,9 @@ export default class AutoConsent {
|
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
296
|
});
|
|
297
|
-
// heuristic CMP is only run in the top frame and only if heuristic action is enabled
|
|
298
|
-
const heuristicRules =
|
|
297
|
+
// heuristic CMP is only run in the top frame and only if heuristic action is enabled and retries is odd
|
|
298
|
+
const heuristicRules =
|
|
299
|
+
isTop && this.config.enableHeuristicAction && this.state.findCmpAttempts % 2 === 0 ? [new AutoConsentHeuristicCMP(this)] : [];
|
|
299
300
|
|
|
300
301
|
const rulesPriorityStages: [string, AutoCMP[]][] = [
|
|
301
302
|
['site-specific', siteSpecificRules],
|
|
@@ -304,11 +305,7 @@ export default class AutoConsent {
|
|
|
304
305
|
];
|
|
305
306
|
const runDetectCmp = async (cmp: AutoCMP) => {
|
|
306
307
|
try {
|
|
307
|
-
this.config.performanceLoggingEnabled && performance.mark(`detectCmp_${cmp.name}`);
|
|
308
308
|
const result = await cmp.detectCmp();
|
|
309
|
-
this.config.performanceLoggingEnabled && performance.mark(`detectCmpEnd_${cmp.name}`);
|
|
310
|
-
this.config.performanceLoggingEnabled &&
|
|
311
|
-
performance.measure(`detectCmp_${cmp.name}`, `detectCmp_${cmp.name}`, `detectCmpEnd_${cmp.name}`);
|
|
312
309
|
if (result) {
|
|
313
310
|
logsConfig.lifecycle && console.log(`Found CMP: ${cmp.name} ${window.location.href}`);
|
|
314
311
|
this.sendContentMessage({
|
|
@@ -351,8 +348,12 @@ export default class AutoConsent {
|
|
|
351
348
|
// if we didn't find a CMP, try again
|
|
352
349
|
// We wait 500ms, and also for some kind of dom mutation to happen before
|
|
353
350
|
// rerunning the findCmp check
|
|
351
|
+
const waitFor: Promise<boolean>[] = [this.domActions.wait(500)];
|
|
352
|
+
if (this.state.findCmpAttempts > 1) {
|
|
353
|
+
waitFor.push(mutationObserver);
|
|
354
|
+
}
|
|
354
355
|
try {
|
|
355
|
-
await Promise.all(
|
|
356
|
+
await Promise.all(waitFor);
|
|
356
357
|
} catch (e) {
|
|
357
358
|
// timeout waiting for mutation - break out of detection
|
|
358
359
|
return [];
|
|
@@ -701,19 +702,4 @@ export default class AutoConsent {
|
|
|
701
702
|
parseDeclarativeRules: getRoundedPerformanceEntries('parseDeclarativeRules'),
|
|
702
703
|
};
|
|
703
704
|
}
|
|
704
|
-
|
|
705
|
-
measureDetailedRulePerformance() {
|
|
706
|
-
const cmpPerformance: Record<string, number> = performance
|
|
707
|
-
.getEntriesByType('measure')
|
|
708
|
-
.filter((m) => m.name.startsWith('detectCmp_'))
|
|
709
|
-
.reduce((acc, m) => {
|
|
710
|
-
const k = m.name.slice(10);
|
|
711
|
-
if (!acc[k]) {
|
|
712
|
-
acc[k] = 0;
|
|
713
|
-
}
|
|
714
|
-
acc[k] += m.duration;
|
|
715
|
-
return acc;
|
|
716
|
-
}, Object.create(null));
|
|
717
|
-
return cmpPerformance;
|
|
718
|
-
}
|
|
719
705
|
}
|
package/package.json
CHANGED
|
@@ -156,7 +156,9 @@ describe('Autoconsent.findCmp', () => {
|
|
|
156
156
|
optIn: [],
|
|
157
157
|
optOut: [],
|
|
158
158
|
});
|
|
159
|
-
|
|
159
|
+
// force findCmpAttempts to 1 so heuristic CMP is run on the first attempt
|
|
160
|
+
autoconsent.state.findCmpAttempts = 1;
|
|
161
|
+
const found = await autoconsent.findCmp(1);
|
|
160
162
|
|
|
161
163
|
expect(found).to.have.length(1);
|
|
162
164
|
expect(found[0].name).to.equal('HEURISTIC');
|