feat: support placeholder selection
This commit is contained in:
@@ -138,8 +138,8 @@ export const BUILTIN_STONES = [
|
|||||||
"machine-like", // 机器风格
|
"machine-like", // 机器风格
|
||||||
"concise", // 简明风格
|
"concise", // 简明风格
|
||||||
];
|
];
|
||||||
export const BUILTIN_PLACEHOULDERS = ["{ }", "{{ }}", "[ ]", "[[ ]]"];
|
export const BUILTIN_PLACEHOLDERS = ["{ }", "{{ }}", "[ ]", "[[ ]]"];
|
||||||
export const BUILTIN_TAG_NAMES = ["i", "a", "span"];
|
export const BUILTIN_PLACETAGS = ["i", "a", "x", "span"];
|
||||||
|
|
||||||
export const OPT_LANGS_TO = [
|
export const OPT_LANGS_TO = [
|
||||||
["en", "English - English"],
|
["en", "English - English"],
|
||||||
@@ -357,10 +357,10 @@ const defaultApi = {
|
|||||||
model: "", // 模型名称
|
model: "", // 模型名称
|
||||||
systemPrompt: defaultSystemPrompt,
|
systemPrompt: defaultSystemPrompt,
|
||||||
userPrompt: "",
|
userPrompt: "",
|
||||||
tone: "neutral", // 翻译风格
|
tone: BUILTIN_STONES[0], // 翻译风格
|
||||||
placeholder: "{ }", // 占位符(todo: 备用)
|
placeholder: BUILTIN_PLACEHOLDERS[0], // 占位符
|
||||||
tagName: "i", // 标签符 (todo: 备用)
|
placetag: [BUILTIN_PLACETAGS[0]], // 占位标签
|
||||||
aiTerms: false, // AI智能专业术语 (todo: 备用)
|
// aiTerms: false, // AI智能专业术语 (todo: 备用)
|
||||||
customHeader: "",
|
customHeader: "",
|
||||||
customBody: "",
|
customBody: "",
|
||||||
reqHook: "", // request 钩子函数
|
reqHook: "", // request 钩子函数
|
||||||
|
|||||||
@@ -1493,4 +1493,14 @@ export const I18N = {
|
|||||||
en: `Mini/Regular Mode`,
|
en: `Mini/Regular Mode`,
|
||||||
zh_TW: `迷你/常規模式`,
|
zh_TW: `迷你/常規模式`,
|
||||||
},
|
},
|
||||||
|
api_placeholder: {
|
||||||
|
zh: `占位符`,
|
||||||
|
en: `Placeholder`,
|
||||||
|
zh_TW: `佔位符`,
|
||||||
|
},
|
||||||
|
api_placetag: {
|
||||||
|
zh: `占位标签`,
|
||||||
|
en: `Placeholder tags`,
|
||||||
|
zh_TW: `佔位標`,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -209,13 +209,6 @@ export class Translator {
|
|||||||
/^\d{1,2}:\d{2}(:\d{2})?$/,
|
/^\d{1,2}:\d{2}(:\d{2})?$/,
|
||||||
];
|
];
|
||||||
|
|
||||||
// 占位符
|
|
||||||
static PLACEHOLDER = {
|
|
||||||
startDelimiter: "{",
|
|
||||||
endDelimiter: "}",
|
|
||||||
tagName: "i",
|
|
||||||
};
|
|
||||||
|
|
||||||
static DEFAULT_OPTIONS = DEFAULT_SETTING; // 默认配置
|
static DEFAULT_OPTIONS = DEFAULT_SETTING; // 默认配置
|
||||||
static DEFAULT_RULE = GLOBLA_RULE; // 默认规则
|
static DEFAULT_RULE = GLOBLA_RULE; // 默认规则
|
||||||
|
|
||||||
@@ -280,6 +273,12 @@ export class Translator {
|
|||||||
#docInfo = {}; // 网页信息
|
#docInfo = {}; // 网页信息
|
||||||
#textClass = {}; // 译文样式class
|
#textClass = {}; // 译文样式class
|
||||||
#textSheet = ""; // 译文样式字典
|
#textSheet = ""; // 译文样式字典
|
||||||
|
#apiSetting = null;
|
||||||
|
#placeholder = {
|
||||||
|
startDelimiter: "{",
|
||||||
|
endDelimiter: "}",
|
||||||
|
tagName: "i",
|
||||||
|
};
|
||||||
|
|
||||||
#isUserscript = false;
|
#isUserscript = false;
|
||||||
#transboxManager = null; // 划词翻译
|
#transboxManager = null; // 划词翻译
|
||||||
@@ -312,6 +311,18 @@ export class Translator {
|
|||||||
constructor(rule = {}, setting = {}, isUserscript) {
|
constructor(rule = {}, setting = {}, isUserscript) {
|
||||||
this.#setting = { ...Translator.DEFAULT_OPTIONS, ...setting };
|
this.#setting = { ...Translator.DEFAULT_OPTIONS, ...setting };
|
||||||
this.#rule = { ...Translator.DEFAULT_RULE, ...rule };
|
this.#rule = { ...Translator.DEFAULT_RULE, ...rule };
|
||||||
|
this.#apiSetting =
|
||||||
|
this.#setting.transApis.find(
|
||||||
|
(api) => api.apiSlug === this.#rule.apiSlug
|
||||||
|
) || DEFAULT_API_SETTING;
|
||||||
|
const [startDelimiter, endDelimiter] =
|
||||||
|
this.#apiSetting.placeholder.split(" ");
|
||||||
|
this.#placeholder = {
|
||||||
|
startDelimiter,
|
||||||
|
endDelimiter,
|
||||||
|
tagName: this.#apiSetting.placetag,
|
||||||
|
};
|
||||||
|
|
||||||
this.#isUserscript = isUserscript;
|
this.#isUserscript = isUserscript;
|
||||||
this.#eventName = genEventName();
|
this.#eventName = genEventName();
|
||||||
this.#docInfo = {
|
this.#docInfo = {
|
||||||
@@ -437,11 +448,9 @@ export class Translator {
|
|||||||
|
|
||||||
#createPlaceholderRegex() {
|
#createPlaceholderRegex() {
|
||||||
const escapedStart = Translator.escapeRegex(
|
const escapedStart = Translator.escapeRegex(
|
||||||
Translator.PLACEHOLDER.startDelimiter
|
this.#placeholder.startDelimiter
|
||||||
);
|
|
||||||
const escapedEnd = Translator.escapeRegex(
|
|
||||||
Translator.PLACEHOLDER.endDelimiter
|
|
||||||
);
|
);
|
||||||
|
const escapedEnd = Translator.escapeRegex(this.#placeholder.endDelimiter);
|
||||||
const patternString = `(${escapedStart}\\d+${escapedEnd}|<\\/?\\w+\\d+>)`;
|
const patternString = `(${escapedStart}\\d+${escapedEnd}|<\\/?\\w+\\d+>)`;
|
||||||
const flags = "g";
|
const flags = "g";
|
||||||
return new RegExp(patternString, flags);
|
return new RegExp(patternString, flags);
|
||||||
@@ -1031,10 +1040,11 @@ export class Translator {
|
|||||||
let replaceCounter = 0; // {{n}}
|
let replaceCounter = 0; // {{n}}
|
||||||
let wrapCounter = 0; // <tagn>
|
let wrapCounter = 0; // <tagn>
|
||||||
const placeholderMap = new Map();
|
const placeholderMap = new Map();
|
||||||
|
const { startDelimiter, endDelimiter } = this.#placeholder;
|
||||||
|
|
||||||
const pushReplace = (html) => {
|
const pushReplace = (html) => {
|
||||||
replaceCounter++;
|
replaceCounter++;
|
||||||
const placeholder = `${Translator.PLACEHOLDER.startDelimiter}${replaceCounter}${Translator.PLACEHOLDER.endDelimiter}`;
|
const placeholder = `${startDelimiter}${replaceCounter}${endDelimiter}`;
|
||||||
placeholderMap.set(placeholder, html);
|
placeholderMap.set(placeholder, html);
|
||||||
return placeholder;
|
return placeholder;
|
||||||
};
|
};
|
||||||
@@ -1095,8 +1105,8 @@ export class Translator {
|
|||||||
|
|
||||||
if (Translator.TAGS.WARP.has(node.tagName)) {
|
if (Translator.TAGS.WARP.has(node.tagName)) {
|
||||||
wrapCounter++;
|
wrapCounter++;
|
||||||
const startPlaceholder = `<${Translator.PLACEHOLDER.tagName}${wrapCounter}>`;
|
const startPlaceholder = `<${this.#placeholder.tagName}${wrapCounter}>`;
|
||||||
const endPlaceholder = `</${Translator.PLACEHOLDER.tagName}${wrapCounter}>`;
|
const endPlaceholder = `</${this.#placeholder.tagName}${wrapCounter}>`;
|
||||||
placeholderMap.set(startPlaceholder, buildOpeningTag(node));
|
placeholderMap.set(startPlaceholder, buildOpeningTag(node));
|
||||||
placeholderMap.set(endPlaceholder, `</${node.localName}>`);
|
placeholderMap.set(endPlaceholder, `</${node.localName}>`);
|
||||||
return `${startPlaceholder}${innerContent}${endPlaceholder}`;
|
return `${startPlaceholder}${innerContent}${endPlaceholder}`;
|
||||||
@@ -1139,16 +1149,13 @@ export class Translator {
|
|||||||
|
|
||||||
// 发起翻译请求
|
// 发起翻译请求
|
||||||
#translateFetch(text, deLang = "") {
|
#translateFetch(text, deLang = "") {
|
||||||
const { apiSlug, fromLang, toLang } = this.#rule;
|
const { fromLang, toLang } = this.#rule;
|
||||||
const apiSetting =
|
|
||||||
this.#setting.transApis.find((api) => api.apiSlug === apiSlug) ||
|
|
||||||
DEFAULT_API_SETTING;
|
|
||||||
|
|
||||||
return apiTranslate({
|
return apiTranslate({
|
||||||
text,
|
text,
|
||||||
fromLang: deLang || fromLang,
|
fromLang: deLang || fromLang,
|
||||||
toLang,
|
toLang,
|
||||||
apiSetting,
|
apiSetting: this.#apiSetting,
|
||||||
docInfo: this.#docInfo,
|
docInfo: this.#docInfo,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ import {
|
|||||||
OPT_ALL_TYPES,
|
OPT_ALL_TYPES,
|
||||||
API_SPE_TYPES,
|
API_SPE_TYPES,
|
||||||
BUILTIN_STONES,
|
BUILTIN_STONES,
|
||||||
// BUILTIN_PLACEHOULDERS,
|
BUILTIN_PLACEHOLDERS,
|
||||||
// BUILTIN_TAG_NAMES,
|
BUILTIN_PLACETAGS,
|
||||||
} from "../../config";
|
} from "../../config";
|
||||||
|
|
||||||
function TestButton({ apiSlug, api }) {
|
function TestButton({ apiSlug, api }) {
|
||||||
@@ -233,8 +233,8 @@ function ApiFields({ apiSlug, isUserApi, deleteApi }) {
|
|||||||
useContext = false,
|
useContext = false,
|
||||||
contextSize = DEFAULT_CONTEXT_SIZE,
|
contextSize = DEFAULT_CONTEXT_SIZE,
|
||||||
tone = "neutral",
|
tone = "neutral",
|
||||||
// placeholder = "{ }",
|
placeholder = BUILTIN_PLACEHOLDERS[0],
|
||||||
// tagName = "i",
|
placetag = BUILTIN_PLACETAGS[0],
|
||||||
// aiTerms = false,
|
// aiTerms = false,
|
||||||
} = formData;
|
} = formData;
|
||||||
|
|
||||||
@@ -360,7 +360,7 @@ function ApiFields({ apiSlug, isUserApi, deleteApi }) {
|
|||||||
freeSolo
|
freeSolo
|
||||||
size="small"
|
size="small"
|
||||||
fullWidth
|
fullWidth
|
||||||
options={BUILTIN_PLACEHOULDERS}
|
options={BUILTIN_PLACEHOLDERS}
|
||||||
name="placeholder"
|
name="placeholder"
|
||||||
label={i18n("placeholder")}
|
label={i18n("placeholder")}
|
||||||
value={placeholder}
|
value={placeholder}
|
||||||
@@ -610,6 +610,45 @@ function ApiFields({ apiSlug, isUserApi, deleteApi }) {
|
|||||||
|
|
||||||
{showMore && (
|
{showMore && (
|
||||||
<>
|
<>
|
||||||
|
<Box>
|
||||||
|
<Grid container spacing={2} columns={12}>
|
||||||
|
<Grid item xs={12} sm={12} md={6} lg={3}>
|
||||||
|
<TextField
|
||||||
|
select
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
name="placeholder"
|
||||||
|
value={placeholder}
|
||||||
|
label={i18n("api_placeholder")}
|
||||||
|
onChange={handleChange}
|
||||||
|
>
|
||||||
|
{BUILTIN_PLACEHOLDERS.map((item) => (
|
||||||
|
<MenuItem key={item} value={item}>
|
||||||
|
{item}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</TextField>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} sm={12} md={6} lg={3}>
|
||||||
|
<TextField
|
||||||
|
select
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
name="placetag"
|
||||||
|
value={placetag}
|
||||||
|
label={i18n("api_placetag")}
|
||||||
|
onChange={handleChange}
|
||||||
|
>
|
||||||
|
{BUILTIN_PLACETAGS.map((item) => (
|
||||||
|
<MenuItem key={item} value={item}>
|
||||||
|
{`<${item}N>`}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</TextField>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<TextField
|
<TextField
|
||||||
size="small"
|
size="small"
|
||||||
label={i18n("custom_header")}
|
label={i18n("custom_header")}
|
||||||
|
|||||||
Reference in New Issue
Block a user