Skip to content

Commit

Permalink
add translate language and enable toggle settings
Browse files Browse the repository at this point in the history
  • Loading branch information
rioam2 committed Mar 5, 2021
1 parent 4f863d0 commit 56a268a
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 21 deletions.
78 changes: 59 additions & 19 deletions content.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
let globalTL = 'en';

// Called for each new caption node mounted to the DOM
function handleCaptionMount(node) {
const text = node.innerText;

// Handle translation request within service-worker to alleviate CORS/security conflicts
const req = { action: 'translate', payload: { text, source_lang: 'no', target_lang: 'en' } };
const req = { action: 'translate', payload: { text, source_lang: 'no', target_lang: globalTL } };
chrome.extension.sendRequest(req, ({ error, response }) => {
if (!error) {
node.setAttribute('data-translation', response);
Expand All @@ -13,23 +14,62 @@ function handleCaptionMount(node) {
});
}

// Listen for captions elements mounting
const captionsContainerQuery = '.ludo-captions';
const containerObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (!mutation.addedNodes) return;
Array.from(mutation.addedNodes).forEach((node) => {
const parent = node.parentElement;
const isCaption = parent && parent.matches(captionsContainerQuery);
if (isCaption) {
handleCaptionMount(node);
}
const CaptionObserver = (function (handler) {
// Listen for captions elements mounting
const captionsContainerQuery = '.ludo-captions';
const captionsObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (!mutation.addedNodes) return;
Array.from(mutation.addedNodes).forEach((node) => {
const parent = node.parentElement;
const isCaption = parent && parent.matches(captionsContainerQuery);
if (isCaption) {
handler(node);
}
});
});
});
});
containerObserver.observe(document.body, {
childList: true,
subtree: true,
attributes: false,
characterData: false,
// Return API interface
return {
enable() {
captionsObserver.observe(document.body, {
childList: true,
subtree: true,
attributes: false,
characterData: false,
});
},
disable() {
captionsObserver.disconnect();
},
};
})(handleCaptionMount);

function handleSettingsUpdate({ en, tl }) {
en ? CaptionObserver.enable() : CaptionObserver.disable();
globalTL = tl;
}

function handleSettingsChanges(changes) {
chrome.storage.sync.get((settings) => {
// Merge changes with current settings
Object.entries(changes).forEach(([setting, { newValue: value }]) => {
settings[setting] = value;
});
// Handle changes
handleSettingsUpdate({
en: settings['settings-en'],
tl: settings['settings-tl'],
});
});
}

// Load current settings on extension mount
handleSettingsChanges({});

// Listen for extension settings updates
chrome.storage.onChanged.addListener(function (changes, area) {
if (area == 'sync') {
handleSettingsChanges(changes);
}
});
8 changes: 6 additions & 2 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
"css": ["styles.css"]
}
],
"options_page": "options.html",
"browser_action": {
"default_icon": {}
}
"default_icon": {},
"default_popup": "options.html"
},
"permissions": ["storage"],
"content_security_policy": "script-src 'self'"
}
40 changes: 40 additions & 0 deletions options.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
* {
width: 100%;
box-sizing: border-box;
padding: 0;
margin: 0;
}

html {
position: relative;
margin: 0 auto;
width: 350px;
height: 100%;
background-color: rgb(54, 50, 77);
}

body {
width: 100%;
height: min-content;
padding: 25px;
}

h1 {
font-weight: 400;
color: white;
margin-bottom: 15px;
}

label {
width: max-content;
color: #e5cfff;
font-size: 15px;
margin-bottom: 8px;
white-space: nowrap;
margin-right: 15px;
}

