diff --git a/src/config/i18n.js b/src/config/i18n.js index 7f90182..df9f5da 100644 --- a/src/config/i18n.js +++ b/src/config/i18n.js @@ -700,9 +700,14 @@ export const I18N = { }, selector_parent_style: { zh: `选择器父节点样式`, - en: `Selector Parent Style`, + en: `Parent Selector Style`, zh_TW: `選擇器父節點樣式`, }, + selector_grand_style: { + zh: `选择器祖节点样式`, + en: `Grand Selector Style`, + zh_TW: `選擇器祖節點樣式`, + }, inject_js: { zh: `注入JS`, en: `Inject JS`, diff --git a/src/config/rules.js b/src/config/rules.js index cbbdc8a..83c1a3e 100644 --- a/src/config/rules.js +++ b/src/config/rules.js @@ -90,6 +90,7 @@ export const DEFAULT_RULE = { textDiyStyle: "", // 自定义译文样式 selectStyle: "", // 选择器节点样式 parentStyle: "", // 选择器父节点样式 + grandStyle: "", // 选择器父节点样式 injectJs: "", // 注入JS injectCss: "", // 注入CSS transOnly: GLOBAL_KEY, // 是否仅显示译文 @@ -127,6 +128,7 @@ export const GLOBLA_RULE = { textDiyStyle: DEFAULT_DIY_STYLE, // 自定义译文样式 selectStyle: DEFAULT_SELECT_STYLE, // 选择器节点样式 parentStyle: DEFAULT_SELECT_STYLE, // 选择器父节点样式 + grandStyle: DEFAULT_SELECT_STYLE, // 选择器祖节点样式 injectJs: "", // 注入JS injectCss: "", // 注入CSS transOnly: "false", // 是否仅显示译文 @@ -178,10 +180,6 @@ const RULES_MAP = { autoScan: `false`, textStyle: OPT_STYLE_BLOCKQUOTE, }, - // "github.com": { - // selector: `.markdown-body ${DEFAULT_SELECTOR}, .repo-description p, .Layout-sidebar .f4, .container-lg .py-4 .f5, .container-lg .my-4 .f5, .Box-row .pr-4, .Box-row article .mt-1, [itemprop="description"], .markdown-title, bdi, .ws-pre-wrap, .status-meta, span.status-meta, .col-10.color-fg-muted, .TimelineItem-body, .pinned-item-list-item-content .color-fg-muted, .markdown-body td, .markdown-body th`, - // keepSelector: DEFAULT_KEEP_SELECTOR, - // }, "twitter.com, https://x.com": { selector: `[data-testid='tweetText']`, keepSelector: `img, svg, span:has(a), div:has(a)`, @@ -191,7 +189,6 @@ const RULES_MAP = { "www.youtube.com": { rootsSelector: `ytd-page-manager`, ignoreSelector: `aside, button, footer, form, header, pre, mark, nav, #player`, - transEndHook: `({ parentNode }) => {parentNode?.parentElement?.style.cssText += "-webkit-line-clamp: unset; max-height: none; height: auto;";}`, textStyle: OPT_STYLE_DASHBOX, }, }; diff --git a/src/libs/rules.js b/src/libs/rules.js index dd7e1f7..bda14ef 100644 --- a/src/libs/rules.js +++ b/src/libs/rules.js @@ -55,6 +55,7 @@ export const matchRule = async (href, { injectRules, subrulesList }) => { "aiTerms", "selectStyle", "parentStyle", + "grandStyle", "injectJs", "injectCss", // "fixerSelector", @@ -138,6 +139,7 @@ export const checkRules = (rules) => { aiTerms, selectStyle, parentStyle, + grandStyle, injectJs, injectCss, apiSlug, @@ -171,6 +173,7 @@ export const checkRules = (rules) => { aiTerms: type(aiTerms) === "string" ? aiTerms : "", selectStyle: type(selectStyle) === "string" ? selectStyle : "", parentStyle: type(parentStyle) === "string" ? parentStyle : "", + grandStyle: type(grandStyle) === "string" ? grandStyle : "", injectJs: type(injectJs) === "string" ? injectJs : "", injectCss: type(injectCss) === "string" ? injectCss : "", bgColor: type(bgColor) === "string" ? bgColor : "", diff --git a/src/libs/translator.js b/src/libs/translator.js index 76091fd..8d3ba0b 100644 --- a/src/libs/translator.js +++ b/src/libs/translator.js @@ -960,6 +960,7 @@ export class Translator { transOnly, selectStyle, parentStyle, + grandStyle, // detectRemote, // toLang, // skipLangs = [], @@ -1046,6 +1047,9 @@ export class Translator { if (parentStyle && parentNode && parentNode.style) { parentNode.style.cssText += parentStyle; } + if (grandStyle && parentNode && parentNode.parentElement) { + parentNode.parentElement.style.cssText += grandStyle; + } // 翻译完成钩子函数 if (transEndHook?.trim()) { diff --git a/src/subtitle/YouTubeCaptionProvider.js b/src/subtitle/YouTubeCaptionProvider.js index b11789d..863c28d 100644 --- a/src/subtitle/YouTubeCaptionProvider.js +++ b/src/subtitle/YouTubeCaptionProvider.js @@ -278,7 +278,10 @@ class YouTubeCaptionProvider { const { segApiSetting, toLang } = this.#setting; const lang = potUrl.searchParams.get("lang"); - const fromLang = OPT_LANGS_TO_CODE[OPT_TRANS_MICROSOFT].get(lang) || lang; + const fromLang = + OPT_LANGS_TO_CODE[OPT_TRANS_MICROSOFT].get(lang) || + OPT_LANGS_TO_CODE[OPT_TRANS_MICROSOFT].get(lang.slice(0, 2)) || + "auto"; if (potUrl.searchParams.get("kind") === "asr" && segApiSetting) { subtitles = await this.#aiSegment({ videoId, diff --git a/src/views/Options/Rules.js b/src/views/Options/Rules.js index 386b278..1a7b9d2 100644 --- a/src/views/Options/Rules.js +++ b/src/views/Options/Rules.js @@ -98,6 +98,7 @@ function RuleFields({ rule, rules, setShow, setKeyword }) { aiTerms = "", selectStyle = "", parentStyle = "", + grandStyle = "", injectJs = "", injectCss = "", apiSlug, @@ -540,6 +541,17 @@ function RuleFields({ rule, rules, setShow, setKeyword }) { maxRows={10} multiline /> +