Skip to content

Commit

Permalink
Adicionado opção de configurar Libretranslate como serviço de traduçã…
Browse files Browse the repository at this point in the history
…o de texto - #278
  • Loading branch information
FilipePS committed May 6, 2023
1 parent 35e8707 commit 9ba8148
Show file tree
Hide file tree
Showing 8 changed files with 239 additions and 7 deletions.
99 changes: 93 additions & 6 deletions src/background/translationService.js
Expand Up @@ -326,7 +326,7 @@ const translationService = (function () {
/**
* Takes a string formatted with the translated text and returns a `resultArray`.
* @callback callback_cbTransformResponse
* @param {String} response
* @param {String} result
* @param {boolean} dontSortResults
* @returns {string[]} resultArray
*/
Expand Down Expand Up @@ -544,7 +544,7 @@ const translationService = (function () {
};

xhr.send(
this.cbGetExtraParameters
this.cbGetRequestBody
? this.cbGetRequestBody(sourceLanguage, targetLanguage, requests)
: undefined
);
Expand Down Expand Up @@ -1156,6 +1156,76 @@ const translationService = (function () {
}
})();

/**
* Creates the libreTranslate translation service from URL and apiKey
* @param {string} url
* @param {string} apiKey
* @returns {Service} libreService
*/
const createLibreService = (url, apiKey) => {
return new (class extends Service {
constructor() {
super(
"libre",
url,
"POST",
function cbTransformRequest(sourceArray) {
return sourceArray[0];
},
function cbParseResponse(response) {
return [
{
text: response.translatedText,
detectedLanguage: response.detectedLanguage.language,
},
];
},
function cbTransformResponse(result, dontSortResults) {
return [result];
},
null,
function cbGetRequestBody(sourceLanguage, targetLanguage, requests) {
const params = new URLSearchParams();
params.append("q", requests[0].originalText);
params.append("source", sourceLanguage);
params.append("target", targetLanguage);
params.append("format", "text");
params.append("api_key", apiKey);
return params.toString();
},
function cbGetExtraHeaders() {
return [
{
name: "Content-Type",
value: "application/x-www-form-urlencoded",
},
];
}
);
}

/**
*
* @param {string} sourceLanguage - This parameter is not used
* @param {*} targetLanguage
* @param {*} sourceArray2d - Only the string `sourceArray2d[0][0]` will be translated.
* @param {*} dontSaveInPersistentCache - This parameter is not used
* @param {*} dontSortResults - This parameter is not used
* @returns
*/
/*
async translate(
sourceLanguage,
targetLanguage,
sourceArray2d,
dontSaveInPersistentCache,
dontSortResults = false
) {
}
//*/
})();
};

/** @type {Map<string, Service>} */
const serviceList = new Map();

Expand All @@ -1174,12 +1244,15 @@ const translationService = (function () {
* @returns {Service} service
*/
const getSafeServiceByName = (serviceName) => {
if (twpConfig.get("enabledServices").includes(serviceName)) {
return serviceList.get(serviceName)
if (
twpConfig.get("enabledServices").includes(serviceName) ||
twpConfig.get("customServices").find((cs) => cs.name === serviceName)
) {
return serviceList.get(serviceName);
} else {
return null
return null;
}
}
};

translationService.translateHTML = async (
serviceName,
Expand Down Expand Up @@ -1314,8 +1387,22 @@ const translationService = (function () {
service.removeTranslationsWithError();
}
});
} else if (request.action === "createLibreService") {
serviceList.set(
"libre",
createLibreService(request.libre.url, request.libre.apiKey)
);
} else if (request.action === "removeLibreService") {
serviceList.delete("libre");
}
});

if (twpConfig.get("customServices").find((cs) => cs.name === "libre")) {
const libre = twpConfig
.get("customServices")
.find((cs) => cs.name === "libre");
serviceList.set("libre", createLibreService(libre.url, libre.apiKey));
}

return translationService;
})();
34 changes: 34 additions & 0 deletions src/contentScript/translateSelected.js
Expand Up @@ -262,6 +262,7 @@ Promise.all([twpConfig.onReady(), getTabHostName()]).then(function (_) {
<li title="Bing" id="sBing">b</li>
<li title="Yandex" id="sYandex">y</li>
<li title="DeepL" id="sDeepL" hidden>d</li>
<li title="Libretranslate" id="sLibre" hidden>l</li>
<li style="opacity: 0; cursor: move;">O</li>
</ul>
</div>
Expand Down Expand Up @@ -397,6 +398,7 @@ Promise.all([twpConfig.onReady(), getTabHostName()]).then(function (_) {
const sYandex = shadowRoot.getElementById("sYandex");
const sBing = shadowRoot.getElementById("sBing");
const sDeepL = shadowRoot.getElementById("sDeepL");
const sLibre = shadowRoot.getElementById("sLibre");
const eCopy = shadowRoot.getElementById("copy");
const eReplace = shadowRoot.getElementById("replace");
const eListenOriginal = shadowRoot.getElementById("listenOriginal");
Expand Down Expand Up @@ -496,6 +498,7 @@ Promise.all([twpConfig.onReady(), getTabHostName()]).then(function (_) {
sYandex.classList.remove("selected");
sBing.classList.remove("selected");
sDeepL.classList.remove("selected");
sLibre.classList.remove("selected");

sGoogle.classList.add("selected");
};
Expand All @@ -508,6 +511,7 @@ Promise.all([twpConfig.onReady(), getTabHostName()]).then(function (_) {
sYandex.classList.remove("selected");
sBing.classList.remove("selected");
sDeepL.classList.remove("selected");
sLibre.classList.remove("selected");

sYandex.classList.add("selected");
};
Expand All @@ -520,6 +524,7 @@ Promise.all([twpConfig.onReady(), getTabHostName()]).then(function (_) {
sYandex.classList.remove("selected");
sBing.classList.remove("selected");
sDeepL.classList.remove("selected");
sLibre.classList.remove("selected");

sBing.classList.add("selected");
};
Expand All @@ -532,9 +537,23 @@ Promise.all([twpConfig.onReady(), getTabHostName()]).then(function (_) {
sYandex.classList.remove("selected");
sBing.classList.remove("selected");
sDeepL.classList.remove("selected");
sLibre.classList.remove("selected");

sDeepL.classList.add("selected");
};
sLibre.onclick = () => {
currentTextTranslatorService = "libre";
twpConfig.set("textTranslatorService", "libre");
translateNewInput();

sGoogle.classList.remove("selected");
sYandex.classList.remove("selected");
sBing.classList.remove("selected");
sDeepL.classList.remove("selected");
sLibre.classList.remove("selected");

sLibre.classList.add("selected");
};

const setTargetLanguage = shadowRoot.getElementById("setTargetLanguage");
setTargetLanguage.onclick = (e) => {
Expand Down Expand Up @@ -640,6 +659,8 @@ Promise.all([twpConfig.onReady(), getTabHostName()]).then(function (_) {
sDeepL.classList.add("selected");
} else if (currentTextTranslatorService == "bing") {
sBing.classList.add("selected");
} else if (currentTextTranslatorService == "libre") {
sLibre.classList.add("selected");
} else {
sGoogle.classList.add("selected");
}
Expand All @@ -665,6 +686,11 @@ Promise.all([twpConfig.onReady(), getTabHostName()]).then(function (_) {
} else {
sDeepL.setAttribute("hidden", "");
}
if (twpConfig.get("customServices").find((cs) => cs.name === "libre")) {
sLibre.removeAttribute("hidden");
} else {
sLibre.setAttribute("hidden", "");
}

if (
twpConfig.get("expandPanelTranslateSelectedText") === "yes" ||
Expand Down Expand Up @@ -709,6 +735,14 @@ Promise.all([twpConfig.onReady(), getTabHostName()]).then(function (_) {
}
break;
}
case "customServices": {
if (newvalue.find((cs) => cs.name === "libre")) {
sLibre.removeAttribute("hidden");
} else {
sLibre.setAttribute("hidden", "");
}
break;
}
case "expandPanelTranslateSelectedText":
const prevHeight = parseInt(getComputedStyle(eDivResult).height);
if (newvalue === "yes") {
Expand Down
3 changes: 2 additions & 1 deletion src/lib/config.js
Expand Up @@ -6,7 +6,7 @@ const twpConfig = (function () {
const defaultTargetLanguages = ["en", "es", "de"];
/**
* all configName available
* @typedef {"pageTranslatorService" | "textTranslatorService" | "enabledServices" | "ttsSpeed" | "enableDeepL" | "targetLanguage" | "targetLanguageTextTranslation" | "targetLanguages" | "alwaysTranslateSites" | "neverTranslateSites" | "sitesToTranslateWhenHovering" | "langsToTranslateWhenHovering" | "alwaysTranslateLangs" | "neverTranslateLangs" | "customDictionary" | "showTranslatePageContextMenu" | "showTranslateSelectedContextMenu" | "showButtonInTheAddressBar" | "showOriginalTextWhenHovering" | "showTranslateSelectedButton" | "showPopupMobile" | "useOldPopup" | "darkMode" | "popupBlueWhenSiteIsTranslated" | "popupPanelSection" | "showReleaseNotes" | "dontShowIfPageLangIsTargetLang" | "dontShowIfPageLangIsUnknown" | "dontShowIfSelectedTextIsTargetLang" | "dontShowIfSelectedTextIsUnknown" | "hotkeys" | "expandPanelTranslateSelectedText" | "translateTag_pre" | "dontSortResults" | "translateDynamicallyCreatedContent" | "autoTranslateWhenClickingALink" | "translateSelectedWhenPressTwice" | "translateTextOverMouseWhenPressTwice" | "translateClickingOnce" | "enableDiskCache" | "useAlternativeService"} DefaultConfigNames
* @typedef {"pageTranslatorService" | "textTranslatorService" | "enabledServices" | "ttsSpeed" | "enableDeepL" | "targetLanguage" | "targetLanguageTextTranslation" | "targetLanguages" | "alwaysTranslateSites" | "neverTranslateSites" | "sitesToTranslateWhenHovering" | "langsToTranslateWhenHovering" | "alwaysTranslateLangs" | "neverTranslateLangs" | "customDictionary" | "showTranslatePageContextMenu" | "showTranslateSelectedContextMenu" | "showButtonInTheAddressBar" | "showOriginalTextWhenHovering" | "showTranslateSelectedButton" | "showPopupMobile" | "useOldPopup" | "darkMode" | "popupBlueWhenSiteIsTranslated" | "popupPanelSection" | "showReleaseNotes" | "dontShowIfPageLangIsTargetLang" | "dontShowIfPageLangIsUnknown" | "dontShowIfSelectedTextIsTargetLang" | "dontShowIfSelectedTextIsUnknown" | "hotkeys" | "expandPanelTranslateSelectedText" | "translateTag_pre" | "dontSortResults" | "translateDynamicallyCreatedContent" | "autoTranslateWhenClickingALink" | "translateSelectedWhenPressTwice" | "translateTextOverMouseWhenPressTwice" | "translateClickingOnce" | "enableDiskCache" | "useAlternativeService" | "customServices"} DefaultConfigNames
*/
const defaultConfig = {
pageTranslatorService: "google", // google yandex bing
Expand Down Expand Up @@ -50,6 +50,7 @@ const twpConfig = (function () {
translateClickingOnce: "no",
enableDiskCache: "no",
useAlternativeService: "yes",
customServices: [],
};
const config = structuredClone(defaultConfig);

Expand Down
32 changes: 32 additions & 0 deletions src/lib/languages.js
Expand Up @@ -5139,6 +5139,38 @@ const twpLang = (function () {
"tr",
"uk",
],
libre: [
"ar",
"az",
"ca",
"cs",
"da",
"de",
"el",
"en",
"eo",
"es",
"fa",
"fi",
"fr",
"ga",
"he",
"hi",
"hu",
"id",
"it",
"ja",
"ko",
"nl",
"pl",
"pt",
"ru",
"sk",
"sv",
"tr",
"uk",
"zh",
],
};

twpLang.UILanguages = Object.keys(allLanguagesNames);
Expand Down
13 changes: 13 additions & 0 deletions src/options/options.html
Expand Up @@ -24,6 +24,7 @@ <h3 class="w3-wide"><b>TWP - Translate Web Pages</b></h3>
<a href="#privacy" class="w3-bar-item w3-button" data-i18n="msgPrivacy">Privacy</a>
<a href="#storage" class="w3-bar-item w3-button" data-i18n="msgStorage">Storage</a>
<a href="#others" class="w3-bar-item w3-button" data-i18n="lblOthers">Others</a>
<a href="#experimental" class="w3-bar-item w3-button" data-i18n="lblExperimental">Experimental</a>
</div>
<b><a href="#donation" class="w3-bar-item w3-button w3-padding"><span data-i18n="lblMakeDonation">Make a
donation</span> &#10084;</a></b>
Expand Down Expand Up @@ -502,6 +503,18 @@ <h3 class="w3-wide"><b>TWP - Translate Web Pages</b></h3>
</select>
</div>
</div>

<div id="experimental" class="w3-container">
<h3>Configure your Libretranslate server for text (not page) translation.</h3>
<label for="libreURL">Your Server URL</label><br>
<input type="text" id="libreURL" placeholder="https://my-libretranslate-server.com/translate" style="width: 90%;"><br>
<br>
<label for="libreKEY">Your API key</label><br>
<input type="text" id="libreKEY" placeholder="c02976e6-ec19-11ed-a05b-0242ac120003" style="width: 90%;"><br>
<br>
<button id="addLibre">Add Libretranslate</button>
<button id="removeLibre">Remove Libretranslate</button>
</div>
</div>

<div>
Expand Down
31 changes: 31 additions & 0 deletions src/options/options.js
Expand Up @@ -60,6 +60,7 @@ twpConfig.onReady(function () {
$("#privacy"),
$("#storage"),
$("#others"),
$("#experimental"),
$("#donation"),
$("#release_notes"),
];
Expand Down Expand Up @@ -1123,6 +1124,36 @@ twpConfig.onReady(function () {
);
};

// experimental options
$("#addLibre").onclick = () => {
const libre = { name: "libre", url: $("#libreURL").value, apiKey: $("#libreKEY").value };
try {
new URL(libre.url)
if (libre.apiKey.length < 10) {
throw new Error("Provides an API Key")
}
} catch (e) {
alert(e)
}
twpConfig.set("customServices", [libre]);
chrome.runtime.sendMessage({ action: "createLibreService", libre });
};

$("#removeLibre").onclick = () => {
twpConfig.set("customServices", []);
chrome.runtime.sendMessage({ action: "removeLibreService" });
if (twpConfig.get("textTranslatorService") === "libre") {
twpConfig.set("textTranslatorService", twpConfig.get("pageTranslatorService"))
}
};

const libre = twpConfig.get("customServices").find(cs => cs.name === "libre")
if (libre) {
$("#libreURL").value = libre.url
$("#libreKEY").value = libre.apiKey
}

// donation options
if (navigator.language === "pt-BR") {
$("#currency").value = "BRL";
$("#donateInUSD").style.display = "none";
Expand Down
1 change: 1 addition & 0 deletions src/popup/popup-translate-text.html
Expand Up @@ -99,6 +99,7 @@
<li title="Bing" id="sBing">b</li>
<li title="Yandex" id="sYandex">y</li>
<li title="DeepL" id="sDeepL" hidden>d</li>
<li title="libre" id="sLibre" hidden>l</li>
</ul>
<ul>
<li title="Copy" data-i18n-title="btnCopy" id="copy">
Expand Down

0 comments on commit 9ba8148

Please sign in to comment.