From 421112eb41af517463fdfccc5f91bca8921e3f86 Mon Sep 17 00:00:00 2001 From: newtextdoc1111 Date: Mon, 19 May 2025 12:21:33 +0900 Subject: [PATCH] feat: Refactor tag source handling and enhance UI with icon support for autocomplete suggestions --- web/css/autocomplete-plus.css | 191 +++++++++++++++++++++++----------- web/js/autocomplete.js | 39 ++++--- web/js/data.js | 55 +++++----- web/js/main.js | 39 ++++--- web/js/related-tags.js | 39 +++++-- web/js/settings.js | 7 +- web/js/utils.js | 33 +++++- 7 files changed, 276 insertions(+), 127 deletions(-) diff --git a/web/css/autocomplete-plus.css b/web/css/autocomplete-plus.css index 0432f28..29b52b8 100644 --- a/web/css/autocomplete-plus.css +++ b/web/css/autocomplete-plus.css @@ -1,39 +1,29 @@ /* Light Theme */ body { - --autocomplete-plus-text-color-cat-general: var(--p-blue-600); - --autocomplete-plus-text-color-cat-artist: var(--p-red-600); - --autocomplete-plus-text-color-cat-copyright: var(--p-purple-600); - --autocomplete-plus-text-color-cat-character: var(--p-green-600); - --autocomplete-plus-text-color-cat-meta: var(--p-yellow-600); - --autocomplete-plus-text-color-cat-unknown: var(--p-gray-600); + --autocomplete-plus-text-color-cat-blue: var(--p-blue-600); + --autocomplete-plus-text-color-cat-red: var(--p-red-600); + --autocomplete-plus-text-color-cat-purple: var(--p-purple-600); + --autocomplete-plus-text-color-cat-green: var(--p-green-600); + --autocomplete-plus-text-color-cat-yellow: var(--p-yellow-600); + --autocomplete-plus-text-color-cat-gray: var(--p-gray-600); + --autocomplete-plus-text-color-cat-sky: var(--p-sky-500); + --autocomplete-plus-text-color-cat-orange: var(--p-orange-600); + --autocomplete-plus-text-color-cat-white: var(--p-neutral-700); --autocomplete-plus-text-color-disabled: var(--p-gray-400); - - /* Selected color */ - --autocomplete-plus-text-color-cat-general-selected: var(--p-blue-200); - --autocomplete-plus-text-color-cat-artist-selected: var(--p-red-200); - --autocomplete-plus-text-color-cat-copyright-selected: var(--p-purple-200); - --autocomplete-plus-text-color-cat-character-selected: var(--p-green-200); - --autocomplete-plus-text-color-cat-meta-selected: var(--p-yellow-200); - --autocomplete-plus-text-color-cat-unknown-selected: var(--p-gray-200); } /* Dark Theme */ body.dark-theme { - --autocomplete-plus-text-color-cat-general: var(--p-blue-400); - --autocomplete-plus-text-color-cat-artist: var(--p-red-400); - --autocomplete-plus-text-color-cat-copyright: var(--p-purple-400); - --autocomplete-plus-text-color-cat-character: var(--p-green-400); - --autocomplete-plus-text-color-cat-meta: var(--p-yellow-400); - --autocomplete-plus-text-color-cat-unknown: var(--p-gray-500); + --autocomplete-plus-text-color-cat-blue: var(--p-blue-400); + --autocomplete-plus-text-color-cat-red: var(--p-red-400); + --autocomplete-plus-text-color-cat-purple: var(--p-purple-400); + --autocomplete-plus-text-color-cat-green: var(--p-green-400); + --autocomplete-plus-text-color-cat-yellow: var(--p-yellow-400); + --autocomplete-plus-text-color-cat-gray: var(--p-gray-400); + --autocomplete-plus-text-color-cat-sky: var(--p-sky-300); + --autocomplete-plus-text-color-cat-orange: var(--p-orange-400); + --autocomplete-plus-text-color-cat-white: var(--p-neutral-200); --autocomplete-plus-text-color-disabled: var(--p-gray-500); - - /* Selected color */ - --autocomplete-plus-text-color-cat-general-selected: var(--p-blue-200); - --autocomplete-plus-text-color-cat-artist-selected: var(--p-red-200); - --autocomplete-plus-text-color-cat-copyright-selected: var(--p-purple-200); - --autocomplete-plus-text-color-cat-character-selected: var(--p-green-200); - --autocomplete-plus-text-color-cat-meta-selected: var(--p-yellow-200); - --autocomplete-plus-text-color-cat-unknown-selected: var(--p-gray-200); } #autocomplete-plus-root { @@ -62,28 +52,60 @@ body.dark-theme { grid-template-columns: subgrid; } -.autocomplete-plus-item[data-tag-category="general"] { - color: var(--autocomplete-plus-text-color-cat-general); +.autocomplete-plus-item.danbooru[data-tag-category="general"] { + color: var(--autocomplete-plus-text-color-cat-blue); } -.autocomplete-plus-item[data-tag-category="artist"] { - color: var(--autocomplete-plus-text-color-cat-artist); +.autocomplete-plus-item.danbooru[data-tag-category="artist"] { + color: var(--autocomplete-plus-text-color-cat-red); } -.autocomplete-plus-item[data-tag-category="copyright"] { - color: var(--autocomplete-plus-text-color-cat-copyright); +.autocomplete-plus-item.danbooru[data-tag-category="copyright"] { + color: var(--autocomplete-plus-text-color-cat-purple); } -.autocomplete-plus-item[data-tag-category="character"] { - color: var(--autocomplete-plus-text-color-cat-character); +.autocomplete-plus-item.danbooru[data-tag-category="character"] { + color: var(--autocomplete-plus-text-color-cat-green); } -.autocomplete-plus-item[data-tag-category="meta"] { - color: var(--autocomplete-plus-text-color-cat-meta); +.autocomplete-plus-item.danbooru[data-tag-category="meta"] { + color: var(--autocomplete-plus-text-color-cat-yellow); } -.autocomplete-plus-item[data-tag-category="unknown"] { - color: var(--autocomplete-plus-text-color-cat-unknown); +.autocomplete-plus-item.danbooru[data-tag-category="unknown"] { + color: var(--autocomplete-plus-text-color-cat-gray); +} + +.autocomplete-plus-item.e621[data-tag-category="general"] { + color: var(--autocomplete-plus-text-color-cat-sky); +} + +.autocomplete-plus-item.e621[data-tag-category="artist"] { + color: var(--autocomplete-plus-text-color-cat-orange); +} + +.autocomplete-plus-item.e621[data-tag-category="copyright"] { + color: var(--autocomplete-plus-text-color-cat-purple); +} + +.autocomplete-plus-item.e621[data-tag-category="character"] { + color: var(--autocomplete-plus-text-color-cat-green); +} + +.autocomplete-plus-item.e621[data-tag-category="species"] { + color: var(--autocomplete-plus-text-color-cat-red); +} + +.autocomplete-plus-item.e621[data-tag-category="meta"] { + color: var(--autocomplete-plus-text-color-cat-white); +} + +.autocomplete-plus-item.e621[data-tag-category="lore"] { + color: var(--autocomplete-plus-text-color-cat-red); +} + +.autocomplete-plus-item.e621[data-tag-category="unknown"] { + color: var(--autocomplete-plus-text-color-cat-purple); } .autocomplete-plus-item span { @@ -113,22 +135,31 @@ body.dark-theme { background-color: var(--comfy-hover-bg); } -.autocomplete-plus-tag-name { - padding: 8px; +.autocomplete-plus-item .autocomplete-plus-tag-name { white-space: nowrap; } +.autocomplete-plus-item .autocomplete-plus-tag-icon-svg { + width: 1em; + height: 1em; + vertical-align: middle; +} + .autocomplete-plus-tag-name.autocomplete-plus-already-exists { color: var(--autocomplete-plus-text-color-disabled); } -.autocomplete-plus-alias { +.autocomplete-plus-item .autocomplete-plus-alias { overflow: hidden; color: var(--descrip-text); text-overflow: ellipsis; white-space: nowrap; } +.autocomplete-plus-item .autocomplete-plus-tag-count { + text-align: right; +} + /* Related Tags UI Styles */ #related-tags-root { position: absolute; @@ -163,9 +194,16 @@ body.dark-theme { font-weight: bold; } +.related-tags-header-tag-name .autocomplete-plus-tag-icon-svg { + width: 1em; + height: 1em; + vertical-align: middle; +} + .related-tags-header-controls { display: flex; align-items: center; + margin-left: 16px; gap: 4px; } @@ -210,28 +248,60 @@ body.dark-theme { grid-template-columns: subgrid; } -.related-tag-item[data-tag-category="general"] { - color: var(--autocomplete-plus-text-color-cat-general); +.related-tag-item.danbooru[data-tag-category="general"] { + color: var(--autocomplete-plus-text-color-cat-blue); } -.related-tag-item[data-tag-category="artist"] { - color: var(--autocomplete-plus-text-color-cat-artist); +.related-tag-item.danbooru[data-tag-category="artist"] { + color: var(--autocomplete-plus-text-color-cat-red); } -.related-tag-item[data-tag-category="copyright"] { - color: var(--autocomplete-plus-text-color-cat-copyright); +.related-tag-item.danbooru[data-tag-category="copyright"] { + color: var(--autocomplete-plus-text-color-cat-purple); } -.related-tag-item[data-tag-category="character"] { - color: var(--autocomplete-plus-text-color-cat-character); +.related-tag-item.danbooru[data-tag-category="character"] { + color: var(--autocomplete-plus-text-color-cat-green); } -.related-tag-item[data-tag-category="meta"] { - color: var(--autocomplete-plus-text-color-cat-meta); +.related-tag-item.danbooru[data-tag-category="meta"] { + color: var(--autocomplete-plus-text-color-cat-yellow); } -.related-tag-item[data-tag-category="unknown"] { - color: var(--autocomplete-plus-text-color-cat-unknown); +.related-tag-item.danbooru[data-tag-category="unknown"] { + color: var(--autocomplete-plus-text-color-cat-gray); +} + +.related-tag-item.e621[data-tag-category="general"] { + color: var(--autocomplete-plus-text-color-cat-sky); +} + +.related-tag-item.e621[data-tag-category="artist"] { + color: var(--autocomplete-plus-text-color-cat-orange); +} + +.related-tag-item.e621[data-tag-category="copyright"] { + color: var(--autocomplete-plus-text-color-cat-purple); +} + +.related-tag-item.e621[data-tag-category="character"] { + color: var(--autocomplete-plus-text-color-cat-green); +} + +.related-tag-item.e621[data-tag-category="species"] { + color: var(--autocomplete-plus-text-color-cat-red); +} + +.related-tag-item.e621[data-tag-category="meta"] { + color: var(--autocomplete-plus-text-color-cat-white); +} + +.related-tag-item.e621[data-tag-category="lore"] { + color: var(--autocomplete-plus-text-color-cat-red); +} + +.related-tag-item.e621[data-tag-category="unknown"] { + color: var(--autocomplete-plus-text-color-cat-gray); } /* stylelint-disable-next-line no-descending-specificity */ @@ -261,23 +331,22 @@ body.dark-theme { font-weight: bold; } -.related-tag-name { - padding: 8px; +.related-tag-item .related-tag-name { white-space: nowrap; } -.related-tag-name.related-tag-already-exists { +.related-tag-item .related-tag-name.related-tag-already-exists { color: var(--autocomplete-plus-text-color-disabled); } -.related-tag-alias { +.related-tag-item .related-tag-alias { overflow: hidden; color: var(--descrip-text); text-overflow: ellipsis; white-space: nowrap; } -.related-tag-similarity { +.related-tag-item .related-tag-similarity { color: var(--descrip-text); text-align: right; white-space: nowrap; @@ -294,4 +363,4 @@ body.dark-theme { color: var(--error-text); font-style: italic; text-align: center; -} +} \ No newline at end of file diff --git a/web/js/autocomplete.js b/web/js/autocomplete.js index 6750f33..d0456e1 100644 --- a/web/js/autocomplete.js +++ b/web/js/autocomplete.js @@ -1,8 +1,8 @@ import { - DanbooruTagCategory, + TagCategory, TagData, autoCompleteData, - getTagSourceInPriorityOrder + getEnabledTagSourceInPriorityOrder } from './data.js'; import { formatCountHumanReadable, @@ -13,7 +13,8 @@ import { normalizeTagToSearch, extractTagsFromTextArea, getCurrentTagRange, - getViewportMargin + getViewportMargin, + IconSvgHtmlString } from './utils.js'; import { settingValues } from './settings.js'; @@ -100,7 +101,7 @@ function searchCompletionCandidates(textareaElement) { queryVariations.add(hiraQuery); } - const sources = getTagSourceInPriorityOrder(); + const sources = getEnabledTagSourceInPriorityOrder(); for (const source of sources) { // Search in sortedTags (already sorted by count) for (const tagData of autoCompleteData[source].sortedTags) { @@ -274,6 +275,13 @@ class AutocompleteUI { this.root = document.createElement('div'); // Use table instead of div this.root.id = 'autocomplete-plus-root'; + // Create svg icon element as definition + this.iconSvgDef = document.createElement('div'); + this.iconSvgDef.style.position = 'absolute'; + this.iconSvgDef.style.display = 'none'; + this.iconSvgDef.innerHTML = IconSvgHtmlString; + this.root.appendChild(this.iconSvgDef); + this.tagsList = document.createElement('div'); this.tagsList.id = 'autocomplete-plus-list'; this.root.appendChild(this.tagsList); @@ -388,17 +396,24 @@ class AutocompleteUI { * @param {boolean} isExisting */ #createTagElement(tagData, isExisting) { - const categoryText = DanbooruTagCategory[tagData.category] || "unknown"; + const categoryText = TagCategory[tagData.source][tagData.category] || "unknown"; const tagRow = document.createElement('div'); - tagRow.classList.add('autocomplete-plus-item'); + tagRow.classList.add('autocomplete-plus-item', tagData.source); tagRow.dataset.tag = tagData.tag; tagRow.dataset.tagCategory = categoryText; - // Tag name + // Tag icon and name + const tagSourceIconHtml = ``; const tagName = document.createElement('span'); - tagName.classList.add('autocomplete-plus-tag-name'); - tagName.textContent = `[${tagData.source[0]}] ${tagData.tag}`; + tagName.className = 'autocomplete-plus-tag-name'; + if (settingValues.tagSourceIconPosition == 'hidden') { + tagName.textContent = tagData.tag; + } else { + tagName.innerHTML = settingValues.tagSourceIconPosition == 'left' + ? `${tagSourceIconHtml} ${tagData.tag}` + : `${tagData.tag} ${tagSourceIconHtml}`; + } // grayout tag name if it already exists if (isExisting) { @@ -407,7 +422,7 @@ class AutocompleteUI { // Alias const alias = document.createElement('span'); - alias.classList.add('autocomplete-plus-alias'); + alias.className = 'autocomplete-plus-alias'; // Display alias if available if (tagData.alias && tagData.alias.length > 0) { @@ -420,10 +435,11 @@ class AutocompleteUI { const category = document.createElement('span'); category.className = `autocomplete-plus-category`; category.textContent = `${categoryText.substring(0, 2)}`; + category.title = categoryText; // Full category on hover // Count const tagCount = document.createElement('span'); - category.className = `autocomplete-plus-tag-count`; + tagCount.className = `autocomplete-plus-tag-count`; tagCount.textContent = formatCountHumanReadable(tagData.count); tagRow.appendChild(tagName); @@ -458,7 +474,6 @@ class AutocompleteUI { const viewportHeight = window.innerHeight; const margin = getViewportMargin(); - const targetRect = this.target.getBoundingClientRect(); const targetElmOffset = this.#calculateElementOffset(this.target); const { top: caretTop, left: caretLeft, lineHeight: caretLineHeight } = this.#getCaretCoordinates(this.target); diff --git a/web/js/data.js b/web/js/data.js index 49d749d..6e85c8f 100644 --- a/web/js/data.js +++ b/web/js/data.js @@ -8,27 +8,27 @@ export const TagSource = { E621: 'e621', } -// Danbooru tag categories for display -export const DanbooruTagCategory = [ - 'general', - 'artist', - 'unused', - 'copyright', - 'character', - 'meta', -] - -export const E621TagCategory = [ - 'general', - 'artist', - 'unused', - 'copyright', - 'character', - 'species', - 'invalid', - 'meta', - 'lore', -] +export const TagCategory = { + 'danbooru': [ + 'general', + 'artist', + 'unused', + 'copyright', + 'character', + 'meta', + ], + 'e621': [ + 'general', + 'artist', + 'unused', + 'copyright', + 'character', + 'species', + 'invalid', + 'meta', + 'lore', + ] +} // --- Data Structures --- @@ -102,10 +102,17 @@ const COUNT_INDEX = TAGS_CSV_HEADER_COLUMNS.indexOf('count'); // --- Helder Functions --- /** - * + * Get the available tag sources in priority order based on the current settings. + * @returns {string[]} Array of available tag sources in priority order */ -export function getTagSourceInPriorityOrder() { - return Object.values(TagSource).toSorted((a, b) => { return a === settingValues.priorityTagSource ? -1 : 1; }); +export function getEnabledTagSourceInPriorityOrder() { + return Object.values(TagSource) + .filter((s) => { + return settingValues.tagSource === s || settingValues.tagSource === 'all'; + }) + .toSorted((a, b) => { + return a === settingValues.primaryTagSource ? -1 : 1; + }); } // --- Data Loading Functions --- diff --git a/web/js/main.js b/web/js/main.js index abbbd21..ead0f80 100644 --- a/web/js/main.js +++ b/web/js/main.js @@ -2,7 +2,7 @@ import { app } from "/scripts/app.js"; import { ComfyWidgets } from "/scripts/widgets.js"; import { settingValues } from "./settings.js"; import { loadCSS } from "./utils.js"; -import { TagSource, fetchCsvList, getTagSourceInPriorityOrder, initializeData } from "./data.js"; +import { TagSource, fetchCsvList, initializeData } from "./data.js"; import { AutocompleteEventHandler } from "./autocomplete.js"; import { RelatedTagsEventHandler } from "./related-tags.js"; @@ -133,7 +133,7 @@ app.registerExtension({ loadCSS(rootPath + "css/autocomplete-plus.css"); // Load CSS for autocomplete fetchCsvList().then((csvList) => { - getTagSourceInPriorityOrder().forEach((source) => { + Object.values(TagSource).forEach((source) => { initializeData(csvList, source); }); }); @@ -141,29 +141,40 @@ app.registerExtension({ // One the Settings Screen, displays reverse order in same category settings: [ - // --- General Settings --- + // --- Tag source Settings --- { - id: id + ".priority_tag_source", - name: "Priotized Tag Source", - tooltip: "If all tag source are enabled, which tag source's tags should be displayed first.", + id: id + ".tag_source_icon_position", + name: "Tag Source Icon Position", + type: "combo", + options: ["left", "right", "hidden"], + defaultValue: "left", + category: [name, "Tag Source", "Tag Source Icon Position"], + onChange: (newVal, oldVal) => { + settingValues.tagSourceIconPosition = newVal; + } + }, + { + id: id + ".primary_tag_source", + name: "Primary source for 'all' Source", + tooltip: "When 'Autocomplete Tag Source' is 'all', this determines which source's tags appear first in suggestions.", type: "combo", options: Object.values(TagSource), defaultValue: TagSource.Danbooru, - category: [name, "General", "Priority Tag Source"], + category: [name, "Tag Source", "Prioritize Tag Source"], onChange: (newVal, oldVal) => { - settingValues.priorityTagSource = newVal; + settingValues.primaryTagSource = newVal; } }, - { - id: id + ".display_tag_source", - name: "Display Tag Source", - tooltip: "If multiple tag source are avirable, which tag source's tags should be displayed.", + { + id: id + ".tag_source", + name: "Autocomplete Tag Source", + tooltip: "Select the tag source for autocomplete suggestions. 'all' includes tags from all loaded sources.", type: "combo", options: [...Object.values(TagSource), "all"], defaultValue: "all", - category: [name, "General", "Display Tag Source"], + category: [name, "Tag Source", "Tag Source"], onChange: (newVal, oldVal) => { - settingValues.displayTagSource = newVal; + settingValues.tagSource = newVal; } }, // --- Autocomplete Settings --- diff --git a/web/js/related-tags.js b/web/js/related-tags.js index 67e4d2f..22a4d0c 100644 --- a/web/js/related-tags.js +++ b/web/js/related-tags.js @@ -1,4 +1,4 @@ -import { TagSource, DanbooruTagCategory, TagData, autoCompleteData, getTagSourceInPriorityOrder } from './data.js'; +import { TagSource, TagCategory, TagData, autoCompleteData } from './data.js'; import { settingValues } from './settings.js'; import { extractTagsFromTextArea, @@ -7,7 +7,7 @@ import { isValidTag, normalizeTagToInsert, normalizeTagToSearch, - getCurrentTagRange + getCurrentTagRange, } from './utils.js'; // --- RelatedTags Logic --- @@ -91,6 +91,7 @@ function searchRelatedTags(tag) { similarity: similarity, alias: tagData.alias, category: tagData.category, + source: tagData.source, count: tagData.count, }); }); @@ -387,13 +388,29 @@ class RelatedTagsUI { * Updates header content */ #updateHeader() { + // Find the tag data for the current tag + const tagData = Object.values(TagSource) + .map((source) => { + if (source in autoCompleteData && autoCompleteData[source].tagMap.has(this.currentTag)) { + return autoCompleteData[source].tagMap.get(this.currentTag); + } + }) + .find((tagData) => tagData !== undefined); + // Update header text with current tag this.headerText.innerHTML = ''; // Clear previous content this.headerText.textContent = 'Tags related to: '; - const tagNameSpan = document.createElement('span'); - tagNameSpan.className = 'related-tags-header-tag-name'; - tagNameSpan.textContent = this.currentTag; - this.headerText.appendChild(tagNameSpan); + const tagName = document.createElement('span'); + tagName.className = 'related-tags-header-tag-name'; + tagName.textContent = this.currentTag; + if (tagData && ['left', 'right'].includes(settingValues.tagSourceIconPosition)) { + const tagSourceIconHtml = ``; + tagName.innerHTML = settingValues.tagSourceIconPosition == 'left' + ? `${tagSourceIconHtml} ${tagData.tag}` + : `${tagData.tag} ${tagSourceIconHtml}`; + } + + this.headerText.appendChild(tagName); // Update pin button this.pinBtn.textContent = this.isPinned ? '🎯' : '📌'; @@ -421,9 +438,9 @@ class RelatedTagsUI { if (!this.relatedTags || this.relatedTags.length === 0) { // Show no related tags message - const messageCell = document.createElement('div'); - messageCell.textContent = 'No related tags found'; - this.tagsContainer.appendChild(messageCell); + const messageDiv = document.createElement('div'); + messageDiv.textContent = 'No related tags found'; + this.tagsContainer.appendChild(messageDiv); return; } @@ -444,10 +461,10 @@ class RelatedTagsUI { * @returns {HTMLTableRowElement} The tag row element */ #createTagElement(tagData, isExisting) { - const categoryText = DanbooruTagCategory[tagData.category] || "unknown"; + const categoryText = TagCategory[tagData.source][tagData.category] || "unknown"; const tagRow = document.createElement('div'); - tagRow.className = 'related-tag-item'; + tagRow.classList.add('related-tag-item', tagData.source); tagRow.dataset.tag = tagData.tag; tagRow.dataset.tagCategory = categoryText; diff --git a/web/js/settings.js b/web/js/settings.js index cdb59b3..6b93e98 100644 --- a/web/js/settings.js +++ b/web/js/settings.js @@ -1,7 +1,8 @@ export const settingValues = { - // General settings - displayTagSource: 'danbooru', // 'danbooru', 'e621', 'all' - priorityTagSource: 'danbooru', // 'danbooru', 'e621', + // Tag source settings + tagSource: 'all', // 'danbooru', 'e621', 'all' + primaryTagSource: 'danbooru', // 'danbooru', 'e621' + tagSourceIconPosition: 'left', // 'left', 'right', 'hidden' // Autocomplete feature settings enabled: true, diff --git a/web/js/utils.js b/web/js/utils.js index 056ff81..ac0246d 100644 --- a/web/js/utils.js +++ b/web/js/utils.js @@ -1,3 +1,29 @@ +// --- Html String constants --- + +/** + * HTML string for the tag source icon. + */ +export const IconSvgHtmlString = ` + + + + + + + + + + + + e + + + + `; + // --- String Helper Functions --- const MAX_PROMPT_WEIGHT_VALUE = 9.9; @@ -491,7 +517,10 @@ export function getCurrentTagRange(text, cursorPos) { // --- End String Helper Functions --- -// Function to load a CSS file +/** + * Load a CSS file dynamically. + * @param {string} href + */ export function loadCSS(href) { const link = document.createElement('link'); link.rel = 'stylesheet'; @@ -500,7 +529,7 @@ export function loadCSS(href) { // Ensure the CSS is loaded before other scripts might rely on its styles // by adding it to the head. document.head.appendChild(link); - console.debug(`Loaded CSS: ${href}`); // Optional: Log loading + // console.debug(`[Autocomplete-Plus] Loaded CSS: ${href}`); // Optional: Log loading } /**