mirror of
https://github.com/koloml/furbooru-tagging-assistant.git
synced 2025-12-23 23:02:58 +00:00
Fixed autocomplete popup duplication
This commit is contained in:
@@ -13,6 +13,8 @@ export class SearchWrapper extends BaseComponent {
|
||||
#arePropertiesSuggestionsEnabled = false;
|
||||
/** @type {"start"|"end"} */
|
||||
#propertiesSuggestionsPosition = "start";
|
||||
/** @type {HTMLElement|null} */
|
||||
#cachedAutocompleteContainer = null;
|
||||
|
||||
build() {
|
||||
this.#searchField = this.container.querySelector('input[name=q]');
|
||||
@@ -113,6 +115,24 @@ export class SearchWrapper extends BaseComponent {
|
||||
return searchValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the autocomplete container from the document. Once resolved, it can be safely reused without breaking
|
||||
* anything. Assuming refactored autocomplete handler is still implemented the way it is.
|
||||
*
|
||||
* This means, that properties will only be suggested once actual autocomplete logic was activated.
|
||||
*
|
||||
* @return {HTMLElement|null} Resolved element or nothing.
|
||||
*/
|
||||
#resolveAutocompleteContainer() {
|
||||
if (this.#cachedAutocompleteContainer) {
|
||||
return this.#cachedAutocompleteContainer;
|
||||
}
|
||||
|
||||
this.#cachedAutocompleteContainer = document.querySelector('.autocomplete');
|
||||
|
||||
return this.#cachedAutocompleteContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the list of suggestions into the existing popup or create and populate a new one.
|
||||
* @param {string[]} suggestions List of suggestion to render the popup from.
|
||||
@@ -124,9 +144,21 @@ export class SearchWrapper extends BaseComponent {
|
||||
.map(suggestedTerm => SearchWrapper.#renderTermSuggestion(suggestedTerm));
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
const autocompleteContainer = document.querySelector('.autocomplete') ?? SearchWrapper.#renderAutocompleteContainer();
|
||||
const autocompleteContainer = this.#resolveAutocompleteContainer();
|
||||
|
||||
for (let existingTerm of autocompleteContainer.querySelectorAll('.autocomplete__item--property')) {
|
||||
if (!autocompleteContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Since the autocomplete popup was refactored to re-use the same element over and over again, we need to remove
|
||||
// the options from the popup manually when autocomplete was removed from the DOM, since site is not doing that.
|
||||
const termsToRemove = autocompleteContainer.isConnected
|
||||
// Only removing properties when element is still connected to the DOM (popup is used by the website)
|
||||
? autocompleteContainer.querySelectorAll('.autocomplete__item--property')
|
||||
// Remove everything if popup was disconnected from the DOM.
|
||||
: autocompleteContainer.querySelectorAll('.autocomplete__item')
|
||||
|
||||
for (let existingTerm of termsToRemove) {
|
||||
existingTerm.remove();
|
||||
}
|
||||
|
||||
@@ -239,23 +271,6 @@ export class SearchWrapper extends BaseComponent {
|
||||
return suggestionsList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a new autocomplete container similar to the one generated by website. Might be sensitive to the updates
|
||||
* made to the Philomena.
|
||||
* @return {HTMLElement}
|
||||
*/
|
||||
static #renderAutocompleteContainer() {
|
||||
const autocompleteContainer = document.createElement('div');
|
||||
autocompleteContainer.className = 'autocomplete';
|
||||
|
||||
const innerListContainer = document.createElement('ul');
|
||||
innerListContainer.className = 'autocomplete__list';
|
||||
|
||||
autocompleteContainer.append(innerListContainer);
|
||||
|
||||
return autocompleteContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a single suggestion item and connect required events to interact with the user.
|
||||
* @param {string} suggestedTerm Term to use for suggestion item.
|
||||
|
||||
Reference in New Issue
Block a user