Feature/#12 search input with hotkey #15
63
enhancements/quickSearch.js
Normal file
63
enhancements/quickSearch.js
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
const quickSearchID = 'ea-quickSearch';
|
||||||
|
const quickSearchLink = 'ea-quickSearchLink';
|
||||||
|
|
||||||
|
runAfterLoad(() => {
|
||||||
|
initSearch();
|
||||||
|
}, ".*");
|
||||||
|
|
||||||
|
function initSearch() {
|
||||||
|
let entry = document.createElement('li');
|
||||||
|
entry.setAttribute('ng-repeat', 'item in navbar');
|
||||||
|
entry.setAttribute('ng-class', '{\'anime-indicator\': item[\'@attributes\'].title==\'Anime\'}');
|
||||||
|
|
||||||
|
let quickSearchElement = document.createElement('input');
|
||||||
|
quickSearchElement.setAttribute('aria-label', 'Quick Search Input');
|
||||||
|
quickSearchElement.setAttribute('ng-model-options', '{debounce: 500}');
|
||||||
|
quickSearchElement.type = 'text';
|
||||||
|
quickSearchElement.classList.add('ng-pristine', 'ng-valid', 'ng-empty', 'ng-touched');
|
||||||
|
quickSearchElement.placeholder = 'Quick Search (Shift + F)';
|
||||||
|
quickSearchElement.id = quickSearchID;
|
||||||
|
// register Enter keybinding
|
||||||
|
quickSearchElement.addEventListener('keypress', event => handleQuickSearch(event));
|
||||||
|
|
||||||
|
entry.appendChild(quickSearchElement);
|
||||||
|
|
||||||
|
// Aniwatch CSS requires the search input to be in some kind of known menu container
|
||||||
|
let linkElement = document.createElement('a');
|
||||||
|
linkElement.appendChild(quickSearchElement);
|
||||||
|
linkElement.id = quickSearchLink;
|
||||||
|
entry.appendChild(linkElement);
|
||||||
|
|
||||||
|
let menu = document.getElementById('materialize-menu-dropdown');
|
||||||
|
menu.insertAdjacentElement('beforeend', entry);
|
||||||
|
|
||||||
|
// register focus hotkey
|
||||||
|
document.addEventListener('keypress', event => handleSearchForShiftF(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleQuickSearch(event) {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
let quickSearchElement = document.getElementById(quickSearchID);
|
||||||
|
let linkElement = document.getElementById(quickSearchLink);
|
||||||
|
|
||||||
|
let url = new URL(window.location.origin)
|
||||||
|
url.pathname = '/search';
|
||||||
|
url.searchParams.append('q', quickSearchElement.value);
|
||||||
|
|
||||||
|
linkElement.href = `${url.pathname}${url.search}`;
|
||||||
|
linkElement.click();
|
||||||
|
|
||||||
|
// clean up afterwards
|
||||||
|
linkElement.href = '';
|
||||||
|
quickSearchElement.value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSearchForShiftF(event) {
|
||||||
|
if (isShiftPressed) {
|
||||||
|
if (event.key === 'F') {
|
||||||
|
event.preventDefault();
|
||||||
|
document.getElementById(quickSearchID).focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@
|
||||||
"*://aniwatch.me/*"
|
"*://aniwatch.me/*"
|
||||||
],
|
],
|
||||||
"js": [
|
"js": [
|
||||||
|
"enhancements/quickSearch.js",
|
||||||
"enhancements/animeRequests.js"
|
"enhancements/animeRequests.js"
|
||||||
],
|
],
|
||||||
"run_at": "document_end"
|
"run_at": "document_end"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
let __scripts = [];
|
let __scripts = [];
|
||||||
|
let __afterLoadScripts = [];
|
||||||
|
|
||||||
function registerScript(func, pattern = '.*') {
|
function registerScript(func, pattern = '.*') {
|
||||||
__scripts.push({ "function": func, "pattern": pattern });
|
__scripts.push({ "function": func, "pattern": pattern });
|
||||||
|
@ -25,3 +26,29 @@ observer.observe(document.documentElement || document.body, {
|
||||||
subtree: true,
|
subtree: true,
|
||||||
attributes: true
|
attributes: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function runAfterLoad(func, pattern = '.*') {
|
||||||
|
__afterLoadScripts.push({ "function": func, "pattern": pattern });
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", event => awaitPageLoaded(), false);
|
||||||
|
|
||||||
|
function awaitPageLoaded() {
|
||||||
|
let preLoader = document.getElementById('preloader');
|
||||||
|
|
||||||
|
if (typeof preLoader === 'undefined') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let loop = setInterval(() => {
|
||||||
|
if (preLoader.style.display === "none") {
|
||||||
|
clearInterval(loop);
|
||||||
|
|
||||||
|
__afterLoadScripts.forEach(script => {
|
||||||
|
if (window.location.pathname.match(script.pattern)) {
|
||||||
|
script.function();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
}
|
|
@ -1,3 +1,25 @@
|
||||||
|
var isShiftPressed = false;
|
||||||
|
var isCtrlPressed = false;
|
||||||
|
|
||||||
function isHtmlElement(object) {
|
function isHtmlElement(object) {
|
||||||
return object instanceof HTMLElement;
|
return object instanceof HTMLElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.addEventListener('keydown', event => handleKeyDown(event));
|
||||||
|
document.addEventListener('keyup', event => handleKeyUp(event));
|
||||||
|
|
||||||
|
function handleKeyDown(event) {
|
||||||
|
handleKeyToggle(event, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleKeyUp(event) {
|
||||||
|
handleKeyToggle(event, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleKeyToggle(event, isPressed) {
|
||||||
|
if (event.key === 'Shift') {
|
||||||
|
isShiftPressed = isPressed;
|
||||||
|
} else if (event.key === 'Control') {
|
||||||
|
isCtrlPressed = isPressed;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue