2018-01-03 19:33:25 +02:00
|
|
|
(function(document) {
|
2019-02-03 23:31:22 +02:00
|
|
|
var $body = document.body,
|
|
|
|
$grid = document.querySelector('.grid'),
|
2018-11-05 02:58:49 +02:00
|
|
|
$icons = $grid.querySelectorAll('.grid-item:not(.grid-item--ad)'),
|
|
|
|
$search = document.querySelector('.search'),
|
|
|
|
$searchClose = $search.querySelector('.search__close'),
|
|
|
|
$searchInput = $search.querySelector('input'),
|
|
|
|
$orderByColor = document.getElementById('sort-color'),
|
|
|
|
$orderAlphabetically = document.getElementById('sort-alphabetically'),
|
|
|
|
$orderByRelevance = document.getElementById('sort-relevance');
|
2018-09-01 11:20:04 +02:00
|
|
|
|
2018-01-03 19:33:25 +02:00
|
|
|
var queryParameter = 'q',
|
2018-11-05 02:58:49 +02:00
|
|
|
orderingPreferenceIdentifier = 'ordering-preference',
|
2018-09-01 11:20:04 +02:00
|
|
|
previousQuery = null,
|
2018-11-05 02:58:49 +02:00
|
|
|
previousOrdering = $orderByColor;
|
2018-01-03 19:33:25 +02:00
|
|
|
|
|
|
|
// Remove the "disabled" attribute from the search input
|
|
|
|
$searchInput.setAttribute('title', 'Search Simple Icons');
|
|
|
|
$searchInput.removeAttribute('disabled');
|
2020-09-18 10:40:34 +02:00
|
|
|
$searchInput.focus();
|
2018-01-03 19:33:25 +02:00
|
|
|
|
|
|
|
// include a modified debounce underscorejs helper function.
|
|
|
|
// see
|
|
|
|
// - http://underscorejs.org/docs/underscore.html#section-83
|
|
|
|
// - http://underscorejs.org/#debounce
|
|
|
|
function debounce(func, wait, immediate) {
|
|
|
|
var timeout, args, context, timestamp, result;
|
|
|
|
|
|
|
|
var later = function() {
|
|
|
|
var last = +new Date - timestamp;
|
|
|
|
|
|
|
|
if (last < wait && last >= 0) {
|
|
|
|
timeout = setTimeout(later, wait - last);
|
|
|
|
} else {
|
|
|
|
timeout = null;
|
|
|
|
if (!immediate) {
|
|
|
|
result = func.apply(context, args);
|
|
|
|
if (!timeout) context = args = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return function() {
|
|
|
|
context = this;
|
|
|
|
args = arguments;
|
|
|
|
timestamp = +new Date;
|
|
|
|
var callNow = immediate && !timeout;
|
|
|
|
if (!timeout) timeout = setTimeout(later, wait);
|
|
|
|
if (callNow) {
|
|
|
|
result = func.apply(context, args);
|
|
|
|
context = args = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-07-31 18:52:07 +02:00
|
|
|
// Get a parameter from the URL's search section (location.search). Based on:
|
2018-01-03 19:33:25 +02:00
|
|
|
// - https://davidwalsh.name/query-string-javascript
|
|
|
|
// - https://github.com/WebReflection/url-search-params
|
2020-07-31 18:52:07 +02:00
|
|
|
// - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Escaping
|
2018-01-03 19:33:25 +02:00
|
|
|
function getUrlParameter(parameter) {
|
2020-07-31 18:52:07 +02:00
|
|
|
var name = parameter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
2018-01-03 19:33:25 +02:00
|
|
|
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
|
|
|
|
var results = regex.exec(location.search);
|
|
|
|
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
|
|
|
|
}
|
|
|
|
|
2020-06-23 17:21:10 +02:00
|
|
|
function normalizeSearchTerm(value) {
|
|
|
|
return value.toLowerCase().toLowerCase()
|
|
|
|
.replace(/à|á|â|ã|ä/g, "a")
|
|
|
|
.replace(/ç|č|ć/g, "c")
|
|
|
|
.replace(/è|é|ê|ë/g, "e")
|
|
|
|
.replace(/ì|í|î|ï/g, "i")
|
|
|
|
.replace(/ñ|ň|ń/g, "n")
|
|
|
|
.replace(/ò|ó|ô|õ|ö/g, "o")
|
|
|
|
.replace(/š|ś/g, "s")
|
|
|
|
.replace(/ù|ú|û|ü/g, "u")
|
|
|
|
.replace(/ý|ÿ/g, "y")
|
|
|
|
.replace(/ž|ź/g, "z");
|
|
|
|
}
|
|
|
|
|
2018-01-03 19:33:25 +02:00
|
|
|
function search(value) {
|
2019-02-03 23:31:22 +02:00
|
|
|
var query = normalizeSearchTerm(value)
|
|
|
|
queryLetters = query.split('');
|
2018-01-03 19:33:25 +02:00
|
|
|
|
2019-02-03 23:31:22 +02:00
|
|
|
var matchedIcons = icons.filter(function(iconName, iconIndex) {
|
2020-07-28 12:33:40 +02:00
|
|
|
var element = $icons[iconIndex];
|
|
|
|
var score = iconName.length - query.length;
|
|
|
|
var index = 0;
|
2018-01-03 19:33:25 +02:00
|
|
|
|
2019-02-03 23:31:22 +02:00
|
|
|
for (var i = 0; i < queryLetters.length; i++) {
|
|
|
|
var letter = queryLetters[i];
|
|
|
|
index = iconName.indexOf(letter, index);
|
2018-01-03 19:33:25 +02:00
|
|
|
|
|
|
|
if (index === -1) {
|
2019-02-03 23:31:22 +02:00
|
|
|
element.classList.add('hidden');
|
|
|
|
return false;
|
2018-01-03 19:33:25 +02:00
|
|
|
}
|
|
|
|
|
2019-02-03 23:31:22 +02:00
|
|
|
score += index;
|
2018-01-03 19:33:25 +02:00
|
|
|
index++;
|
|
|
|
}
|
|
|
|
|
2019-02-03 23:31:22 +02:00
|
|
|
element.style.setProperty("--order-relevance", score);
|
2018-09-01 11:20:04 +02:00
|
|
|
element.classList.remove('hidden');
|
2019-02-03 23:31:22 +02:00
|
|
|
return true;
|
2018-01-03 19:33:25 +02:00
|
|
|
});
|
|
|
|
|
2018-10-29 19:21:34 +02:00
|
|
|
$grid.classList.toggle('search__empty', matchedIcons.length == 0);
|
2019-02-03 23:31:22 +02:00
|
|
|
$body.classList.toggle('search__active', matchedIcons.length < icons.length);
|
|
|
|
|
2018-09-01 11:20:04 +02:00
|
|
|
if (query === '') {
|
2018-11-05 02:58:49 +02:00
|
|
|
if ($orderByRelevance.classList.contains('active')) {
|
|
|
|
selectOrdering(previousOrdering);
|
2018-09-01 11:20:04 +02:00
|
|
|
}
|
|
|
|
} else {
|
2019-02-03 23:31:22 +02:00
|
|
|
if (previousQuery === '') {
|
2018-11-05 02:58:49 +02:00
|
|
|
selectOrdering($orderByRelevance);
|
2018-09-01 11:20:04 +02:00
|
|
|
}
|
|
|
|
}
|
2019-02-03 23:31:22 +02:00
|
|
|
|
|
|
|
previousQuery = query;
|
2018-09-01 11:20:04 +02:00
|
|
|
}
|
2018-11-05 02:58:49 +02:00
|
|
|
function selectOrdering(selected) {
|
2019-02-03 23:31:22 +02:00
|
|
|
// Set the ordering type as a class on body
|
|
|
|
$body.classList.remove('order-alphabetically', 'order-by-color', 'order-by-relevance');
|
|
|
|
if (selected === $orderByColor) {
|
|
|
|
$body.classList.add('order-by-color');
|
|
|
|
} else if (selected === $orderAlphabetically) {
|
|
|
|
$body.classList.add('order-alphabetically');
|
|
|
|
} else if (selected === $orderByRelevance) {
|
|
|
|
$body.classList.add('order-by-relevance');
|
2018-09-01 11:20:04 +02:00
|
|
|
}
|
|
|
|
|
2018-11-05 02:58:49 +02:00
|
|
|
// Store ordering preference
|
|
|
|
var preferenceOptions = [$orderByColor, $orderAlphabetically];
|
|
|
|
if (localStorage && preferenceOptions.includes(selected)) {
|
|
|
|
localStorage.setItem(orderingPreferenceIdentifier, selected.id);
|
|
|
|
}
|
2019-02-03 23:31:22 +02:00
|
|
|
if (selected !== $orderByRelevance) {
|
|
|
|
previousOrdering = selected;
|
|
|
|
}
|
2018-01-03 19:33:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
2018-11-05 02:58:49 +02:00
|
|
|
// Restore ordering preference of the user. This should be performed before
|
|
|
|
// applying the search query as it would overwrite "order by relevance"
|
|
|
|
if (localStorage) {
|
|
|
|
var storedOrderingId = localStorage.getItem(orderingPreferenceIdentifier);
|
|
|
|
var ordering = document.getElementById(storedOrderingId);
|
|
|
|
if (ordering) selectOrdering(ordering);
|
|
|
|
}
|
|
|
|
|
2018-01-03 19:33:25 +02:00
|
|
|
// Load search query if present
|
|
|
|
var query = getUrlParameter(queryParameter);
|
|
|
|
if (query) {
|
|
|
|
$search.classList.add('search--active');
|
|
|
|
$searchInput.value = query;
|
|
|
|
search(query);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
$search.addEventListener('input', debounce(function(e) {
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
var value = e.target.value;
|
|
|
|
if (value) {
|
|
|
|
$search.classList.add('search--active');
|
|
|
|
window.history.replaceState(null, '', '?' + queryParameter + '=' + value);
|
|
|
|
} else {
|
|
|
|
$search.classList.remove('search--active');
|
|
|
|
window.history.replaceState(null, '', '/');
|
|
|
|
}
|
|
|
|
search(value);
|
2019-02-03 23:32:44 +02:00
|
|
|
}, 200), false);
|
2018-01-03 19:33:25 +02:00
|
|
|
$searchClose.addEventListener('click', function(e) {
|
|
|
|
e.stopPropagation();
|
|
|
|
|
|
|
|
$searchInput.value = '';
|
|
|
|
$search.classList.remove('search--active');
|
|
|
|
window.history.replaceState(null, '', '/');
|
|
|
|
search('');
|
|
|
|
}, false);
|
|
|
|
|
2018-11-05 02:58:49 +02:00
|
|
|
$orderByColor.addEventListener('click', function() {
|
|
|
|
selectOrdering($orderByColor);
|
2018-01-03 19:33:25 +02:00
|
|
|
});
|
2018-11-05 02:58:49 +02:00
|
|
|
$orderAlphabetically.addEventListener('click', function() {
|
|
|
|
selectOrdering($orderAlphabetically);
|
2018-09-01 11:20:04 +02:00
|
|
|
});
|
2018-11-05 02:58:49 +02:00
|
|
|
$orderByRelevance.addEventListener('click', function() {
|
|
|
|
selectOrdering($orderByRelevance);
|
2018-01-03 19:33:25 +02:00
|
|
|
});
|
|
|
|
})( document );
|