forked from insightbrowser/scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprobable_autoclick.js
176 lines (134 loc) · 5.06 KB
/
probable_autoclick.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
(() => {
const COOKIES_MODAL_MIN_HEIGHT = 100.0;
const buildSelector = (element) => {
let currentElement = element;
let selectors = [];
while (currentElement) {
let id;
// Selector rule should not start with number
if (currentElement.id.trim() && !currentElement.id.trim().match('^\\d')) {
id = `#${ currentElement.id.trim() }`;
}
let selector = id || currentElement.tagName.toLowerCase();
const classes = [ ...currentElement.classList ];
if (classes.length) {
selector = `${ selector }.${ classes.join('.') }`;
}
selectors.unshift(selector);
if (currentElement === document.body ||
currentElement.parentElement && currentElement.parentElement === document.body) {
break;
}
currentElement = currentElement.parentElement;
}
return selectors;
};
const clickElement = (el, selector, tryCount) => {
el.click();
// If element still exists maybe it did not work correctly, try again
setTimeout(() => document.querySelector(selector) && tryCount < 3 && clickElement(el, selector, tryCount + 1), 250);
};
const hasFormAncestor = (element) => {
let parent = element.parentElement;
let hasForm = false;
while(parent) {
hasForm = parent instanceof HTMLFormElement
if (hasForm) { break; }
parent = parent.parentElement;
}
return hasForm
};
const isPossibleAcceptCookies = (element) => {
// We don't want to autoclick elements inside forms
if (hasFormAncestor(element)) {
return null;
}
// If anchor element, check that is does not have an href that navigates out of the page
if (element instanceof HTMLAnchorElement && element.href && !element.href.startsWith('#')) {
const href = element.href.replace(document.location.href, '');
if (!href.startsWith('#')) {
return null;
}
}
const mustHaveWords = [
'ok', 'accept', 'yes', 'continue', 'agree', 'allow',
'aceito', 'aceitar', 'sim', 'continuar', 'concordo', 'permitir', 'prosseguir',
'akzeptieren', 'ja', 'weiter', 'zustimmen', 'erlauben',
'好的', '接受', '是的', '继续', '同意', '允许',
];
// Since we don't know the order of the element we are testing in the modal
// Let's look for the ones with positive words
const innerText = element.innerText.toLocaleLowerCase();
if (!mustHaveWords.some((word) => innerText.match(`\\b${ word }\\b`))) {
return null;
}
const highestParent = () => {
let parent = element.parentElement;
if (parent === document.body) {
return null;
}
while (parent) {
if (!parent.parentElement ||
parent.parentElement === document.body ||
parent.parentElement.clientHeight === 0) { break; }
parent = parent.parentElement;
}
return parent;
};
const parent = highestParent();
const parentInnerText = parent.innerText.toLocaleLowerCase();
const foundCookies = parentInnerText.includes('cookie') || parentInnerText.includes('cookies');
const hasEnoughSize = parent.clientHeight >= COOKIES_MODAL_MIN_HEIGHT;
return foundCookies && hasEnoughSize ? element : null;
};
const run = () => {
const checkElementsIn = (element) => {
try {
const elements = Array.from(element.querySelectorAll('button, a'));
for (let element of elements) {
if (isPossibleAcceptCookies(element)) {
return element;
}
}
} catch {}
};
const buildRuleAndClick = (element) => {
if (!element) { return; }
const selector = buildSelector(element).join(' > ');
clickElement(element, selector, 0);
};
const possibleElement = checkElementsIn(document.body);
if (possibleElement) {
buildRuleAndClick(possibleElement);
} else {
const observer = new MutationObserver((mutationsList) => {
const findPossibleCookie = () => {
for(const mutation of mutationsList) {
if (mutation.type === 'childList') {
const nodes = Array.from(mutation.addedNodes);
for (const node of nodes) {
const isTarget = node instanceof HTMLButtonElement || node instanceof HTMLAnchorElement;
if (isTarget && isPossibleAcceptCookies(node)) {
return node;
} else if (node.nodeType == Node.ELEMENT_NODE) {
const possibleElement = checkElementsIn(node);
if (possibleElement) {
return possibleElement;
}
}
}
}
}
}
const element = findPossibleCookie();
if (element) {
buildRuleAndClick(element);
observer.disconnect();
}
});
observer.observe(document, { childList: true, subtree: true });
setTimeout(() => observer.disconnect(), 10 * 1000);
}
};
run();
})();