This repository has been archived by the owner on Nov 21, 2022. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 13
/
opt-out-ext.js
114 lines (103 loc) · 3.36 KB
/
opt-out-ext.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
let selector;
let option = 'text_crossed';
let slider = '1';
function updateOption(result) {
option = result.optOut.selector;
slider = result.optOut.slider;
}
function onError(error) {
console.log(`Error: ${error}`);
}
browser.storage.sync.get('optOut').then(updateOption, onError);
const root = document.getElementById('doc') || document.getElementById('react-root');
if (document.querySelector('body').classList.contains('logged-out')) {
console.log('offline');
selector = '.tweet';
} else {
console.log('online');
selector = '[data-testid="tweet"]';
}
/*
Depending on `option` sets classes to tweet nodes
*/
const styleTweet = function (element, selectedOption, sliderValue) {
if ((selectedOption === 'text_white') && (sliderValue === '1')) element.classList.add('opt-out-tw');
else element.classList.remove('opt-out-tw');
if ((selectedOption === 'text_crossed') && (sliderValue === '1')) element.classList.add('opt-out-tc');
else element.classList.remove('opt-out-tc');
if ((selectedOption === 'text_removed') && (sliderValue === '1')) element.classList.add('opt-out-trem');
else element.classList.remove('opt-out-trem');
};
/*
function which calls server for given node, and depending on the response,
applies pre-defined action
*/
const checkText = function (node) {
console.log('Sending Request');
const link = 'https://api.optoutools.com/predict';
const xhr = new XMLHttpRequest();
xhr.open('POST', link, true);
xhr.setRequestHeader('Content-type', 'application/json;charset=UTF-8');
xhr.withCredentials = true;
xhr.onreadystatechange = function (e) {
if (xhr.readyState !== 4) {
return;
}
if (xhr.status === 200) {
console.log(
'Response received as ',
JSON.parse(xhr.response).predictions[0],
);
if (JSON.parse(xhr.response).predictions[0]) {
node.classList.add('processed-true');
const tweetText = node.querySelector(
`${selector} > div ~ div > div ~ div`,
);
styleTweet(tweetText, option, slider);
} else {
node.classList.add('processed-false');
}
} else {
console.error(e);
console.log('Failed response', xhr);
}
};
xhr.send(
JSON.stringify({
texts: [node.innerText],
}),
);
};
/*
* Predefines action and changes it depending on user action
*/
browser.runtime.onMessage.addListener((message) => {
if ((option !== message.selector) || (slider !== message.slider)) {
option = message.selector;
slider = message.slider;
const posts = document.querySelectorAll('.processed-true');
posts.forEach((post) => {
const tweetText = post.querySelector(
`${selector} > div ~ div > div ~ div`,
); // selecting text inside tweet
styleTweet(tweetText, option, slider);
});
}
});
const processTweets = function () {
const posts = document.querySelectorAll(selector); // selecting tweet object
posts.forEach((post) => {
if (post.classList.contains('processed-true')) return;
if (post.classList.contains('processed-false')) return;
checkText(post);
});
};
const checkTweetList = function (mutationsList) {
mutationsList.forEach((mutation) => {
if (mutation.type === 'childList') {
processTweets();
}
});
};
const checkTweetListObserver = new MutationObserver(checkTweetList);
checkTweetListObserver.observe(root, { childList: true, subtree: true });