diff --git a/index.html b/index.html index e6bcdc2..eaf1ce7 100644 --- a/index.html +++ b/index.html @@ -243,6 +243,17 @@ +
+ + + +

No results found!

@@ -252,7 +263,6 @@ -
diff --git a/public/css/styles.css b/public/css/styles.css index faca105..e5ec6c0 100644 --- a/public/css/styles.css +++ b/public/css/styles.css @@ -568,6 +568,42 @@ body{ opacity: .55; pointer-events: none; } +.checkbox-container { + display: flex; + align-items: center; + margin: 10px 0; +} +.checkbox-container input[type="checkbox"] { + appearance: none; + width: 20px; + height: 20px; + border: 2px solid #ccc; + border-radius: 4px; + margin-right: 10px; + cursor: pointer; + transition: all 0.3s ease; +} +.checkbox-container input[type="checkbox"]:checked { + background-color: #aaa; + border-color: #aaa; +} +.checkbox-container input[type="checkbox"]:hover { + border-color: #fff; +} +.checkbox-container label { + font-size: 16px; + font-weight: 500; +} +.checkbox-container input[type="checkbox"]:checked::before { + content: '✔'; + font-size: 14px; + position: absolute; + left: 4px; + top: 2px; +} +.checkbox-container:hover { + border-radius: 8px; +} @keyframes pop { from{ diff --git a/public/js/search.js b/public/js/search.js index b2f3e9b..2cbf1e1 100644 --- a/public/js/search.js +++ b/public/js/search.js @@ -5,159 +5,201 @@ const searchWordInput = document.querySelector(".srch"); const replaceWordInput = document.querySelector(".rep"); searchCard.addEventListener("input", (e) => { - if (replaceWordInput.value.length <= 0) return replaceBtn.classList.add("no"); - else { - return replaceBtn.classList.remove("no"); - } + if (replaceWordInput.value.length <= 0) return replaceBtn.classList.add("no"); + else { + return replaceBtn.classList.remove("no"); + } }); const openSearchMenu = () => { - searchBg.style.display = 'flex'; - searchBg.classList.remove("hide"); - searchCard.classList.add("ani"); - searchCard.classList.remove("hide"); - - setTimeout(() => { - searchCard.classList.remove("up"); - searchWordInput.focus(); - }, 500); + searchBg.style.display = "flex"; + searchBg.classList.remove("hide"); + searchCard.classList.add("ani"); + searchCard.classList.remove("hide"); + + setTimeout(() => { + searchCard.classList.remove("up"); + searchWordInput.focus(); + }, 500); }; const closeSearchMenu = () => { - searchCard.classList.add("down"); - searchCard.classList.add("anti-ani"); - setTimeout(() => { - searchCard.classList.add("hide"); - }, 700); - setTimeout(() => { - searchBg.classList.add("hide"); - searchCard.classList.remove("anti-ani"); - searchCard.classList.add("hide"); - }, 1000); - - setTimeout(() => { - searchCard.classList.add("up"); - searchCard.classList.remove("down"); - searchCard.classList.remove("ani"); - searchBg.style.display = 'none'; - }, 1200); + searchCard.classList.add("down"); + searchCard.classList.add("anti-ani"); + setTimeout(() => { + searchCard.classList.add("hide"); + }, 700); + setTimeout(() => { + searchBg.classList.add("hide"); + searchCard.classList.remove("anti-ani"); + searchCard.classList.add("hide"); + }, 1000); + + setTimeout(() => { + searchCard.classList.add("up"); + searchCard.classList.remove("down"); + searchCard.classList.remove("ani"); + searchBg.style.display = "none"; + }, 1200); }; searchBtn.addEventListener("click", (e) => { - try { - if (textInput.innerText.length <= 0) { - throw new Error("There isn't any text available to search!\nTry entering some text for this to work!"); - } - openSearchMenu(); - } catch (error) { - alert(error.message); - console.error(error); + try { + if (textInput.innerText.length <= 0) { + throw new Error( + "There isn't any text available to search!\nTry entering some text for this to work!" + ); } + openSearchMenu(); + } catch (error) { + alert(error.message); + console.error(error); + } }); closeSearchCardBtn.addEventListener("click", (e) => { - return closeSearchMenu(); + return closeSearchMenu(); }); -const replaceWord = (string, oldWord, newWord) => { - if (!string) { - throw new Error("No string input provided!"); - } - if (!oldWord) { - throw new Error("No word supplied for checking!"); - } - if (!newWord) { - throw new Error("No word supplied for replacing!"); - } +const searchRefresh = function (e) { + try { + if (e.target.value.length <= 0) return; - const regex = new RegExp(`\\b${oldWord.replace(/\//g, "\\/")}\\b`, `g`); - const matches = string.match(regex); - if (!matches) { - throw new Error(`No matches found for the word '${oldWord}' in the text!`); - } + resultMatch.classList.remove("ok"); + resultMatch.classList.remove("err"); + resultMatch.innerText = `Searching...`; - wordsCount.innerText = `Total Words: ${string.length}`; - resultMatch.innerText = `Replaced ${matches.length} occurrences`; - return string.replace(regex, newWord); + setTimeout(() => { + searchString(textInput.innerText, searchWordInput.value); + }, 1000); + } catch (error) { + alert(error.message); + return console.error(error); + } +}; + +const wholeWordCheckbox = document.getElementById("whole-word"); +const caseSensitiveCheckbox = document.getElementById("case-sensitive"); +const replaceNotationCheckbox = document.getElementById("replace-notation"); + +wholeWordCheckbox.addEventListener("click", searchRefresh); +caseSensitiveCheckbox.addEventListener("click", searchRefresh); +replaceNotationCheckbox.addEventListener("click", searchRefresh); + +const replaceWord = (string, oldWord, newWord) => { + if (!string) throw new Error("No string input provided!"); + if (!oldWord) throw new Error("No word supplied for checking!"); + if (!newWord) throw new Error("No word supplied for replacing!"); + + if (replaceNotationCheckbox.checked) { + oldWord = oldWord.replace(/\\n/g, "\n").replace(/\\t/g, "\t"); + newWord = newWord.replace(/\\n/g, "\n").replace(/\\t/g, "\t"); + } + + let flags = "g"; + if (caseSensitiveCheckbox.checked) { + flags += "i"; + } + + const wordBoundary = wholeWordCheckbox.checked ? "\\b" : ""; + const regex = new RegExp( + `${wordBoundary}${oldWord.replace(/\//g, "\\/")}${wordBoundary}`, + flags + ); + + const matches = string.match(regex); + if (!matches) + throw new Error(`No matches found for the word '${oldWord}' in the text!`); + + wordsCount.innerText = `Total Words: ${string.length}`; + resultMatch.innerText = `Replaced ${matches.length} occurrences`; + + return string.replace(regex, newWord); }; const searchString = (string, word) => { - if (!string) { - throw new Error("No value available to search!"); - } - if (!word) { - throw new Error("No word supplied for checking!"); - } + if (!string) throw new Error("No value available to search!"); + if (!word) throw new Error("No word supplied for checking!"); + + let flags = "g"; + if (caseSensitiveCheckbox.checked) { + flags += "i"; + } + + const wordBoundary = wholeWordCheckbox.checked ? "\\b" : ""; + if (!replaceNotationCheckbox.checked) { + word = escapeRegExp(word); + } + let regex; + try{ + regex = new RegExp(`${wordBoundary}${word}${wordBoundary}`, flags); + }catch(e){ + alert("Please enter correct notation"); + return; + } + + const matches = string.match(regex); + if (matches) { + resultMatch.classList.add("ok"); + resultMatch.classList.remove("err"); + resultMatch.innerText = `${matches.length} matches found!`; + } else { + resultMatch.classList.remove("ok"); + resultMatch.classList.add("err"); + resultMatch.innerText = `No matches found!`; + } +}; - const regex = new RegExp(`\\b${word.replace(/\//g, "\\/")}\\b`, `g`); - const matches = string.match(regex); - if (matches) { - resultMatch.classList.add("ok"); - resultMatch.classList.remove("err"); - resultMatch.innerText = `${matches.length} matches found!`; - } else { - resultMatch.classList.remove("ok"); - resultMatch.classList.add("err"); - resultMatch.innerText = `No matches found!`; - } +const escapeRegExp = (string) => { + return string.replace(/[.*+?^=!:${}()|\[\]\/\\]/g, "\\$&"); }; replaceBtn.addEventListener("click", async (e) => { - try { - if (!textInput.innerText.includes(searchWordInput.value)) { - throw new Error(`No match found for the word '${searchWordInput.value.trim()}' in the active document!`); - } - - const output = replaceWord(textInput.innerText, searchWordInput.value, replaceWordInput.value); - textInput.innerText = output; - } catch (error) { - alert(error.message); - console.error(error); + try { + let oldWord = searchWordInput.value; + let newWord = replaceWordInput.value; + if (replaceNotationCheckbox.checked) { + oldWord = oldWord.replace(/\\n/g, "\n").replace(/\\t/g, "\t"); + newWord = newWord.replace(/\\n/g, "\n").replace(/\\t/g, "\t"); } + if (!replaceNotationCheckbox.checked) { + oldWord = escapeRegExp(oldWord); + } + let flags = "g"; + if (caseSensitiveCheckbox.checked) { + flags += "i"; + } + const wordBoundary = wholeWordCheckbox.checked ? "\\b" : ""; + const regex = new RegExp(`${wordBoundary}${oldWord}${wordBoundary}`, flags); + if (!regex.test(textInput.innerText)) { + throw new Error( + `No match found for the word '${searchWordInput.value.trim()}' in the active document!` + ); + } + const output = replaceWord(textInput.innerText, oldWord, newWord); + textInput.innerText = output; + } catch (error) { + alert(error.message); + console.error(error); + } }); searchWordInput.addEventListener("input", (e) => { - try { - if (e.target.value.length <= 0) return; - - resultMatch.classList.remove("ok"); - resultMatch.classList.remove("err"); - resultMatch.innerText = `Searching...`; - - setTimeout(() => { - searchString(textInput.innerText, searchWordInput.value); - }, 1000); - } catch (error) { - alert(error.message); - return console.error(error); - } + searchRefresh(e); }); searchWordInput.addEventListener("keydown", (e) => { - try { - if (e.key === 'Backspace') { - console.log("Yes"); - } - } catch (error) { - alert(error); - return console.error(error); - } -}) - -searchWordInput.addEventListener("keydown", (e) => { - try { - if(e.target.value.length <= 0) return; - if(e.keyCode === 13) return replaceWordInput.focus(); - } catch (error) { - alert(error); - return console.error(error); - } -}) - + try { + if (e.target.value.length <= 0) return; + if (e.keyCode === 13) return replaceWordInput.focus(); + } catch (error) { + alert(error); + return console.error(error); + } +}); replaceWordInput.addEventListener("keydown", (e) => { - if(e.keyCode === 13) { - return replaceBtn.click(); - } -}) - + if (e.keyCode === 13) { + return replaceBtn.click(); + } +});