.field-container {
display: flex;
margin-bottom: 15px;
}
85 changes: 85 additions & 0 deletions options.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<!DOCTYPE html>
<html>
<head>
<title>NRK TV Dual Subtitles Preferences</title>
<link rel="stylesheet" href="options.css" />
</head>
<body>
<form id="settings-form">
<div class="field-container">
<label for="settings-tl">Translated language</label>
<select id="settings-tl">
<option selected value="en">English</option>
<option value="sq">Albanian</option>
<option value="ar">Arabic</option>
<option value="hy">Armenian</option>
<option value="az">Azerbaijani</option>
<option value="eu">Basque</option>
<option value="be">Belarusian</option>
<option value="bn">Bengali</option>
<option value="bg">Bulgarian</option>
<option value="ca">Catalan</option>
<option value="zh-CN">Chinese (Simplified)</option>
<option value="zh-TW">Chinese (Traditional)</option>
<option value="hr">Croatian</option>
<option value="cs">Czech</option>
<option value="da">Danish</option>
<option value="nl">Dutch</option>
<option value="eo">Esperanto</option>
<option value="et">Estonian</option>
<option value="tl">Filipino</option>
<option value="fi">Finnish</option>
<option value="fr">French</option>
<option value="gl">Galician</option>
<option value="ka">Georgian</option>
<option value="de">German</option>
<option value="el">Greek</option>
<option value="gu">Gujarati</option>
<option value="ht">Haitian (Creole)</option>
<option value="iw">Hebrew</option>
<option value="hi">Hindi</option>
<option value="hu">Hungarian</option>
<option value="is">Icelandic</option>
<option value="id">Indonesian</option>
<option value="ga">Irish</option>
<option value="it">Italian</option>
<option value="ja">Japanese</option>
<option value="kn">Kannada</option>
<option value="ko">Korean</option>
<option value="la">Latin</option>
<option value="lv">Latvian</option>
<option value="lt">Lithuanian</option>
<option value="mk">Macedonian</option>
<option value="ms">Malay</option>
<option value="mt">Maltese</option>
<option value="fa">Persian</option>
<option value="pl">Polish</option>
<option value="pt">Portuguese</option>
<option value="ro">Romanian</option>
<option value="ru">Russian</option>
<option value="sr">Serbian</option>
<option value="sk">Slovak</option>
<option value="sl">Slovenian</option>
<option value="es">Spanish</option>
<option value="sw">Swahili</option>
<option value="sv">Swedish</option>
<option value="ta">Tamil</option>
<option value="te">Telugu</option>
<option value="th">Thai</option>
<option value="tr">Turkish</option>
<option value="uk">Ukrainian</option>
<option value="ur">Urdu</option>
<option value="vi">Vietnamese</option>
<option value="cy">Welsh</option>
<option value="yi">Yiddish</option>
</select>
</div>
<div class="field-container">
<label for="settings-en">Enable dual-subtitles</label>
<input type="checkbox" id="settings-en" />
</div>
<button type="submit">Save</button>
</form>
<script src="options.js"></script>
</body>
</html>
43 changes: 43 additions & 0 deletions options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const settingsForm = document.getElementById('settings-form');

function forEachSetting(cb) {
Array.from(settingsForm.childNodes).forEach((fieldWrapper) => {
const children = Array.from(fieldWrapper.childNodes).filter((n) => n.nodeName !== '#text');
const field = children[1];
if (field) cb(field);
});
}

// Save settings
settingsForm.addEventListener('submit', function handleSaveSettings(e) {
e.preventDefault();

const newSettings = {};
forEachSetting((node) => {
console.log(node);
if (node.type === 'checkbox') {
newSettings[node.id] = node.checked;
} else {
newSettings[node.id] = node.value;
}
});
chrome.storage.sync.set(newSettings, function () {});
});

// Restore settings
document.addEventListener('DOMContentLoaded', function () {
chrome.storage.sync.get((settings) => {
forEachSetting((node) => {
const key = node.id;
const value = settings[key];
console.log({ key, value });
if (value) {
if (node.type === 'checkbox') {
node.checked = value;
} else {
node.value = value;
}
}
});
});
});

0 comments on commit 56a268a

Please sign in to comment.