mirror of
https://github.com/obsqrbtz/goose-highlighter.git
synced 2026-04-08 20:19:06 +03:00
feat: add word search
This commit is contained in:
@@ -88,5 +88,8 @@
|
|||||||
},
|
},
|
||||||
"global_highlight_toggle": {
|
"global_highlight_toggle": {
|
||||||
"message": "Aktivieren"
|
"message": "Aktivieren"
|
||||||
}
|
},
|
||||||
|
"search_placeholder": {
|
||||||
|
"message": "Suchen..."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -88,5 +88,8 @@
|
|||||||
},
|
},
|
||||||
"global_highlight_toggle": {
|
"global_highlight_toggle": {
|
||||||
"message": "Enable"
|
"message": "Enable"
|
||||||
|
},
|
||||||
|
"search_placeholder": {
|
||||||
|
"message": "Search..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,5 +88,8 @@
|
|||||||
},
|
},
|
||||||
"global_highlight_toggle": {
|
"global_highlight_toggle": {
|
||||||
"message": "Activar"
|
"message": "Activar"
|
||||||
|
},
|
||||||
|
"search_placeholder": {
|
||||||
|
"message": "Buscar..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,5 +88,8 @@
|
|||||||
},
|
},
|
||||||
"global_highlight_toggle": {
|
"global_highlight_toggle": {
|
||||||
"message": "Activer"
|
"message": "Activer"
|
||||||
|
},
|
||||||
|
"search_placeholder": {
|
||||||
|
"message": "Rechercher..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,5 +88,8 @@
|
|||||||
},
|
},
|
||||||
"global_highlight_toggle": {
|
"global_highlight_toggle": {
|
||||||
"message": "सक्षम करें"
|
"message": "सक्षम करें"
|
||||||
|
},
|
||||||
|
"search_placeholder": {
|
||||||
|
"message": "खोजें..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,5 +88,8 @@
|
|||||||
},
|
},
|
||||||
"global_highlight_toggle": {
|
"global_highlight_toggle": {
|
||||||
"message": "Attiva"
|
"message": "Attiva"
|
||||||
|
},
|
||||||
|
"search_placeholder": {
|
||||||
|
"message": "Cerca..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,5 +88,8 @@
|
|||||||
},
|
},
|
||||||
"global_highlight_toggle": {
|
"global_highlight_toggle": {
|
||||||
"message": "有効にする"
|
"message": "有効にする"
|
||||||
|
},
|
||||||
|
"search_placeholder": {
|
||||||
|
"message": "検索..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,5 +88,8 @@
|
|||||||
},
|
},
|
||||||
"global_highlight_toggle": {
|
"global_highlight_toggle": {
|
||||||
"message": "활성화"
|
"message": "활성화"
|
||||||
|
},
|
||||||
|
"search_placeholder": {
|
||||||
|
"message": "검색..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,5 +88,8 @@
|
|||||||
},
|
},
|
||||||
"global_highlight_toggle": {
|
"global_highlight_toggle": {
|
||||||
"message": "Inschakelen"
|
"message": "Inschakelen"
|
||||||
|
},
|
||||||
|
"search_placeholder": {
|
||||||
|
"message": "Zoeken..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,5 +88,8 @@
|
|||||||
},
|
},
|
||||||
"global_highlight_toggle": {
|
"global_highlight_toggle": {
|
||||||
"message": "Włącz"
|
"message": "Włącz"
|
||||||
|
},
|
||||||
|
"search_placeholder": {
|
||||||
|
"message": "Szukaj..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,5 +88,8 @@
|
|||||||
},
|
},
|
||||||
"global_highlight_toggle": {
|
"global_highlight_toggle": {
|
||||||
"message": "Ativar"
|
"message": "Ativar"
|
||||||
}
|
},
|
||||||
|
"search_placeholder": {
|
||||||
|
"message": "Pesquisar..."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -88,5 +88,8 @@
|
|||||||
},
|
},
|
||||||
"global_highlight_toggle": {
|
"global_highlight_toggle": {
|
||||||
"message": "Вкл"
|
"message": "Вкл"
|
||||||
|
},
|
||||||
|
"search_placeholder": {
|
||||||
|
"message": "Поиск..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,5 +88,8 @@
|
|||||||
},
|
},
|
||||||
"global_highlight_toggle": {
|
"global_highlight_toggle": {
|
||||||
"message": "Etkinleştir"
|
"message": "Etkinleştir"
|
||||||
|
},
|
||||||
|
"search_placeholder": {
|
||||||
|
"message": "Ara..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,5 +88,8 @@
|
|||||||
},
|
},
|
||||||
"global_highlight_toggle": {
|
"global_highlight_toggle": {
|
||||||
"message": "启用"
|
"message": "启用"
|
||||||
}
|
},
|
||||||
|
"search_placeholder": {
|
||||||
|
"message": "搜索..."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -236,6 +236,12 @@ button.danger:hover {
|
|||||||
gap: 6px;
|
gap: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#wordSearch{
|
||||||
|
width:100%;
|
||||||
|
margin-bottom:8px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
#wordList {
|
#wordList {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -77,6 +77,7 @@
|
|||||||
<button id="disableSelectedBtn"><span data-i18n="disable_selected">Disable</span></button>
|
<button id="disableSelectedBtn"><span data-i18n="disable_selected">Disable</span></button>
|
||||||
<button id="deleteSelectedBtn" class="danger"><span data-i18n="delete_selected">Delete</span></button>
|
<button id="deleteSelectedBtn" class="danger"><span data-i18n="delete_selected">Delete</span></button>
|
||||||
</div>
|
</div>
|
||||||
|
<input type="text" id="wordSearch" data-i18n="search_placeholder" placeholder="Search..."/>
|
||||||
<div id="wordList"></div>
|
<div id="wordList"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ let currentListIndex = 0;
|
|||||||
let saveTimeout;
|
let saveTimeout;
|
||||||
let selectedCheckboxes = new Set();
|
let selectedCheckboxes = new Set();
|
||||||
let globalHighlightEnabled = true;
|
let globalHighlightEnabled = true;
|
||||||
|
let wordSearchQuery = "";
|
||||||
|
|
||||||
function escapeHtml(str) {
|
function escapeHtml(str) {
|
||||||
return str.replace(/[&<>"']/g, function (m) {
|
return str.replace(/[&<>"']/g, function (m) {
|
||||||
@@ -108,7 +109,12 @@ function updateListForm() {
|
|||||||
|
|
||||||
function renderWords() {
|
function renderWords() {
|
||||||
const list = lists[currentListIndex];
|
const list = lists[currentListIndex];
|
||||||
const fragment = document.createDocumentFragment();
|
|
||||||
|
let filteredWords = list.words;
|
||||||
|
if (wordSearchQuery.trim()) {
|
||||||
|
const q = wordSearchQuery.trim().toLowerCase();
|
||||||
|
filteredWords = list.words.filter(w => w.wordStr.toLowerCase().includes(q));
|
||||||
|
}
|
||||||
|
|
||||||
const itemHeight = 32;
|
const itemHeight = 32;
|
||||||
const containerHeight = wordList.clientHeight;
|
const containerHeight = wordList.clientHeight;
|
||||||
@@ -116,18 +122,19 @@ function renderWords() {
|
|||||||
const startIndex = Math.floor(scrollTop / itemHeight);
|
const startIndex = Math.floor(scrollTop / itemHeight);
|
||||||
const endIndex = Math.min(
|
const endIndex = Math.min(
|
||||||
startIndex + Math.ceil(containerHeight / itemHeight) + 2,
|
startIndex + Math.ceil(containerHeight / itemHeight) + 2,
|
||||||
list.words.length
|
filteredWords.length
|
||||||
);
|
);
|
||||||
|
|
||||||
wordList.innerHTML = '';
|
wordList.innerHTML = '';
|
||||||
|
|
||||||
const spacer = document.createElement('div');
|
const spacer = document.createElement('div');
|
||||||
spacer.style.position = 'relative';
|
spacer.style.position = 'relative';
|
||||||
spacer.style.height = `${list.words.length * itemHeight}px`;
|
spacer.style.height = `${filteredWords.length * itemHeight}px`;
|
||||||
spacer.style.width = '100%';
|
spacer.style.width = '100%';
|
||||||
|
|
||||||
for (let i = startIndex; i < endIndex; i++) {
|
for (let i = startIndex; i < endIndex; i++) {
|
||||||
const w = list.words[i];
|
const w = filteredWords[i];
|
||||||
|
if (!w) continue;
|
||||||
const container = document.createElement("div");
|
const container = document.createElement("div");
|
||||||
container.style.height = `${itemHeight}px`;
|
container.style.height = `${itemHeight}px`;
|
||||||
container.style.position = 'absolute';
|
container.style.position = 'absolute';
|
||||||
@@ -143,18 +150,20 @@ function renderWords() {
|
|||||||
container.style.background = 'var(--highlight-tag)';
|
container.style.background = 'var(--highlight-tag)';
|
||||||
container.style.border = '1px solid var(--highlight-tag-border)';
|
container.style.border = '1px solid var(--highlight-tag-border)';
|
||||||
|
|
||||||
|
const realIndex = list.words.indexOf(w);
|
||||||
|
|
||||||
const cbSelect = document.createElement("input");
|
const cbSelect = document.createElement("input");
|
||||||
cbSelect.type = "checkbox";
|
cbSelect.type = "checkbox";
|
||||||
cbSelect.className = "word-checkbox";
|
cbSelect.className = "word-checkbox";
|
||||||
cbSelect.dataset.index = i;
|
cbSelect.dataset.index = realIndex;
|
||||||
if (selectedCheckboxes.has(i)) {
|
if (selectedCheckboxes.has(realIndex)) {
|
||||||
cbSelect.checked = true;
|
cbSelect.checked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const inputWord = document.createElement("input");
|
const inputWord = document.createElement("input");
|
||||||
inputWord.type = "text";
|
inputWord.type = "text";
|
||||||
inputWord.value = w.wordStr;
|
inputWord.value = w.wordStr;
|
||||||
inputWord.dataset.wordEdit = i;
|
inputWord.dataset.wordEdit = realIndex;
|
||||||
inputWord.style.flexGrow = '1';
|
inputWord.style.flexGrow = '1';
|
||||||
inputWord.style.minWidth = '0';
|
inputWord.style.minWidth = '0';
|
||||||
inputWord.style.padding = '4px 8px';
|
inputWord.style.padding = '4px 8px';
|
||||||
@@ -166,7 +175,7 @@ function renderWords() {
|
|||||||
const inputBg = document.createElement("input");
|
const inputBg = document.createElement("input");
|
||||||
inputBg.type = "color";
|
inputBg.type = "color";
|
||||||
inputBg.value = w.background || list.background;
|
inputBg.value = w.background || list.background;
|
||||||
inputBg.dataset.bgEdit = i;
|
inputBg.dataset.bgEdit = realIndex;
|
||||||
inputBg.style.width = '24px';
|
inputBg.style.width = '24px';
|
||||||
inputBg.style.height = '24px';
|
inputBg.style.height = '24px';
|
||||||
inputBg.style.flexShrink = '0';
|
inputBg.style.flexShrink = '0';
|
||||||
@@ -174,7 +183,7 @@ function renderWords() {
|
|||||||
const inputFg = document.createElement("input");
|
const inputFg = document.createElement("input");
|
||||||
inputFg.type = "color";
|
inputFg.type = "color";
|
||||||
inputFg.value = w.foreground || list.foreground;
|
inputFg.value = w.foreground || list.foreground;
|
||||||
inputFg.dataset.fgEdit = i;
|
inputFg.dataset.fgEdit = realIndex;
|
||||||
inputFg.style.width = '24px';
|
inputFg.style.width = '24px';
|
||||||
inputFg.style.height = '24px';
|
inputFg.style.height = '24px';
|
||||||
inputFg.style.flexShrink = '0';
|
inputFg.style.flexShrink = '0';
|
||||||
@@ -189,7 +198,7 @@ function renderWords() {
|
|||||||
const cbActive = document.createElement("input");
|
const cbActive = document.createElement("input");
|
||||||
cbActive.type = "checkbox";
|
cbActive.type = "checkbox";
|
||||||
cbActive.checked = w.active !== false;
|
cbActive.checked = w.active !== false;
|
||||||
cbActive.dataset.activeEdit = i;
|
cbActive.dataset.activeEdit = realIndex;
|
||||||
cbActive.className = "switch";
|
cbActive.className = "switch";
|
||||||
|
|
||||||
activeContainer.appendChild(cbActive);
|
activeContainer.appendChild(cbActive);
|
||||||
@@ -207,7 +216,7 @@ function renderWords() {
|
|||||||
|
|
||||||
const wordCount = document.getElementById('wordCount');
|
const wordCount = document.getElementById('wordCount');
|
||||||
if (wordCount) {
|
if (wordCount) {
|
||||||
wordCount.textContent = list.words.length;
|
wordCount.textContent = filteredWords.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,7 +230,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
renderWords();
|
renderWords();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add event listener for the global toggle
|
|
||||||
document.getElementById("globalHighlightToggle").addEventListener('change', function () {
|
document.getElementById("globalHighlightToggle").addEventListener('change', function () {
|
||||||
globalHighlightEnabled = this.checked;
|
globalHighlightEnabled = this.checked;
|
||||||
updateGlobalToggleState();
|
updateGlobalToggleState();
|
||||||
@@ -415,5 +423,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
renderWords();
|
renderWords();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const wordSearch = document.getElementById("wordSearch");
|
||||||
|
wordSearch.addEventListener("input", (e) => {
|
||||||
|
wordSearchQuery = e.target.value;
|
||||||
|
renderWords();
|
||||||
|
});
|
||||||
|
|
||||||
load();
|
load();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user