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();
+ }
+});