mirror of
https://github.com/zombieFox/nightTab.git
synced 2024-11-28 11:03:16 +01:00
261 lines
8.4 KiB
JavaScript
261 lines
8.4 KiB
JavaScript
|
var autoSuggest = (function() {
|
||
|
|
||
|
var _timer = null;
|
||
|
var _currentInputOptions = {};
|
||
|
var _autoSuggestActive = false;
|
||
|
|
||
|
var _delayRender = function(options) {
|
||
|
render(options);
|
||
|
};
|
||
|
|
||
|
var bind = function(override) {
|
||
|
var options = {
|
||
|
input: null,
|
||
|
type: null,
|
||
|
postFocus: null
|
||
|
};
|
||
|
if (override) {
|
||
|
options = helper.applyOptions(options, override);
|
||
|
};
|
||
|
if (options.input) {
|
||
|
options.input.addEventListener("focus", function() {
|
||
|
if (!_autoSuggestActive) {
|
||
|
clearTimeout(_timer);
|
||
|
_timer = setTimeout(_delayRender, 300, options);
|
||
|
};
|
||
|
}, false);
|
||
|
options.input.addEventListener("input", function() {
|
||
|
clearTimeout(_timer);
|
||
|
_timer = setTimeout(_delayRender, 300, options);
|
||
|
}, false);
|
||
|
};
|
||
|
};
|
||
|
|
||
|
var _navigateResults = function(event) {
|
||
|
var elementToFocus = null;
|
||
|
var focusIndex = null;
|
||
|
var allSuggestItems = helper.eA(".auto-suggest-link");
|
||
|
var _findInput = function() {
|
||
|
if (event.target.classList.contains("auto-suggest-input")) {
|
||
|
_currentInputOptions.input = event.target;
|
||
|
};
|
||
|
};
|
||
|
var _findFocus = function() {
|
||
|
for (var i = 0; i < allSuggestItems.length; i++) {
|
||
|
if (allSuggestItems[i] == document.activeElement) {
|
||
|
focusIndex = i;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
var _keyEvents = function() {
|
||
|
// up
|
||
|
if (event.keyCode == 38) {
|
||
|
event.preventDefault();
|
||
|
if (focusIndex == null) {
|
||
|
elementToFocus = allSuggestItems[allSuggestItems.length - 1];
|
||
|
} else {
|
||
|
if (focusIndex > 2 && focusIndex <= allSuggestItems.length - 1) {
|
||
|
elementToFocus = allSuggestItems[focusIndex - 3];
|
||
|
} else {
|
||
|
elementToFocus = _currentInputOptions.input;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
// down
|
||
|
if (event.keyCode == 40) {
|
||
|
event.preventDefault();
|
||
|
if (focusIndex == null) {
|
||
|
elementToFocus = allSuggestItems[0];
|
||
|
} else {
|
||
|
if (focusIndex < allSuggestItems.length - 3) {
|
||
|
elementToFocus = allSuggestItems[focusIndex + 3];
|
||
|
} else {
|
||
|
elementToFocus = _currentInputOptions.input;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
// right
|
||
|
if (event.keyCode == 39 && document.activeElement != _currentInputOptions.input) {
|
||
|
event.preventDefault();
|
||
|
if (focusIndex == null) {
|
||
|
elementToFocus = allSuggestItems[0];
|
||
|
} else {
|
||
|
if (focusIndex >= 0 && focusIndex < allSuggestItems.length - 1) {
|
||
|
elementToFocus = allSuggestItems[focusIndex + 1];
|
||
|
} else {
|
||
|
elementToFocus = _currentInputOptions.input;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
// left
|
||
|
if (event.keyCode == 37 && document.activeElement != _currentInputOptions.input) {
|
||
|
event.preventDefault();
|
||
|
if (focusIndex == null) {
|
||
|
elementToFocus = allSuggestItems[allSuggestItems.length - 1];
|
||
|
} else {
|
||
|
if (focusIndex > 0 && focusIndex <= allSuggestItems.length - 1) {
|
||
|
elementToFocus = allSuggestItems[focusIndex - 1];
|
||
|
} else {
|
||
|
elementToFocus = _currentInputOptions.input;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
// tab
|
||
|
if (!event.shiftKey && event.keyCode == 9 && document.activeElement == _currentInputOptions.input) {
|
||
|
event.preventDefault();
|
||
|
elementToFocus = allSuggestItems[0];
|
||
|
};
|
||
|
if (!event.shiftKey && event.keyCode == 9 && document.activeElement == allSuggestItems[allSuggestItems.length - 1]) {
|
||
|
event.preventDefault();
|
||
|
elementToFocus = _currentInputOptions.postFocus;
|
||
|
destroy();
|
||
|
};
|
||
|
// shift tab
|
||
|
if (event.shiftKey && event.keyCode == 9 && document.activeElement == allSuggestItems[0]) {
|
||
|
event.preventDefault();
|
||
|
elementToFocus = _currentInputOptions.input;
|
||
|
};
|
||
|
if (event.shiftKey && event.keyCode == 9 && document.activeElement == _currentInputOptions.input) {
|
||
|
destroy();
|
||
|
};
|
||
|
};
|
||
|
_findInput();
|
||
|
_findFocus();
|
||
|
_keyEvents();
|
||
|
if (elementToFocus) {
|
||
|
elementToFocus.focus();
|
||
|
};
|
||
|
};
|
||
|
|
||
|
var _addDocumentEvent = function() {
|
||
|
document.addEventListener("click", _checkClick, false);
|
||
|
document.addEventListener("keydown", _navigateResults, false);
|
||
|
};
|
||
|
|
||
|
var _removeDocumentEvent = function() {
|
||
|
document.removeEventListener("click", _checkClick, false);
|
||
|
document.removeEventListener("keydown", _navigateResults, false);
|
||
|
};
|
||
|
|
||
|
var _checkClick = function(event) {
|
||
|
if (!(event.target.classList.contains("auto-suggest-list")) && !(event.target.classList.contains("auto-suggest-input"))) {
|
||
|
destroy();
|
||
|
};
|
||
|
};
|
||
|
|
||
|
var destroy = function() {
|
||
|
var autoSuggestList = helper.e(".auto-suggest-list");
|
||
|
if (autoSuggestList) {
|
||
|
autoSuggestList.remove();
|
||
|
_removeDocumentEvent();
|
||
|
helper.setObject({
|
||
|
object: state.get(),
|
||
|
path: "autoSuggest",
|
||
|
newValue: false
|
||
|
});
|
||
|
_currentInputOptions = {};
|
||
|
_autoSuggestActive = false;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
var _getSuggestItems = function() {
|
||
|
var searchTerm = _currentInputOptions.input.value.replace(/^\s+/, "").replace(/\s+$/, "").toLowerCase();
|
||
|
var action = {
|
||
|
fontawesomeIcon: function() {
|
||
|
if (searchTerm == "" || searchTerm == undefined) {
|
||
|
return fontawesome.icons;
|
||
|
} else {
|
||
|
return fontawesome.icons.filter(function(item) {
|
||
|
var match = false;
|
||
|
if (item.name.toLowerCase().includes(searchTerm) || item.label.toLowerCase().includes(searchTerm)) {
|
||
|
match = true;
|
||
|
};
|
||
|
item.search.forEach(function(item, index) {
|
||
|
if (item.toLowerCase().includes(searchTerm)) {
|
||
|
match = true;
|
||
|
};
|
||
|
});
|
||
|
item.styles.forEach(function(item, index) {
|
||
|
if (item.toLowerCase().includes(searchTerm)) {
|
||
|
match = true;
|
||
|
};
|
||
|
});
|
||
|
return match;
|
||
|
});
|
||
|
};
|
||
|
}
|
||
|
};
|
||
|
return action[_currentInputOptions.type]();
|
||
|
};
|
||
|
|
||
|
var render = function(options) {
|
||
|
_currentInputOptions = options;
|
||
|
var body = helper.e("body");
|
||
|
var suggestItems = _getSuggestItems(options);
|
||
|
var _populateList = function(list) {
|
||
|
var action = {
|
||
|
fontawesomeIcon: function() {
|
||
|
suggestItems.forEach(function(arrayItem) {
|
||
|
var li = helper.node("li|class:auto-suggest-list-item");
|
||
|
var anchor = helper.node("a|href:#,tabindex:1,class:auto-suggest-link");
|
||
|
var icon = helper.node("span|class:auto-suggest-icon fa-" + arrayItem.name);
|
||
|
if (arrayItem.styles.includes("solid")) {
|
||
|
helper.addClass(icon, "fas");
|
||
|
} else if (arrayItem.styles.includes("brands")) {
|
||
|
helper.addClass(icon, "fab");
|
||
|
};
|
||
|
anchor.addEventListener("click", function() {
|
||
|
link.autoSuggestIconAction(arrayItem);
|
||
|
}, false);
|
||
|
var text = helper.node("span:" + arrayItem.label + "|class:auto-suggest-icon-text");
|
||
|
anchor.appendChild(icon);
|
||
|
anchor.appendChild(text);
|
||
|
li.appendChild(anchor);
|
||
|
list.appendChild(li);
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
action[_currentInputOptions.type]();
|
||
|
};
|
||
|
|
||
|
var _render_autoSuggestList = function() {
|
||
|
var autoSuggestWrapper = helper.e(".auto-suggest-wrapper");
|
||
|
var autoSuggestList = helper.e(".auto-suggest-list");
|
||
|
if (autoSuggestList) {
|
||
|
while (autoSuggestList.lastChild) {
|
||
|
autoSuggestList.removeChild(autoSuggestList.lastChild);
|
||
|
};
|
||
|
} else {
|
||
|
var style = {
|
||
|
left: autoSuggestWrapper.getBoundingClientRect().left,
|
||
|
top: autoSuggestWrapper.getBoundingClientRect().bottom + window.scrollY,
|
||
|
width: autoSuggestWrapper.getBoundingClientRect().width
|
||
|
};
|
||
|
var autoSuggestList = helper.node("ul|class:auto-suggest-list list-unstyled");
|
||
|
body.appendChild(autoSuggestList);
|
||
|
autoSuggestList.setAttribute("style", "width: " + style.width + "px; top: " + style.top + "px; left: " + style.left + "px;");
|
||
|
_addDocumentEvent();
|
||
|
};
|
||
|
_populateList(autoSuggestList);
|
||
|
};
|
||
|
if (suggestItems.length > 0) {
|
||
|
_autoSuggestActive = true;
|
||
|
helper.setObject({
|
||
|
object: state.get(),
|
||
|
path: "autoSuggest",
|
||
|
newValue: true
|
||
|
});
|
||
|
_render_autoSuggestList();
|
||
|
} else {
|
||
|
destroy();
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// exposed methods
|
||
|
return {
|
||
|
bind: bind,
|
||
|
destroy: destroy
|
||
|
};
|
||
|
|
||
|
})();
|