From 389800dd4d7426f9a619de75e9c1d38284ab8120 Mon Sep 17 00:00:00 2001 From: alectimison-maker Date: Sun, 16 Aug 2026 20:57:30 +0800 Subject: [PATCH] fix(i18n): localize the window permission verb and harden the prompt fallback resize_window maps to Capability.WINDOW but no locale defined sp.perm.verb.window, so the permission prompt rendered the raw key ("WebBrain wants to sp.perm.verb.window example.com. Allow it?") in every locale. Add the key to all 23 locales in both trees, and add a CAPABILITY_LABEL fallback in the sidepanel so a capability added without a locale verb can never render its raw key on a security-consent prompt. --- src/chrome/src/ui/locales/ar.js | 1 + src/chrome/src/ui/locales/bn.js | 1 + src/chrome/src/ui/locales/de.js | 1 + src/chrome/src/ui/locales/en.js | 1 + src/chrome/src/ui/locales/es.js | 1 + src/chrome/src/ui/locales/fa.js | 1 + src/chrome/src/ui/locales/fr.js | 1 + src/chrome/src/ui/locales/he.js | 1 + src/chrome/src/ui/locales/hi.js | 1 + src/chrome/src/ui/locales/id.js | 1 + src/chrome/src/ui/locales/ja.js | 1 + src/chrome/src/ui/locales/ko.js | 1 + src/chrome/src/ui/locales/ms.js | 1 + src/chrome/src/ui/locales/nl.js | 1 + src/chrome/src/ui/locales/pl.js | 1 + src/chrome/src/ui/locales/pt.js | 1 + src/chrome/src/ui/locales/ru.js | 1 + src/chrome/src/ui/locales/th.js | 1 + src/chrome/src/ui/locales/tl.js | 1 + src/chrome/src/ui/locales/tr.js | 1 + src/chrome/src/ui/locales/uk.js | 1 + src/chrome/src/ui/locales/vi.js | 1 + src/chrome/src/ui/locales/zh.js | 1 + src/chrome/src/ui/sidepanel.js | 10 ++++++++-- src/firefox/src/ui/locales/ar.js | 1 + src/firefox/src/ui/locales/bn.js | 1 + src/firefox/src/ui/locales/de.js | 1 + src/firefox/src/ui/locales/en.js | 1 + src/firefox/src/ui/locales/es.js | 1 + src/firefox/src/ui/locales/fa.js | 1 + src/firefox/src/ui/locales/fr.js | 1 + src/firefox/src/ui/locales/he.js | 1 + src/firefox/src/ui/locales/hi.js | 1 + src/firefox/src/ui/locales/id.js | 1 + src/firefox/src/ui/locales/ja.js | 1 + src/firefox/src/ui/locales/ko.js | 1 + src/firefox/src/ui/locales/ms.js | 1 + src/firefox/src/ui/locales/nl.js | 1 + src/firefox/src/ui/locales/pl.js | 1 + src/firefox/src/ui/locales/pt.js | 1 + src/firefox/src/ui/locales/ru.js | 1 + src/firefox/src/ui/locales/th.js | 1 + src/firefox/src/ui/locales/tl.js | 1 + src/firefox/src/ui/locales/tr.js | 1 + src/firefox/src/ui/locales/uk.js | 1 + src/firefox/src/ui/locales/vi.js | 1 + src/firefox/src/ui/locales/zh.js | 1 + src/firefox/src/ui/sidepanel.js | 10 ++++++++-- test/run.js | 21 ++++++++++++++++++++- 49 files changed, 82 insertions(+), 5 deletions(-) diff --git a/src/chrome/src/ui/locales/ar.js b/src/chrome/src/ui/locales/ar.js index ed4a2abbd..1461ff5c7 100644 --- a/src/chrome/src/ui/locales/ar.js +++ b/src/chrome/src/ui/locales/ar.js @@ -591,6 +591,7 @@ export default { 'sp.scratchpad.cleared': 'تم مسح المسودة.', 'sp.scratchpad.error': 'منطقة المسودة غير متاحة: {msg}', 'sp.perm.verb.schedule': 'جدولة عمل مستقبلي لـ', + 'sp.perm.verb.window': 'تغيير حجم نافذة المتصفح على', 'tool.schedule_resume': 'جدولة استئناف', 'tool.schedule_task': 'جدولة مهمة', 'st.display.scheduled_tasks.label': 'المهام المجدوَلة', diff --git a/src/chrome/src/ui/locales/bn.js b/src/chrome/src/ui/locales/bn.js index 756c15ed5..0b1c99be6 100644 --- a/src/chrome/src/ui/locales/bn.js +++ b/src/chrome/src/ui/locales/bn.js @@ -331,6 +331,7 @@ export default { 'sp.perm.verb.upload': "একটি ফাইল আপলোড করুন", 'sp.perm.verb.record': "ট্যাব (এবং মাইক্রোফোন) চালু করুন", 'sp.perm.verb.schedule': "ভবিষ্যত কাজের সময়সূচী", + 'sp.perm.verb.window': 'ব্রাউজার উইন্ডোর আকার পরিবর্তন করুন', 'sp.step.details': "বিস্তারিত", 'sp.step.input_label': "ইনপুট", diff --git a/src/chrome/src/ui/locales/de.js b/src/chrome/src/ui/locales/de.js index a7fa93cb4..6452d9e44 100644 --- a/src/chrome/src/ui/locales/de.js +++ b/src/chrome/src/ui/locales/de.js @@ -341,6 +341,7 @@ export default { 'sp.perm.verb.upload': 'Datei hochladen zu', 'sp.perm.verb.record': 'Tab (und Mikrofon) aufnehmen auf', 'sp.perm.verb.schedule': 'zukünftige Aufgaben planen für', + 'sp.perm.verb.window': 'die Größe des Browserfensters ändern auf', 'sp.help.shortcuts_html': 'Tastenkürzel
Ctrl/Cmd+/ — Eingabefeld fokussieren
Ctrl/Cmd+Shift+A — Zum Fragen-Modus wechseln
Ctrl/Cmd+Shift+X — Zum Handeln-Modus wechseln
Ctrl/Cmd+Shift+D — Zum Dev-Modus wechseln
Escape — Aktiven Durchlauf stoppen
Escape zweimal — Aktive Aufnahme stoppen', 'sp.compact.nothing_to_compact': 'Noch nichts zu kompaktieren — es gibt nicht genügend älteren Kontext.', 'sp.compact.busy': 'Kompaktierung nicht möglich, während ein Durchlauf läuft — warten Sie auf dessen Abschluss.', diff --git a/src/chrome/src/ui/locales/en.js b/src/chrome/src/ui/locales/en.js index 85a1553a9..04c22c26b 100644 --- a/src/chrome/src/ui/locales/en.js +++ b/src/chrome/src/ui/locales/en.js @@ -331,6 +331,7 @@ export default { 'sp.perm.verb.upload': 'upload a file to', 'sp.perm.verb.record': 'record the tab (and microphone) on', 'sp.perm.verb.schedule': 'schedule future work for', + 'sp.perm.verb.window': 'resize the browser window for', 'sp.step.details': 'details', 'sp.step.input_label': 'Input', diff --git a/src/chrome/src/ui/locales/es.js b/src/chrome/src/ui/locales/es.js index 48fcc3289..0859d9e73 100644 --- a/src/chrome/src/ui/locales/es.js +++ b/src/chrome/src/ui/locales/es.js @@ -591,6 +591,7 @@ export default { 'sp.scratchpad.cleared': 'Bloc de notas borrado.', 'sp.scratchpad.error': 'Bloc de notas no disponible: {msg}', 'sp.perm.verb.schedule': 'programar trabajo futuro en', + 'sp.perm.verb.window': 'cambiar el tamaño de la ventana del navegador en', 'tool.schedule_resume': 'Programando reanudación', 'tool.schedule_task': 'Programando tarea', 'st.display.scheduled_tasks.label': 'Tareas programadas', diff --git a/src/chrome/src/ui/locales/fa.js b/src/chrome/src/ui/locales/fa.js index b6d92a81c..eb9599fe8 100644 --- a/src/chrome/src/ui/locales/fa.js +++ b/src/chrome/src/ui/locales/fa.js @@ -331,6 +331,7 @@ export default { 'sp.perm.verb.upload': "آپلود فایل به", 'sp.perm.verb.record': "زبانه (و میکروفون) را روی آن ضبط کنید", 'sp.perm.verb.schedule': "برای کارهای آینده برنامه ریزی کنید", + 'sp.perm.verb.window': 'اندازه پنجره مرورگر را تغییر دهید در', 'sp.step.details': "جزئیات", 'sp.step.input_label': "ورودی", diff --git a/src/chrome/src/ui/locales/fr.js b/src/chrome/src/ui/locales/fr.js index 66c53e25f..47a3d0511 100644 --- a/src/chrome/src/ui/locales/fr.js +++ b/src/chrome/src/ui/locales/fr.js @@ -591,6 +591,7 @@ export default { 'sp.scratchpad.cleared': 'Bloc-notes effacé.', 'sp.scratchpad.error': 'Bloc-notes indisponible : {msg}', 'sp.perm.verb.schedule': 'planifier des tâches futures pour', + 'sp.perm.verb.window': 'redimensionner la fenêtre du navigateur sur', 'tool.schedule_resume': 'Planification de la reprise', 'tool.schedule_task': 'Planification de la tâche', 'st.display.scheduled_tasks.label': 'Tâches planifiées', diff --git a/src/chrome/src/ui/locales/he.js b/src/chrome/src/ui/locales/he.js index 1a0b38b1d..f7a83544f 100644 --- a/src/chrome/src/ui/locales/he.js +++ b/src/chrome/src/ui/locales/he.js @@ -305,6 +305,7 @@ export default { "sp.perm.verb.download": "להוריד קבצים מ", "sp.perm.verb.upload": "להעלות קובץ ל", "sp.perm.verb.schedule": "לתזמן עבודה עתידית עבור", + "sp.perm.verb.window": "לשנות את גודל חלון הדפדפן באתר", "sp.step.details": "פרטים", "sp.step.input_label": "קלט", "sp.step.result_label": "תוצאה", diff --git a/src/chrome/src/ui/locales/hi.js b/src/chrome/src/ui/locales/hi.js index 730ea4de2..d166eace0 100644 --- a/src/chrome/src/ui/locales/hi.js +++ b/src/chrome/src/ui/locales/hi.js @@ -331,6 +331,7 @@ export default { 'sp.perm.verb.upload': "पर एक फ़ाइल अपलोड करें", 'sp.perm.verb.record': "टैब (और माइक्रोफ़ोन) को चालू रखें", 'sp.perm.verb.schedule': "भविष्य के लिए कार्य शेड्यूल करें", + 'sp.perm.verb.window': 'ब्राउज़र विंडो का आकार बदलें', 'sp.step.details': "विवरण", 'sp.step.input_label': "इनपुट", diff --git a/src/chrome/src/ui/locales/id.js b/src/chrome/src/ui/locales/id.js index 1d853338b..ebadd7eaf 100644 --- a/src/chrome/src/ui/locales/id.js +++ b/src/chrome/src/ui/locales/id.js @@ -591,6 +591,7 @@ export default { 'sp.scratchpad.cleared': 'Bak pasir dikosongkan.', 'sp.scratchpad.error': 'Bak pasir tidak tersedia: {msg}', 'sp.perm.verb.schedule': 'menjadwalkan pekerjaan mendatang untuk', + 'sp.perm.verb.window': 'mengubah ukuran jendela browser di', 'tool.schedule_resume': 'Menjadwalkan lanjutan', 'tool.schedule_task': 'Menjadwalkan tugas', 'st.display.scheduled_tasks.label': 'Tugas terjadwal', diff --git a/src/chrome/src/ui/locales/ja.js b/src/chrome/src/ui/locales/ja.js index eca7acae0..497baa781 100644 --- a/src/chrome/src/ui/locales/ja.js +++ b/src/chrome/src/ui/locales/ja.js @@ -591,6 +591,7 @@ export default { 'sp.scratchpad.cleared': 'スクラッチパッドをクリアしました。', 'sp.scratchpad.error': 'スクラッチパッドを取得できませんでした: {msg}', 'sp.perm.verb.schedule': 'での将来の作業のスケジュールを', + 'sp.perm.verb.window': 'でのブラウザウィンドウのサイズ変更を', 'tool.schedule_resume': '再開をスケジュール中', 'tool.schedule_task': 'タスクをスケジュール中', 'st.display.scheduled_tasks.label': 'スケジュールタスク', diff --git a/src/chrome/src/ui/locales/ko.js b/src/chrome/src/ui/locales/ko.js index a51523c4c..2acca1cb2 100644 --- a/src/chrome/src/ui/locales/ko.js +++ b/src/chrome/src/ui/locales/ko.js @@ -591,6 +591,7 @@ export default { 'sp.scratchpad.cleared': '스크래치패드가 지워졌습니다.', 'sp.scratchpad.error': '스크래치패드를 사용할 수 없습니다: {msg}', 'sp.perm.verb.schedule': '미래 작업 예약', + 'sp.perm.verb.window': '브라우저 창 크기 조절', 'tool.schedule_resume': '재개 예약 중', 'tool.schedule_task': '작업 예약 중', 'st.display.scheduled_tasks.label': '예약된 작업', diff --git a/src/chrome/src/ui/locales/ms.js b/src/chrome/src/ui/locales/ms.js index 1dcab821a..a58f0d9c4 100644 --- a/src/chrome/src/ui/locales/ms.js +++ b/src/chrome/src/ui/locales/ms.js @@ -591,6 +591,7 @@ export default { 'sp.scratchpad.cleared': 'Pad nota dikosongkan.', 'sp.scratchpad.error': 'Pad nota tidak tersedia: {msg}', 'sp.perm.verb.schedule': 'menjadualkan kerja masa hadapan untuk', + 'sp.perm.verb.window': 'menukar saiz tetingkap pelayar pada', 'tool.schedule_resume': 'Menjadualkan sambungan semula', 'tool.schedule_task': 'Menjadualkan tugas', 'st.display.scheduled_tasks.label': 'Tugas berjadual', diff --git a/src/chrome/src/ui/locales/nl.js b/src/chrome/src/ui/locales/nl.js index 8ad60766f..a9c770945 100644 --- a/src/chrome/src/ui/locales/nl.js +++ b/src/chrome/src/ui/locales/nl.js @@ -319,6 +319,7 @@ export default { 'sp.perm.verb.upload': 'een bestand uploaden naar', 'sp.perm.verb.record': 'het tabblad (en microfoon) opnemen op', 'sp.perm.verb.schedule': 'geplande taken instellen voor', + 'sp.perm.verb.window': 'het browservenster aanpassen op', 'sp.step.details': 'details', 'sp.step.input_label': 'Invoer', 'sp.step.result_label': 'Resultaat', diff --git a/src/chrome/src/ui/locales/pl.js b/src/chrome/src/ui/locales/pl.js index 5e2cd1751..d46651625 100644 --- a/src/chrome/src/ui/locales/pl.js +++ b/src/chrome/src/ui/locales/pl.js @@ -239,6 +239,7 @@ export default { 'sp.perm.verb.upload': 'przesłać plik do', 'sp.perm.verb.record': 'nagrać kartę (i mikrofon) na', 'sp.perm.verb.schedule': 'zaplanować przyszłe działania dla', + 'sp.perm.verb.window': 'zmienić rozmiar okna przeglądarki na', 'sp.step.details': 'szczegóły', 'sp.step.input_label': 'Wejście', 'sp.step.result_label': 'Wynik', diff --git a/src/chrome/src/ui/locales/pt.js b/src/chrome/src/ui/locales/pt.js index 75b1868d9..65b3b884f 100644 --- a/src/chrome/src/ui/locales/pt.js +++ b/src/chrome/src/ui/locales/pt.js @@ -331,6 +331,7 @@ export default { 'sp.perm.verb.upload': "carregar um arquivo para", 'sp.perm.verb.record': "grave a guia (e o microfone) em", 'sp.perm.verb.schedule': "agendar trabalhos futuros para", + 'sp.perm.verb.window': 'redimensionar a janela do navegador em', 'sp.step.details': "detalhes", 'sp.step.input_label': "Entrada", diff --git a/src/chrome/src/ui/locales/ru.js b/src/chrome/src/ui/locales/ru.js index 4643f3e1f..c3d48ec6f 100644 --- a/src/chrome/src/ui/locales/ru.js +++ b/src/chrome/src/ui/locales/ru.js @@ -591,6 +591,7 @@ export default { 'sp.scratchpad.cleared': 'Блокнот очищен.', 'sp.scratchpad.error': 'Блокнот недоступен: {msg}', 'sp.perm.verb.schedule': 'запланировать будущие действия для', + 'sp.perm.verb.window': 'изменить размер окна браузера на', 'tool.schedule_resume': 'Планирование возобновления', 'tool.schedule_task': 'Планирование задачи', 'st.display.scheduled_tasks.label': 'Запланированные задачи', diff --git a/src/chrome/src/ui/locales/th.js b/src/chrome/src/ui/locales/th.js index 1cd152066..d1f3590e1 100644 --- a/src/chrome/src/ui/locales/th.js +++ b/src/chrome/src/ui/locales/th.js @@ -591,6 +591,7 @@ export default { 'sp.scratchpad.cleared': 'ล้างกระดานร่างแล้ว', 'sp.scratchpad.error': 'ไม่สามารถใช้กระดานร่างได้: {msg}', 'sp.perm.verb.schedule': 'ตั้งเวลางานในอนาคตสำหรับ', + 'sp.perm.verb.window': 'ปรับขนาดหน้าต่างเบราว์เซอร์บน', 'tool.schedule_resume': 'กำลังตั้งเวลาต่องาน', 'tool.schedule_task': 'กำลังตั้งเวลางาน', 'st.display.scheduled_tasks.label': 'งานที่ตั้งเวลาไว้', diff --git a/src/chrome/src/ui/locales/tl.js b/src/chrome/src/ui/locales/tl.js index 328e1990b..5e7bc5c1e 100644 --- a/src/chrome/src/ui/locales/tl.js +++ b/src/chrome/src/ui/locales/tl.js @@ -591,6 +591,7 @@ export default { 'sp.scratchpad.cleared': 'Na-clear ang scratchpad.', 'sp.scratchpad.error': 'Hindi available ang scratchpad: {msg}', 'sp.perm.verb.schedule': 'mag-iskedyul ng gawaing hinaharap para sa', + 'sp.perm.verb.window': 'baguhin ang laki ng window ng browser sa', 'tool.schedule_resume': 'Nag-iiskedyul ng pagpapatuloy', 'tool.schedule_task': 'Nag-iiskedyul ng gawain', 'st.display.scheduled_tasks.label': 'Mga naka-iskedyul na gawain', diff --git a/src/chrome/src/ui/locales/tr.js b/src/chrome/src/ui/locales/tr.js index 37516dfb6..768f1bbe3 100644 --- a/src/chrome/src/ui/locales/tr.js +++ b/src/chrome/src/ui/locales/tr.js @@ -630,6 +630,7 @@ export default { 'sp.scratchpad.cleared': 'Not defteri temizlendi.', 'sp.scratchpad.error': 'Not defterine erişilemiyor: {msg}', 'sp.perm.verb.schedule': 'gelecekteki çalışmayı zamanlamak için', + 'sp.perm.verb.window': 'tarayıcı penceresinin boyutunu değiştirmek', 'tool.schedule_resume': 'Devam zamanlama', 'tool.schedule_task': 'Görev zamanlama', 'st.display.scheduled_tasks.label': 'Zamanlanmış görevler', diff --git a/src/chrome/src/ui/locales/uk.js b/src/chrome/src/ui/locales/uk.js index 0f37dbc03..09625e10b 100644 --- a/src/chrome/src/ui/locales/uk.js +++ b/src/chrome/src/ui/locales/uk.js @@ -591,6 +591,7 @@ export default { 'sp.scratchpad.cleared': 'Чернетник очищено.', 'sp.scratchpad.error': 'Чернетник недоступний: {msg}', 'sp.perm.verb.schedule': 'запланувати майбутню роботу для', + 'sp.perm.verb.window': 'змінити розмір вікна браузера на', 'tool.schedule_resume': 'Планування відновлення', 'tool.schedule_task': 'Планування завдання', 'st.display.scheduled_tasks.label': 'Заплановані завдання', diff --git a/src/chrome/src/ui/locales/vi.js b/src/chrome/src/ui/locales/vi.js index c66df90f8..26cd6f003 100644 --- a/src/chrome/src/ui/locales/vi.js +++ b/src/chrome/src/ui/locales/vi.js @@ -331,6 +331,7 @@ export default { 'sp.perm.verb.upload': "tải một tập tin lên", 'sp.perm.verb.record': "ghi lại tab (và micrô) trên", 'sp.perm.verb.schedule': "sắp xếp công việc trong tương lai cho", + 'sp.perm.verb.window': 'thay đổi kích thước cửa sổ trình duyệt trên', 'sp.step.details': "chi tiết", 'sp.step.input_label': "đầu vào", diff --git a/src/chrome/src/ui/locales/zh.js b/src/chrome/src/ui/locales/zh.js index 65e3422fd..1f17b4c34 100644 --- a/src/chrome/src/ui/locales/zh.js +++ b/src/chrome/src/ui/locales/zh.js @@ -591,6 +591,7 @@ export default { 'sp.scratchpad.cleared': '草稿板已清除。', 'sp.scratchpad.error': '草稿板不可用:{msg}', 'sp.perm.verb.schedule': '为以下对象安排后续任务', + 'sp.perm.verb.window': '调整浏览器窗口大小于', 'tool.schedule_resume': '正在安排恢复', 'tool.schedule_task': '正在安排任务', 'st.display.scheduled_tasks.label': '定时任务', diff --git a/src/chrome/src/ui/sidepanel.js b/src/chrome/src/ui/sidepanel.js index 63f901e2c..f579858dd 100644 --- a/src/chrome/src/ui/sidepanel.js +++ b/src/chrome/src/ui/sidepanel.js @@ -4,6 +4,7 @@ */ import { t, getLocale, setLocale, LANGUAGES, applyDOMTranslations } from './i18n.js'; +import { CAPABILITY_LABEL } from '../agent/permission-gate.js'; import { sanitizeMarkdownLinks } from './markdown-link.js'; import { codeFenceLanguage, highlightCode, renderMarkdownHeadings } from './markdown-render.js'; import { applyMode, loadMode, watch } from './theme.js'; @@ -9315,8 +9316,13 @@ function renderClarifyCard(data) { card.dataset.permission = '1'; const host = String(data.permission.host || ''); const cap = String(data.permission.capability || ''); - const verb = t('sp.perm.verb.' + cap); - qEl.textContent = t('sp.perm.question', { verb, host }); + const verbKey = 'sp.perm.verb.' + cap; + const verb = t(verbKey); + // English falls back to the single CAPABILITY_LABEL source of truth so the + // consent wording cannot drift between two English copies; other locales + // carry their own translation under the key. + const resolvedVerb = verb === verbKey ? (CAPABILITY_LABEL[cap] || cap) : verb; + qEl.textContent = t('sp.perm.question', { verb: resolvedVerb, host }); const reasonEl = document.createElement('div'); reasonEl.className = 'clarify-reason'; diff --git a/src/firefox/src/ui/locales/ar.js b/src/firefox/src/ui/locales/ar.js index 80da198cf..e5ea78a4e 100644 --- a/src/firefox/src/ui/locales/ar.js +++ b/src/firefox/src/ui/locales/ar.js @@ -575,6 +575,7 @@ export default { 'sp.scratchpad.cleared': 'تم مسح المسودة.', 'sp.scratchpad.error': 'منطقة المسودة غير متاحة: {msg}', 'sp.perm.verb.schedule': 'جدولة عمل مستقبلي لـ', + 'sp.perm.verb.window': 'تغيير حجم نافذة المتصفح على', 'tool.schedule_resume': 'جدولة استئناف', 'tool.schedule_task': 'جدولة مهمة', 'st.display.scheduled_tasks.label': 'المهام المجدوَلة', diff --git a/src/firefox/src/ui/locales/bn.js b/src/firefox/src/ui/locales/bn.js index a4a6f7cbf..16c46ef66 100644 --- a/src/firefox/src/ui/locales/bn.js +++ b/src/firefox/src/ui/locales/bn.js @@ -329,6 +329,7 @@ export default { 'sp.perm.verb.upload': "একটি ফাইল আপলোড করুন", 'sp.perm.verb.record': "ট্যাব (এবং মাইক্রোফোন) চালু করুন", 'sp.perm.verb.schedule': "ভবিষ্যত কাজের সময়সূচী", + 'sp.perm.verb.window': 'ব্রাউজার উইন্ডোর আকার পরিবর্তন করুন', 'sp.step.details': "বিস্তারিত", 'sp.step.input_label': "ইনপুট", diff --git a/src/firefox/src/ui/locales/de.js b/src/firefox/src/ui/locales/de.js index e9a14d40d..ba4ad4702 100644 --- a/src/firefox/src/ui/locales/de.js +++ b/src/firefox/src/ui/locales/de.js @@ -339,6 +339,7 @@ export default { 'sp.perm.verb.upload': 'Datei hochladen zu', 'sp.perm.verb.record': 'Tab (und Mikrofon) aufnehmen auf', 'sp.perm.verb.schedule': 'zukünftige Aufgaben planen für', + 'sp.perm.verb.window': 'die Größe des Browserfensters ändern auf', 'sp.help.shortcuts_html': 'Tastenkürzel
Ctrl/Cmd+/ — Eingabefeld fokussieren
Ctrl/Cmd+Shift+A — Zum Fragen-Modus wechseln
Ctrl/Cmd+Shift+X — Zum Handeln-Modus wechseln
Ctrl/Cmd+Shift+D — Zum Dev-Modus wechseln
Escape — Aktiven Durchlauf stoppen
Escape zweimal — Aktive Aufnahme stoppen', 'sp.compact.nothing_to_compact': 'Noch nichts zu kompaktieren — es gibt nicht genügend älteren Kontext.', 'sp.compact.busy': 'Kompaktierung nicht möglich, während ein Durchlauf läuft — warten Sie auf dessen Abschluss.', diff --git a/src/firefox/src/ui/locales/en.js b/src/firefox/src/ui/locales/en.js index 9043b6d2f..e5ec9c0c7 100644 --- a/src/firefox/src/ui/locales/en.js +++ b/src/firefox/src/ui/locales/en.js @@ -329,6 +329,7 @@ export default { 'sp.perm.verb.upload': 'upload a file to', 'sp.perm.verb.record': 'record the tab (and microphone) on', 'sp.perm.verb.schedule': 'schedule future work for', + 'sp.perm.verb.window': 'resize the browser window for', 'sp.step.details': 'details', 'sp.step.input_label': 'Input', diff --git a/src/firefox/src/ui/locales/es.js b/src/firefox/src/ui/locales/es.js index 142b15723..8a22839be 100644 --- a/src/firefox/src/ui/locales/es.js +++ b/src/firefox/src/ui/locales/es.js @@ -575,6 +575,7 @@ export default { 'sp.scratchpad.cleared': 'Bloc de notas borrado.', 'sp.scratchpad.error': 'Bloc de notas no disponible: {msg}', 'sp.perm.verb.schedule': 'programar trabajo futuro en', + 'sp.perm.verb.window': 'cambiar el tamaño de la ventana del navegador en', 'tool.schedule_resume': 'Programando reanudación', 'tool.schedule_task': 'Programando tarea', 'st.display.scheduled_tasks.label': 'Tareas programadas', diff --git a/src/firefox/src/ui/locales/fa.js b/src/firefox/src/ui/locales/fa.js index 2bcbd817c..30ced7a6a 100644 --- a/src/firefox/src/ui/locales/fa.js +++ b/src/firefox/src/ui/locales/fa.js @@ -329,6 +329,7 @@ export default { 'sp.perm.verb.upload': "آپلود فایل به", 'sp.perm.verb.record': "زبانه (و میکروفون) را روی آن ضبط کنید", 'sp.perm.verb.schedule': "برای کارهای آینده برنامه ریزی کنید", + 'sp.perm.verb.window': 'اندازه پنجره مرورگر را تغییر دهید در', 'sp.step.details': "جزئیات", 'sp.step.input_label': "ورودی", diff --git a/src/firefox/src/ui/locales/fr.js b/src/firefox/src/ui/locales/fr.js index 395764fb4..779f91ab0 100644 --- a/src/firefox/src/ui/locales/fr.js +++ b/src/firefox/src/ui/locales/fr.js @@ -575,6 +575,7 @@ export default { 'sp.scratchpad.cleared': 'Bloc-notes effacé.', 'sp.scratchpad.error': 'Bloc-notes indisponible : {msg}', 'sp.perm.verb.schedule': 'planifier des tâches futures pour', + 'sp.perm.verb.window': 'redimensionner la fenêtre du navigateur sur', 'tool.schedule_resume': 'Planification de la reprise', 'tool.schedule_task': 'Planification de la tâche', 'st.display.scheduled_tasks.label': 'Tâches planifiées', diff --git a/src/firefox/src/ui/locales/he.js b/src/firefox/src/ui/locales/he.js index ebaa29d80..bc7d4d53a 100644 --- a/src/firefox/src/ui/locales/he.js +++ b/src/firefox/src/ui/locales/he.js @@ -303,6 +303,7 @@ export default { "sp.perm.verb.download": "להוריד קבצים מ", "sp.perm.verb.upload": "להעלות קובץ ל", "sp.perm.verb.schedule": "לתזמן עבודה עתידית עבור", + "sp.perm.verb.window": "לשנות את גודל חלון הדפדפן באתר", "sp.step.details": "פרטים", "sp.step.input_label": "קלט", "sp.step.result_label": "תוצאה", diff --git a/src/firefox/src/ui/locales/hi.js b/src/firefox/src/ui/locales/hi.js index 048a7336f..ae494ce20 100644 --- a/src/firefox/src/ui/locales/hi.js +++ b/src/firefox/src/ui/locales/hi.js @@ -329,6 +329,7 @@ export default { 'sp.perm.verb.upload': "पर एक फ़ाइल अपलोड करें", 'sp.perm.verb.record': "टैब (और माइक्रोफ़ोन) को चालू रखें", 'sp.perm.verb.schedule': "भविष्य के लिए कार्य शेड्यूल करें", + 'sp.perm.verb.window': 'ब्राउज़र विंडो का आकार बदलें', 'sp.step.details': "विवरण", 'sp.step.input_label': "इनपुट", diff --git a/src/firefox/src/ui/locales/id.js b/src/firefox/src/ui/locales/id.js index 89a00e197..9515fd263 100644 --- a/src/firefox/src/ui/locales/id.js +++ b/src/firefox/src/ui/locales/id.js @@ -575,6 +575,7 @@ export default { 'sp.scratchpad.cleared': 'Bak pasir dikosongkan.', 'sp.scratchpad.error': 'Bak pasir tidak tersedia: {msg}', 'sp.perm.verb.schedule': 'menjadwalkan pekerjaan mendatang untuk', + 'sp.perm.verb.window': 'mengubah ukuran jendela browser di', 'tool.schedule_resume': 'Menjadwalkan lanjutan', 'tool.schedule_task': 'Menjadwalkan tugas', 'st.display.scheduled_tasks.label': 'Tugas terjadwal', diff --git a/src/firefox/src/ui/locales/ja.js b/src/firefox/src/ui/locales/ja.js index 4ba0c92d6..26596e951 100644 --- a/src/firefox/src/ui/locales/ja.js +++ b/src/firefox/src/ui/locales/ja.js @@ -575,6 +575,7 @@ export default { 'sp.scratchpad.cleared': 'スクラッチパッドをクリアしました。', 'sp.scratchpad.error': 'スクラッチパッドを取得できませんでした: {msg}', 'sp.perm.verb.schedule': 'での将来の作業のスケジュールを', + 'sp.perm.verb.window': 'でのブラウザウィンドウのサイズ変更を', 'tool.schedule_resume': '再開をスケジュール中', 'tool.schedule_task': 'タスクをスケジュール中', 'st.display.scheduled_tasks.label': 'スケジュールタスク', diff --git a/src/firefox/src/ui/locales/ko.js b/src/firefox/src/ui/locales/ko.js index da4c5d988..2c3d0ea01 100644 --- a/src/firefox/src/ui/locales/ko.js +++ b/src/firefox/src/ui/locales/ko.js @@ -575,6 +575,7 @@ export default { 'sp.scratchpad.cleared': '스크래치패드가 지워졌습니다.', 'sp.scratchpad.error': '스크래치패드를 사용할 수 없습니다: {msg}', 'sp.perm.verb.schedule': '미래 작업 예약', + 'sp.perm.verb.window': '브라우저 창 크기 조절', 'tool.schedule_resume': '재개 예약 중', 'tool.schedule_task': '작업 예약 중', 'st.display.scheduled_tasks.label': '예약된 작업', diff --git a/src/firefox/src/ui/locales/ms.js b/src/firefox/src/ui/locales/ms.js index 286af4d48..d553d7b30 100644 --- a/src/firefox/src/ui/locales/ms.js +++ b/src/firefox/src/ui/locales/ms.js @@ -575,6 +575,7 @@ export default { 'sp.scratchpad.cleared': 'Pad nota dikosongkan.', 'sp.scratchpad.error': 'Pad nota tidak tersedia: {msg}', 'sp.perm.verb.schedule': 'menjadualkan kerja masa hadapan untuk', + 'sp.perm.verb.window': 'menukar saiz tetingkap pelayar pada', 'tool.schedule_resume': 'Menjadualkan sambungan semula', 'tool.schedule_task': 'Menjadualkan tugas', 'st.display.scheduled_tasks.label': 'Tugas berjadual', diff --git a/src/firefox/src/ui/locales/nl.js b/src/firefox/src/ui/locales/nl.js index 238e73239..c48bffa1b 100644 --- a/src/firefox/src/ui/locales/nl.js +++ b/src/firefox/src/ui/locales/nl.js @@ -317,6 +317,7 @@ export default { 'sp.perm.verb.upload': 'een bestand uploaden naar', 'sp.perm.verb.record': 'het tabblad (en microfoon) opnemen op', 'sp.perm.verb.schedule': 'geplande taken instellen voor', + 'sp.perm.verb.window': 'het browservenster aanpassen op', 'sp.step.details': 'details', 'sp.step.input_label': 'Invoer', 'sp.step.result_label': 'Resultaat', diff --git a/src/firefox/src/ui/locales/pl.js b/src/firefox/src/ui/locales/pl.js index 599f9f900..ca3e0145e 100644 --- a/src/firefox/src/ui/locales/pl.js +++ b/src/firefox/src/ui/locales/pl.js @@ -238,6 +238,7 @@ export default { 'sp.perm.verb.upload': 'przesłać plik do', 'sp.perm.verb.record': 'nagrać kartę (i mikrofon) na', 'sp.perm.verb.schedule': 'zaplanować przyszłe działania dla', + 'sp.perm.verb.window': 'zmienić rozmiar okna przeglądarki na', 'sp.step.details': 'szczegóły', 'sp.step.input_label': 'Wejście', 'sp.step.result_label': 'Wynik', diff --git a/src/firefox/src/ui/locales/pt.js b/src/firefox/src/ui/locales/pt.js index f72cf61a2..248cfa0fb 100644 --- a/src/firefox/src/ui/locales/pt.js +++ b/src/firefox/src/ui/locales/pt.js @@ -329,6 +329,7 @@ export default { 'sp.perm.verb.upload': "carregar um arquivo para", 'sp.perm.verb.record': "grave a guia (e o microfone) em", 'sp.perm.verb.schedule': "agendar trabalhos futuros para", + 'sp.perm.verb.window': 'redimensionar a janela do navegador em', 'sp.step.details': "detalhes", 'sp.step.input_label': "Entrada", diff --git a/src/firefox/src/ui/locales/ru.js b/src/firefox/src/ui/locales/ru.js index 4f10132f7..9aadd0bf9 100644 --- a/src/firefox/src/ui/locales/ru.js +++ b/src/firefox/src/ui/locales/ru.js @@ -575,6 +575,7 @@ export default { 'sp.scratchpad.cleared': 'Блокнот очищен.', 'sp.scratchpad.error': 'Блокнот недоступен: {msg}', 'sp.perm.verb.schedule': 'запланировать будущие действия для', + 'sp.perm.verb.window': 'изменить размер окна браузера на', 'tool.schedule_resume': 'Планирование возобновления', 'tool.schedule_task': 'Планирование задачи', 'st.display.scheduled_tasks.label': 'Запланированные задачи', diff --git a/src/firefox/src/ui/locales/th.js b/src/firefox/src/ui/locales/th.js index aa9c46c66..4a15c38e4 100644 --- a/src/firefox/src/ui/locales/th.js +++ b/src/firefox/src/ui/locales/th.js @@ -575,6 +575,7 @@ export default { 'sp.scratchpad.cleared': 'ล้างกระดานร่างแล้ว', 'sp.scratchpad.error': 'ไม่สามารถใช้กระดานร่างได้: {msg}', 'sp.perm.verb.schedule': 'ตั้งเวลางานในอนาคตสำหรับ', + 'sp.perm.verb.window': 'ปรับขนาดหน้าต่างเบราว์เซอร์บน', 'tool.schedule_resume': 'กำลังตั้งเวลาต่องาน', 'tool.schedule_task': 'กำลังตั้งเวลางาน', 'st.display.scheduled_tasks.label': 'งานที่ตั้งเวลาไว้', diff --git a/src/firefox/src/ui/locales/tl.js b/src/firefox/src/ui/locales/tl.js index 3cfc0657d..b8da08f22 100644 --- a/src/firefox/src/ui/locales/tl.js +++ b/src/firefox/src/ui/locales/tl.js @@ -575,6 +575,7 @@ export default { 'sp.scratchpad.cleared': 'Na-clear ang scratchpad.', 'sp.scratchpad.error': 'Hindi available ang scratchpad: {msg}', 'sp.perm.verb.schedule': 'mag-iskedyul ng gawaing hinaharap para sa', + 'sp.perm.verb.window': 'baguhin ang laki ng window ng browser sa', 'tool.schedule_resume': 'Nag-iiskedyul ng pagpapatuloy', 'tool.schedule_task': 'Nag-iiskedyul ng gawain', 'st.display.scheduled_tasks.label': 'Mga naka-iskedyul na gawain', diff --git a/src/firefox/src/ui/locales/tr.js b/src/firefox/src/ui/locales/tr.js index 7fc178bcc..a91520565 100644 --- a/src/firefox/src/ui/locales/tr.js +++ b/src/firefox/src/ui/locales/tr.js @@ -614,6 +614,7 @@ export default { 'sp.scratchpad.cleared': 'Not defteri temizlendi.', 'sp.scratchpad.error': 'Not defterine erişilemiyor: {msg}', 'sp.perm.verb.schedule': 'gelecekteki çalışmayı zamanlamak için', + 'sp.perm.verb.window': 'tarayıcı penceresinin boyutunu değiştirmek', 'tool.schedule_resume': 'Devam zamanlama', 'tool.schedule_task': 'Görev zamanlama', 'st.display.scheduled_tasks.label': 'Zamanlanmış görevler', diff --git a/src/firefox/src/ui/locales/uk.js b/src/firefox/src/ui/locales/uk.js index 43b80975e..839804ce3 100644 --- a/src/firefox/src/ui/locales/uk.js +++ b/src/firefox/src/ui/locales/uk.js @@ -575,6 +575,7 @@ export default { 'sp.scratchpad.cleared': 'Чернетник очищено.', 'sp.scratchpad.error': 'Чернетник недоступний: {msg}', 'sp.perm.verb.schedule': 'запланувати майбутню роботу для', + 'sp.perm.verb.window': 'змінити розмір вікна браузера на', 'tool.schedule_resume': 'Планування відновлення', 'tool.schedule_task': 'Планування завдання', 'st.display.scheduled_tasks.label': 'Заплановані завдання', diff --git a/src/firefox/src/ui/locales/vi.js b/src/firefox/src/ui/locales/vi.js index dca99b7d0..b9ba98679 100644 --- a/src/firefox/src/ui/locales/vi.js +++ b/src/firefox/src/ui/locales/vi.js @@ -329,6 +329,7 @@ export default { 'sp.perm.verb.upload': "tải một tập tin lên", 'sp.perm.verb.record': "ghi lại tab (và micrô) trên", 'sp.perm.verb.schedule': "sắp xếp công việc trong tương lai cho", + 'sp.perm.verb.window': 'thay đổi kích thước cửa sổ trình duyệt trên', 'sp.step.details': "chi tiết", 'sp.step.input_label': "đầu vào", diff --git a/src/firefox/src/ui/locales/zh.js b/src/firefox/src/ui/locales/zh.js index 7ae459f06..3acbd226c 100644 --- a/src/firefox/src/ui/locales/zh.js +++ b/src/firefox/src/ui/locales/zh.js @@ -575,6 +575,7 @@ export default { 'sp.scratchpad.cleared': '草稿板已清除。', 'sp.scratchpad.error': '草稿板不可用:{msg}', 'sp.perm.verb.schedule': '为以下对象安排后续任务', + 'sp.perm.verb.window': '调整浏览器窗口大小于', 'tool.schedule_resume': '正在安排恢复', 'tool.schedule_task': '正在安排任务', 'st.display.scheduled_tasks.label': '定时任务', diff --git a/src/firefox/src/ui/sidepanel.js b/src/firefox/src/ui/sidepanel.js index 99db46a49..30d536c76 100644 --- a/src/firefox/src/ui/sidepanel.js +++ b/src/firefox/src/ui/sidepanel.js @@ -4,6 +4,7 @@ */ import { t, getLocale, setLocale, LANGUAGES, applyDOMTranslations } from './i18n.js'; +import { CAPABILITY_LABEL } from '../agent/permission-gate.js'; import { sanitizeMarkdownLinks } from './markdown-link.js'; import { codeFenceLanguage, highlightCode, renderMarkdownHeadings } from './markdown-render.js'; import { applyMode, loadMode, watch } from './theme.js'; @@ -8801,8 +8802,13 @@ function renderClarifyCard(data) { card.dataset.permission = '1'; const host = String(data.permission.host || ''); const cap = String(data.permission.capability || ''); - const verb = t('sp.perm.verb.' + cap); - qEl.textContent = t('sp.perm.question', { verb, host }); + const verbKey = 'sp.perm.verb.' + cap; + const verb = t(verbKey); + // English falls back to the single CAPABILITY_LABEL source of truth so the + // consent wording cannot drift between two English copies; other locales + // carry their own translation under the key. + const resolvedVerb = verb === verbKey ? (CAPABILITY_LABEL[cap] || cap) : verb; + qEl.textContent = t('sp.perm.question', { verb: resolvedVerb, host }); const reasonEl = document.createElement('div'); reasonEl.className = 'clarify-reason'; diff --git a/test/run.js b/test/run.js index cbab07c8a..d3333f638 100644 --- a/test/run.js +++ b/test/run.js @@ -567,11 +567,12 @@ const { createContextMenuPromptHandler: createContextMenuPromptHandlerFx } = awa ); // permission-gate.js is pure JS (deterministic capability × origin gate). -const { Capability, capabilityFor, capabilitiesFor, normalizeHost, hostForCapability, requiredHosts, frameHostMatches, isNetworkMutation, PermissionManager, UNTRUSTED_CONTENT_TOOLS } = await import( +const { Capability, CAPABILITY_LABEL, capabilityFor, capabilitiesFor, normalizeHost, hostForCapability, requiredHosts, frameHostMatches, isNetworkMutation, PermissionManager, UNTRUSTED_CONTENT_TOOLS } = await import( 'file://' + path.join(ROOT, 'src/firefox/src/agent/permission-gate.js').replace(/\\/g, '/') ); const { Capability: CapabilityCh, + CAPABILITY_LABEL: CAPABILITY_LABEL_CH, capabilityFor: capabilityForCh, PermissionManager: PermissionManagerCh, normalizeHost: normalizeHostCh, @@ -25142,6 +25143,24 @@ test('all locales cover English keys and preserve interpolation placeholders', a } }); +test('every permission-gate capability has an English verb and a sidepanel fallback', () => { + for (const [label, Cap, LABEL, prefix] of [ + ['chrome', CapabilityCh, CAPABILITY_LABEL_CH, 'src/chrome'], + ['firefox', Capability, CAPABILITY_LABEL, 'src/firefox'], + ]) { + for (const cap of Object.values(Cap)) { + const labelText = LABEL[cap]; + assert.equal(typeof labelText, 'string', `${label}: ${cap} missing from CAPABILITY_LABEL`); + assert.ok(labelText.length > 0, `${label}: ${cap} English verb must not be empty`); + } + // The permission prompt must fall back to CAPABILITY_LABEL (not the raw + // key) when a locale lacks sp.perm.verb., so a newly added capability + // can never render its raw key on the consent prompt. + const sidepanel = fs.readFileSync(path.join(ROOT, prefix, 'src/ui/sidepanel.js'), 'utf8'); + assert.match(sidepanel, /CAPABILITY_LABEL\[cap\] \|\| cap/, `${label}: sidepanel permission prompt must fall back to CAPABILITY_LABEL`); + } +}); + test('Apocalypse Mode copy is translated instead of inherited from English in every locale', async () => { const requiredTranslatedKeys = [ 'st.display.apocalypse_mode.desc',