Skip to content

Commit 695eb0b

Browse files
committed
v0.1
basic translator 1lang
1 parent c391193 commit 695eb0b

5 files changed

Lines changed: 165 additions & 0 deletions

File tree

background.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
2+
if (request.action === 'translate') {
3+
translateWord(request.word, request.targetLanguage)
4+
.then(translation => sendResponse({translation}))
5+
.catch(error => sendResponse({error: error.toString()}));
6+
return true;
7+
}
8+
});
9+
10+
async function translateWord(word, targetLanguage) {
11+
const translateUrl = `https://translate.google.com/translate_a/single?client=gtx&sl=auto&tl=${targetLanguage}&dt=t&q=${encodeURIComponent(word)}`;
12+
13+
try {
14+
const response = await fetch(translateUrl);
15+
const data = await response.json();
16+
return data[0][0][0];
17+
} catch (error) {
18+
console.error('Translation error:', error);
19+
throw error;
20+
}
21+
}

content.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
let enabled = true;
2+
let targetLanguage = 'es';
3+
4+
chrome.storage.sync.get(['enabled', 'language'], function(result) {
5+
enabled = result.enabled !== undefined ? result.enabled : true;
6+
targetLanguage = result.language || 'es';
7+
});
8+
9+
chrome.storage.onChanged.addListener(function(changes, namespace) {
10+
if (changes.enabled) {
11+
enabled = changes.enabled.newValue;
12+
}
13+
if (changes.language) {
14+
targetLanguage = changes.language.newValue;
15+
}
16+
});
17+
18+
function translateWord(word) {
19+
return new Promise((resolve, reject) => {
20+
chrome.runtime.sendMessage({action: 'translate', word, targetLanguage}, response => {
21+
if (response.error) {
22+
reject(new Error(response.error));
23+
} else {
24+
resolve(response.translation);
25+
}
26+
});
27+
});
28+
}
29+
30+
const observer = new MutationObserver(mutations => {
31+
if (!enabled) return;
32+
33+
mutations.forEach(mutation => {
34+
if (mutation.type === 'childList') {
35+
const wordElement = document.querySelector('#rs-word span');
36+
if (wordElement) {
37+
const originalWord = wordElement.textContent;
38+
translateWord(originalWord).then(translatedWord => {
39+
wordElement.textContent = translatedWord;
40+
}).catch(error => console.error('Translation error:', error));
41+
}
42+
}
43+
});
44+
});
45+
46+
observer.observe(document.body, {
47+
childList: true,
48+
subtree: true
49+
});

manifest.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"manifest_version": 3,
3+
"name": "RapScript Translator",
4+
"version": "0.1.0",
5+
"description": "Translates words on RapScript in real-time",
6+
"permissions": [
7+
"activeTab",
8+
"storage",
9+
"scripting"
10+
],
11+
"host_permissions": [
12+
"https://rapscript.net/*",
13+
"https://translate.google.com/*"
14+
],
15+
"action": {
16+
"default_popup": "popup.html"
17+
},
18+
"content_scripts": [
19+
{
20+
"matches": ["https://rapscript.net/*"],
21+
"js": ["content.js"]
22+
}
23+
],
24+
"background": {
25+
"service_worker": "background.js"
26+
}
27+
}

popup.html

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<style>
5+
body { width: 250px; padding: 10px; }
6+
#languageSearch { width: 100%; margin-top: 10px; }
7+
#languageList { max-height: 200px; overflow-y: auto; margin-top: 10px; }
8+
</style>
9+
</head>
10+
<body>
11+
<label>
12+
<input type="checkbox" id="enableTranslation"> Enable Translation
13+
</label>
14+
<input type="text" id="languageSearch" placeholder="Search language...">
15+
<div id="languageList"></div>
16+
<script src="popup.js"></script>
17+
</body>
18+
</html>

popup.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
document.addEventListener('DOMContentLoaded', function() {
2+
const enableCheckbox = document.getElementById('enableTranslation');
3+
const languageSearch = document.getElementById('languageSearch');
4+
const languageList = document.getElementById('languageList');
5+
6+
let languages = [];
7+
let selectedLanguage = 'es';
8+
9+
// Fetch languages from Google Translate
10+
fetch('https://translate.googleapis.com/translate_a/l?client=gtx&dt=t')
11+
.then(response => response.json())
12+
.then(data => {
13+
languages = Object.entries(data.tl).map(([code, name]) => ({ code, name }));
14+
updateLanguageList();
15+
})
16+
.catch(error => console.error('Error fetching languages:', error));
17+
18+
chrome.storage.sync.get(['enabled', 'language'], function(result) {
19+
enableCheckbox.checked = result.enabled !== undefined ? result.enabled : true;
20+
selectedLanguage = result.language || 'es';
21+
updateLanguageList();
22+
});
23+
24+
enableCheckbox.addEventListener('change', function() {
25+
chrome.storage.sync.set({enabled: this.checked});
26+
});
27+
28+
languageSearch.addEventListener('input', updateLanguageList);
29+
30+
function updateLanguageList() {
31+
const searchTerm = languageSearch.value.toLowerCase();
32+
const filteredLanguages = languages.filter(lang =>
33+
lang.name.toLowerCase().includes(searchTerm) || lang.code.toLowerCase().includes(searchTerm)
34+
);
35+
36+
languageList.innerHTML = filteredLanguages.map(lang =>
37+
`<div>
38+
<input type="radio" name="language" id="${lang.code}" value="${lang.code}" ${lang.code === selectedLanguage ? 'checked' : ''}>
39+
<label for="${lang.code}">${lang.name} (${lang.code})</label>
40+
</div>`
41+
).join('');
42+
43+
languageList.addEventListener('change', function(e) {
44+
if (e.target.type === 'radio') {
45+
selectedLanguage = e.target.value;
46+
chrome.storage.sync.set({language: selectedLanguage});
47+
}
48+
});
49+
}
50+
});

0 commit comments

Comments
 (0)