bookwyrm-mastodon/bookwyrm/static/js/autocomplete.js

112 lines
2.4 KiB
JavaScript
Raw Normal View History

2022-01-10 19:55:30 -05:00
(function () {
"use strict";
2021-12-27 15:41:27 -05:00
/**
* Suggest a completion as a user types
*
* Use `data-autocomplete="<completions set identifier>"`on the input field.
* specifying the trie to be used for autocomplete
*
* @example
* <input
* type="input"
* data-autocomplete="mimetype"
* >
* @param {Event} event
* @return {undefined}
*/
function autocomplete(event) {
const input = event.target;
// Get suggestions
let suggestions = getSuggestions(input.value, mimetypeTrie);
const boxId = input.getAttribute("list");
2021-12-27 15:41:27 -05:00
// Create suggestion box, if needed
let suggestionsBox = document.getElementById(boxId);
// Clear existing suggestions
suggestionsBox.innerHTML = "";
// Populate suggestions box
2022-01-10 19:55:30 -05:00
suggestions.forEach((suggestion) => {
const suggestionItem = document.createElement("option");
2021-12-27 15:41:27 -05:00
suggestionItem.textContent = suggestion;
suggestionsBox.appendChild(suggestionItem);
});
}
function getSuggestions(input, trie) {
// Follow the trie through the provided input
2022-01-10 19:55:30 -05:00
input.split("").forEach((letter) => {
2021-12-27 15:41:27 -05:00
trie = trie[letter];
if (!trie) {
return;
}
});
if (!trie) {
return [];
}
2022-01-10 19:44:43 -05:00
return searchTrie(trie);
2021-12-27 15:41:27 -05:00
}
2022-01-10 19:44:43 -05:00
function searchTrie(trie) {
const options = Object.values(trie);
2021-12-27 15:41:27 -05:00
2022-01-10 19:55:30 -05:00
if (typeof trie == "string") {
2022-01-10 19:53:30 -05:00
return [trie];
2021-12-27 15:41:27 -05:00
}
2022-01-10 19:55:30 -05:00
return options
.map((option) => {
const newTrie = option;
2021-12-27 15:41:27 -05:00
2022-01-10 19:55:30 -05:00
if (typeof newTrie == "string") {
return [newTrie];
}
2022-01-10 19:53:30 -05:00
2022-01-10 19:55:30 -05:00
return searchTrie(newTrie);
})
.reduce((prev, next) => prev.concat(next));
2021-12-27 15:41:27 -05:00
}
2022-01-10 19:55:30 -05:00
document.querySelectorAll("[data-autocomplete]").forEach((input) => {
input.addEventListener("input", autocomplete);
});
2021-12-27 15:41:27 -05:00
})();
const mimetypeTrie = {
2022-01-10 19:55:30 -05:00
a: {
a: {
c: "AAC",
},
z: {
w: "AZW",
2022-01-10 19:53:30 -05:00
},
},
2022-01-10 19:55:30 -05:00
d: "Daisy",
e: "ePub",
f: "FLAC",
h: "HTML",
m: {
4: {
a: "M4A",
b: "M4B",
2022-01-10 19:53:30 -05:00
},
2022-01-10 19:55:30 -05:00
o: "MOBI",
p: "MP3",
2022-01-10 19:53:30 -05:00
},
2022-01-10 19:55:30 -05:00
o: "OGG",
p: {
d: {
f: "PDF",
2021-12-27 15:41:27 -05:00
},
2022-01-10 19:55:30 -05:00
l: "Plaintext",
2022-01-10 19:44:43 -05:00
},
2021-12-27 15:41:27 -05:00
};