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
/>
+