This commit is contained in:
@@ -26,3 +26,16 @@ export const langToDefaultLocale = (langCode: string): string => {
|
||||
|
||||
return mapping[langCode] || langCode;
|
||||
};
|
||||
|
||||
export const localeToLang = (locale: string): string => {
|
||||
const mapping: Record<string, string> = {
|
||||
'zh-CN': 'zh-Hans',
|
||||
'zh-TW': 'zh-Hant',
|
||||
'zh-HK': 'zh-Hant',
|
||||
};
|
||||
|
||||
if (locale.startsWith('zh')) {
|
||||
return mapping[locale] || 'zh-Hans';
|
||||
}
|
||||
return mapping[locale] || locale.split('-')[0]!.toLowerCase();
|
||||
};
|
||||
|
||||
@@ -40,6 +40,14 @@ export const getUserLang = () => {
|
||||
return locale.split('-')[0] || 'en';
|
||||
};
|
||||
|
||||
export const getTargetLang = () => {
|
||||
const locale = getLocale();
|
||||
if (locale.startsWith('zh')) {
|
||||
return locale === 'zh-Hant' || locale === 'zh-HK' || locale === 'zh-TW' ? 'zh-Hant' : 'zh-Hans';
|
||||
}
|
||||
return locale.split('-')[0] || 'en';
|
||||
};
|
||||
|
||||
export const isCJKEnv = () => {
|
||||
const browserLanguage = navigator.language || '';
|
||||
const uiLanguage = localStorage?.getItem('i18nextLng') || '';
|
||||
|
||||
@@ -353,6 +353,16 @@ export const getFootnoteStyles = () => `
|
||||
}
|
||||
`;
|
||||
|
||||
const getTranslationStyles = () => `
|
||||
.translation-block-wrapper {
|
||||
display: inline-block !important;
|
||||
margin: 0.5em 0 !important;
|
||||
}
|
||||
.translation-target.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
`;
|
||||
|
||||
export interface ThemeCode {
|
||||
bg: string;
|
||||
fg: string;
|
||||
@@ -432,8 +442,9 @@ export const getStyles = (viewSettings: ViewSettings, themeCode?: ThemeCode) =>
|
||||
viewSettings.overrideFont!,
|
||||
themeCode,
|
||||
);
|
||||
const translationStyles = getTranslationStyles();
|
||||
const userStylesheet = viewSettings.userStylesheet!;
|
||||
return `${layoutStyles}\n${fontStyles}\n${userStylesheet}`;
|
||||
return `${layoutStyles}\n${fontStyles}\n${translationStyles}\n${userStylesheet}`;
|
||||
};
|
||||
|
||||
export const mountAdditionalFonts = (document: Document) => {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
export const walkTextNodes = (root: HTMLElement): HTMLElement[] => {
|
||||
const elements: HTMLElement[] = [];
|
||||
const walk = (node: HTMLElement | Document | ShadowRoot, depth = 0) => {
|
||||
if (depth > 15) return;
|
||||
if (node instanceof HTMLElement && node.shadowRoot) {
|
||||
walk(node.shadowRoot, depth + 1);
|
||||
}
|
||||
const children = 'children' in node ? (Array.from(node.children) as HTMLElement[]) : [];
|
||||
for (const child of children) {
|
||||
if (child.tagName === 'STYLE' || child.tagName === 'LINK') {
|
||||
continue;
|
||||
}
|
||||
if (child.shadowRoot) {
|
||||
walk(child.shadowRoot, depth + 1);
|
||||
}
|
||||
if (child.tagName === 'IFRAME') {
|
||||
const iframe = child as HTMLIFrameElement;
|
||||
const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;
|
||||
if (iframeDoc && iframeDoc.body) {
|
||||
walk(iframeDoc.body, depth + 1);
|
||||
}
|
||||
}
|
||||
const hasDirectText =
|
||||
child.childNodes &&
|
||||
Array.from(child.childNodes).some(
|
||||
(node) => node.nodeType === Node.TEXT_NODE && node.textContent?.trim(),
|
||||
);
|
||||
if (child.children.length === 0 && child.textContent?.trim()) {
|
||||
elements.push(child);
|
||||
} else if (hasDirectText) {
|
||||
elements.push(child);
|
||||
} else if (child.children.length > 0) {
|
||||
walk(child, depth + 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
walk(root);
|
||||
return elements;
|
||||
};
|
||||
Reference in New Issue
Block a user