@duckduckgo/autoconsent 14.93.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 +12 -0
- package/dist/addon-firefox/background.bundle.js +2 -1
- package/dist/addon-firefox/content.bundle.js +23 -12
- 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 -12
- package/dist/addon-mv3/manifest.json +1 -1
- package/dist/addon-mv3/popup.bundle.js +2 -1
- package/dist/autoconsent.cjs.js +23 -12
- package/dist/autoconsent.esm.js +23 -12
- package/dist/autoconsent.extra.cjs.js +23 -12
- package/dist/autoconsent.extra.esm.js +23 -12
- package/dist/autoconsent.playwright.js +23 -12
- package/dist/types/heuristics.d.ts +1 -1
- package/dist/types/types.d.ts +1 -0
- 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 -3
- package/package.json +1 -1
- package/tests-wtr/lifecycle/find-cmp.ts +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
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
|
+
|
|
1
13
|
# v14.93.0 (Wed Jun 10 2026)
|
|
2
14
|
|
|
3
15
|
#### 🚀 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],
|
|
@@ -3530,8 +3537,12 @@
|
|
|
3530
3537
|
}
|
|
3531
3538
|
this.detectHeuristics();
|
|
3532
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
|
+
}
|
|
3533
3544
|
try {
|
|
3534
|
-
await Promise.all(
|
|
3545
|
+
await Promise.all(waitFor2);
|
|
3535
3546
|
} catch (e) {
|
|
3536
3547
|
return [];
|
|
3537
3548
|
}
|
|
@@ -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],
|
|
@@ -3530,8 +3537,12 @@
|
|
|
3530
3537
|
}
|
|
3531
3538
|
this.detectHeuristics();
|
|
3532
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
|
+
}
|
|
3533
3544
|
try {
|
|
3534
|
-
await Promise.all(
|
|
3545
|
+
await Promise.all(waitFor2);
|
|
3535
3546
|
} catch (e) {
|
|
3536
3547
|
return [];
|
|
3537
3548
|
}
|
|
@@ -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],
|
|
@@ -3798,8 +3805,12 @@ var AutoConsent = class {
|
|
|
3798
3805
|
}
|
|
3799
3806
|
this.detectHeuristics();
|
|
3800
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
|
+
}
|
|
3801
3812
|
try {
|
|
3802
|
-
await Promise.all(
|
|
3813
|
+
await Promise.all(waitFor2);
|
|
3803
3814
|
} catch (e) {
|
|
3804
3815
|
return [];
|
|
3805
3816
|
}
|
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],
|
|
@@ -3768,8 +3775,12 @@ var AutoConsent = class {
|
|
|
3768
3775
|
}
|
|
3769
3776
|
this.detectHeuristics();
|
|
3770
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
|
+
}
|
|
3771
3782
|
try {
|
|
3772
|
-
await Promise.all(
|
|
3783
|
+
await Promise.all(waitFor2);
|
|
3773
3784
|
} catch (e) {
|
|
3774
3785
|
return [];
|
|
3775
3786
|
}
|
|
@@ -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],
|
|
@@ -14796,8 +14803,12 @@ var AutoConsent = class {
|
|
|
14796
14803
|
}
|
|
14797
14804
|
this.detectHeuristics();
|
|
14798
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
|
+
}
|
|
14799
14810
|
try {
|
|
14800
|
-
await Promise.all(
|
|
14811
|
+
await Promise.all(waitFor2);
|
|
14801
14812
|
} catch (e) {
|
|
14802
14813
|
return [];
|
|
14803
14814
|
}
|
|
@@ -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],
|
|
@@ -14730,8 +14737,12 @@ var AutoConsent = class {
|
|
|
14730
14737
|
}
|
|
14731
14738
|
this.detectHeuristics();
|
|
14732
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
|
+
}
|
|
14733
14744
|
try {
|
|
14734
|
-
await Promise.all(
|
|
14745
|
+
await Promise.all(waitFor2);
|
|
14735
14746
|
} catch (e) {
|
|
14736
14747
|
return [];
|
|
14737
14748
|
}
|
|
@@ -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],
|
|
@@ -3538,8 +3545,12 @@
|
|
|
3538
3545
|
}
|
|
3539
3546
|
this.detectHeuristics();
|
|
3540
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
|
+
}
|
|
3541
3552
|
try {
|
|
3542
|
-
await Promise.all(
|
|
3553
|
+
await Promise.all(waitFor2);
|
|
3543
3554
|
} catch (e) {
|
|
3544
3555
|
return [];
|
|
3545
3556
|
}
|
|
@@ -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/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],
|
|
@@ -347,8 +348,12 @@ export default class AutoConsent {
|
|
|
347
348
|
// if we didn't find a CMP, try again
|
|
348
349
|
// We wait 500ms, and also for some kind of dom mutation to happen before
|
|
349
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
|
+
}
|
|
350
355
|
try {
|
|
351
|
-
await Promise.all(
|
|
356
|
+
await Promise.all(waitFor);
|
|
352
357
|
} catch (e) {
|
|
353
358
|
// timeout waiting for mutation - break out of detection
|
|
354
359
|
return [];
|
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');
|