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 = `
+ `;
+
// --- 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
}
/**