From 05209cd0490c3d7e48687493fce44278e6a29d76 Mon Sep 17 00:00:00 2001 From: Daniel Dada Date: Wed, 11 Feb 2026 09:19:19 +0300 Subject: [PATCH] added export/import settubgs --- _locales/de/messages.json | 12 +++++ _locales/en/messages.json | 12 +++++ _locales/es/messages.json | 12 +++++ _locales/fr/messages.json | 12 +++++ _locales/hi/messages.json | 12 +++++ _locales/it/messages.json | 12 +++++ _locales/ja/messages.json | 12 +++++ _locales/ko/messages.json | 12 +++++ _locales/nl/messages.json | 12 +++++ _locales/pl/messages.json | 12 +++++ _locales/pt_BR/messages.json | 12 +++++ _locales/ru/messages.json | 12 +++++ _locales/tr/messages.json | 12 +++++ _locales/zh_CN/messages.json | 12 +++++ popup/popup.css | 24 ++++++++++ popup/popup.html | 16 +++++++ src/popup/PopupController.ts | 92 +++++++++++++++++++++++++++++++++++- 17 files changed, 299 insertions(+), 1 deletion(-) diff --git a/_locales/de/messages.json b/_locales/de/messages.json index 426dca1..c8663f5 100644 --- a/_locales/de/messages.json +++ b/_locales/de/messages.json @@ -322,5 +322,17 @@ }, "rename_list": { "message": "Liste umbenennen" + }, + "export_settings": { + "message": "Exportieren" + }, + "import_settings": { + "message": "Importieren" + }, + "export_import_settings_label": { + "message": "Export / Import" + }, + "export_import_settings_hint": { + "message": "Listen und Website-Ausnahmen sichern oder wiederherstellen." } } \ No newline at end of file diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 7082edb..bb23a84 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -358,5 +358,17 @@ }, "close": { "message": "Close" + }, + "export_settings": { + "message": "Export" + }, + "import_settings": { + "message": "Import" + }, + "export_import_settings_label": { + "message": "Export / Import" + }, + "export_import_settings_hint": { + "message": "Back up or restore lists and site exceptions." } } \ No newline at end of file diff --git a/_locales/es/messages.json b/_locales/es/messages.json index e5916e9..2aa4da7 100644 --- a/_locales/es/messages.json +++ b/_locales/es/messages.json @@ -328,5 +328,17 @@ }, "rename_list": { "message": "Renombrar lista" + }, + "export_settings": { + "message": "Exportar" + }, + "import_settings": { + "message": "Importar" + }, + "export_import_settings_label": { + "message": "Exportar / Importar" + }, + "export_import_settings_hint": { + "message": "Hacer copia de seguridad o restaurar listas y excepciones de sitios." } } \ No newline at end of file diff --git a/_locales/fr/messages.json b/_locales/fr/messages.json index f6a3193..e6837fd 100644 --- a/_locales/fr/messages.json +++ b/_locales/fr/messages.json @@ -328,5 +328,17 @@ }, "rename_list": { "message": "Renommer la liste" + }, + "export_settings": { + "message": "Exporter" + }, + "import_settings": { + "message": "Importer" + }, + "export_import_settings_label": { + "message": "Exporter / Importer" + }, + "export_import_settings_hint": { + "message": "Sauvegarder ou restaurer les listes et les exceptions de sites." } } \ No newline at end of file diff --git a/_locales/hi/messages.json b/_locales/hi/messages.json index 8c67242..0ac772d 100644 --- a/_locales/hi/messages.json +++ b/_locales/hi/messages.json @@ -328,5 +328,17 @@ }, "rename_list": { "message": "सूची का नाम बदलें" + }, + "export_settings": { + "message": "निर्यात" + }, + "import_settings": { + "message": "आयात" + }, + "export_import_settings_label": { + "message": "निर्यात / आयात" + }, + "export_import_settings_hint": { + "message": "सूचियों और साइट अपवादों का बैकअप लें या पुनर्स्थापित करें।" } } \ No newline at end of file diff --git a/_locales/it/messages.json b/_locales/it/messages.json index ea510b1..ddeb16d 100644 --- a/_locales/it/messages.json +++ b/_locales/it/messages.json @@ -328,5 +328,17 @@ }, "rename_list": { "message": "Rinomina elenco" + }, + "export_settings": { + "message": "Esporta" + }, + "import_settings": { + "message": "Importa" + }, + "export_import_settings_label": { + "message": "Esporta / Importa" + }, + "export_import_settings_hint": { + "message": "Backup o ripristino di elenchi e eccezioni di siti." } } \ No newline at end of file diff --git a/_locales/ja/messages.json b/_locales/ja/messages.json index b9b1bbe..1ccd326 100644 --- a/_locales/ja/messages.json +++ b/_locales/ja/messages.json @@ -328,5 +328,17 @@ }, "rename_list": { "message": "リスト名を変更" + }, + "export_settings": { + "message": "エクスポート" + }, + "import_settings": { + "message": "インポート" + }, + "export_import_settings_label": { + "message": "エクスポート / インポート" + }, + "export_import_settings_hint": { + "message": "リストとサイトの例外をバックアップまたは復元します。" } } \ No newline at end of file diff --git a/_locales/ko/messages.json b/_locales/ko/messages.json index 96afc0e..95d4403 100644 --- a/_locales/ko/messages.json +++ b/_locales/ko/messages.json @@ -328,5 +328,17 @@ }, "rename_list": { "message": "리스트 이름 변경" + }, + "export_settings": { + "message": "내보내기" + }, + "import_settings": { + "message": "가져오기" + }, + "export_import_settings_label": { + "message": "내보내기 / 가져오기" + }, + "export_import_settings_hint": { + "message": "목록 및 사이트 예외를 백업하거나 복원합니다." } } \ No newline at end of file diff --git a/_locales/nl/messages.json b/_locales/nl/messages.json index e2aaa32..83df711 100644 --- a/_locales/nl/messages.json +++ b/_locales/nl/messages.json @@ -328,5 +328,17 @@ }, "rename_list": { "message": "Lijst hernoemen" + }, + "export_settings": { + "message": "Exporteren" + }, + "import_settings": { + "message": "Importeren" + }, + "export_import_settings_label": { + "message": "Exporteren / Importeren" + }, + "export_import_settings_hint": { + "message": "Back-up maken of lijsten en site-uitzonderingen herstellen." } } \ No newline at end of file diff --git a/_locales/pl/messages.json b/_locales/pl/messages.json index b4954da..d0d164c 100644 --- a/_locales/pl/messages.json +++ b/_locales/pl/messages.json @@ -328,5 +328,17 @@ }, "rename_list": { "message": "Zmień nazwę listy" + }, + "export_settings": { + "message": "Eksportuj" + }, + "import_settings": { + "message": "Importuj" + }, + "export_import_settings_label": { + "message": "Eksport / Import" + }, + "export_import_settings_hint": { + "message": "Utwórz kopię zapasową lub przywróć listy i wyjątki witryn." } } \ No newline at end of file diff --git a/_locales/pt_BR/messages.json b/_locales/pt_BR/messages.json index db45070..d37c977 100644 --- a/_locales/pt_BR/messages.json +++ b/_locales/pt_BR/messages.json @@ -328,5 +328,17 @@ }, "rename_list": { "message": "Renomear lista" + }, + "export_settings": { + "message": "Exportar" + }, + "import_settings": { + "message": "Importar" + }, + "export_import_settings_label": { + "message": "Exportar / Importar" + }, + "export_import_settings_hint": { + "message": "Fazer backup ou restaurar listas e exceções de sites." } } \ No newline at end of file diff --git a/_locales/ru/messages.json b/_locales/ru/messages.json index 5e3b2f7..9b5238d 100644 --- a/_locales/ru/messages.json +++ b/_locales/ru/messages.json @@ -329,5 +329,17 @@ }, "rename_list": { "message": "Переименовать список" + }, + "export_settings": { + "message": "Экспорт" + }, + "import_settings": { + "message": "Импорт" + }, + "export_import_settings_label": { + "message": "Экспорт / Импорт" + }, + "export_import_settings_hint": { + "message": "Резервное копирование или восстановление списков и исключений сайтов." } } \ No newline at end of file diff --git a/_locales/tr/messages.json b/_locales/tr/messages.json index 6ae5aef..762c7d7 100644 --- a/_locales/tr/messages.json +++ b/_locales/tr/messages.json @@ -328,5 +328,17 @@ }, "rename_list": { "message": "Listeyi Yeniden Adlandır" + }, + "export_settings": { + "message": "Dışa Aktar" + }, + "import_settings": { + "message": "İçe Aktar" + }, + "export_import_settings_label": { + "message": "Dışa Aktar / İçe Aktar" + }, + "export_import_settings_hint": { + "message": "Listeleri ve site istisnalarını yedekleyin veya geri yükleyin." } } \ No newline at end of file diff --git a/_locales/zh_CN/messages.json b/_locales/zh_CN/messages.json index 0f9e2b0..c9b623e 100644 --- a/_locales/zh_CN/messages.json +++ b/_locales/zh_CN/messages.json @@ -328,5 +328,17 @@ }, "rename_list": { "message": "重命名列表" + }, + "export_settings": { + "message": "导出" + }, + "import_settings": { + "message": "导入" + }, + "export_import_settings_label": { + "message": "导出 / 导入" + }, + "export_import_settings_hint": { + "message": "备份或恢复列表和站点例外。" } } \ No newline at end of file diff --git a/popup/popup.css b/popup/popup.css index ef586bd..bfa6075 100644 --- a/popup/popup.css +++ b/popup/popup.css @@ -1214,6 +1214,30 @@ body { opacity: 0.6; } +.settings-export-import-section { + padding: 8px 10px; + background: var(--input-bg); + border: 1px solid var(--input-border); + border-radius: 6px; + display: flex; + flex-direction: column; + gap: 8px; +} + +.settings-export-import-label { + font-size: var(--text-md); + font-weight: 500; + color: var(--text-color); + margin: 0; +} + +.settings-export-import-hint { + font-size: var(--text-sm); + color: var(--text-color); + opacity: 0.6; + margin: 0; +} + .options-buttons { display: flex; gap: 8px; diff --git a/popup/popup.html b/popup/popup.html index f45c3bc..40bb8a4 100644 --- a/popup/popup.html +++ b/popup/popup.html @@ -276,6 +276,22 @@ +
+

Export / Import

+

Back up or restore lists and site exceptions.

+
+ + + +
+
+ diff --git a/src/popup/PopupController.ts b/src/popup/PopupController.ts index 042fb29..3c4ef11 100644 --- a/src/popup/PopupController.ts +++ b/src/popup/PopupController.ts @@ -1,4 +1,4 @@ -import { HighlightList, HighlightWord, HighlightInfo } from '../types.js'; +import { HighlightList, HighlightWord, HighlightInfo, ExportData } from '../types.js'; import { StorageService } from '../services/StorageService.js'; import { MessageService } from '../services/MessageService.js'; import { DOMUtils } from '../utils/DOMUtils.js'; @@ -231,6 +231,7 @@ export class PopupController { this.setupTabs(); this.setupScrollListeners(); this.setupSettingsOverlay(); + this.setupSettingsExportImport(); this.setupListManagement(); this.setupWordManagement(); this.setupSettings(); @@ -261,6 +262,95 @@ export class PopupController { }); } + private setupSettingsExportImport(): void { + const importSettingsInput = document.getElementById('importSettingsInput') as HTMLInputElement; + + document.getElementById('exportSettingsBtn')?.addEventListener('click', () => { + const data: ExportData = { + lists: this.lists, + exceptionsList: [...this.exceptionsList] + }; + const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = 'goose-highlighter-settings.json'; + a.click(); + URL.revokeObjectURL(url); + }); + + document.getElementById('importSettingsBtn')?.addEventListener('click', () => { + importSettingsInput?.click(); + }); + + importSettingsInput?.addEventListener('change', (e) => { + const file = (e.target as HTMLInputElement).files?.[0]; + if (!file) return; + + const reader = new FileReader(); + reader.onload = async (event) => { + try { + const raw = event.target?.result as string; + const data = JSON.parse(raw) as unknown; + + if (!data || typeof data !== 'object') { + alert(chrome.i18n.getMessage('invalid_import_format') || 'Invalid file format. Please select a valid export file.'); + importSettingsInput.value = ''; + return; + } + + const obj = data as Record; + let listsApplied = false; + let exceptionsApplied = false; + + if (Array.isArray(obj.lists) && obj.lists.length > 0) { + const baseId = Date.now(); + const validLists = obj.lists + .filter((item: unknown) => this.isValidList(item)) + .map((item: HighlightList, i: number) => ({ ...item, id: baseId + i })); + if (validLists.length > 0) { + this.lists = validLists; + this.currentListIndex = Math.min(this.currentListIndex, this.lists.length - 1); + listsApplied = true; + } + } + + if (Array.isArray(obj.exceptionsList)) { + this.exceptionsList = obj.exceptionsList.filter((d): d is string => typeof d === 'string'); + exceptionsApplied = true; + } + + if (!listsApplied && !exceptionsApplied) { + alert(chrome.i18n.getMessage('invalid_import_format') || 'Invalid file format. Please select a valid export file.'); + importSettingsInput.value = ''; + return; + } + + if (listsApplied && this.lists.length === 0) { + this.lists.push({ + id: Date.now(), + name: chrome.i18n.getMessage('default_list_name') || 'Default List', + background: '#ffff00', + foreground: '#000000', + active: true, + words: [] + }); + } + + await this.save(); + MessageService.sendToAllTabs({ type: 'WORD_LIST_UPDATED' }); + MessageService.sendToAllTabs({ type: 'EXCEPTIONS_LIST_UPDATED' }); + this.render(); + importSettingsInput.value = ''; + } catch (err) { + alert((chrome.i18n.getMessage('invalid_json_error') || 'Invalid JSON file') + ': ' + (err as Error).message); + importSettingsInput.value = ''; + } + }; + reader.readAsText(file); + }); + } + private setupTabs(): void { document.querySelectorAll('.tab-button').forEach(button => { button.addEventListener('click', () => {