This repository was archived by the owner on Oct 13, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathautodict.js
90 lines (76 loc) · 2.48 KB
/
autodict.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
// Firefox doesn't change the dictionary until the element loses focus, then gains it again. This is a workaround.
function forceDictionaryChange(node) {
if (node.nodeName == "INPUT" || node.nodeName == "TEXTAREA") {
node.spellcheck = false;
node.spellcheck = true;
} else {
node.contentEditable = false;
node.contentEditable = true;
}
}
function getContent(node) {
if (node.nodeName == "INPUT" || node.nodeName == "TEXTAREA") {
return node.value;
} else {
return node.innerText;
}
}
async function detectLanguage(event) {
const node = event.target;
const content = getContent(node);
// console.log("Detecting language for", node, "with content", content)
const detectedLanguage = await browser.i18n.detectLanguage(content);
if (detectedLanguage.isReliable && detectedLanguage.languages.length > 0) {
const language = detectedLanguage.languages[0].language;
if (node.lang !== language) {
//console.log("Setting language to", language, "for", node);
node.lang = language;
forceDictionaryChange(node);
}
}
}
const throttledDetectLanguages = _.throttle(detectLanguage, 2000);
function detectChanges(node) {
if(!node.spellcheck) {
return;
}
if (!(node.nodeName === "INPUT"
|| node.nodeName === "TEXTAREA"
|| (node.nodeName === "DIV" && node.contentEditable === "true"))) {
return;
}
// console.log("Adding listener for", node);
node.addEventListener("input", throttledDetectLanguages);
detectLanguage({ target: node });
}
function detectChildChanges(root) {
if (!root.querySelectorAll) {
return;
}
const nodes = root.querySelectorAll("input, textarea, div[contenteditable]");
for (const node of nodes) {
detectChanges(node);
}
}
const observer = new MutationObserver(mutations => {
for (const mutation of mutations) {
switch(mutation.type) {
case "attributes":
detectChanges(mutation.target);
break;
case "childList":
for (const newNode of mutation.addedNodes) {
detectChanges(newNode);
detectChildChanges(newNode);
}
break;
}
};
});
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ["contenteditable"]
});
detectChildChanges(document);