diff --git a/index.html b/index.html
index c819519..f765bb3 100644
--- a/index.html
+++ b/index.html
@@ -35,6 +35,9 @@
+
diff --git a/src/helpers.js b/src/helpers.js
index 13c5889..e1a13be 100644
--- a/src/helpers.js
+++ b/src/helpers.js
@@ -32,3 +32,21 @@ export function removeTags(html) {
export function slugify(string) {
return removeDiacritics(string).replace(/[!a-zA-Z0-9-_]/g, '-');
}
+
+export function getIndicesOf(searchStr, findIn, caseSensitive) {
+ // https://stackoverflow.com/a/3410557
+ const searchStrLen = searchStr.length;
+ if (searchStrLen == 0) {
+ return [];
+ }
+ let startIndex = 0, index, indices = [];
+ if (!caseSensitive) {
+ findIn = findIn.toLowerCase();
+ searchStr = searchStr.toLowerCase();
+ }
+ while ((index = findIn.indexOf(searchStr, startIndex)) > -1) {
+ indices.push(index);
+ startIndex = index + searchStrLen;
+ }
+ return indices;
+}
diff --git a/src/js/search.js b/src/js/search.js
index 9e024a7..261623c 100644
--- a/src/js/search.js
+++ b/src/js/search.js
@@ -1,4 +1,5 @@
-import { cloneObject } from "../helpers";
+import { cloneObject, getIndicesOf } from "../helpers";
+import removeDiacritics from "./StackOverflow/removeDiacritics";
export function getSearchTerm() {
return document.getElementById('searchBox').value;
@@ -7,6 +8,7 @@ export function getSearchTerm() {
export function getSearchFilters() {
const filters = {
caseSensitive: document.getElementById('searchCaseSensitive').checked,
+ ignoreDiacritics: document.getElementById('searchIgnoreDiacritics').checked,
exact: document.getElementById('searchExactWords').checked,
name: document.getElementById('searchIncludeName').checked,
definition: document.getElementById('searchIncludeDefinition').checked,
@@ -39,17 +41,19 @@ export function getMatchingSearchWords() {
}
return true;
}).filter(word => {
+ searchTerm = filters.ignoreDiacritics ? removeDiacritics(searchTerm) : searchTerm;
searchTerm = filters.caseSensitive ? searchTerm : searchTerm.toLowerCase();
- const name = filters.caseSensitive ? word.name : word.name.toLowerCase();
- const simpleDefinition = filters.caseSensitive ? word.simpleDefinition : word.simpleDefinition.toLowerCase();
- const longDefinition = filters.caseSensitive ? word.longDefinition : word.longDefinition.toLowerCase();
+ let name = filters.ignoreDiacritics ? removeDiacritics(word.name) : word.name;
+ name = filters.caseSensitive ? name : name.toLowerCase();
+ let simpleDefinition = filters.ignoreDiacritics ? removeDiacritics(word.simpleDefinition) : word.simpleDefinition;
+ simpleDefinition = filters.caseSensitive ? simpleDefinition : simpleDefinition.toLowerCase();
+ let longDefinition = filters.ignoreDiacritics ? removeDiacritics(word.longDefinition) : word.longDefinition;
+ longDefinition = filters.caseSensitive ? longDefinition : longDefinition.toLowerCase();
- const isInName = filters.name
- && (filters.exact
+ const isInName = filters.name && (filters.exact
? searchTerm == name
: new RegExp(searchTerm, 'g').test(name));
- const isInDefinition = filters.definition
- && (filters.exact
+ const isInDefinition = filters.definition && (filters.exact
? searchTerm == simpleDefinition
: new RegExp(searchTerm, 'g').test(simpleDefinition));
const isInDetails = filters.details && new RegExp(searchTerm, 'g').test(longDefinition);
@@ -62,14 +66,52 @@ export function getMatchingSearchWords() {
}
export function highlightSearchTerm(word) {
- const searchTerm = getSearchTerm();
+ let searchTerm = getSearchTerm();
if (searchTerm) {
const filters = getSearchFilters();
- const regexMethod = 'g' + (filters.caseSensitive ? '' : 'i');
const markedUpWord = cloneObject(word);
- markedUpWord.name = markedUpWord.name.replace(new RegExp(`(${searchTerm})`, regexMethod), `$1`);
- markedUpWord.simpleDefinition = markedUpWord.simpleDefinition.replace(new RegExp(`(${searchTerm})`, regexMethod), `$1`);
- markedUpWord.longDefinition = markedUpWord.longDefinition.replace(new RegExp(`(${searchTerm})`, regexMethod), `$1`);
+ if (filters.ignoreDiacritics) {
+ const searchTermLength = searchTerm.length;
+ searchTerm = removeDiacritics(searchTerm);
+ if (filters.name) {
+ const nameMatches = getIndicesOf(searchTerm, removeDiacritics(markedUpWord.name), filters.caseSensitive);
+ nameMatches.forEach((wordIndex, i) => {
+ wordIndex += ''.length * i;
+ markedUpWord.name = markedUpWord.name.substring(0, wordIndex)
+ + '' + markedUpWord.name.substr(wordIndex, searchTermLength) + ''
+ + markedUpWord.name.substr(wordIndex + searchTermLength);
+ });
+ }
+ if (filters.definition) {
+ const simpleDefinitionMatches = getIndicesOf(searchTerm, removeDiacritics(markedUpWord.simpleDefinition), filters.caseSensitive);
+ simpleDefinitionMatches.forEach((wordIndex, i) => {
+ wordIndex += ''.length * i;
+ markedUpWord.simpleDefinition = markedUpWord.simpleDefinition.substring(0, wordIndex)
+ + '' + markedUpWord.simpleDefinition.substr(wordIndex, searchTermLength) + ''
+ + markedUpWord.simpleDefinition.substr(wordIndex + searchTermLength);
+ });
+ }
+ if (filters.details) {
+ const longDefinitionMatches = getIndicesOf(searchTerm, removeDiacritics(markedUpWord.longDefinition), filters.caseSensitive);
+ longDefinitionMatches.forEach((wordIndex, i) => {
+ wordIndex += ''.length * i;
+ markedUpWord.longDefinition = markedUpWord.longDefinition.substring(0, wordIndex)
+ + '' + markedUpWord.longDefinition.substr(wordIndex, searchTermLength) + ''
+ + markedUpWord.longDefinition.substr(wordIndex + searchTermLength);
+ });
+ }
+ } else {
+ const regexMethod = 'g' + (filters.caseSensitive ? '' : 'i');
+ if (filters.name) {
+ markedUpWord.name = markedUpWord.name.replace(new RegExp(`(${searchTerm})`, regexMethod), `$1`);
+ }
+ if (filters.definition) {
+ markedUpWord.simpleDefinition = markedUpWord.simpleDefinition.replace(new RegExp(`(${searchTerm})`, regexMethod), `$1`);
+ }
+ if (filters.details) {
+ markedUpWord.longDefinition = markedUpWord.longDefinition.replace(new RegExp(`(${searchTerm})`, regexMethod), `$1`);
+ }
+ }
return markedUpWord;
}
return word;
diff --git a/src/js/setupListeners.js b/src/js/setupListeners.js
index fcdf5c4..c976f79 100644
--- a/src/js/setupListeners.js
+++ b/src/js/setupListeners.js
@@ -84,6 +84,7 @@ function setupSearchBar() {
const searchBox = document.getElementById('searchBox'),
clearSearchButton = document.getElementById('clearSearchButton'),
openSearchModal = document.getElementById('openSearchModal'),
+ searchIgnoreDiacritics = document.getElementById('searchIgnoreDiacritics'),
searchExactWords = document.getElementById('searchExactWords'),
searchIncludeDetails = document.getElementById('searchIncludeDetails');
searchBox.addEventListener('change', () => {
@@ -102,7 +103,7 @@ function setupSearchBar() {
searchBox.focus();
});
- searchExactWords.addEventListener('change', () => {
+ const toggleDetailsCheck = function() {
if (searchExactWords.checked) {
searchIncludeDetails.checked = false;
searchIncludeDetails.disabled = true;
@@ -110,7 +111,19 @@ function setupSearchBar() {
searchIncludeDetails.disabled = false;
searchIncludeDetails.checked = true;
}
+ }
+
+ searchIgnoreDiacritics.addEventListener('change', () => {
+ if (searchIgnoreDiacritics.checked) {
+ searchExactWords.checked = false;
+ searchExactWords.disabled = true;
+ } else {
+ searchExactWords.disabled = false;
+ }
+ toggleDetailsCheck();
});
+
+ searchExactWords.addEventListener('change', () => toggleDetailsCheck());
}
export function setupSearchFilters() {