mirror of
https://github.com/obsqrbtz/goose-highlighter.git
synced 2026-04-08 20:19:06 +03:00
feat: new tabbed layout
This commit is contained in:
2
.vscode/settings.json
vendored
Normal file
2
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
{
|
||||
}
|
||||
@@ -105,7 +105,7 @@
|
||||
"message": "Zu Ausnahmen hinzufügen"
|
||||
},
|
||||
"remove_exception": {
|
||||
"message": "Aus Ausnahmen entfernen"
|
||||
"message": "Aktuelle entfernen"
|
||||
},
|
||||
"manage_exceptions": {
|
||||
"message": "Verwalten"
|
||||
@@ -121,5 +121,35 @@
|
||||
},
|
||||
"remove": {
|
||||
"message": "Entfernen"
|
||||
},
|
||||
"tab_lists": {
|
||||
"message": "Listen"
|
||||
},
|
||||
"tab_words": {
|
||||
"message": "Wörter"
|
||||
},
|
||||
"tab_exceptions": {
|
||||
"message": "Ausnahmen"
|
||||
},
|
||||
"no_exceptions": {
|
||||
"message": "Keine Ausnahmen"
|
||||
},
|
||||
"toggle_highlighting_title": {
|
||||
"message": "Hervorhebung umschalten"
|
||||
},
|
||||
"toggle_dark_mode_title": {
|
||||
"message": "Dunkelmodus umschalten"
|
||||
},
|
||||
"select_title": {
|
||||
"message": "Auswählen"
|
||||
},
|
||||
"word_placeholder": {
|
||||
"message": "Wort oder Phrase"
|
||||
},
|
||||
"background_color_title": {
|
||||
"message": "Hintergrundfarbe"
|
||||
},
|
||||
"text_color_title": {
|
||||
"message": "Textfarbe"
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@
|
||||
"message": "Add to Exceptions"
|
||||
},
|
||||
"remove_exception": {
|
||||
"message": "Remove from Exceptions"
|
||||
"message": "Remove current"
|
||||
},
|
||||
"manage_exceptions": {
|
||||
"message": "Manage"
|
||||
@@ -127,5 +127,35 @@
|
||||
},
|
||||
"remove": {
|
||||
"message": "Remove"
|
||||
},
|
||||
"tab_lists": {
|
||||
"message": "Lists"
|
||||
},
|
||||
"tab_words": {
|
||||
"message": "Words"
|
||||
},
|
||||
"tab_exceptions": {
|
||||
"message": "Exceptions"
|
||||
},
|
||||
"no_exceptions": {
|
||||
"message": "No exceptions"
|
||||
},
|
||||
"toggle_highlighting_title": {
|
||||
"message": "Toggle highlighting"
|
||||
},
|
||||
"toggle_dark_mode_title": {
|
||||
"message": "Toggle dark mode"
|
||||
},
|
||||
"select_title": {
|
||||
"message": "Select"
|
||||
},
|
||||
"word_placeholder": {
|
||||
"message": "Word or phrase"
|
||||
},
|
||||
"background_color_title": {
|
||||
"message": "Background color"
|
||||
},
|
||||
"text_color_title": {
|
||||
"message": "Text color"
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@
|
||||
"message": "Agregar a excepciones"
|
||||
},
|
||||
"remove_exception": {
|
||||
"message": "Quitar de excepciones"
|
||||
"message": "Eliminar actual"
|
||||
},
|
||||
"manage_exceptions": {
|
||||
"message": "Gestionar"
|
||||
@@ -127,5 +127,35 @@
|
||||
},
|
||||
"remove": {
|
||||
"message": "Eliminar"
|
||||
},
|
||||
"tab_lists": {
|
||||
"message": "Listas"
|
||||
},
|
||||
"tab_words": {
|
||||
"message": "Palabras"
|
||||
},
|
||||
"tab_exceptions": {
|
||||
"message": "Excepciones"
|
||||
},
|
||||
"no_exceptions": {
|
||||
"message": "Sin excepciones"
|
||||
},
|
||||
"toggle_highlighting_title": {
|
||||
"message": "Alternar resaltado"
|
||||
},
|
||||
"toggle_dark_mode_title": {
|
||||
"message": "Alternar modo oscuro"
|
||||
},
|
||||
"select_title": {
|
||||
"message": "Seleccionar"
|
||||
},
|
||||
"word_placeholder": {
|
||||
"message": "Palabra o frase"
|
||||
},
|
||||
"background_color_title": {
|
||||
"message": "Color de fondo"
|
||||
},
|
||||
"text_color_title": {
|
||||
"message": "Color de texto"
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@
|
||||
"message": "Ajouter aux exceptions"
|
||||
},
|
||||
"remove_exception": {
|
||||
"message": "Retirer des exceptions"
|
||||
"message": "Supprimer l'actuel"
|
||||
},
|
||||
"manage_exceptions": {
|
||||
"message": "Gérer"
|
||||
@@ -127,5 +127,35 @@
|
||||
},
|
||||
"remove": {
|
||||
"message": "Supprimer"
|
||||
},
|
||||
"tab_lists": {
|
||||
"message": "Listes"
|
||||
},
|
||||
"tab_words": {
|
||||
"message": "Mots"
|
||||
},
|
||||
"tab_exceptions": {
|
||||
"message": "Exceptions"
|
||||
},
|
||||
"no_exceptions": {
|
||||
"message": "Aucune exception"
|
||||
},
|
||||
"toggle_highlighting_title": {
|
||||
"message": "Activer/désactiver la surbrillance"
|
||||
},
|
||||
"toggle_dark_mode_title": {
|
||||
"message": "Activer/désactiver le mode sombre"
|
||||
},
|
||||
"select_title": {
|
||||
"message": "Sélectionner"
|
||||
},
|
||||
"word_placeholder": {
|
||||
"message": "Mot ou phrase"
|
||||
},
|
||||
"background_color_title": {
|
||||
"message": "Couleur d'arrière-plan"
|
||||
},
|
||||
"text_color_title": {
|
||||
"message": "Couleur du texte"
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@
|
||||
"message": "अपवादों में जोड़ें"
|
||||
},
|
||||
"remove_exception": {
|
||||
"message": "अपवादों से हटाएं"
|
||||
"message": "वर्तमान हटाएं"
|
||||
},
|
||||
"manage_exceptions": {
|
||||
"message": "प्रबंधित करें"
|
||||
@@ -127,5 +127,35 @@
|
||||
},
|
||||
"remove": {
|
||||
"message": "हटाएं"
|
||||
},
|
||||
"tab_lists": {
|
||||
"message": "सूचियाँ"
|
||||
},
|
||||
"tab_words": {
|
||||
"message": "शब्द"
|
||||
},
|
||||
"tab_exceptions": {
|
||||
"message": "अपवाद"
|
||||
},
|
||||
"no_exceptions": {
|
||||
"message": "कोई अपवाद नहीं"
|
||||
},
|
||||
"toggle_highlighting_title": {
|
||||
"message": "हाइलाइटिंग टॉगल करें"
|
||||
},
|
||||
"toggle_dark_mode_title": {
|
||||
"message": "डार्क मोड टॉगल करें"
|
||||
},
|
||||
"select_title": {
|
||||
"message": "चुनें"
|
||||
},
|
||||
"word_placeholder": {
|
||||
"message": "शब्द या वाक्यांश"
|
||||
},
|
||||
"background_color_title": {
|
||||
"message": "पृष्ठभूमि रंग"
|
||||
},
|
||||
"text_color_title": {
|
||||
"message": "पाठ रंग"
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@
|
||||
"message": "Aggiungi alle eccezioni"
|
||||
},
|
||||
"remove_exception": {
|
||||
"message": "Rimuovi dalle eccezioni"
|
||||
"message": "Rimuovi corrente"
|
||||
},
|
||||
"manage_exceptions": {
|
||||
"message": "Gestisci"
|
||||
@@ -127,5 +127,35 @@
|
||||
},
|
||||
"remove": {
|
||||
"message": "Rimuovi"
|
||||
},
|
||||
"tab_lists": {
|
||||
"message": "Elenchi"
|
||||
},
|
||||
"tab_words": {
|
||||
"message": "Parole"
|
||||
},
|
||||
"tab_exceptions": {
|
||||
"message": "Eccezioni"
|
||||
},
|
||||
"no_exceptions": {
|
||||
"message": "Nessuna eccezione"
|
||||
},
|
||||
"toggle_highlighting_title": {
|
||||
"message": "Attiva/disattiva evidenziazione"
|
||||
},
|
||||
"toggle_dark_mode_title": {
|
||||
"message": "Attiva/disattiva modalità scura"
|
||||
},
|
||||
"select_title": {
|
||||
"message": "Seleziona"
|
||||
},
|
||||
"word_placeholder": {
|
||||
"message": "Parola o frase"
|
||||
},
|
||||
"background_color_title": {
|
||||
"message": "Colore di sfondo"
|
||||
},
|
||||
"text_color_title": {
|
||||
"message": "Colore del testo"
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@
|
||||
"message": "例外に追加"
|
||||
},
|
||||
"remove_exception": {
|
||||
"message": "例外から削除"
|
||||
"message": "現在を削除"
|
||||
},
|
||||
"manage_exceptions": {
|
||||
"message": "管理"
|
||||
@@ -127,5 +127,35 @@
|
||||
},
|
||||
"remove": {
|
||||
"message": "削除"
|
||||
},
|
||||
"tab_lists": {
|
||||
"message": "リスト"
|
||||
},
|
||||
"tab_words": {
|
||||
"message": "単語"
|
||||
},
|
||||
"tab_exceptions": {
|
||||
"message": "例外"
|
||||
},
|
||||
"no_exceptions": {
|
||||
"message": "例外なし"
|
||||
},
|
||||
"toggle_highlighting_title": {
|
||||
"message": "ハイライトの切り替え"
|
||||
},
|
||||
"toggle_dark_mode_title": {
|
||||
"message": "ダークモードの切り替え"
|
||||
},
|
||||
"select_title": {
|
||||
"message": "選択"
|
||||
},
|
||||
"word_placeholder": {
|
||||
"message": "単語またはフレーズ"
|
||||
},
|
||||
"background_color_title": {
|
||||
"message": "背景色"
|
||||
},
|
||||
"text_color_title": {
|
||||
"message": "文字色"
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@
|
||||
"message": "예외에 추가"
|
||||
},
|
||||
"remove_exception": {
|
||||
"message": "예외에서 제거"
|
||||
"message": "현재 제거"
|
||||
},
|
||||
"manage_exceptions": {
|
||||
"message": "관리"
|
||||
@@ -127,5 +127,35 @@
|
||||
},
|
||||
"remove": {
|
||||
"message": "제거"
|
||||
},
|
||||
"tab_lists": {
|
||||
"message": "리스트"
|
||||
},
|
||||
"tab_words": {
|
||||
"message": "단어"
|
||||
},
|
||||
"tab_exceptions": {
|
||||
"message": "예외"
|
||||
},
|
||||
"no_exceptions": {
|
||||
"message": "예외 없음"
|
||||
},
|
||||
"toggle_highlighting_title": {
|
||||
"message": "하이라이트 전환"
|
||||
},
|
||||
"toggle_dark_mode_title": {
|
||||
"message": "다크 모드 전환"
|
||||
},
|
||||
"select_title": {
|
||||
"message": "선택"
|
||||
},
|
||||
"word_placeholder": {
|
||||
"message": "단어 또는 구문"
|
||||
},
|
||||
"background_color_title": {
|
||||
"message": "배경색"
|
||||
},
|
||||
"text_color_title": {
|
||||
"message": "글자색"
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@
|
||||
"message": "Toevoegen aan uitzonderingen"
|
||||
},
|
||||
"remove_exception": {
|
||||
"message": "Verwijderen uit uitzonderingen"
|
||||
"message": "Huidige verwijderen"
|
||||
},
|
||||
"manage_exceptions": {
|
||||
"message": "Beheren"
|
||||
@@ -127,5 +127,35 @@
|
||||
},
|
||||
"remove": {
|
||||
"message": "Verwijderen"
|
||||
},
|
||||
"tab_lists": {
|
||||
"message": "Lijsten"
|
||||
},
|
||||
"tab_words": {
|
||||
"message": "Woorden"
|
||||
},
|
||||
"tab_exceptions": {
|
||||
"message": "Uitzonderingen"
|
||||
},
|
||||
"no_exceptions": {
|
||||
"message": "Geen uitzonderingen"
|
||||
},
|
||||
"toggle_highlighting_title": {
|
||||
"message": "Markeren in-/uitschakelen"
|
||||
},
|
||||
"toggle_dark_mode_title": {
|
||||
"message": "Donkere modus in-/uitschakelen"
|
||||
},
|
||||
"select_title": {
|
||||
"message": "Selecteren"
|
||||
},
|
||||
"word_placeholder": {
|
||||
"message": "Woord of zin"
|
||||
},
|
||||
"background_color_title": {
|
||||
"message": "Achtergrondkleur"
|
||||
},
|
||||
"text_color_title": {
|
||||
"message": "Tekstkleur"
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@
|
||||
"message": "Dodaj do wyjątków"
|
||||
},
|
||||
"remove_exception": {
|
||||
"message": "Usuń z wyjątków"
|
||||
"message": "Usuń bieżący"
|
||||
},
|
||||
"manage_exceptions": {
|
||||
"message": "Zarządzaj"
|
||||
@@ -127,5 +127,35 @@
|
||||
},
|
||||
"remove": {
|
||||
"message": "Usuń"
|
||||
},
|
||||
"tab_lists": {
|
||||
"message": "Listy"
|
||||
},
|
||||
"tab_words": {
|
||||
"message": "Słowa"
|
||||
},
|
||||
"tab_exceptions": {
|
||||
"message": "Wyjątki"
|
||||
},
|
||||
"no_exceptions": {
|
||||
"message": "Brak wyjątków"
|
||||
},
|
||||
"toggle_highlighting_title": {
|
||||
"message": "Przełącz podświetlanie"
|
||||
},
|
||||
"toggle_dark_mode_title": {
|
||||
"message": "Przełącz tryb ciemny"
|
||||
},
|
||||
"select_title": {
|
||||
"message": "Zaznacz"
|
||||
},
|
||||
"word_placeholder": {
|
||||
"message": "Słowo lub fraza"
|
||||
},
|
||||
"background_color_title": {
|
||||
"message": "Kolor tła"
|
||||
},
|
||||
"text_color_title": {
|
||||
"message": "Kolor tekstu"
|
||||
}
|
||||
}
|
||||
@@ -105,7 +105,7 @@
|
||||
"message": "Adicionar às exceções"
|
||||
},
|
||||
"remove_exception": {
|
||||
"message": "Remover das exceções"
|
||||
"message": "Remover atual"
|
||||
},
|
||||
"manage_exceptions": {
|
||||
"message": "Gerenciar"
|
||||
@@ -121,5 +121,35 @@
|
||||
},
|
||||
"remove": {
|
||||
"message": "Remover"
|
||||
},
|
||||
"tab_lists": {
|
||||
"message": "Listas"
|
||||
},
|
||||
"tab_words": {
|
||||
"message": "Palavras"
|
||||
},
|
||||
"tab_exceptions": {
|
||||
"message": "Exceções"
|
||||
},
|
||||
"no_exceptions": {
|
||||
"message": "Sem exceções"
|
||||
},
|
||||
"toggle_highlighting_title": {
|
||||
"message": "Alternar destaque"
|
||||
},
|
||||
"toggle_dark_mode_title": {
|
||||
"message": "Alternar modo escuro"
|
||||
},
|
||||
"select_title": {
|
||||
"message": "Selecionar"
|
||||
},
|
||||
"word_placeholder": {
|
||||
"message": "Palavra ou frase"
|
||||
},
|
||||
"background_color_title": {
|
||||
"message": "Cor de fundo"
|
||||
},
|
||||
"text_color_title": {
|
||||
"message": "Cor do texto"
|
||||
}
|
||||
}
|
||||
@@ -127,5 +127,35 @@
|
||||
},
|
||||
"remove": {
|
||||
"message": "Удалить"
|
||||
},
|
||||
"tab_lists": {
|
||||
"message": "Списки"
|
||||
},
|
||||
"tab_words": {
|
||||
"message": "Слова"
|
||||
},
|
||||
"tab_exceptions": {
|
||||
"message": "Исключения"
|
||||
},
|
||||
"no_exceptions": {
|
||||
"message": "Нет исключений"
|
||||
},
|
||||
"toggle_highlighting_title": {
|
||||
"message": "Выделение(вкл/выкл)"
|
||||
},
|
||||
"toggle_dark_mode_title": {
|
||||
"message": "Темная/светлая тема"
|
||||
},
|
||||
"select_title": {
|
||||
"message": "Выбрать"
|
||||
},
|
||||
"word_placeholder": {
|
||||
"message": "Слово или фраза"
|
||||
},
|
||||
"background_color_title": {
|
||||
"message": "Цвет фона"
|
||||
},
|
||||
"text_color_title": {
|
||||
"message": "Цвет текста"
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@
|
||||
"message": "İstisnalara Ekle"
|
||||
},
|
||||
"remove_exception": {
|
||||
"message": "İstisnalardan Çıkar"
|
||||
"message": "Mevcut olanı kaldır"
|
||||
},
|
||||
"manage_exceptions": {
|
||||
"message": "Yönet"
|
||||
@@ -127,5 +127,35 @@
|
||||
},
|
||||
"remove": {
|
||||
"message": "Kaldır"
|
||||
},
|
||||
"tab_lists": {
|
||||
"message": "Listeler"
|
||||
},
|
||||
"tab_words": {
|
||||
"message": "Kelimeler"
|
||||
},
|
||||
"tab_exceptions": {
|
||||
"message": "İstisnalar"
|
||||
},
|
||||
"no_exceptions": {
|
||||
"message": "İstisna yok"
|
||||
},
|
||||
"toggle_highlighting_title": {
|
||||
"message": "Vurgulamayı aç/kapat"
|
||||
},
|
||||
"toggle_dark_mode_title": {
|
||||
"message": "Karanlık modu aç/kapat"
|
||||
},
|
||||
"select_title": {
|
||||
"message": "Seç"
|
||||
},
|
||||
"word_placeholder": {
|
||||
"message": "Kelime veya ifade"
|
||||
},
|
||||
"background_color_title": {
|
||||
"message": "Arka plan rengi"
|
||||
},
|
||||
"text_color_title": {
|
||||
"message": "Metin rengi"
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@
|
||||
"message": "添加到例外"
|
||||
},
|
||||
"remove_exception": {
|
||||
"message": "从例外中移除"
|
||||
"message": "移除当前"
|
||||
},
|
||||
"manage_exceptions": {
|
||||
"message": "管理"
|
||||
@@ -127,5 +127,35 @@
|
||||
},
|
||||
"remove": {
|
||||
"message": "移除"
|
||||
},
|
||||
"tab_lists": {
|
||||
"message": "列表"
|
||||
},
|
||||
"tab_words": {
|
||||
"message": "单词"
|
||||
},
|
||||
"tab_exceptions": {
|
||||
"message": "例外"
|
||||
},
|
||||
"no_exceptions": {
|
||||
"message": "无例外"
|
||||
},
|
||||
"toggle_highlighting_title": {
|
||||
"message": "切换高亮"
|
||||
},
|
||||
"toggle_dark_mode_title": {
|
||||
"message": "切换暗黑模式"
|
||||
},
|
||||
"select_title": {
|
||||
"message": "选择"
|
||||
},
|
||||
"word_placeholder": {
|
||||
"message": "单词或短语"
|
||||
},
|
||||
"background_color_title": {
|
||||
"message": "背景颜色"
|
||||
},
|
||||
"text_color_title": {
|
||||
"message": "文字颜色"
|
||||
}
|
||||
}
|
||||
897
popup/popup.css
897
popup/popup.css
File diff suppressed because it is too large
Load Diff
@@ -18,45 +18,26 @@
|
||||
<i class="fa-solid fa-highlighter"></i> Goose Highlighter
|
||||
</span>
|
||||
<div class="icon-toggles">
|
||||
<label class="icon-toggle" title="Toggle highlighting">
|
||||
<label class="icon-toggle" data-i18n-title="toggle_highlighting_title" title="Toggle highlighting">
|
||||
<input type="checkbox" class="hidden-toggle" id="globalHighlightToggle" />
|
||||
<i class="toggle-icon global-icon fa-solid"></i>
|
||||
</label>
|
||||
<label class="icon-toggle" title="Toggle dark mode">
|
||||
<label class="icon-toggle" data-i18n-title="toggle_dark_mode_title" title="Toggle dark mode">
|
||||
<input type="checkbox" class="hidden-toggle" id="themeToggle" />
|
||||
<i class="toggle-icon theme-icon fa-solid"></i>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" data-section="exceptions">
|
||||
<div class="section-header">
|
||||
<h2><i class="fa-solid fa-ban"></i> <span data-i18n="site_exceptions">Site Exceptions</span></h2>
|
||||
<button class="collapse-toggle" data-target="exceptions">
|
||||
<i class="fa-solid fa-chevron-up"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="section-content" id="exceptions-content">
|
||||
<div class="button-row">
|
||||
<button id="toggleExceptionBtn"><i class="fa-solid fa-ban"></i> <span id="exceptionBtnText" data-i18n="add_exception">Add to Exceptions</span></button>
|
||||
<button id="manageExceptionsBtn"><i class="fa-solid fa-list"></i> <span data-i18n="manage_exceptions">Manage</span></button>
|
||||
</div>
|
||||
<div id="exceptionsPanel" class="exceptions-panel" style="display: none;">
|
||||
<h3 data-i18n="exceptions_list">Exception Sites:</h3>
|
||||
<div id="exceptionsList" class="exceptions-list"></div>
|
||||
<button id="clearExceptionsBtn" class="danger"><i class="fa-solid fa-trash"></i> <span data-i18n="clear_all">Clear All</span></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tabs">
|
||||
<button class="tab-button active" data-tab="lists"><i class="fa-solid fa-list"></i> <span data-i18n="tab_lists">Lists</span></button>
|
||||
<button class="tab-button" data-tab="words"><i class="fa-solid fa-tags"></i> <span data-i18n="tab_words">Words</span></button>
|
||||
<button class="tab-button" data-tab="exceptions"><i class="fa-solid fa-ban"></i> <span data-i18n="tab_exceptions">Exceptions</span></button>
|
||||
<button class="tab-button" data-tab="options"><i class="fa-solid fa-sliders"></i> <span data-i18n="options">Options</span></button>
|
||||
</div>
|
||||
|
||||
<div class="tab-content active" data-tab-content="lists">
|
||||
<div class="section" data-section="lists">
|
||||
<div class="section-header">
|
||||
<h2><i class="fa-solid fa-list"></i> <span data-i18n="highlight_lists">Highlight Lists</span></h2>
|
||||
<button class="collapse-toggle" data-target="lists">
|
||||
<i class="fa-solid fa-chevron-up"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="section-content" id="lists-content">
|
||||
<label for="listSelect" data-i18n="select_list">Select List:</label>
|
||||
<select id="listSelect"></select>
|
||||
<div class="button-row">
|
||||
@@ -65,16 +46,9 @@
|
||||
data-i18n="delete_list">Delete</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" data-section="settings">
|
||||
<div class="section-header">
|
||||
<h2><i class="fa-solid fa-gear"></i> <span data-i18n="list_settings">List Settings</span></h2>
|
||||
<button class="collapse-toggle" data-target="settings">
|
||||
<i class="fa-solid fa-chevron-up"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="section-content" id="settings-content">
|
||||
<h3><i class="fa-solid fa-gear"></i> <span data-i18n="list_settings">List Settings</span></h3>
|
||||
<label><span data-i18n="list_name">List Name:</span> <input type="text" id="listName" /></label>
|
||||
<div class="color-row">
|
||||
<div class="color-label">
|
||||
@@ -94,28 +68,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-content" data-tab-content="words">
|
||||
<div class="section" data-section="addwords">
|
||||
<div class="section-header">
|
||||
<h2><i class="fa-solid fa-pen"></i> <span data-i18n="add_words">Add Words</span></h2>
|
||||
<button class="collapse-toggle" data-target="addwords">
|
||||
<i class="fa-solid fa-chevron-up"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="section-content" id="addwords-content">
|
||||
<h3><i class="fa-solid fa-pen"></i> <span data-i18n="add_words">Add Words</span></h3>
|
||||
<textarea id="bulkPaste" data-i18n="paste_hint" placeholder="Paste words here..."></textarea>
|
||||
<button id="addWordsBtn"><span data-i18n="apply_paste">Add Words</span></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" data-section="wordlist">
|
||||
<div class="section-header">
|
||||
<h2><i class="fa-solid fa-tags"></i> <span data-i18n="word_list">Word List</span>(<span id="wordCount">0</span>)
|
||||
</h2>
|
||||
<button class="collapse-toggle" data-target="wordlist">
|
||||
<i class="fa-solid fa-chevron-up"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="section-content" id="wordlist-content">
|
||||
<h3><i class="fa-solid fa-tags"></i> <span data-i18n="word_list">Word List</span> (<span id="wordCount">0</span>)</h3>
|
||||
<div class="button-row wrap">
|
||||
<button id="selectAllBtn"><span data-i18n="select_all">Select All</span></button>
|
||||
<button id="deselectAllBtn"><span data-i18n="deselect_all">Clear</span></button>
|
||||
@@ -128,14 +89,21 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" data-section="options">
|
||||
<div class="section-header">
|
||||
<h2><i class="fa-solid fa-sliders"></i> <span data-i18n="options">Options</span></h2>
|
||||
<button class="collapse-toggle" data-target="options">
|
||||
<i class="fa-solid fa-chevron-up"></i>
|
||||
</button>
|
||||
<div class="tab-content" data-tab-content="exceptions">
|
||||
<div class="section" data-section="exceptions">
|
||||
<h3><i class="fa-solid fa-ban"></i> <span data-i18n="site_exceptions">Site Exceptions</span></h3>
|
||||
<div class="button-row">
|
||||
<button id="toggleExceptionBtn"><i class="fa-solid fa-plus"></i> <span id="exceptionBtnText" data-i18n="add_exception">Add to Exceptions</span></button>
|
||||
</div>
|
||||
<div class="section-content" id="options-content">
|
||||
<h3 data-i18n="exceptions_list">Exception Sites:</h3>
|
||||
<div id="exceptionsList" class="exceptions-list"></div>
|
||||
<button id="clearExceptionsBtn" class="danger"><i class="fa-solid fa-trash"></i> <span data-i18n="clear_all">Clear All</span></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-content" data-tab-content="options">
|
||||
<div class="section" data-section="options">
|
||||
<h3><i class="fa-solid fa-sliders"></i> <span data-i18n="options">Options</span></h3>
|
||||
<div class="button-row" style="margin-bottom:8px;">
|
||||
<label><input type="checkbox" id="matchCase" /> <span data-i18n="match_case">Match Case</span></label>
|
||||
<label><input type="checkbox" id="matchWhole" /> <span data-i18n="match_whole">Match Whole Word</span></label>
|
||||
|
||||
@@ -13,13 +13,13 @@ export class PopupController {
|
||||
private matchWholeEnabled = false;
|
||||
private exceptionsList: string[] = [];
|
||||
private currentTabHost = '';
|
||||
private sectionStates: Record<string, boolean> = {};
|
||||
private activeTab = 'lists';
|
||||
|
||||
async initialize(): Promise<void> {
|
||||
await this.loadData();
|
||||
await this.getCurrentTab();
|
||||
this.loadSectionStates();
|
||||
this.initializeSectionStates();
|
||||
this.loadActiveTab();
|
||||
this.translateTitles();
|
||||
this.setupEventListeners();
|
||||
this.render();
|
||||
}
|
||||
@@ -56,32 +56,44 @@ export class PopupController {
|
||||
}
|
||||
}
|
||||
|
||||
private loadSectionStates(): void {
|
||||
const saved = localStorage.getItem('goose-highlighter-section-states');
|
||||
private loadActiveTab(): void {
|
||||
const saved = localStorage.getItem('goose-highlighter-active-tab');
|
||||
if (saved) {
|
||||
try {
|
||||
this.sectionStates = JSON.parse(saved);
|
||||
} catch {
|
||||
this.sectionStates = {};
|
||||
}
|
||||
this.activeTab = saved;
|
||||
}
|
||||
}
|
||||
|
||||
private saveSectionStates(): void {
|
||||
localStorage.setItem('goose-highlighter-section-states', JSON.stringify(this.sectionStates));
|
||||
private translateTitles(): void {
|
||||
document.querySelectorAll('[data-i18n-title]').forEach(element => {
|
||||
const key = element.getAttribute('data-i18n-title');
|
||||
if (key) {
|
||||
const translation = chrome.i18n.getMessage(key);
|
||||
if (translation) {
|
||||
element.setAttribute('title', translation);
|
||||
}
|
||||
|
||||
private initializeSectionStates(): void {
|
||||
Object.keys(this.sectionStates).forEach(sectionName => {
|
||||
const section = document.querySelector(`[data-section="${sectionName}"]`);
|
||||
if (section && this.sectionStates[sectionName]) {
|
||||
section.classList.add('collapsed');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private saveActiveTab(): void {
|
||||
localStorage.setItem('goose-highlighter-active-tab', this.activeTab);
|
||||
}
|
||||
|
||||
private switchTab(tabName: string): void {
|
||||
this.activeTab = tabName;
|
||||
this.saveActiveTab();
|
||||
|
||||
document.querySelectorAll('.tab-button').forEach(btn => {
|
||||
btn.classList.toggle('active', btn.getAttribute('data-tab') === tabName);
|
||||
});
|
||||
|
||||
document.querySelectorAll('.tab-content').forEach(content => {
|
||||
content.classList.toggle('active', content.getAttribute('data-tab-content') === tabName);
|
||||
});
|
||||
}
|
||||
|
||||
private setupEventListeners(): void {
|
||||
this.setupSectionToggles();
|
||||
this.setupTabs();
|
||||
this.setupListManagement();
|
||||
this.setupWordManagement();
|
||||
this.setupSettings();
|
||||
@@ -90,44 +102,15 @@ export class PopupController {
|
||||
this.setupTheme();
|
||||
}
|
||||
|
||||
private setupSectionToggles(): void {
|
||||
document.querySelectorAll('.collapse-toggle').forEach(button => {
|
||||
button.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
const targetSection = (button as HTMLElement).getAttribute('data-target');
|
||||
if (targetSection) this.toggleSection(targetSection);
|
||||
private setupTabs(): void {
|
||||
document.querySelectorAll('.tab-button').forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
const tabName = (button as HTMLElement).getAttribute('data-tab');
|
||||
if (tabName) this.switchTab(tabName);
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.section-header').forEach(header => {
|
||||
header.addEventListener('click', (e) => {
|
||||
if ((e.target as HTMLElement).tagName === 'BUTTON' ||
|
||||
(e.target as HTMLElement).tagName === 'INPUT' ||
|
||||
(e.target as HTMLElement).closest('button')) {
|
||||
return;
|
||||
}
|
||||
const section = (header as HTMLElement).closest('.section');
|
||||
const sectionName = section?.getAttribute('data-section');
|
||||
if (sectionName) this.toggleSection(sectionName);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private toggleSection(sectionName: string): void {
|
||||
const section = document.querySelector(`[data-section="${sectionName}"]`);
|
||||
if (!section) return;
|
||||
|
||||
const isCollapsed = section.classList.contains('collapsed');
|
||||
|
||||
if (isCollapsed) {
|
||||
section.classList.remove('collapsed');
|
||||
this.sectionStates[sectionName] = false;
|
||||
} else {
|
||||
section.classList.add('collapsed');
|
||||
this.sectionStates[sectionName] = true;
|
||||
}
|
||||
|
||||
this.saveSectionStates();
|
||||
this.switchTab(this.activeTab);
|
||||
}
|
||||
|
||||
private setupListManagement(): void {
|
||||
@@ -199,8 +182,7 @@ export class PopupController {
|
||||
private setupWordListEvents(wordList: HTMLDivElement): void {
|
||||
wordList.addEventListener('change', (e) => {
|
||||
const target = e.target as HTMLInputElement;
|
||||
if (target.type === 'checkbox') {
|
||||
if (target.dataset.index != null) {
|
||||
if (target.type === 'checkbox' && target.dataset.index != null) {
|
||||
const index = +target.dataset.index;
|
||||
if (target.checked) {
|
||||
this.selectedCheckboxes.add(index);
|
||||
@@ -208,11 +190,6 @@ export class PopupController {
|
||||
this.selectedCheckboxes.delete(index);
|
||||
}
|
||||
this.renderWords();
|
||||
} else if (target.dataset.activeEdit != null) {
|
||||
const index = +target.dataset.activeEdit;
|
||||
this.lists[this.currentListIndex].words[index].active = target.checked;
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -334,14 +311,6 @@ export class PopupController {
|
||||
this.save();
|
||||
});
|
||||
|
||||
document.getElementById('manageExceptionsBtn')?.addEventListener('click', () => {
|
||||
const panel = document.getElementById('exceptionsPanel');
|
||||
if (panel) {
|
||||
const isVisible = panel.style.display !== 'none';
|
||||
panel.style.display = isVisible ? 'none' : 'block';
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('clearExceptionsBtn')?.addEventListener('click', () => {
|
||||
if (confirm(chrome.i18n.getMessage('confirm_clear_exceptions') || 'Clear all exceptions?')) {
|
||||
this.exceptionsList = [];
|
||||
@@ -527,11 +496,13 @@ export class PopupController {
|
||||
}
|
||||
|
||||
const itemHeight = 32;
|
||||
const containerHeight = wordList.clientHeight;
|
||||
const itemSpacing = 2;
|
||||
const totalItemHeight = itemHeight + itemSpacing;
|
||||
const containerHeight = wordList.clientHeight || 250;
|
||||
const scrollTop = wordList.scrollTop;
|
||||
const startIndex = Math.floor(scrollTop / itemHeight);
|
||||
const startIndex = Math.floor(scrollTop / totalItemHeight);
|
||||
const endIndex = Math.min(
|
||||
startIndex + Math.ceil(containerHeight / itemHeight) + 2,
|
||||
startIndex + Math.ceil(containerHeight / totalItemHeight) + 2,
|
||||
filteredWords.length
|
||||
);
|
||||
|
||||
@@ -539,7 +510,7 @@ export class PopupController {
|
||||
|
||||
const spacer = document.createElement('div');
|
||||
spacer.style.position = 'relative';
|
||||
spacer.style.height = `${filteredWords.length * itemHeight}px`;
|
||||
spacer.style.height = `${filteredWords.length * totalItemHeight}px`;
|
||||
spacer.style.width = '100%';
|
||||
|
||||
for (let i = startIndex; i < endIndex; i++) {
|
||||
@@ -561,32 +532,22 @@ export class PopupController {
|
||||
|
||||
private createWordItem(word: HighlightWord, realIndex: number, displayIndex: number, itemHeight: number): HTMLDivElement {
|
||||
const container = document.createElement('div');
|
||||
container.className = 'word-item';
|
||||
if (word.active === false) {
|
||||
container.classList.add('disabled');
|
||||
}
|
||||
container.style.cssText = `
|
||||
height: ${itemHeight}px;
|
||||
position: absolute;
|
||||
top: ${displayIndex * itemHeight}px;
|
||||
width: calc(100% - 8px);
|
||||
left: 4px;
|
||||
right: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 0 4px;
|
||||
box-sizing: border-box;
|
||||
background: var(--highlight-tag);
|
||||
border: 1px solid var(--highlight-tag-border);
|
||||
top: ${displayIndex * (itemHeight + 2)}px;
|
||||
`;
|
||||
|
||||
const list = this.lists[this.currentListIndex];
|
||||
|
||||
container.innerHTML = `
|
||||
<input type="checkbox" class="word-checkbox" data-index="${realIndex}" ${this.selectedCheckboxes.has(realIndex) ? 'checked' : ''}>
|
||||
<input type="text" value="${DOMUtils.escapeHtml(word.wordStr)}" data-word-edit="${realIndex}" style="flex-grow: 1; min-width: 0; padding: 4px 8px; border-radius: 4px; border: 1px solid var(--input-border); background-color: var(--input-bg); color: var(--text-color);">
|
||||
<input type="color" value="${word.background || list.background}" data-bg-edit="${realIndex}" style="width: 24px; height: 24px; flex-shrink: 0;">
|
||||
<input type="color" value="${word.foreground || list.foreground}" data-fg-edit="${realIndex}" style="width: 24px; height: 24px; flex-shrink: 0;">
|
||||
<label class="word-active" style="display: flex; align-items: center; gap: 4px; flex-shrink: 0;">
|
||||
<input type="checkbox" ${word.active !== false ? 'checked' : ''} data-active-edit="${realIndex}" class="switch">
|
||||
</label>
|
||||
<input type="checkbox" class="word-checkbox" data-index="${realIndex}" ${this.selectedCheckboxes.has(realIndex) ? 'checked' : ''} title="${chrome.i18n.getMessage('select_title') || 'Select'}">
|
||||
<input type="text" value="${DOMUtils.escapeHtml(word.wordStr)}" data-word-edit="${realIndex}" placeholder="${chrome.i18n.getMessage('word_placeholder') || 'Word or phrase'}">
|
||||
<input type="color" value="${word.background || list.background}" data-bg-edit="${realIndex}" title="${chrome.i18n.getMessage('background_color_title') || 'Background color'}">
|
||||
<input type="color" value="${word.foreground || list.foreground}" data-fg-edit="${realIndex}" title="${chrome.i18n.getMessage('text_color_title') || 'Text color'}">
|
||||
`;
|
||||
|
||||
return container;
|
||||
@@ -604,12 +565,12 @@ export class PopupController {
|
||||
btnText.textContent = chrome.i18n.getMessage('remove_exception') || 'Remove from Exceptions';
|
||||
toggleBtn.className = 'danger';
|
||||
const icon = toggleBtn.querySelector('i');
|
||||
if (icon) icon.className = 'fa-solid fa-check';
|
||||
if (icon) icon.className = 'fa-solid fa-trash';
|
||||
} else {
|
||||
btnText.textContent = chrome.i18n.getMessage('add_exception') || 'Add to Exceptions';
|
||||
toggleBtn.className = '';
|
||||
const icon = toggleBtn.querySelector('i');
|
||||
if (icon) icon.className = 'fa-solid fa-ban';
|
||||
if (icon) icon.className = 'fa-solid fa-plus';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,7 +579,7 @@ export class PopupController {
|
||||
if (!container) return;
|
||||
|
||||
if (this.exceptionsList.length === 0) {
|
||||
container.innerHTML = '<div class="exception-item">No exceptions</div>';
|
||||
container.innerHTML = `<div class="exception-item">${chrome.i18n.getMessage('no_exceptions') || 'No exceptions'}</div>`;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user