weploy-translate
Version:
Translate your React.js or Next.js app with AI
154 lines (128 loc) • 6.69 kB
JavaScript
const { isBrowser, getGlobalseoOptions, SPECIAL_API_KEYS } = require('./utils/configs.js');
const { createLanguageSelect } = require('./utils/selector/createLanguageSelect.js');
const { getLanguageFromLocalStorage } = require('./utils/languages/getSelectedLanguage.js');
const setOptions = require('./utils/options/setOptions.js');
const startTranslationCycle = require('./utils/translation/startTranslationCycle.js');
const extractOptionsFromScript = require('./extractOptionsFromScript.js');
const replaceLinks = require('./replaceLinks.js');
const { renderSelectorState } = require('./utils/selector/renderSelectorState.js');
async function getTranslations(window, apiKey, optsArgs = {}) {
try {
// console.log("GLOBALSEO initializing...", isBrowser());
if (!optsArgs?.originalLanguage && !SPECIAL_API_KEYS.includes(apiKey)) {
console.error("GLOBALSEO: data-original-language is required, please add it to the script tag")
return;
}
const debounceDuration = optsArgs.debounceDuration == null ? 0 : optsArgs.debounceDuration;
setOptions(window, apiKey, optsArgs)
// save language to local storage & delay 1 second to wait google translate
// await Promise.allSettled([
// optsArgs.originalLanguage ? getDefinedLanguages(optsArgs.originalLanguage, optsArgs.allowedLanguages) : fetchLanguageList(apiKey),
// // delay(1000)
// ]);
if (optsArgs.createSelector && isBrowser()) {
await createLanguageSelect(window, optsArgs);
}
// handle google translate
if (isBrowser() && (window.document.querySelector('html.translated-ltr') || window.document.querySelector('html.translated-rtl'))) return;
const timeout = getGlobalseoOptions(window).timeout;
return await startTranslationCycle(window, window.document.body, apiKey, timeout, true)
.then(() => {
// console.log("GLOBALSEO: Translation cycle completed")
return window
}) // return window object as response
.catch((err) => {
console.log("getTranslations error", err);
if (window.shouldConsoleglobalseoError) console.error(err);
})
.finally(() => {
// resolve(window)
// console.log("GLOBALSEO: MutationObserver added")
if (isBrowser() && !window.isDomListenerAdded) {
// Select the target node
const targetNode = window.document.body;
// Create an observer instance with a callback to handle mutations
const observer = new MutationObserver(function(mutationsList) {
let nodes = [];
// check if the selectors need to be recreated
let elementsWeploy = Array.from(window.document.querySelectorAll('.weploy-select')).filter(el => !el.querySelector('.weploy-lang-selector-ready-icon'));
let elementsGlobalSeo = Array.from(window.document.querySelectorAll('.globalseo-select')).filter(el => !el.querySelector('.globalseo-lang-selector-ready-icon'));
let elements = [...elementsWeploy, ...elementsGlobalSeo];
// remove classname to recreate selectors
elements.forEach(el => {
const details = el.querySelector('details')
if (details) {
details.classList.remove('globalseo-lang-selector-element');
details.classList.remove('weploy-lang-selector-element');
}
})
for(let mutation of mutationsList) {
if (mutation.type === 'childList') {
function getIsLangSelector() {
try {
return (mutation?.target?.className || "").includes("globalseo-lang-selector-value") || (mutation?.target?.className || "").includes("weploy-lang-selector-value")
} catch(err) {
return false;
}
}
const isLangSelector = getIsLangSelector();
// Handling added nodes
for(let addedNode of mutation.addedNodes) {
if (!isLangSelector) nodes.push(addedNode)
}
// // Handling removed nodes
// for(let removedNode of mutation.removedNodes) {
// if (!isLangSelector) nodes.push(removedNode)
// }
}
}
if (elements.length && optsArgs.createSelector) {
createLanguageSelect(window, optsArgs).then(() => {
if (nodes.length) startTranslationCycle(window, window.document.body, apiKey, debounceDuration).catch(console.log)
});
} else {
if (nodes.length) startTranslationCycle(window, window.document.body, apiKey, debounceDuration).catch(console.log)
}
});
// Set up observer configuration: what to observe
const config = { childList: true, subtree: true };
// Start observing the target node with configured settings
observer.observe(targetNode, config);
window.isDomListenerAdded = true;
}
})
// return await new Promise(async (resolve, reject) => {
// try {
// await startTranslationCycle(window, window.document.body, apiKey, timeout, true).catch(reject).finally(() => resolve(window));
// } catch(err) {
// console.log("getTranslations error", err);
// if (window.shouldConsoleglobalseoError) console.error(err);
// resolve(undefined);
// }
// })
} catch(err) {
console.log("getTranslations error 2", err);
if (window.shouldConsoleglobalseoError) console.error(err);
}
}
if (isBrowser()) {
if (!window.globalseoUtils) {
window.globalseoUtils = {}
}
window.globalseoUtils.isBrowser = isBrowser;
window.globalseoUtils.getTranslations = getTranslations;
window.globalseoUtils.createLanguageSelect = createLanguageSelect;
window.globalseoUtils.getLanguageFromLocalStorage = getLanguageFromLocalStorage;
window.globalseoUtils.setOptions = setOptions
window.globalseoUtils.extractOptionsFromScript = extractOptionsFromScript;
window.globalseoUtils.replaceLinks = replaceLinks;
window.globalseoUtils.renderSelectorState = renderSelectorState;
}
module.exports.isBrowser = isBrowser;
module.exports.getTranslations = getTranslations;
module.exports.createLanguageSelect = createLanguageSelect;
module.exports.getLanguageFromLocalStorage = getLanguageFromLocalStorage;
module.exports.setOptions = setOptions;
module.exports.extractOptionsFromScript = extractOptionsFromScript;
module.exports.replaceLinks = replaceLinks;
module.exports.renderSelectorState = renderSelectorState;