@duckduckgo/autoconsent 1.0.5 → 1.0.8
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/dist/autoconsent.cjs.js +105 -34
- package/dist/autoconsent.esm.js +105 -34
- package/dist/autoconsent.puppet.js +109 -11
- package/lib/cmps/all.js +2 -0
- package/lib/cmps/all.ts +2 -0
- package/lib/cmps/base.js +5 -1
- package/lib/cmps/base.ts +5 -1
- package/lib/cmps/cookiebot.js +6 -2
- package/lib/cmps/cookiebot.ts +8 -2
- package/lib/cmps/onetrust.js +34 -0
- package/lib/cmps/onetrust.ts +47 -0
- package/lib/cmps/trustarc.js +2 -2
- package/lib/cmps/trustarc.ts +2 -2
- package/lib/config.js +1 -0
- package/lib/config.ts +1 -0
- package/lib/detector.js +4 -0
- package/lib/detector.ts +4 -0
- package/lib/hider.js +1 -1
- package/lib/hider.ts +1 -1
- package/lib/messages.d.ts +3 -0
- package/lib/node.js +8 -3
- package/lib/node.ts +10 -5
- package/lib/puppet/tab.js +10 -3
- package/lib/puppet/tab.ts +13 -3
- package/lib/tabwrapper.js +6 -0
- package/lib/tabwrapper.ts +6 -0
- package/lib/types.d.ts +2 -2
- package/lib/web/content-utils.js +29 -0
- package/lib/web/content-utils.ts +31 -0
- package/lib/web/content.js +20 -22
- package/lib/web/content.ts +19 -22
- package/lib/web/tab.js +12 -6
- package/lib/web/tab.ts +13 -6
- package/lib/web.js +5 -0
- package/lib/web.ts +5 -0
- package/package.json +1 -1
- package/readme.md +1 -1
- package/rules/autoconsent/192.json +17 -0
- package/rules/autoconsent/ausopen.json +7 -0
- package/rules/autoconsent/aws-amazon.json +1 -1
- package/rules/autoconsent/bing.json +14 -0
- package/rules/autoconsent/bundesregierung-de.json +1 -1
- package/rules/autoconsent/dunelm.json +18 -0
- package/rules/autoconsent/etsy.json +13 -0
- package/rules/autoconsent/gov-uk.json +10 -0
- package/rules/autoconsent/marksandspencer.json +7 -0
- package/rules/autoconsent/{paypal-de.json → paypal.json} +6 -2
- package/rules/autoconsent/uswitch.json +8 -0
- package/rules/autoconsent/waitrose.json +28 -0
- package/rules/autoconsent/wetransfer.json +7 -0
- package/rules/rules.json +308 -50
- package/tests/192.spec.ts +7 -0
- package/tests/ausopen.spec.ts +7 -0
- package/tests/cookiebot.spec.ts +1 -0
- package/tests/dunelm.spec.ts +7 -0
- package/tests/etsy.spec.ts +7 -0
- package/tests/gov-uk.spec.ts +9 -0
- package/tests/marksandspencer.spec.ts +7 -0
- package/tests/onetrust.spec.ts +6 -0
- package/tests/paypal.spec.ts +7 -5
- package/tests/runner.ts +1 -1
- package/tests/trustarc.spec.ts +1 -0
- package/tests/uswitch.spec.ts +7 -0
- package/tests/waitrose.spec.ts +7 -0
- package/tests/wetransfer.spec.ts +7 -0
- package/rules/autoconsent/onetrust.json +0 -24
package/dist/autoconsent.cjs.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
const enableLogs = false; // change this to enable debug logs
|
|
6
|
+
|
|
5
7
|
/* eslint-disable no-restricted-syntax,no-await-in-loop,no-underscore-dangle */
|
|
6
8
|
async function waitFor(predicate, maxTimes, interval) {
|
|
7
9
|
let result = await predicate();
|
|
@@ -17,7 +19,7 @@ async function waitFor(predicate, maxTimes, interval) {
|
|
|
17
19
|
async function success(action) {
|
|
18
20
|
const result = await action;
|
|
19
21
|
if (!result) {
|
|
20
|
-
throw new Error(`Action failed: ${action}`);
|
|
22
|
+
throw new Error(`Action failed: ${action} ${result}`);
|
|
21
23
|
}
|
|
22
24
|
return result;
|
|
23
25
|
}
|
|
@@ -181,7 +183,6 @@ class TabActions {
|
|
|
181
183
|
this.id = tabId;
|
|
182
184
|
}
|
|
183
185
|
async elementExists(selector, frameId = 0) {
|
|
184
|
-
console.log(`check for ${selector} in tab ${this.id}, frame ${frameId}`);
|
|
185
186
|
return this.sendContentMessage(this.id, {
|
|
186
187
|
type: "elemExists",
|
|
187
188
|
selector
|
|
@@ -190,7 +191,6 @@ class TabActions {
|
|
|
190
191
|
});
|
|
191
192
|
}
|
|
192
193
|
async clickElement(selector, frameId = 0) {
|
|
193
|
-
console.log(`click element ${selector} in tab ${this.id}`);
|
|
194
194
|
return this.sendContentMessage(this.id, {
|
|
195
195
|
type: "click",
|
|
196
196
|
selector
|
|
@@ -199,7 +199,6 @@ class TabActions {
|
|
|
199
199
|
});
|
|
200
200
|
}
|
|
201
201
|
async clickElements(selector, frameId = 0) {
|
|
202
|
-
console.log(`click elements ${selector} in tab ${this.id}`);
|
|
203
202
|
return this.sendContentMessage(this.id, {
|
|
204
203
|
type: "click",
|
|
205
204
|
all: true,
|
|
@@ -242,10 +241,11 @@ class TabActions {
|
|
|
242
241
|
}
|
|
243
242
|
return false;
|
|
244
243
|
}
|
|
245
|
-
async hideElements(selectors, frameId = 0) {
|
|
244
|
+
async hideElements(selectors, frameId = 0, method = 'display') {
|
|
246
245
|
return this.sendContentMessage(this.id, {
|
|
247
246
|
type: "hide",
|
|
248
|
-
selectors
|
|
247
|
+
selectors,
|
|
248
|
+
method,
|
|
249
249
|
}, { frameId });
|
|
250
250
|
}
|
|
251
251
|
async undoHideElements(frameId = 0) {
|
|
@@ -261,7 +261,9 @@ class TabActions {
|
|
|
261
261
|
}
|
|
262
262
|
wait(ms) {
|
|
263
263
|
return new Promise(resolve => {
|
|
264
|
-
setTimeout(() =>
|
|
264
|
+
setTimeout(() => {
|
|
265
|
+
resolve(true);
|
|
266
|
+
}, ms);
|
|
265
267
|
});
|
|
266
268
|
}
|
|
267
269
|
matches(matcherConfig) {
|
|
@@ -645,9 +647,37 @@ async function evalAction(config) {
|
|
|
645
647
|
});
|
|
646
648
|
}
|
|
647
649
|
|
|
650
|
+
// get or create a style container for CSS overrides
|
|
651
|
+
function getStyleElementUtil() {
|
|
652
|
+
const styleOverrideElementId = "autoconsent-css-rules";
|
|
653
|
+
const styleSelector = `style#${styleOverrideElementId}`;
|
|
654
|
+
const existingElement = document.querySelector(styleSelector);
|
|
655
|
+
if (existingElement && existingElement instanceof HTMLStyleElement) {
|
|
656
|
+
return existingElement;
|
|
657
|
+
}
|
|
658
|
+
else {
|
|
659
|
+
const parent = document.head ||
|
|
660
|
+
document.getElementsByTagName("head")[0] ||
|
|
661
|
+
document.documentElement;
|
|
662
|
+
const css = document.createElement("style");
|
|
663
|
+
css.id = styleOverrideElementId;
|
|
664
|
+
parent.appendChild(css);
|
|
665
|
+
return css;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
// hide elements with a CSS rule
|
|
669
|
+
function hideElementsUtil(selectors, method) {
|
|
670
|
+
const hidingSnippet = method === 'display' ? `display: none` : `opacity: 0`;
|
|
671
|
+
const rule = `${selectors.join(",")} { ${hidingSnippet} !important; z-index: -1 !important; pointer-events: none !important; } `;
|
|
672
|
+
const styleEl = getStyleElementUtil();
|
|
673
|
+
if (styleEl instanceof HTMLStyleElement) {
|
|
674
|
+
styleEl.innerText += rule;
|
|
675
|
+
return selectors.length > 0;
|
|
676
|
+
}
|
|
677
|
+
return false;
|
|
678
|
+
}
|
|
679
|
+
|
|
648
680
|
let actionQueue = Promise.resolve(null);
|
|
649
|
-
const styleOverrideElementId = "autoconsent-css-rules";
|
|
650
|
-
const styleSelector = `style#${styleOverrideElementId}`;
|
|
651
681
|
function handleMessage(message, debug = false) {
|
|
652
682
|
if (message.type === "click") {
|
|
653
683
|
const elem = document.querySelectorAll(message.selector);
|
|
@@ -671,8 +701,19 @@ function handleMessage(message, debug = false) {
|
|
|
671
701
|
const elem = document.querySelectorAll(message.selector);
|
|
672
702
|
const results = new Array(elem.length);
|
|
673
703
|
elem.forEach((e, i) => {
|
|
674
|
-
|
|
704
|
+
// check for display: none
|
|
705
|
+
results[i] = false;
|
|
706
|
+
if (e.offsetParent !== null) {
|
|
707
|
+
results[i] = true;
|
|
708
|
+
}
|
|
709
|
+
else {
|
|
710
|
+
const css = window.getComputedStyle(e);
|
|
711
|
+
if (css.position === 'fixed' && css.display !== "none") { // fixed elements may be visible even if the parent is not
|
|
712
|
+
results[i] = true;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
675
715
|
});
|
|
716
|
+
debug && console.log("[visible?]", message.selector, elem, results);
|
|
676
717
|
if (results.length === 0) {
|
|
677
718
|
return false;
|
|
678
719
|
}
|
|
@@ -687,6 +728,7 @@ function handleMessage(message, debug = false) {
|
|
|
687
728
|
}
|
|
688
729
|
else if (message.type === "getAttribute") {
|
|
689
730
|
const elem = document.querySelector(message.selector);
|
|
731
|
+
debug && console.log("[getAttribute]", message.selector, elem);
|
|
690
732
|
if (!elem) {
|
|
691
733
|
return false;
|
|
692
734
|
}
|
|
@@ -694,31 +736,16 @@ function handleMessage(message, debug = false) {
|
|
|
694
736
|
}
|
|
695
737
|
else if (message.type === "eval") {
|
|
696
738
|
// TODO: chrome support
|
|
739
|
+
debug && console.log("about to [eval]", message.script); // this will not show in Webkit console
|
|
697
740
|
const result = window.eval(message.script); // eslint-disable-line no-eval
|
|
698
|
-
debug && console.log("[eval]", message.script, result);
|
|
699
741
|
return result;
|
|
700
742
|
}
|
|
701
743
|
else if (message.type === "hide") {
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
document.documentElement;
|
|
705
|
-
const rule = `${message.selectors.join(",")} { display: none !important; z-index: -1 !important; } `;
|
|
706
|
-
const existingElement = document.querySelector(styleSelector);
|
|
707
|
-
debug && console.log("[hide]", message.selectors, !!existingElement);
|
|
708
|
-
if (existingElement && existingElement instanceof HTMLStyleElement) {
|
|
709
|
-
existingElement.innerText += rule;
|
|
710
|
-
}
|
|
711
|
-
else {
|
|
712
|
-
const css = document.createElement("style");
|
|
713
|
-
css.type = "text/css";
|
|
714
|
-
css.id = styleOverrideElementId;
|
|
715
|
-
css.appendChild(document.createTextNode(rule));
|
|
716
|
-
parent.appendChild(css);
|
|
717
|
-
}
|
|
718
|
-
return message.selectors.length > 0;
|
|
744
|
+
debug && console.log("[hide]", message.selectors);
|
|
745
|
+
return hideElementsUtil(message.selectors, message.method);
|
|
719
746
|
}
|
|
720
747
|
else if (message.type === "undohide") {
|
|
721
|
-
const existingElement =
|
|
748
|
+
const existingElement = getStyleElementUtil();
|
|
722
749
|
debug && console.log("[unhide]", !!existingElement);
|
|
723
750
|
if (existingElement) {
|
|
724
751
|
existingElement.remove();
|
|
@@ -727,9 +754,11 @@ function handleMessage(message, debug = false) {
|
|
|
727
754
|
}
|
|
728
755
|
else if (message.type === "matches") {
|
|
729
756
|
const matched = matches(message.config);
|
|
757
|
+
debug && console.log("[matches?]", message.config.type, JSON.stringify(message.config), matched);
|
|
730
758
|
return matched;
|
|
731
759
|
}
|
|
732
760
|
else if (message.type === "executeAction") {
|
|
761
|
+
debug && console.log("[executeAction]", message);
|
|
733
762
|
actionQueue = actionQueue.then(() => executeAction(message.config, message.param));
|
|
734
763
|
return true;
|
|
735
764
|
}
|
|
@@ -758,10 +787,12 @@ class TabConsent {
|
|
|
758
787
|
}
|
|
759
788
|
async doOptOut() {
|
|
760
789
|
try {
|
|
790
|
+
enableLogs && console.log(`doing opt out ${this.getCMPName()} in tab ${this.tab.id}`);
|
|
761
791
|
this.optOutStatus = await this.rule.optOut(this.tab);
|
|
762
792
|
return this.optOutStatus;
|
|
763
793
|
}
|
|
764
794
|
catch (e) {
|
|
795
|
+
console.error('error during opt out', e);
|
|
765
796
|
this.optOutStatus = e;
|
|
766
797
|
throw e;
|
|
767
798
|
}
|
|
@@ -806,6 +837,7 @@ async function detectDialog(tab, retries, rules) {
|
|
|
806
837
|
try {
|
|
807
838
|
if (await r.detectCmp(tab)) {
|
|
808
839
|
earlyReturn = true;
|
|
840
|
+
enableLogs && console.log(`Found CMP in [${tab.id}]: ${r.name}`);
|
|
809
841
|
resolve(index);
|
|
810
842
|
}
|
|
811
843
|
}
|
|
@@ -844,10 +876,10 @@ class TrustArc extends AutoConsentBase {
|
|
|
844
876
|
tab.frame.url.startsWith("https://consent-pref.trustarc.com/?")) {
|
|
845
877
|
return true;
|
|
846
878
|
}
|
|
847
|
-
return tab.elementExists("#truste-show-consent");
|
|
879
|
+
return tab.elementExists("#truste-show-consent,#truste-consent-track");
|
|
848
880
|
}
|
|
849
881
|
async detectPopup(tab) {
|
|
850
|
-
return ((await tab.elementsAreVisible("#truste-consent-content,#trustarc-banner-overlay")) ||
|
|
882
|
+
return ((await tab.elementsAreVisible("#truste-consent-content,.truste-consent-content,#trustarc-banner-overlay")) ||
|
|
851
883
|
(tab.frame &&
|
|
852
884
|
(await tab.waitForElement("#defaultpreferencemanager", 5000, tab.frame.id))));
|
|
853
885
|
}
|
|
@@ -937,7 +969,7 @@ class TrustArc extends AutoConsentBase {
|
|
|
937
969
|
class Cookiebot extends AutoConsentBase {
|
|
938
970
|
constructor() {
|
|
939
971
|
super('Cybotcookiebot');
|
|
940
|
-
this.prehideSelectors = ["#CybotCookiebotDialog,#dtcookie-container,#cookiebanner"];
|
|
972
|
+
this.prehideSelectors = ["#CybotCookiebotDialog,#dtcookie-container,#cookiebanner,#cb-cookieoverlay"];
|
|
941
973
|
}
|
|
942
974
|
async detectCmp(tab) {
|
|
943
975
|
try {
|
|
@@ -948,7 +980,7 @@ class Cookiebot extends AutoConsentBase {
|
|
|
948
980
|
}
|
|
949
981
|
}
|
|
950
982
|
detectPopup(tab) {
|
|
951
|
-
return tab.elementExists('#CybotCookiebotDialog,#dtcookie-container,#cookiebanner');
|
|
983
|
+
return tab.elementExists('#CybotCookiebotDialog,#dtcookie-container,#cookiebanner,#cb-cookiebanner');
|
|
952
984
|
}
|
|
953
985
|
async optOut(tab) {
|
|
954
986
|
if (await tab.elementExists('.cookie-alert-extended-detail-link')) {
|
|
@@ -987,6 +1019,10 @@ class Cookiebot extends AutoConsentBase {
|
|
|
987
1019
|
await tab.eval('Cookiebot.dialog.submitConsent() || true');
|
|
988
1020
|
await tab.wait(500);
|
|
989
1021
|
}
|
|
1022
|
+
// site with 3rd confirm settings modal
|
|
1023
|
+
if (await tab.elementExists('#cb-confirmedSettings')) {
|
|
1024
|
+
await tab.eval('endCookieProcess()');
|
|
1025
|
+
}
|
|
990
1026
|
return true;
|
|
991
1027
|
}
|
|
992
1028
|
async optIn(tab) {
|
|
@@ -1146,12 +1182,47 @@ class Evidon extends AutoConsentBase {
|
|
|
1146
1182
|
}
|
|
1147
1183
|
}
|
|
1148
1184
|
|
|
1185
|
+
class Onetrust extends AutoConsentBase {
|
|
1186
|
+
constructor() {
|
|
1187
|
+
super("Onetrust");
|
|
1188
|
+
this.prehideSelectors = ["#onetrust-banner-sdk,#onetrust-consent-sdk,.optanon-alert-box-wrapper,.onetrust-pc-dark-filter,.js-consent-banner"];
|
|
1189
|
+
}
|
|
1190
|
+
detectCmp(tab) {
|
|
1191
|
+
return tab.elementExists("#onetrust-banner-sdk,.optanon-alert-box-wrapper");
|
|
1192
|
+
}
|
|
1193
|
+
detectPopup(tab) {
|
|
1194
|
+
return tab.elementsAreVisible("#onetrust-banner-sdk,.optanon-alert-box-wrapper");
|
|
1195
|
+
}
|
|
1196
|
+
async optOut(tab) {
|
|
1197
|
+
if (await tab.elementExists("#onetrust-pc-btn-handler")) { // "show purposes" button inside a popup
|
|
1198
|
+
await success(tab.clickElement("#onetrust-pc-btn-handler"));
|
|
1199
|
+
}
|
|
1200
|
+
else { // otherwise look for a generic "show settings" button
|
|
1201
|
+
await success(tab.clickElement(".ot-sdk-show-settings,button.js-cookie-settings"));
|
|
1202
|
+
}
|
|
1203
|
+
await success(tab.waitForElement("#onetrust-consent-sdk", 2000));
|
|
1204
|
+
await success(tab.wait(1000));
|
|
1205
|
+
await tab.clickElements("#onetrust-consent-sdk input.category-switch-handler:checked,.js-editor-toggle-state:checked"); // optional step
|
|
1206
|
+
await success(tab.waitForThenClick(".save-preference-btn-handler,.js-consent-save", 1000));
|
|
1207
|
+
// popup doesn't disappear immediately
|
|
1208
|
+
await waitFor(async () => !(await tab.elementsAreVisible("#onetrust-banner-sdk")), 10, 500);
|
|
1209
|
+
return true;
|
|
1210
|
+
}
|
|
1211
|
+
async optIn(tab) {
|
|
1212
|
+
return tab.clickElement("onetrust-accept-btn-handler,js-accept-cookies");
|
|
1213
|
+
}
|
|
1214
|
+
async test(tab) {
|
|
1215
|
+
return tab.eval("window.OnetrustActiveGroups.split(',').filter(s => s.length > 0).length <= 1");
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1149
1219
|
const rules = [
|
|
1150
1220
|
new TrustArc(),
|
|
1151
1221
|
new Cookiebot(),
|
|
1152
1222
|
new SourcePoint(),
|
|
1153
1223
|
new ConsentManager(),
|
|
1154
1224
|
new Evidon(),
|
|
1225
|
+
new Onetrust(),
|
|
1155
1226
|
];
|
|
1156
1227
|
function createAutoCMP(config) {
|
|
1157
1228
|
return new AutoConsent(config);
|
|
@@ -1223,7 +1294,7 @@ async function prehideElements(tab, rules) {
|
|
|
1223
1294
|
}
|
|
1224
1295
|
return selectorList;
|
|
1225
1296
|
}, globalHidden);
|
|
1226
|
-
await tab.hideElements(selectors);
|
|
1297
|
+
await tab.hideElements(selectors, undefined, 'opacity');
|
|
1227
1298
|
}
|
|
1228
1299
|
|
|
1229
1300
|
class AutoConsent$1 {
|
package/dist/autoconsent.esm.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const enableLogs = false; // change this to enable debug logs
|
|
2
|
+
|
|
1
3
|
/* eslint-disable no-restricted-syntax,no-await-in-loop,no-underscore-dangle */
|
|
2
4
|
async function waitFor(predicate, maxTimes, interval) {
|
|
3
5
|
let result = await predicate();
|
|
@@ -13,7 +15,7 @@ async function waitFor(predicate, maxTimes, interval) {
|
|
|
13
15
|
async function success(action) {
|
|
14
16
|
const result = await action;
|
|
15
17
|
if (!result) {
|
|
16
|
-
throw new Error(`Action failed: ${action}`);
|
|
18
|
+
throw new Error(`Action failed: ${action} ${result}`);
|
|
17
19
|
}
|
|
18
20
|
return result;
|
|
19
21
|
}
|
|
@@ -177,7 +179,6 @@ class TabActions {
|
|
|
177
179
|
this.id = tabId;
|
|
178
180
|
}
|
|
179
181
|
async elementExists(selector, frameId = 0) {
|
|
180
|
-
console.log(`check for ${selector} in tab ${this.id}, frame ${frameId}`);
|
|
181
182
|
return this.sendContentMessage(this.id, {
|
|
182
183
|
type: "elemExists",
|
|
183
184
|
selector
|
|
@@ -186,7 +187,6 @@ class TabActions {
|
|
|
186
187
|
});
|
|
187
188
|
}
|
|
188
189
|
async clickElement(selector, frameId = 0) {
|
|
189
|
-
console.log(`click element ${selector} in tab ${this.id}`);
|
|
190
190
|
return this.sendContentMessage(this.id, {
|
|
191
191
|
type: "click",
|
|
192
192
|
selector
|
|
@@ -195,7 +195,6 @@ class TabActions {
|
|
|
195
195
|
});
|
|
196
196
|
}
|
|
197
197
|
async clickElements(selector, frameId = 0) {
|
|
198
|
-
console.log(`click elements ${selector} in tab ${this.id}`);
|
|
199
198
|
return this.sendContentMessage(this.id, {
|
|
200
199
|
type: "click",
|
|
201
200
|
all: true,
|
|
@@ -238,10 +237,11 @@ class TabActions {
|
|
|
238
237
|
}
|
|
239
238
|
return false;
|
|
240
239
|
}
|
|
241
|
-
async hideElements(selectors, frameId = 0) {
|
|
240
|
+
async hideElements(selectors, frameId = 0, method = 'display') {
|
|
242
241
|
return this.sendContentMessage(this.id, {
|
|
243
242
|
type: "hide",
|
|
244
|
-
selectors
|
|
243
|
+
selectors,
|
|
244
|
+
method,
|
|
245
245
|
}, { frameId });
|
|
246
246
|
}
|
|
247
247
|
async undoHideElements(frameId = 0) {
|
|
@@ -257,7 +257,9 @@ class TabActions {
|
|
|
257
257
|
}
|
|
258
258
|
wait(ms) {
|
|
259
259
|
return new Promise(resolve => {
|
|
260
|
-
setTimeout(() =>
|
|
260
|
+
setTimeout(() => {
|
|
261
|
+
resolve(true);
|
|
262
|
+
}, ms);
|
|
261
263
|
});
|
|
262
264
|
}
|
|
263
265
|
matches(matcherConfig) {
|
|
@@ -641,9 +643,37 @@ async function evalAction(config) {
|
|
|
641
643
|
});
|
|
642
644
|
}
|
|
643
645
|
|
|
646
|
+
// get or create a style container for CSS overrides
|
|
647
|
+
function getStyleElementUtil() {
|
|
648
|
+
const styleOverrideElementId = "autoconsent-css-rules";
|
|
649
|
+
const styleSelector = `style#${styleOverrideElementId}`;
|
|
650
|
+
const existingElement = document.querySelector(styleSelector);
|
|
651
|
+
if (existingElement && existingElement instanceof HTMLStyleElement) {
|
|
652
|
+
return existingElement;
|
|
653
|
+
}
|
|
654
|
+
else {
|
|
655
|
+
const parent = document.head ||
|
|
656
|
+
document.getElementsByTagName("head")[0] ||
|
|
657
|
+
document.documentElement;
|
|
658
|
+
const css = document.createElement("style");
|
|
659
|
+
css.id = styleOverrideElementId;
|
|
660
|
+
parent.appendChild(css);
|
|
661
|
+
return css;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
// hide elements with a CSS rule
|
|
665
|
+
function hideElementsUtil(selectors, method) {
|
|
666
|
+
const hidingSnippet = method === 'display' ? `display: none` : `opacity: 0`;
|
|
667
|
+
const rule = `${selectors.join(",")} { ${hidingSnippet} !important; z-index: -1 !important; pointer-events: none !important; } `;
|
|
668
|
+
const styleEl = getStyleElementUtil();
|
|
669
|
+
if (styleEl instanceof HTMLStyleElement) {
|
|
670
|
+
styleEl.innerText += rule;
|
|
671
|
+
return selectors.length > 0;
|
|
672
|
+
}
|
|
673
|
+
return false;
|
|
674
|
+
}
|
|
675
|
+
|
|
644
676
|
let actionQueue = Promise.resolve(null);
|
|
645
|
-
const styleOverrideElementId = "autoconsent-css-rules";
|
|
646
|
-
const styleSelector = `style#${styleOverrideElementId}`;
|
|
647
677
|
function handleMessage(message, debug = false) {
|
|
648
678
|
if (message.type === "click") {
|
|
649
679
|
const elem = document.querySelectorAll(message.selector);
|
|
@@ -667,8 +697,19 @@ function handleMessage(message, debug = false) {
|
|
|
667
697
|
const elem = document.querySelectorAll(message.selector);
|
|
668
698
|
const results = new Array(elem.length);
|
|
669
699
|
elem.forEach((e, i) => {
|
|
670
|
-
|
|
700
|
+
// check for display: none
|
|
701
|
+
results[i] = false;
|
|
702
|
+
if (e.offsetParent !== null) {
|
|
703
|
+
results[i] = true;
|
|
704
|
+
}
|
|
705
|
+
else {
|
|
706
|
+
const css = window.getComputedStyle(e);
|
|
707
|
+
if (css.position === 'fixed' && css.display !== "none") { // fixed elements may be visible even if the parent is not
|
|
708
|
+
results[i] = true;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
671
711
|
});
|
|
712
|
+
debug && console.log("[visible?]", message.selector, elem, results);
|
|
672
713
|
if (results.length === 0) {
|
|
673
714
|
return false;
|
|
674
715
|
}
|
|
@@ -683,6 +724,7 @@ function handleMessage(message, debug = false) {
|
|
|
683
724
|
}
|
|
684
725
|
else if (message.type === "getAttribute") {
|
|
685
726
|
const elem = document.querySelector(message.selector);
|
|
727
|
+
debug && console.log("[getAttribute]", message.selector, elem);
|
|
686
728
|
if (!elem) {
|
|
687
729
|
return false;
|
|
688
730
|
}
|
|
@@ -690,31 +732,16 @@ function handleMessage(message, debug = false) {
|
|
|
690
732
|
}
|
|
691
733
|
else if (message.type === "eval") {
|
|
692
734
|
// TODO: chrome support
|
|
735
|
+
debug && console.log("about to [eval]", message.script); // this will not show in Webkit console
|
|
693
736
|
const result = window.eval(message.script); // eslint-disable-line no-eval
|
|
694
|
-
debug && console.log("[eval]", message.script, result);
|
|
695
737
|
return result;
|
|
696
738
|
}
|
|
697
739
|
else if (message.type === "hide") {
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
document.documentElement;
|
|
701
|
-
const rule = `${message.selectors.join(",")} { display: none !important; z-index: -1 !important; } `;
|
|
702
|
-
const existingElement = document.querySelector(styleSelector);
|
|
703
|
-
debug && console.log("[hide]", message.selectors, !!existingElement);
|
|
704
|
-
if (existingElement && existingElement instanceof HTMLStyleElement) {
|
|
705
|
-
existingElement.innerText += rule;
|
|
706
|
-
}
|
|
707
|
-
else {
|
|
708
|
-
const css = document.createElement("style");
|
|
709
|
-
css.type = "text/css";
|
|
710
|
-
css.id = styleOverrideElementId;
|
|
711
|
-
css.appendChild(document.createTextNode(rule));
|
|
712
|
-
parent.appendChild(css);
|
|
713
|
-
}
|
|
714
|
-
return message.selectors.length > 0;
|
|
740
|
+
debug && console.log("[hide]", message.selectors);
|
|
741
|
+
return hideElementsUtil(message.selectors, message.method);
|
|
715
742
|
}
|
|
716
743
|
else if (message.type === "undohide") {
|
|
717
|
-
const existingElement =
|
|
744
|
+
const existingElement = getStyleElementUtil();
|
|
718
745
|
debug && console.log("[unhide]", !!existingElement);
|
|
719
746
|
if (existingElement) {
|
|
720
747
|
existingElement.remove();
|
|
@@ -723,9 +750,11 @@ function handleMessage(message, debug = false) {
|
|
|
723
750
|
}
|
|
724
751
|
else if (message.type === "matches") {
|
|
725
752
|
const matched = matches(message.config);
|
|
753
|
+
debug && console.log("[matches?]", message.config.type, JSON.stringify(message.config), matched);
|
|
726
754
|
return matched;
|
|
727
755
|
}
|
|
728
756
|
else if (message.type === "executeAction") {
|
|
757
|
+
debug && console.log("[executeAction]", message);
|
|
729
758
|
actionQueue = actionQueue.then(() => executeAction(message.config, message.param));
|
|
730
759
|
return true;
|
|
731
760
|
}
|
|
@@ -754,10 +783,12 @@ class TabConsent {
|
|
|
754
783
|
}
|
|
755
784
|
async doOptOut() {
|
|
756
785
|
try {
|
|
786
|
+
enableLogs && console.log(`doing opt out ${this.getCMPName()} in tab ${this.tab.id}`);
|
|
757
787
|
this.optOutStatus = await this.rule.optOut(this.tab);
|
|
758
788
|
return this.optOutStatus;
|
|
759
789
|
}
|
|
760
790
|
catch (e) {
|
|
791
|
+
console.error('error during opt out', e);
|
|
761
792
|
this.optOutStatus = e;
|
|
762
793
|
throw e;
|
|
763
794
|
}
|
|
@@ -802,6 +833,7 @@ async function detectDialog(tab, retries, rules) {
|
|
|
802
833
|
try {
|
|
803
834
|
if (await r.detectCmp(tab)) {
|
|
804
835
|
earlyReturn = true;
|
|
836
|
+
enableLogs && console.log(`Found CMP in [${tab.id}]: ${r.name}`);
|
|
805
837
|
resolve(index);
|
|
806
838
|
}
|
|
807
839
|
}
|
|
@@ -840,10 +872,10 @@ class TrustArc extends AutoConsentBase {
|
|
|
840
872
|
tab.frame.url.startsWith("https://consent-pref.trustarc.com/?")) {
|
|
841
873
|
return true;
|
|
842
874
|
}
|
|
843
|
-
return tab.elementExists("#truste-show-consent");
|
|
875
|
+
return tab.elementExists("#truste-show-consent,#truste-consent-track");
|
|
844
876
|
}
|
|
845
877
|
async detectPopup(tab) {
|
|
846
|
-
return ((await tab.elementsAreVisible("#truste-consent-content,#trustarc-banner-overlay")) ||
|
|
878
|
+
return ((await tab.elementsAreVisible("#truste-consent-content,.truste-consent-content,#trustarc-banner-overlay")) ||
|
|
847
879
|
(tab.frame &&
|
|
848
880
|
(await tab.waitForElement("#defaultpreferencemanager", 5000, tab.frame.id))));
|
|
849
881
|
}
|
|
@@ -933,7 +965,7 @@ class TrustArc extends AutoConsentBase {
|
|
|
933
965
|
class Cookiebot extends AutoConsentBase {
|
|
934
966
|
constructor() {
|
|
935
967
|
super('Cybotcookiebot');
|
|
936
|
-
this.prehideSelectors = ["#CybotCookiebotDialog,#dtcookie-container,#cookiebanner"];
|
|
968
|
+
this.prehideSelectors = ["#CybotCookiebotDialog,#dtcookie-container,#cookiebanner,#cb-cookieoverlay"];
|
|
937
969
|
}
|
|
938
970
|
async detectCmp(tab) {
|
|
939
971
|
try {
|
|
@@ -944,7 +976,7 @@ class Cookiebot extends AutoConsentBase {
|
|
|
944
976
|
}
|
|
945
977
|
}
|
|
946
978
|
detectPopup(tab) {
|
|
947
|
-
return tab.elementExists('#CybotCookiebotDialog,#dtcookie-container,#cookiebanner');
|
|
979
|
+
return tab.elementExists('#CybotCookiebotDialog,#dtcookie-container,#cookiebanner,#cb-cookiebanner');
|
|
948
980
|
}
|
|
949
981
|
async optOut(tab) {
|
|
950
982
|
if (await tab.elementExists('.cookie-alert-extended-detail-link')) {
|
|
@@ -983,6 +1015,10 @@ class Cookiebot extends AutoConsentBase {
|
|
|
983
1015
|
await tab.eval('Cookiebot.dialog.submitConsent() || true');
|
|
984
1016
|
await tab.wait(500);
|
|
985
1017
|
}
|
|
1018
|
+
// site with 3rd confirm settings modal
|
|
1019
|
+
if (await tab.elementExists('#cb-confirmedSettings')) {
|
|
1020
|
+
await tab.eval('endCookieProcess()');
|
|
1021
|
+
}
|
|
986
1022
|
return true;
|
|
987
1023
|
}
|
|
988
1024
|
async optIn(tab) {
|
|
@@ -1142,12 +1178,47 @@ class Evidon extends AutoConsentBase {
|
|
|
1142
1178
|
}
|
|
1143
1179
|
}
|
|
1144
1180
|
|
|
1181
|
+
class Onetrust extends AutoConsentBase {
|
|
1182
|
+
constructor() {
|
|
1183
|
+
super("Onetrust");
|
|
1184
|
+
this.prehideSelectors = ["#onetrust-banner-sdk,#onetrust-consent-sdk,.optanon-alert-box-wrapper,.onetrust-pc-dark-filter,.js-consent-banner"];
|
|
1185
|
+
}
|
|
1186
|
+
detectCmp(tab) {
|
|
1187
|
+
return tab.elementExists("#onetrust-banner-sdk,.optanon-alert-box-wrapper");
|
|
1188
|
+
}
|
|
1189
|
+
detectPopup(tab) {
|
|
1190
|
+
return tab.elementsAreVisible("#onetrust-banner-sdk,.optanon-alert-box-wrapper");
|
|
1191
|
+
}
|
|
1192
|
+
async optOut(tab) {
|
|
1193
|
+
if (await tab.elementExists("#onetrust-pc-btn-handler")) { // "show purposes" button inside a popup
|
|
1194
|
+
await success(tab.clickElement("#onetrust-pc-btn-handler"));
|
|
1195
|
+
}
|
|
1196
|
+
else { // otherwise look for a generic "show settings" button
|
|
1197
|
+
await success(tab.clickElement(".ot-sdk-show-settings,button.js-cookie-settings"));
|
|
1198
|
+
}
|
|
1199
|
+
await success(tab.waitForElement("#onetrust-consent-sdk", 2000));
|
|
1200
|
+
await success(tab.wait(1000));
|
|
1201
|
+
await tab.clickElements("#onetrust-consent-sdk input.category-switch-handler:checked,.js-editor-toggle-state:checked"); // optional step
|
|
1202
|
+
await success(tab.waitForThenClick(".save-preference-btn-handler,.js-consent-save", 1000));
|
|
1203
|
+
// popup doesn't disappear immediately
|
|
1204
|
+
await waitFor(async () => !(await tab.elementsAreVisible("#onetrust-banner-sdk")), 10, 500);
|
|
1205
|
+
return true;
|
|
1206
|
+
}
|
|
1207
|
+
async optIn(tab) {
|
|
1208
|
+
return tab.clickElement("onetrust-accept-btn-handler,js-accept-cookies");
|
|
1209
|
+
}
|
|
1210
|
+
async test(tab) {
|
|
1211
|
+
return tab.eval("window.OnetrustActiveGroups.split(',').filter(s => s.length > 0).length <= 1");
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1145
1215
|
const rules = [
|
|
1146
1216
|
new TrustArc(),
|
|
1147
1217
|
new Cookiebot(),
|
|
1148
1218
|
new SourcePoint(),
|
|
1149
1219
|
new ConsentManager(),
|
|
1150
1220
|
new Evidon(),
|
|
1221
|
+
new Onetrust(),
|
|
1151
1222
|
];
|
|
1152
1223
|
function createAutoCMP(config) {
|
|
1153
1224
|
return new AutoConsent(config);
|
|
@@ -1219,7 +1290,7 @@ async function prehideElements(tab, rules) {
|
|
|
1219
1290
|
}
|
|
1220
1291
|
return selectorList;
|
|
1221
1292
|
}, globalHidden);
|
|
1222
|
-
await tab.hideElements(selectors);
|
|
1293
|
+
await tab.hideElements(selectors, undefined, 'opacity');
|
|
1223
1294
|
}
|
|
1224
1295
|
|
|
1225
1296
|
class AutoConsent$1 {
|