mirror of
https://github.com/hangwin/mcp-chrome.git
synced 2026-10-29 17:53:16 +08:00
feat(options/i18n): add i18n for Userscripts Manager UI (en, zh_CN)
Use chrome.i18n in App.vue and add locale messages
This commit is contained in:
@@ -442,5 +442,53 @@
|
||||
"pagesUnit": {
|
||||
"message": "pages",
|
||||
"description": "Pages count unit"
|
||||
}
|
||||
},
|
||||
"userscriptsManagerTitle": {
|
||||
"message": "Userscripts Manager",
|
||||
"description": "Options page title"
|
||||
},
|
||||
"emergencySwitchLabel": { "message": "Emergency Switch", "description": "Global disable switch" },
|
||||
"createRunSectionTitle": {
|
||||
"message": "Create / Run",
|
||||
"description": "Create & run section title"
|
||||
},
|
||||
"nameLabel": { "message": "Name", "description": "Name input label" },
|
||||
"runAtLabel": { "message": "Run At", "description": "runAt select label" },
|
||||
"runAtAuto": { "message": "auto", "description": "runAt auto" },
|
||||
"runAtDocumentStart": { "message": "document_start", "description": "runAt document_start" },
|
||||
"runAtDocumentEnd": { "message": "document_end", "description": "runAt document_end" },
|
||||
"runAtDocumentIdle": { "message": "document_idle", "description": "runAt document_idle" },
|
||||
"worldLabel": { "message": "World", "description": "world select label" },
|
||||
"worldAuto": { "message": "auto", "description": "world auto" },
|
||||
"worldIsolated": { "message": "ISOLATED", "description": "ISOLATED world" },
|
||||
"worldMain": { "message": "MAIN", "description": "MAIN world" },
|
||||
"modeLabel": { "message": "Mode", "description": "mode select label" },
|
||||
"modeAuto": { "message": "auto", "description": "mode auto" },
|
||||
"modePersistent": { "message": "persistent", "description": "mode persistent" },
|
||||
"modeCss": { "message": "css", "description": "mode css" },
|
||||
"modeOnce": { "message": "once", "description": "mode once" },
|
||||
"allFramesLabel": { "message": "All Frames", "description": "allFrames checkbox" },
|
||||
"persistLabel": { "message": "Persist", "description": "persist checkbox" },
|
||||
"dnrFallbackLabel": { "message": "DNR Fallback", "description": "dnr fallback checkbox" },
|
||||
"matchesInputLabel": { "message": "Matches (comma-separated)", "description": "matches input" },
|
||||
"excludesInputLabel": {
|
||||
"message": "Excludes (comma-separated)",
|
||||
"description": "excludes input"
|
||||
},
|
||||
"tagsInputLabel": { "message": "Tags (comma-separated)", "description": "tags input" },
|
||||
"scriptLabel": { "message": "Script", "description": "script textarea label" },
|
||||
"applyButton": { "message": "Apply", "description": "apply button" },
|
||||
"runOnceButton": { "message": "Run Once (CDP)", "description": "run once button" },
|
||||
"listSectionTitle": { "message": "List", "description": "list section title" },
|
||||
"queryLabel": { "message": "Query", "description": "query input label" },
|
||||
"statusAll": { "message": "all", "description": "status all" },
|
||||
"statusEnabled": { "message": "enabled", "description": "status enabled" },
|
||||
"statusDisabled": { "message": "disabled", "description": "status disabled" },
|
||||
"domainLabel": { "message": "Domain", "description": "domain filter label" },
|
||||
"exportAllButton": { "message": "Export All", "description": "export button" },
|
||||
"tableHeaderName": { "message": "Name", "description": "table header name" },
|
||||
"tableHeaderWorld": { "message": "World", "description": "table header world" },
|
||||
"tableHeaderRunAt": { "message": "Run At", "description": "table header runAt" },
|
||||
"tableHeaderUpdated": { "message": "Updated", "description": "table header updated" },
|
||||
"deleteButton": { "message": "Delete", "description": "delete button" }
|
||||
}
|
||||
|
||||
@@ -442,5 +442,44 @@
|
||||
"pagesUnit": {
|
||||
"message": "页",
|
||||
"description": "页面计数单位"
|
||||
}
|
||||
},
|
||||
"userscriptsManagerTitle": { "message": "脚本管理器", "description": "Options 页标题" },
|
||||
"emergencySwitchLabel": { "message": "紧急开关", "description": "紧急关闭开关" },
|
||||
"createRunSectionTitle": { "message": "创建 / 运行", "description": "创建与运行分区标题" },
|
||||
"nameLabel": { "message": "名称", "description": "名称输入标签" },
|
||||
"runAtLabel": { "message": "运行时机", "description": "runAt 选择标签" },
|
||||
"runAtAuto": { "message": "自动", "description": "runAt auto" },
|
||||
"runAtDocumentStart": { "message": "document_start", "description": "runAt document_start" },
|
||||
"runAtDocumentEnd": { "message": "document_end", "description": "runAt document_end" },
|
||||
"runAtDocumentIdle": { "message": "document_idle", "description": "runAt document_idle" },
|
||||
"worldLabel": { "message": "执行上下文", "description": "world 选择标签" },
|
||||
"worldAuto": { "message": "自动", "description": "world auto" },
|
||||
"worldIsolated": { "message": "隔离 (ISOLATED)", "description": "ISOLATED world" },
|
||||
"worldMain": { "message": "页面 (MAIN)", "description": "MAIN world" },
|
||||
"modeLabel": { "message": "模式", "description": "模式选择标签" },
|
||||
"modeAuto": { "message": "自动", "description": "mode auto" },
|
||||
"modePersistent": { "message": "持久", "description": "mode persistent" },
|
||||
"modeCss": { "message": "仅样式 (CSS)", "description": "mode css" },
|
||||
"modeOnce": { "message": "一次运行 (CDP)", "description": "mode once" },
|
||||
"allFramesLabel": { "message": "全部 frame", "description": "allFrames 复选框" },
|
||||
"persistLabel": { "message": "持久化", "description": "persist 复选框" },
|
||||
"dnrFallbackLabel": { "message": "DNR 回退", "description": "DNR fallback 复选框" },
|
||||
"matchesInputLabel": { "message": "匹配(逗号分隔)", "description": "matches 输入" },
|
||||
"excludesInputLabel": { "message": "排除(逗号分隔)", "description": "excludes 输入" },
|
||||
"tagsInputLabel": { "message": "标签(逗号分隔)", "description": "tags 输入" },
|
||||
"scriptLabel": { "message": "脚本", "description": "脚本文本标签" },
|
||||
"applyButton": { "message": "应用", "description": "应用按钮" },
|
||||
"runOnceButton": { "message": "一次运行(CDP)", "description": "一次运行按钮" },
|
||||
"listSectionTitle": { "message": "脚本列表", "description": "列表分区标题" },
|
||||
"queryLabel": { "message": "搜索", "description": "查询输入标签" },
|
||||
"statusAll": { "message": "全部", "description": "状态-全部" },
|
||||
"statusEnabled": { "message": "启用", "description": "状态-启用" },
|
||||
"statusDisabled": { "message": "禁用", "description": "状态-禁用" },
|
||||
"domainLabel": { "message": "域名", "description": "域名过滤标签" },
|
||||
"exportAllButton": { "message": "导出全部", "description": "导出按钮" },
|
||||
"tableHeaderName": { "message": "名称", "description": "表头-名称" },
|
||||
"tableHeaderWorld": { "message": "执行上下文", "description": "表头-World" },
|
||||
"tableHeaderRunAt": { "message": "运行时机", "description": "表头-RunAt" },
|
||||
"tableHeaderUpdated": { "message": "更新时间", "description": "表头-更新时间" },
|
||||
"deleteButton": { "message": "删除", "description": "删除按钮" }
|
||||
}
|
||||
|
||||
@@ -1,115 +1,115 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<header class="topbar">
|
||||
<h1>Userscripts Manager</h1>
|
||||
<h1>{{ m('userscriptsManagerTitle') }}</h1>
|
||||
<div class="switch">
|
||||
<label>
|
||||
<input type="checkbox" v-model="emergencyDisabled" @change="saveEmergency" />
|
||||
<span>Emergency OFF/ON</span>
|
||||
<span>{{ m('emergencySwitchLabel') }}</span>
|
||||
</label>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="create">
|
||||
<h2>Create / Run</h2>
|
||||
<h2>{{ m('createRunSectionTitle') }}</h2>
|
||||
<div class="grid">
|
||||
<label>
|
||||
Name
|
||||
{{ m('nameLabel') }}
|
||||
<input v-model="form.name" placeholder="optional" />
|
||||
</label>
|
||||
<label>
|
||||
RunAt
|
||||
{{ m('runAtLabel') }}
|
||||
<select v-model="form.runAt">
|
||||
<option value="auto">auto</option>
|
||||
<option value="document_start">document_start</option>
|
||||
<option value="document_end">document_end</option>
|
||||
<option value="document_idle">document_idle</option>
|
||||
<option value="auto">{{ m('runAtAuto') }}</option>
|
||||
<option value="document_start">{{ m('runAtDocumentStart') }}</option>
|
||||
<option value="document_end">{{ m('runAtDocumentEnd') }}</option>
|
||||
<option value="document_idle">{{ m('runAtDocumentIdle') }}</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
World
|
||||
{{ m('worldLabel') }}
|
||||
<select v-model="form.world">
|
||||
<option value="auto">auto</option>
|
||||
<option value="ISOLATED">ISOLATED</option>
|
||||
<option value="MAIN">MAIN</option>
|
||||
<option value="auto">{{ m('worldAuto') }}</option>
|
||||
<option value="ISOLATED">{{ m('worldIsolated') }}</option>
|
||||
<option value="MAIN">{{ m('worldMain') }}</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Mode
|
||||
{{ m('modeLabel') }}
|
||||
<select v-model="form.mode">
|
||||
<option value="auto">auto</option>
|
||||
<option value="persistent">persistent</option>
|
||||
<option value="css">css</option>
|
||||
<option value="once">once</option>
|
||||
<option value="auto">{{ m('modeAuto') }}</option>
|
||||
<option value="persistent">{{ m('modePersistent') }}</option>
|
||||
<option value="css">{{ m('modeCss') }}</option>
|
||||
<option value="once">{{ m('modeOnce') }}</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
All Frames
|
||||
{{ m('allFramesLabel') }}
|
||||
<input type="checkbox" v-model="form.allFrames" />
|
||||
</label>
|
||||
<label>
|
||||
Persist
|
||||
{{ m('persistLabel') }}
|
||||
<input type="checkbox" v-model="form.persist" />
|
||||
</label>
|
||||
<label>
|
||||
DNR Fallback
|
||||
{{ m('dnrFallbackLabel') }}
|
||||
<input type="checkbox" v-model="form.dnrFallback" />
|
||||
</label>
|
||||
</div>
|
||||
<label>
|
||||
Matches (comma-separated)
|
||||
{{ m('matchesInputLabel') }}
|
||||
<input v-model="form.matches" placeholder="e.g. https://*.example.com/*" />
|
||||
</label>
|
||||
<label>
|
||||
Excludes (comma-separated)
|
||||
{{ m('excludesInputLabel') }}
|
||||
<input v-model="form.excludes" placeholder="optional" />
|
||||
</label>
|
||||
<label>
|
||||
Tags (comma-separated)
|
||||
{{ m('tagsInputLabel') }}
|
||||
<input v-model="form.tags" placeholder="optional" />
|
||||
</label>
|
||||
<label>
|
||||
Script
|
||||
{{ m('scriptLabel') }}
|
||||
<textarea v-model="form.script" placeholder="Paste JS/CSS/TM here" rows="8" />
|
||||
</label>
|
||||
<div class="row">
|
||||
<button :disabled="submitting" @click="apply('auto')">Apply</button>
|
||||
<button :disabled="submitting" @click="apply('once')">Run Once (CDP)</button>
|
||||
<button :disabled="submitting" @click="apply('auto')">{{ m('applyButton') }}</button>
|
||||
<button :disabled="submitting" @click="apply('once')">{{ m('runOnceButton') }}</button>
|
||||
<span class="hint" v-if="lastResult">{{ lastResult }}</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="filters">
|
||||
<h2>List</h2>
|
||||
<h2>{{ m('listSectionTitle') }}</h2>
|
||||
<div class="grid">
|
||||
<label>
|
||||
Query
|
||||
{{ m('queryLabel') }}
|
||||
<input v-model="filters.query" @input="reload()" />
|
||||
</label>
|
||||
<label>
|
||||
Status
|
||||
{{ m('statusLabel') }}
|
||||
<select v-model="filters.status" @change="reload()">
|
||||
<option value="">all</option>
|
||||
<option value="enabled">enabled</option>
|
||||
<option value="disabled">disabled</option>
|
||||
<option value="">{{ m('statusAll') }}</option>
|
||||
<option value="enabled">{{ m('statusEnabled') }}</option>
|
||||
<option value="disabled">{{ m('statusDisabled') }}</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Domain
|
||||
{{ m('domainLabel') }}
|
||||
<input v-model="filters.domain" @input="reload()" placeholder="example.com" />
|
||||
</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<button @click="exportAll">Export All</button>
|
||||
<button @click="exportAll">{{ m('exportAllButton') }}</button>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Status</th>
|
||||
<th>World</th>
|
||||
<th>RunAt</th>
|
||||
<th>Updated</th>
|
||||
<th>{{ m('tableHeaderName') }}</th>
|
||||
<th>{{ m('statusLabel') }}</th>
|
||||
<th>{{ m('tableHeaderWorld') }}</th>
|
||||
<th>{{ m('tableHeaderRunAt') }}</th>
|
||||
<th>{{ m('tableHeaderUpdated') }}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -126,7 +126,7 @@
|
||||
<td>{{ it.runAt }}</td>
|
||||
<td>{{ formatTime(it.updatedAt) }}</td>
|
||||
<td class="actions">
|
||||
<button @click="remove(it)">Delete</button>
|
||||
<button @click="remove(it)">{{ m('deleteButton') }}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -287,6 +287,11 @@ onMounted(async () => {
|
||||
await loadEmergency();
|
||||
await reload();
|
||||
});
|
||||
|
||||
function m(key: string, substitutions?: string | string[]) {
|
||||
const msg = (globalThis.chrome?.i18n?.getMessage(key, substitutions as any) || '').trim();
|
||||
return msg || key;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user