@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/lib/puppet/tab.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { waitFor } from '../cmps/base';
|
|
2
2
|
import Tools from '../web/consentomatic/tools';
|
|
3
3
|
import { matches } from '../web/consentomatic/index';
|
|
4
|
+
import { hideElementsUtil, getStyleElementUtil } from '../web/content-utils';
|
|
4
5
|
const DEBUG = false;
|
|
5
6
|
export default class Tab {
|
|
6
7
|
constructor(page, url, frames) {
|
|
@@ -9,6 +10,10 @@ export default class Tab {
|
|
|
9
10
|
this.page = page;
|
|
10
11
|
this.url = url;
|
|
11
12
|
this.frames = frames;
|
|
13
|
+
this._utilsSnippet = `
|
|
14
|
+
${getStyleElementUtil.toString()}
|
|
15
|
+
${hideElementsUtil.toString()}
|
|
16
|
+
`;
|
|
12
17
|
}
|
|
13
18
|
async elementExists(selector, frameId = 0) {
|
|
14
19
|
const elements = await this.frames[frameId].$$(selector);
|
|
@@ -84,9 +89,11 @@ export default class Tab {
|
|
|
84
89
|
}
|
|
85
90
|
return false;
|
|
86
91
|
}
|
|
87
|
-
async hideElements(selectors, frameId = 0) {
|
|
88
|
-
|
|
89
|
-
|
|
92
|
+
async hideElements(selectors, frameId = 0, method = 'display') {
|
|
93
|
+
return await this.frames[frameId].evaluate(`(() => {
|
|
94
|
+
${this._utilsSnippet}
|
|
95
|
+
return hideElementsUtil(${JSON.stringify(selectors)}, '${method}');
|
|
96
|
+
})()`);
|
|
90
97
|
}
|
|
91
98
|
undoHideElements(frameId) {
|
|
92
99
|
return Promise.resolve(true);
|
package/lib/puppet/tab.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { waitFor } from '../cmps/base';
|
|
|
2
2
|
import { TabActor } from '../types';
|
|
3
3
|
import Tools from '../web/consentomatic/tools';
|
|
4
4
|
import { matches } from '../web/consentomatic/index';
|
|
5
|
+
import { HideMethod } from '../messages';
|
|
6
|
+
import { hideElementsUtil, getStyleElementUtil } from '../web/content-utils';
|
|
5
7
|
|
|
6
8
|
const DEBUG = false;
|
|
7
9
|
|
|
@@ -17,10 +19,16 @@ export default class Tab implements TabActor {
|
|
|
17
19
|
url: string
|
|
18
20
|
}
|
|
19
21
|
|
|
22
|
+
_utilsSnippet: string // serialized RPC functions borrowed from content script
|
|
23
|
+
|
|
20
24
|
constructor(page: any, url: string, frames: { [id: number]: any }) {
|
|
21
25
|
this.page = page;
|
|
22
26
|
this.url = url;
|
|
23
27
|
this.frames = frames;
|
|
28
|
+
this._utilsSnippet = `
|
|
29
|
+
${getStyleElementUtil.toString()}
|
|
30
|
+
${hideElementsUtil.toString()}
|
|
31
|
+
`;
|
|
24
32
|
}
|
|
25
33
|
|
|
26
34
|
async elementExists(selector: string, frameId = 0) {
|
|
@@ -101,9 +109,11 @@ export default class Tab implements TabActor {
|
|
|
101
109
|
return false;
|
|
102
110
|
}
|
|
103
111
|
|
|
104
|
-
async hideElements(selectors: string[], frameId = 0) {
|
|
105
|
-
|
|
106
|
-
|
|
112
|
+
async hideElements(selectors: string[], frameId = 0, method: HideMethod = 'display') {
|
|
113
|
+
return await this.frames[frameId].evaluate(`(() => {
|
|
114
|
+
${this._utilsSnippet}
|
|
115
|
+
return hideElementsUtil(${JSON.stringify(selectors)}, '${method}');
|
|
116
|
+
})()`);
|
|
107
117
|
}
|
|
108
118
|
|
|
109
119
|
undoHideElements(frameId?: number): Promise<boolean> {
|
package/lib/tabwrapper.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { enableLogs } from './config';
|
|
1
2
|
export default class TabConsent {
|
|
2
3
|
constructor(tab, ruleCheckPromise) {
|
|
3
4
|
this.tab = tab;
|
|
@@ -12,23 +13,28 @@ export default class TabConsent {
|
|
|
12
13
|
return null;
|
|
13
14
|
}
|
|
14
15
|
async isPopupOpen(retries = 1, interval = 1000) {
|
|
16
|
+
enableLogs && console.log('checking if popup is open...', this.tab.id, this.rule.name);
|
|
15
17
|
const isOpen = await this.rule.detectPopup(this.tab);
|
|
16
18
|
if (!isOpen && retries > 0) {
|
|
17
19
|
return new Promise((resolve) => setTimeout(() => resolve(this.isPopupOpen(retries - 1, interval)), interval));
|
|
18
20
|
}
|
|
21
|
+
enableLogs && console.log(`popup is ${isOpen ? 'open' : 'not open'}`);
|
|
19
22
|
return isOpen;
|
|
20
23
|
}
|
|
21
24
|
async doOptOut() {
|
|
22
25
|
try {
|
|
26
|
+
enableLogs && console.log(`doing opt out ${this.getCMPName()} in tab ${this.tab.id}`);
|
|
23
27
|
this.optOutStatus = await this.rule.optOut(this.tab);
|
|
24
28
|
return this.optOutStatus;
|
|
25
29
|
}
|
|
26
30
|
catch (e) {
|
|
31
|
+
console.error('error during opt out', e);
|
|
27
32
|
this.optOutStatus = e;
|
|
28
33
|
throw e;
|
|
29
34
|
}
|
|
30
35
|
finally {
|
|
31
36
|
if (!this.rule.isHidingRule) {
|
|
37
|
+
enableLogs && console.log('unhiding elements');
|
|
32
38
|
if (this.getCMPName().startsWith('com_')) {
|
|
33
39
|
this.tab.wait(5000).then(() => this.tab.undoHideElements());
|
|
34
40
|
}
|
package/lib/tabwrapper.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { enableLogs } from './config';
|
|
1
2
|
import { AutoCMP, TabActor } from './types';
|
|
2
3
|
|
|
3
4
|
export default class TabConsent {
|
|
@@ -18,22 +19,27 @@ export default class TabConsent {
|
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
async isPopupOpen(retries = 1, interval = 1000): Promise<boolean> {
|
|
22
|
+
enableLogs && console.log('checking if popup is open...', this.tab.id, this.rule.name);
|
|
21
23
|
const isOpen = await this.rule.detectPopup(this.tab);
|
|
22
24
|
if (!isOpen && retries > 0) {
|
|
23
25
|
return new Promise((resolve) => setTimeout(() => resolve(this.isPopupOpen(retries - 1, interval)), interval));
|
|
24
26
|
}
|
|
27
|
+
enableLogs && console.log(`popup is ${isOpen ? 'open' : 'not open'}`);
|
|
25
28
|
return isOpen;
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
async doOptOut() {
|
|
29
32
|
try {
|
|
33
|
+
enableLogs && console.log(`doing opt out ${this.getCMPName()} in tab ${this.tab.id}`);
|
|
30
34
|
this.optOutStatus = await this.rule.optOut(this.tab);
|
|
31
35
|
return this.optOutStatus;
|
|
32
36
|
} catch (e) {
|
|
37
|
+
console.error('error during opt out', e);
|
|
33
38
|
this.optOutStatus = e;
|
|
34
39
|
throw e;
|
|
35
40
|
} finally {
|
|
36
41
|
if (!this.rule.isHidingRule) {
|
|
42
|
+
enableLogs && console.log('unhiding elements');
|
|
37
43
|
if (this.getCMPName().startsWith('com_')) {
|
|
38
44
|
this.tab.wait(5000).then(() => this.tab.undoHideElements())
|
|
39
45
|
} else {
|
package/lib/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ContentScriptMessage } from "./messages";
|
|
1
|
+
import { ContentScriptMessage, HideMethod } from "./messages";
|
|
2
2
|
|
|
3
3
|
type Tab = {
|
|
4
4
|
url: string
|
|
@@ -27,7 +27,7 @@ export interface TabActor {
|
|
|
27
27
|
eval(script: string, frameId?: number): Promise<boolean>
|
|
28
28
|
waitForElement(selector: string, timeout: number, frameId?: number): Promise<boolean>
|
|
29
29
|
waitForThenClick(selector: string, timeout?: number, frameId?: number): Promise<boolean>
|
|
30
|
-
hideElements(selectors: string[], frameId?: number): Promise<boolean>
|
|
30
|
+
hideElements(selectors: string[], frameId?: number, method?: HideMethod): Promise<boolean>
|
|
31
31
|
undoHideElements(frameId?: number): Promise<boolean>
|
|
32
32
|
goto(url: string): Promise<void>
|
|
33
33
|
wait(ms: number): Promise<true>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// get or create a style container for CSS overrides
|
|
2
|
+
export function getStyleElementUtil() {
|
|
3
|
+
const styleOverrideElementId = "autoconsent-css-rules";
|
|
4
|
+
const styleSelector = `style#${styleOverrideElementId}`;
|
|
5
|
+
const existingElement = document.querySelector(styleSelector);
|
|
6
|
+
if (existingElement && existingElement instanceof HTMLStyleElement) {
|
|
7
|
+
return existingElement;
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
const parent = document.head ||
|
|
11
|
+
document.getElementsByTagName("head")[0] ||
|
|
12
|
+
document.documentElement;
|
|
13
|
+
const css = document.createElement("style");
|
|
14
|
+
css.id = styleOverrideElementId;
|
|
15
|
+
parent.appendChild(css);
|
|
16
|
+
return css;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
// hide elements with a CSS rule
|
|
20
|
+
export function hideElementsUtil(selectors, method) {
|
|
21
|
+
const hidingSnippet = method === 'display' ? `display: none` : `opacity: 0`;
|
|
22
|
+
const rule = `${selectors.join(",")} { ${hidingSnippet} !important; z-index: -1 !important; pointer-events: none !important; } `;
|
|
23
|
+
const styleEl = getStyleElementUtil();
|
|
24
|
+
if (styleEl instanceof HTMLStyleElement) {
|
|
25
|
+
styleEl.innerText += rule;
|
|
26
|
+
return selectors.length > 0;
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { HideMethod } from "../messages";
|
|
2
|
+
|
|
3
|
+
// get or create a style container for CSS overrides
|
|
4
|
+
export function getStyleElementUtil(): HTMLStyleElement {
|
|
5
|
+
const styleOverrideElementId = "autoconsent-css-rules";
|
|
6
|
+
const styleSelector = `style#${styleOverrideElementId}`;
|
|
7
|
+
const existingElement = document.querySelector(styleSelector);
|
|
8
|
+
if (existingElement && existingElement instanceof HTMLStyleElement) {
|
|
9
|
+
return existingElement;
|
|
10
|
+
} else {
|
|
11
|
+
const parent = document.head ||
|
|
12
|
+
document.getElementsByTagName("head")[0] ||
|
|
13
|
+
document.documentElement;
|
|
14
|
+
const css = document.createElement("style");
|
|
15
|
+
css.id = styleOverrideElementId;
|
|
16
|
+
parent.appendChild(css);
|
|
17
|
+
return css;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// hide elements with a CSS rule
|
|
22
|
+
export function hideElementsUtil(selectors: string[], method: HideMethod): boolean {
|
|
23
|
+
const hidingSnippet = method === 'display' ? `display: none` : `opacity: 0`;
|
|
24
|
+
const rule = `${selectors.join(",")} { ${hidingSnippet} !important; z-index: -1 !important; pointer-events: none !important; } `;
|
|
25
|
+
const styleEl = getStyleElementUtil();
|
|
26
|
+
if (styleEl instanceof HTMLStyleElement) {
|
|
27
|
+
styleEl.innerText += rule;
|
|
28
|
+
return selectors.length > 0;
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
}
|
package/lib/web/content.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { matches, executeAction } from "./consentomatic/index";
|
|
2
|
+
import { hideElementsUtil, getStyleElementUtil } from "./content-utils";
|
|
2
3
|
let actionQueue = Promise.resolve(null);
|
|
3
|
-
const styleOverrideElementId = "autoconsent-css-rules";
|
|
4
|
-
const styleSelector = `style#${styleOverrideElementId}`;
|
|
5
4
|
export default function handleMessage(message, debug = false) {
|
|
6
5
|
if (message.type === "click") {
|
|
7
6
|
const elem = document.querySelectorAll(message.selector);
|
|
@@ -25,8 +24,19 @@ export default function handleMessage(message, debug = false) {
|
|
|
25
24
|
const elem = document.querySelectorAll(message.selector);
|
|
26
25
|
const results = new Array(elem.length);
|
|
27
26
|
elem.forEach((e, i) => {
|
|
28
|
-
|
|
27
|
+
// check for display: none
|
|
28
|
+
results[i] = false;
|
|
29
|
+
if (e.offsetParent !== null) {
|
|
30
|
+
results[i] = true;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const css = window.getComputedStyle(e);
|
|
34
|
+
if (css.position === 'fixed' && css.display !== "none") { // fixed elements may be visible even if the parent is not
|
|
35
|
+
results[i] = true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
29
38
|
});
|
|
39
|
+
debug && console.log("[visible?]", message.selector, elem, results);
|
|
30
40
|
if (results.length === 0) {
|
|
31
41
|
return false;
|
|
32
42
|
}
|
|
@@ -41,6 +51,7 @@ export default function handleMessage(message, debug = false) {
|
|
|
41
51
|
}
|
|
42
52
|
else if (message.type === "getAttribute") {
|
|
43
53
|
const elem = document.querySelector(message.selector);
|
|
54
|
+
debug && console.log("[getAttribute]", message.selector, elem);
|
|
44
55
|
if (!elem) {
|
|
45
56
|
return false;
|
|
46
57
|
}
|
|
@@ -48,31 +59,16 @@ export default function handleMessage(message, debug = false) {
|
|
|
48
59
|
}
|
|
49
60
|
else if (message.type === "eval") {
|
|
50
61
|
// TODO: chrome support
|
|
62
|
+
debug && console.log("about to [eval]", message.script); // this will not show in Webkit console
|
|
51
63
|
const result = window.eval(message.script); // eslint-disable-line no-eval
|
|
52
|
-
debug && console.log("[eval]", message.script, result);
|
|
53
64
|
return result;
|
|
54
65
|
}
|
|
55
66
|
else if (message.type === "hide") {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
document.documentElement;
|
|
59
|
-
const rule = `${message.selectors.join(",")} { display: none !important; z-index: -1 !important; } `;
|
|
60
|
-
const existingElement = document.querySelector(styleSelector);
|
|
61
|
-
debug && console.log("[hide]", message.selectors, !!existingElement);
|
|
62
|
-
if (existingElement && existingElement instanceof HTMLStyleElement) {
|
|
63
|
-
existingElement.innerText += rule;
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
const css = document.createElement("style");
|
|
67
|
-
css.type = "text/css";
|
|
68
|
-
css.id = styleOverrideElementId;
|
|
69
|
-
css.appendChild(document.createTextNode(rule));
|
|
70
|
-
parent.appendChild(css);
|
|
71
|
-
}
|
|
72
|
-
return message.selectors.length > 0;
|
|
67
|
+
debug && console.log("[hide]", message.selectors);
|
|
68
|
+
return hideElementsUtil(message.selectors, message.method);
|
|
73
69
|
}
|
|
74
70
|
else if (message.type === "undohide") {
|
|
75
|
-
const existingElement =
|
|
71
|
+
const existingElement = getStyleElementUtil();
|
|
76
72
|
debug && console.log("[unhide]", !!existingElement);
|
|
77
73
|
if (existingElement) {
|
|
78
74
|
existingElement.remove();
|
|
@@ -81,9 +77,11 @@ export default function handleMessage(message, debug = false) {
|
|
|
81
77
|
}
|
|
82
78
|
else if (message.type === "matches") {
|
|
83
79
|
const matched = matches(message.config);
|
|
80
|
+
debug && console.log("[matches?]", message.config.type, JSON.stringify(message.config), matched);
|
|
84
81
|
return matched;
|
|
85
82
|
}
|
|
86
83
|
else if (message.type === "executeAction") {
|
|
84
|
+
debug && console.log("[executeAction]", message);
|
|
87
85
|
actionQueue = actionQueue.then(() => executeAction(message.config, message.param));
|
|
88
86
|
return true;
|
|
89
87
|
}
|
package/lib/web/content.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { matches, executeAction } from "./consentomatic/index";
|
|
2
2
|
import { ContentScriptMessage } from "../messages";
|
|
3
|
+
import { hideElementsUtil, getStyleElementUtil } from "./content-utils";
|
|
3
4
|
|
|
4
5
|
let actionQueue = Promise.resolve(null);
|
|
5
|
-
const styleOverrideElementId = "autoconsent-css-rules";
|
|
6
|
-
const styleSelector = `style#${styleOverrideElementId}`;
|
|
7
6
|
|
|
8
7
|
export default function handleMessage(message: ContentScriptMessage, debug = false) {
|
|
9
8
|
if (message.type === "click") {
|
|
@@ -25,8 +24,18 @@ export default function handleMessage(message: ContentScriptMessage, debug = fal
|
|
|
25
24
|
const elem = document.querySelectorAll<HTMLElement>(message.selector);
|
|
26
25
|
const results = new Array(elem.length);
|
|
27
26
|
elem.forEach((e, i) => {
|
|
28
|
-
|
|
27
|
+
// check for display: none
|
|
28
|
+
results[i] = false;
|
|
29
|
+
if (e.offsetParent !== null) {
|
|
30
|
+
results[i] = true;
|
|
31
|
+
} else {
|
|
32
|
+
const css = window.getComputedStyle(e);
|
|
33
|
+
if (css.position === 'fixed' && css.display !== "none") { // fixed elements may be visible even if the parent is not
|
|
34
|
+
results[i] = true;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
29
37
|
});
|
|
38
|
+
debug && console.log("[visible?]", message.selector, elem, results);
|
|
30
39
|
if (results.length === 0) {
|
|
31
40
|
return false;
|
|
32
41
|
} else if (message.check === "any") {
|
|
@@ -38,35 +47,21 @@ export default function handleMessage(message: ContentScriptMessage, debug = fal
|
|
|
38
47
|
return results.every(r => r);
|
|
39
48
|
} else if (message.type === "getAttribute") {
|
|
40
49
|
const elem = document.querySelector(message.selector);
|
|
50
|
+
debug && console.log("[getAttribute]", message.selector, elem);
|
|
41
51
|
if (!elem) {
|
|
42
52
|
return false;
|
|
43
53
|
}
|
|
44
54
|
return elem.getAttribute(message.attribute);
|
|
45
55
|
} else if (message.type === "eval") {
|
|
46
56
|
// TODO: chrome support
|
|
57
|
+
debug && console.log("about to [eval]", message.script); // this will not show in Webkit console
|
|
47
58
|
const result = window.eval(message.script); // eslint-disable-line no-eval
|
|
48
|
-
debug && console.log("[eval]", message.script, result);
|
|
49
59
|
return result;
|
|
50
60
|
} else if (message.type === "hide") {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
document.getElementsByTagName("head")[0] ||
|
|
54
|
-
document.documentElement;
|
|
55
|
-
const rule = `${message.selectors.join(",")} { display: none !important; z-index: -1 !important; } `;
|
|
56
|
-
const existingElement = document.querySelector(styleSelector);
|
|
57
|
-
debug && console.log("[hide]", message.selectors, !!existingElement);
|
|
58
|
-
if (existingElement && existingElement instanceof HTMLStyleElement) {
|
|
59
|
-
existingElement.innerText += rule;
|
|
60
|
-
} else {
|
|
61
|
-
const css = document.createElement("style");
|
|
62
|
-
css.type = "text/css";
|
|
63
|
-
css.id = styleOverrideElementId;
|
|
64
|
-
css.appendChild(document.createTextNode(rule));
|
|
65
|
-
parent.appendChild(css);
|
|
66
|
-
}
|
|
67
|
-
return message.selectors.length > 0;
|
|
61
|
+
debug && console.log("[hide]", message.selectors);
|
|
62
|
+
return hideElementsUtil(message.selectors, message.method);
|
|
68
63
|
} else if (message.type === "undohide") {
|
|
69
|
-
const existingElement =
|
|
64
|
+
const existingElement = getStyleElementUtil();
|
|
70
65
|
debug && console.log("[unhide]", !!existingElement);
|
|
71
66
|
if (existingElement) {
|
|
72
67
|
existingElement.remove();
|
|
@@ -74,8 +69,10 @@ export default function handleMessage(message: ContentScriptMessage, debug = fal
|
|
|
74
69
|
return !!existingElement
|
|
75
70
|
} else if (message.type === "matches") {
|
|
76
71
|
const matched = matches(message.config);
|
|
72
|
+
debug && console.log("[matches?]", message.config.type, JSON.stringify(message.config), matched);
|
|
77
73
|
return matched;
|
|
78
74
|
} else if (message.type === "executeAction") {
|
|
75
|
+
debug && console.log("[executeAction]", message);
|
|
79
76
|
actionQueue = actionQueue.then(() => executeAction(message.config, message.param));
|
|
80
77
|
return true;
|
|
81
78
|
}
|
package/lib/web/tab.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { waitFor } from "../cmps/base";
|
|
2
|
+
import { enableLogs } from "../config";
|
|
2
3
|
export default class TabActions {
|
|
3
4
|
constructor(tabId, frame, sendContentMessage, browser) {
|
|
4
5
|
this.frame = frame;
|
|
@@ -7,7 +8,6 @@ export default class TabActions {
|
|
|
7
8
|
this.id = tabId;
|
|
8
9
|
}
|
|
9
10
|
async elementExists(selector, frameId = 0) {
|
|
10
|
-
console.log(`check for ${selector} in tab ${this.id}, frame ${frameId}`);
|
|
11
11
|
return this.sendContentMessage(this.id, {
|
|
12
12
|
type: "elemExists",
|
|
13
13
|
selector
|
|
@@ -16,7 +16,7 @@ export default class TabActions {
|
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
18
|
async clickElement(selector, frameId = 0) {
|
|
19
|
-
console.log(`click element ${selector} in tab ${this.id}`);
|
|
19
|
+
enableLogs && console.log(`click element ${selector} in tab ${this.id}`);
|
|
20
20
|
return this.sendContentMessage(this.id, {
|
|
21
21
|
type: "click",
|
|
22
22
|
selector
|
|
@@ -25,7 +25,7 @@ export default class TabActions {
|
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
async clickElements(selector, frameId = 0) {
|
|
28
|
-
console.log(`click elements ${selector} in tab ${this.id}`);
|
|
28
|
+
enableLogs && console.log(`click elements ${selector} in tab ${this.id}`);
|
|
29
29
|
return this.sendContentMessage(this.id, {
|
|
30
30
|
type: "click",
|
|
31
31
|
all: true,
|
|
@@ -68,10 +68,12 @@ export default class TabActions {
|
|
|
68
68
|
}
|
|
69
69
|
return false;
|
|
70
70
|
}
|
|
71
|
-
async hideElements(selectors, frameId = 0) {
|
|
71
|
+
async hideElements(selectors, frameId = 0, method = 'display') {
|
|
72
|
+
enableLogs && console.log('Sending hide elements to', this.id, selectors);
|
|
72
73
|
return this.sendContentMessage(this.id, {
|
|
73
74
|
type: "hide",
|
|
74
|
-
selectors
|
|
75
|
+
selectors,
|
|
76
|
+
method,
|
|
75
77
|
}, { frameId });
|
|
76
78
|
}
|
|
77
79
|
async undoHideElements(frameId = 0) {
|
|
@@ -86,8 +88,12 @@ export default class TabActions {
|
|
|
86
88
|
return this.browser.tabs.update(this.id, { url });
|
|
87
89
|
}
|
|
88
90
|
wait(ms) {
|
|
91
|
+
enableLogs && console.log(`waiting for ${ms}ms in tab ${this.id}`);
|
|
89
92
|
return new Promise(resolve => {
|
|
90
|
-
setTimeout(() =>
|
|
93
|
+
setTimeout(() => {
|
|
94
|
+
enableLogs && console.log(`done waiting in tab ${this.id}`);
|
|
95
|
+
resolve(true);
|
|
96
|
+
}, ms);
|
|
91
97
|
});
|
|
92
98
|
}
|
|
93
99
|
matches(matcherConfig) {
|
package/lib/web/tab.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { waitFor } from "../cmps/base";
|
|
2
|
+
import { enableLogs } from "../config";
|
|
3
|
+
import { HideMethod } from "../messages";
|
|
2
4
|
import { TabActor, MessageSender, Browser } from "../types";
|
|
3
5
|
|
|
4
6
|
export default class TabActions implements TabActor {
|
|
@@ -14,7 +16,6 @@ export default class TabActions implements TabActor {
|
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
async elementExists(selector: string, frameId = 0) {
|
|
17
|
-
console.log(`check for ${selector} in tab ${this.id}, frame ${frameId}`);
|
|
18
19
|
return this.sendContentMessage(
|
|
19
20
|
this.id,
|
|
20
21
|
{
|
|
@@ -28,7 +29,7 @@ export default class TabActions implements TabActor {
|
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
async clickElement(selector: string, frameId = 0) {
|
|
31
|
-
console.log(`click element ${selector} in tab ${this.id}`);
|
|
32
|
+
enableLogs && console.log(`click element ${selector} in tab ${this.id}`);
|
|
32
33
|
return this.sendContentMessage(
|
|
33
34
|
this.id,
|
|
34
35
|
{
|
|
@@ -42,7 +43,7 @@ export default class TabActions implements TabActor {
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
async clickElements(selector: string, frameId = 0) {
|
|
45
|
-
console.log(`click elements ${selector} in tab ${this.id}`);
|
|
46
|
+
enableLogs && console.log(`click elements ${selector} in tab ${this.id}`);
|
|
46
47
|
return this.sendContentMessage(
|
|
47
48
|
this.id,
|
|
48
49
|
{
|
|
@@ -111,12 +112,14 @@ export default class TabActions implements TabActor {
|
|
|
111
112
|
return false;
|
|
112
113
|
}
|
|
113
114
|
|
|
114
|
-
async hideElements(selectors: string[], frameId = 0) {
|
|
115
|
+
async hideElements(selectors: string[], frameId = 0, method: HideMethod = 'display') {
|
|
116
|
+
enableLogs && console.log('Sending hide elements to', this.id, selectors);
|
|
115
117
|
return this.sendContentMessage(
|
|
116
118
|
this.id,
|
|
117
119
|
{
|
|
118
120
|
type: "hide",
|
|
119
|
-
selectors
|
|
121
|
+
selectors,
|
|
122
|
+
method,
|
|
120
123
|
},
|
|
121
124
|
{ frameId }
|
|
122
125
|
);
|
|
@@ -141,8 +144,12 @@ export default class TabActions implements TabActor {
|
|
|
141
144
|
}
|
|
142
145
|
|
|
143
146
|
wait(ms: number): Promise<true> {
|
|
147
|
+
enableLogs && console.log(`waiting for ${ms}ms in tab ${this.id}`);
|
|
144
148
|
return new Promise(resolve => {
|
|
145
|
-
setTimeout(() =>
|
|
149
|
+
setTimeout(() => {
|
|
150
|
+
enableLogs && console.log(`done waiting in tab ${this.id}`);
|
|
151
|
+
resolve(true);
|
|
152
|
+
}, ms);
|
|
146
153
|
});
|
|
147
154
|
}
|
|
148
155
|
|
package/lib/web.js
CHANGED
|
@@ -5,6 +5,7 @@ import detectDialog from './detector';
|
|
|
5
5
|
import { rules, createAutoCMP } from './index';
|
|
6
6
|
import { ConsentOMaticCMP } from './consentomatic/index';
|
|
7
7
|
import prehideElements from './hider';
|
|
8
|
+
import { enableLogs } from './config';
|
|
8
9
|
export * from './index';
|
|
9
10
|
export { Tab, handleContentMessage, };
|
|
10
11
|
export default class AutoConsent {
|
|
@@ -29,6 +30,7 @@ export default class AutoConsent {
|
|
|
29
30
|
return new Tab(tabId, this.consentFrames.get(tabId), this.sendContentMessage, this.browser);
|
|
30
31
|
}
|
|
31
32
|
async checkTab(tabId, prehide = true) {
|
|
33
|
+
enableLogs && console.log('checking tab', tabId, this.consentFrames, this.tabCmps);
|
|
32
34
|
const tab = this.createTab(tabId);
|
|
33
35
|
if (prehide) {
|
|
34
36
|
this.prehideElements(tab);
|
|
@@ -39,12 +41,15 @@ export default class AutoConsent {
|
|
|
39
41
|
consent.checked.then((rule) => {
|
|
40
42
|
if (this.consentFrames.has(tabId) && rule) {
|
|
41
43
|
const frame = this.consentFrames.get(tabId);
|
|
44
|
+
enableLogs && console.log(`Found ${rule.name} in a nested iframe ${frame.id} inside tab ${tabId}`);
|
|
42
45
|
if (frame.type === rule.name) {
|
|
43
46
|
consent.tab.frame = frame;
|
|
44
47
|
}
|
|
45
48
|
}
|
|
49
|
+
enableLogs && console.log('finished checking tab', tabId, this.consentFrames, this.tabCmps);
|
|
46
50
|
// no CMP detected, undo hiding
|
|
47
51
|
if (!rule && prehide) {
|
|
52
|
+
enableLogs && console.log('no CMP detected, undo hiding');
|
|
48
53
|
tab.undoHideElements();
|
|
49
54
|
}
|
|
50
55
|
});
|
package/lib/web.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { Browser, MessageSender, AutoCMP, TabActor } from './types';
|
|
|
7
7
|
import { ConsentOMaticCMP, ConsentOMaticConfig } from './consentomatic/index';
|
|
8
8
|
import { AutoConsentCMPRule } from './rules';
|
|
9
9
|
import prehideElements from './hider';
|
|
10
|
+
import { enableLogs } from './config';
|
|
10
11
|
|
|
11
12
|
export * from './index';
|
|
12
13
|
export {
|
|
@@ -44,6 +45,7 @@ export default class AutoConsent {
|
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
async checkTab(tabId: number, prehide = true) {
|
|
48
|
+
enableLogs && console.log('checking tab', tabId, this.consentFrames, this.tabCmps);
|
|
47
49
|
const tab = this.createTab(tabId);
|
|
48
50
|
if (prehide) {
|
|
49
51
|
this.prehideElements(tab);
|
|
@@ -54,12 +56,15 @@ export default class AutoConsent {
|
|
|
54
56
|
consent.checked.then((rule) => {
|
|
55
57
|
if (this.consentFrames.has(tabId) && rule) {
|
|
56
58
|
const frame = this.consentFrames.get(tabId);
|
|
59
|
+
enableLogs && console.log(`Found ${rule.name} in a nested iframe ${frame.id} inside tab ${tabId}`);
|
|
57
60
|
if (frame.type === rule.name) {
|
|
58
61
|
consent.tab.frame = frame;
|
|
59
62
|
}
|
|
60
63
|
}
|
|
64
|
+
enableLogs && console.log('finished checking tab', tabId, this.consentFrames, this.tabCmps);
|
|
61
65
|
// no CMP detected, undo hiding
|
|
62
66
|
if (!rule && prehide) {
|
|
67
|
+
enableLogs && console.log('no CMP detected, undo hiding');
|
|
63
68
|
tab.undoHideElements();
|
|
64
69
|
}
|
|
65
70
|
});
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -84,7 +84,7 @@ Returns true if an element returned from `document.querySelect(selector)` is cur
|
|
|
84
84
|
"eval": "code"
|
|
85
85
|
}
|
|
86
86
|
```
|
|
87
|
-
Evaluates `code` in the context of the page
|
|
87
|
+
Evaluates `code` in the context of the page. NB: the result of this action depends on the truthiness of the evaluated expression, make sure it returns `true` in case of success.
|
|
88
88
|
|
|
89
89
|
#### Wait for element
|
|
90
90
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "192.com",
|
|
3
|
+
"detectCmp": [{ "exists": ".ont-cookies"}],
|
|
4
|
+
"detectPopup": [{ "visible": ".ont-cookies" }],
|
|
5
|
+
"optIn": [{ "click": ".ont-btn-main.ont-cookies-btn.js-ont-btn-ok2" }],
|
|
6
|
+
"optOut": [
|
|
7
|
+
{
|
|
8
|
+
"click": ".ont-cookes-btn-manage"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"click": ".ont-btn-main.ont-cookies-btn.js-ont-btn-choose"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"test": [
|
|
15
|
+
{"eval": "document.cookie.includes('CC_ADVERTISING=NO') && document.cookie.includes('CC_ANALYTICS=NO')"}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aws.amazon.com",
|
|
3
|
-
"prehideSelectors": ["#awsccc-cb-content", "#awsccc-cs-container-inner"],
|
|
3
|
+
"prehideSelectors": ["#awsccc-cb-content", "#awsccc-cs-container", "#awsccc-cs-modalOverlay", "#awsccc-cs-container-inner"],
|
|
4
4
|
"detectCmp": [{ "exists": "#awsccc-cb-content" }],
|
|
5
5
|
"detectPopup": [{ "visible": "#awsccc-cb-content" }],
|
|
6
6
|
"optIn": [{ "click": "button[data-id=awsccc-cb-btn-accept" }],
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bing.com",
|
|
3
|
+
"prehideSelectors": ["#bnp_container"],
|
|
4
|
+
"detectCmp": [{ "exists": "#bnp_cookie_banner"}],
|
|
5
|
+
"detectPopup": [{ "visible": "#bnp_cookie_banner" }],
|
|
6
|
+
"optIn": [{ "click": "#bnp_btn_accept" }],
|
|
7
|
+
"optOut": [
|
|
8
|
+
{ "click": "#bnp_btn_preference"},
|
|
9
|
+
{ "click": "#mcp_savesettings"}
|
|
10
|
+
],
|
|
11
|
+
"test": [
|
|
12
|
+
{ "eval": "document.cookie.includes('AL=0') && document.cookie.includes('AD=0') && document.cookie.includes('SM=0')"}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "bundesregierung.de",
|
|
3
3
|
"prehideSelectors": [".bpa-cookie-banner"],
|
|
4
4
|
"detectCmp": [{ "exists": ".bpa-cookie-banner" }],
|
|
5
|
-
"detectPopup": [{ "visible": ".bpa-module-full-hero" }],
|
|
5
|
+
"detectPopup": [{ "visible": ".bpa-cookie-banner .bpa-module-full-hero" }],
|
|
6
6
|
"optIn": [{ "click": ".bpa-accept-all-button" }],
|
|
7
7
|
"optOut": [
|
|
8
8
|
{
|