-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontent.js
executable file
·133 lines (114 loc) · 3.67 KB
/
content.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
let _dictionary;
let _secondary_dictionary;
let _regex;
// Checks current settings to determine runner() should work on the page
chrome.runtime.sendMessage({
todo: "getSettings"
},
function(response) {
const sites = response.sites
const paused = response.paused
const alwaysOn = response.alwaysOn
if (paused === true) {
chrome.runtime.sendMessage({
todo: "toggleIcon",
state: "paused"
})
return
} else if (alwaysOn === true) {
chrome.runtime.sendMessage({
todo: "toggleIcon",
state: "alwaysOn"
})
runner()
} else {
match = siteChecker(sites)
if (match === true) {
chrome.runtime.sendMessage({
todo: "toggleIcon",
state: "on"
})
runner()
} else {
chrome.runtime.sendMessage({
todo: "toggleIcon",
state: "off"
})
}
}
}
)
let running = false;
// Takes one pass at page once it's loaded. Then adds a MutationObserver to check
// any asynchronously loaded content
function runner() {
chrome.runtime.sendMessage({
todo: "getDictionary"
},
function(response) {
_dictionary = response.dictionary;
_secondary_dictionary = response.secondary_dictionary;
regex = RegExp('(' + '\\b' + Object.keys(_dictionary).join('\\b|\\b') + '\\b' + ')', 'ig')
const loadedPage = loadTextNodes()
replacer(loadedPage)
const options = {
attributes: true,
subtree: true
}
const observer = new MutationObserver(function(mutations) {
// Needed to add this otherwise it gets into an endless loop of self-scrutiny
if (running) {
running = false;
return;
}
const loadedPage = loadTextNodes()
replacer(loadedPage)
})
observer.observe(document.body, options)
}
)
}
function loadTextNodes() {
let textNodes = []
const treeWalker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_TEXT,
// filter out any nodes that are just whitespace
{
acceptNode: function(node) {
return NodeFilter.FILTER_ACCEPT
}
},
false
)
while (treeWalker.nextNode()) {
textNodes.push(treeWalker.currentNode)
}
return textNodes
}
function replacer(nodes) {
running = true;
nodes.forEach(function(node) {
node.nodeValue = node.nodeValue.replace(regex,
function(match) {
let replacementWord = _dictionary[match.toLowerCase()]
if (replacementWord === undefined) {
replacementWord = _secondary_dictionary[match.toLowerCase()]
}
if (match != match.toLowerCase()) {
if (match == match.toUpperCase()) {
replacementWord = replacementWord.toUpperCase()
} else if (match.charAt(0) == match.charAt(0).toUpperCase()) {
replacementWord = replacementWord.charAt(0).toUpperCase() + replacementWord.slice(1)
}
}
return replacementWord
}
)
});
}
function siteChecker(sites) {
return sites.some(function(site) {
return window.location.href.indexOf(site) != -1
})
}