mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-04-18 04:37:22 +02:00
Debug Func to track missing dynamic translations
- Add debug function to the debug menu that enables tracking of missing dynamic translations (via `t` or `translate`) once enabled - Only works with non-English language loaded - Prints it together with the existing debug print
This commit is contained in:
parent
ae51c39c09
commit
08e184de26
@ -9,6 +9,9 @@ var langs;
|
|||||||
// eslint-disable-next-line prefer-const
|
// eslint-disable-next-line prefer-const
|
||||||
var localeData;
|
var localeData;
|
||||||
|
|
||||||
|
/** @type {Array<string>|null} Array of translations keys if they should be tracked - if not tracked then null */
|
||||||
|
let trackMissingDynamicTranslate = null;
|
||||||
|
|
||||||
export const getCurrentLocale = () => localeFile;
|
export const getCurrentLocale = () => localeFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,6 +100,9 @@ export function t(strings, ...values) {
|
|||||||
*/
|
*/
|
||||||
export function translate(text, key = null) {
|
export function translate(text, key = null) {
|
||||||
const translationKey = key || text;
|
const translationKey = key || text;
|
||||||
|
if (trackMissingDynamicTranslate && localeData && !Object.hasOwn(localeData, translationKey) && !trackMissingDynamicTranslate.includes(translationKey)) {
|
||||||
|
trackMissingDynamicTranslate.push(translationKey);
|
||||||
|
}
|
||||||
return localeData?.[translationKey] || text;
|
return localeData?.[translationKey] || text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,13 +159,28 @@ function translateElement(element) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given locale is supported and not English.
|
||||||
|
* @param {string} [locale=null] The locale to check (defaults to the current locale)
|
||||||
|
* @returns {boolean} True if the locale is not English and supported
|
||||||
|
*/
|
||||||
|
function isSupportedNonEnglish(locale = null) {
|
||||||
|
const lang = locale || localeFile;
|
||||||
|
return lang && lang != 'en' && findLang(lang);
|
||||||
|
}
|
||||||
|
|
||||||
async function getMissingTranslations() {
|
async function getMissingTranslations() {
|
||||||
|
/** @type {Array<{key: string, language: string, value: string}>} */
|
||||||
const missingData = [];
|
const missingData = [];
|
||||||
|
|
||||||
|
if (trackMissingDynamicTranslate) {
|
||||||
|
for (const key of trackMissingDynamicTranslate) {
|
||||||
|
missingData.push({ key, language: localeFile, value: key });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Determine locales to search for untranslated strings
|
// Determine locales to search for untranslated strings
|
||||||
const isNotSupported = !findLang(localeFile);
|
const langsToProcess = isSupportedNonEnglish() ? [findLang(localeFile)] : langs;
|
||||||
const langsToProcess = (isNotSupported || localeFile == 'en') ? langs : [findLang(localeFile)];
|
|
||||||
|
|
||||||
for (const language of langsToProcess) {
|
for (const language of langsToProcess) {
|
||||||
const localeData = await getLocaleData(language.lang);
|
const localeData = await getLocaleData(language.lang);
|
||||||
@ -170,7 +191,7 @@ async function getMissingTranslations() {
|
|||||||
if (attributeMatch) { // attribute-tagged key
|
if (attributeMatch) { // attribute-tagged key
|
||||||
const localizedValue = localeData?.[attributeMatch[2]];
|
const localizedValue = localeData?.[attributeMatch[2]];
|
||||||
if (!localizedValue) {
|
if (!localizedValue) {
|
||||||
missingData.push({ key, language: language.lang, value: $(this).attr(attributeMatch[1]) });
|
missingData.push({ key, language: language.lang, value: String($(this).attr(attributeMatch[1])) });
|
||||||
}
|
}
|
||||||
} else { // No attribute tag, treat as 'text'
|
} else { // No attribute tag, treat as 'text'
|
||||||
const localizedValue = localeData?.[key];
|
const localizedValue = localeData?.[key];
|
||||||
@ -196,15 +217,19 @@ async function getMissingTranslations() {
|
|||||||
// Map to { language: { key: value } }
|
// Map to { language: { key: value } }
|
||||||
let missingDataMap = {};
|
let missingDataMap = {};
|
||||||
for (const { key, value } of uniqueMissingData) {
|
for (const { key, value } of uniqueMissingData) {
|
||||||
if (!missingDataMap) {
|
|
||||||
missingDataMap = {};
|
|
||||||
}
|
|
||||||
missingDataMap[key] = value;
|
missingDataMap[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('Missing Translations:');
|
||||||
console.table(uniqueMissingData);
|
console.table(uniqueMissingData);
|
||||||
|
console.log('Full map of missing data:');
|
||||||
console.log(missingDataMap);
|
console.log(missingDataMap);
|
||||||
|
|
||||||
|
if (trackMissingDynamicTranslate) {
|
||||||
|
console.log('Dynamic translations missing:');
|
||||||
|
console.log(trackMissingDynamicTranslate);
|
||||||
|
}
|
||||||
|
|
||||||
toastr.success(`Found ${uniqueMissingData.length} missing translations. See browser console for details.`);
|
toastr.success(`Found ${uniqueMissingData.length} missing translations. See browser console for details.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,6 +291,31 @@ export async function initLocales() {
|
|||||||
attributeFilter: ['data-i18n'],
|
attributeFilter: ['data-i18n'],
|
||||||
});
|
});
|
||||||
|
|
||||||
registerDebugFunction('getMissingTranslations', 'Get missing translations', 'Detects missing localization data in the current locale and dumps the data into the browser console. If the current locale is English, searches all other locales.', getMissingTranslations);
|
if (localStorage.getItem('trackDynamicTranslate') === 'true' && isSupportedNonEnglish()) {
|
||||||
|
trackMissingDynamicTranslate = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
registerDebugFunction('getMissingTranslations', 'Get missing translations',
|
||||||
|
'Detects missing localization data in the current locale and dumps the data into the browser console. ' +
|
||||||
|
'If the current locale is English, searches all other locales.',
|
||||||
|
getMissingTranslations);
|
||||||
|
registerDebugFunction('trackDynamicTranslate', 'Track dynamic translation',
|
||||||
|
'Toggles tracking of dynamic translations, which will be dumped into the missing translations translations too. ' +
|
||||||
|
'This includes things translated via the t`...` function and translate(). It will only track strings translated <b>after</b> this is toggled on, '
|
||||||
|
+ 'and when they actually pop up, so refreshing the page and opening popups, etc, is needed. Will only track if the current locale is not English.',
|
||||||
|
() => {
|
||||||
|
const isTracking = localStorage.getItem('trackDynamicTranslate') !== 'true';
|
||||||
|
localStorage.setItem('trackDynamicTranslate', isTracking ? 'true' : 'false');
|
||||||
|
if (isTracking && isSupportedNonEnglish()) {
|
||||||
|
trackMissingDynamicTranslate = [];
|
||||||
|
toastr.success('Dynamic translation tracking enabled.');
|
||||||
|
} else if (isTracking) {
|
||||||
|
trackMissingDynamicTranslate = null;
|
||||||
|
toastr.warning('Dynamic translation tracking enabled, but will not be tracked with locale English.');
|
||||||
|
} else {
|
||||||
|
trackMissingDynamicTranslate = null;
|
||||||
|
toastr.info('Dynamic translation tracking disabled.');
|
||||||
|
}
|
||||||
|
});
|
||||||
registerDebugFunction('applyLocale', 'Apply locale', 'Reapplies the currently selected locale to the page.', applyLocale);
|
registerDebugFunction('applyLocale', 'Apply locale', 'Reapplies the currently selected locale to the page.', applyLocale);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user