refactor: Rename similar tags to related tags and update related settings
This commit is contained in:
@@ -114,8 +114,8 @@ body.dark-theme {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Similar Tags UI Styles */
|
||||
#similar-tags-container {
|
||||
/* Related Tags UI Styles */
|
||||
#related-tags-container {
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
top: 0;
|
||||
@@ -127,7 +127,7 @@ body.dark-theme {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#similar-tags-header {
|
||||
#related-tags-header {
|
||||
position: sticky;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
@@ -137,89 +137,89 @@ body.dark-theme {
|
||||
color: var(--descrip-text);
|
||||
}
|
||||
|
||||
.similar-tags-header-tag-name {
|
||||
.related-tags-header-tag-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#similar-tags-list {
|
||||
#related-tags-list {
|
||||
display: grid;
|
||||
box-shadow: 0 2px 8px rgb(0 0 0 / 30%);
|
||||
grid-auto-rows: auto;
|
||||
grid-template-columns: max-content 1fr auto auto;
|
||||
}
|
||||
|
||||
.similar-tag-item {
|
||||
.related-tag-item {
|
||||
display: contents;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.similar-tag-item[data-tag-category="general"] {
|
||||
.related-tag-item[data-tag-category="general"] {
|
||||
color: var(--autocomplete-plus-text-color-cat-general);
|
||||
}
|
||||
|
||||
.similar-tag-item[data-tag-category="artist"] {
|
||||
.related-tag-item[data-tag-category="artist"] {
|
||||
color: var(--autocomplete-plus-text-color-cat-artist);
|
||||
}
|
||||
|
||||
.similar-tag-item[data-tag-category="copyright"] {
|
||||
.related-tag-item[data-tag-category="copyright"] {
|
||||
color: var(--autocomplete-plus-text-color-cat-copyright);
|
||||
}
|
||||
|
||||
.similar-tag-item[data-tag-category="character"] {
|
||||
.related-tag-item[data-tag-category="character"] {
|
||||
color: var(--autocomplete-plus-text-color-cat-character);
|
||||
}
|
||||
|
||||
.similar-tag-item[data-tag-category="meta"] {
|
||||
.related-tag-item[data-tag-category="meta"] {
|
||||
color: var(--autocomplete-plus-text-color-cat-meta);
|
||||
}
|
||||
|
||||
.similar-tag-item[data-tag-category="unknown"] {
|
||||
.related-tag-item[data-tag-category="unknown"] {
|
||||
color: var(--autocomplete-plus-text-color-cat-unknown);
|
||||
}
|
||||
|
||||
.similar-tag-item span {
|
||||
.related-tag-item span {
|
||||
align-content: center;
|
||||
padding: 4px 8px;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.similar-tag-item:nth-child(even) span {
|
||||
.related-tag-item:nth-child(even) span {
|
||||
background-color: var(--comfy-menu-bg);
|
||||
}
|
||||
|
||||
.similar-tag-item:nth-child(odd) span {
|
||||
.related-tag-item:nth-child(odd) span {
|
||||
background-color: var(--comfy-menu-secondary-bg);
|
||||
}
|
||||
|
||||
.similar-tag-item:hover span {
|
||||
.related-tag-item:hover span {
|
||||
background-color: var(--p-form-field-filled-hover-background);
|
||||
}
|
||||
|
||||
.similar-tag-name {
|
||||
.related-tag-name {
|
||||
padding: 8px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.similar-tag-alias {
|
||||
.related-tag-alias {
|
||||
overflow: hidden;
|
||||
color: var(--descrip-text);
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.similar-tag-similarity {
|
||||
.related-tag-relatedity {
|
||||
color: var(--descrip-text);
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.similar-tags-loading-message {
|
||||
.related-tags-loading-message {
|
||||
padding: 12px;
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.similar-tags-empty {
|
||||
.related-tags-empty {
|
||||
padding: 12px;
|
||||
color: var(--error-text);
|
||||
font-style: italic;
|
||||
|
||||
+30
-30
@@ -4,11 +4,11 @@ import { settingValues } from "./settings.js";
|
||||
import { loadCSS } from "./utils.js";
|
||||
import { loadAllData } from "./data.js";
|
||||
import { AutocompleteEventHandler } from "./autocomplete.js";
|
||||
import { SimilarTagsEventHandler } from "./similar-tags.js";
|
||||
import { RelatedTagsEventHandler } from "./related-tags.js";
|
||||
|
||||
function initializeEventHandlers() {
|
||||
const autocompleteEventHandler = new AutocompleteEventHandler();
|
||||
const similarTagsEventHandler = new SimilarTagsEventHandler();
|
||||
const relatedTagsEventHandler = new RelatedTagsEventHandler();
|
||||
const attachedElements = new WeakSet(); // Keep track of elements that have listeners attached
|
||||
|
||||
// Function to attach listeners
|
||||
@@ -22,7 +22,7 @@ function initializeEventHandlers() {
|
||||
element.addEventListener('keyup', handleKeyUp);
|
||||
element.addEventListener('keypress', handleKeyPress);
|
||||
|
||||
// Add new event listeners for similar tags feature
|
||||
// Add new event listeners for related tags feature
|
||||
element.addEventListener('mousemove', handleMouseMove);
|
||||
element.addEventListener('click', handleClick);
|
||||
|
||||
@@ -38,7 +38,7 @@ function initializeEventHandlers() {
|
||||
const result = originalStringWidget.apply(this, arguments);
|
||||
|
||||
// Check if the widget has an inputEl and if it's a TEXTAREA
|
||||
// This is to ensure we are targeting multiline text inputs, similar to '.comfy-multiline-input'
|
||||
// This is to ensure we are targeting multiline text inputs, related to '.comfy-multiline-input'
|
||||
if (result && result.widget && result.widget.inputEl && result.widget.inputEl.tagName === 'TEXTAREA') {
|
||||
const widgetConfig = inputData && inputData[1] ? inputData[1] : {};
|
||||
// Future: Add checks for Autocomplete Plus specific configurations if needed
|
||||
@@ -85,44 +85,44 @@ function initializeEventHandlers() {
|
||||
|
||||
function handleInput(event) {
|
||||
autocompleteEventHandler.handleInput(event);
|
||||
similarTagsEventHandler.handleInput(event);
|
||||
relatedTagsEventHandler.handleInput(event);
|
||||
}
|
||||
|
||||
function handleFocus(event) {
|
||||
autocompleteEventHandler.handleFocus(event);
|
||||
similarTagsEventHandler.handleFocus(event);
|
||||
relatedTagsEventHandler.handleFocus(event);
|
||||
}
|
||||
|
||||
function handleBlur(event) {
|
||||
autocompleteEventHandler.handleBlur(event);
|
||||
similarTagsEventHandler.handleBlur(event);
|
||||
relatedTagsEventHandler.handleBlur(event);
|
||||
}
|
||||
|
||||
function handleKeyDown(event) {
|
||||
autocompleteEventHandler.handleKeyDown(event);
|
||||
similarTagsEventHandler.handleKeyDown(event);
|
||||
relatedTagsEventHandler.handleKeyDown(event);
|
||||
}
|
||||
|
||||
function handleKeyUp(event) {
|
||||
autocompleteEventHandler.handleKeyUp(event);
|
||||
similarTagsEventHandler.handleKeyUp(event);
|
||||
relatedTagsEventHandler.handleKeyUp(event);
|
||||
}
|
||||
|
||||
function handleKeyPress(event) {
|
||||
autocompleteEventHandler.handleKeyPress(event);
|
||||
similarTagsEventHandler.handleKeyPress(event);
|
||||
relatedTagsEventHandler.handleKeyPress(event);
|
||||
}
|
||||
|
||||
// New event handler for mousemove to show similar tags on hover
|
||||
// New event handler for mousemove to show related tags on hover
|
||||
function handleMouseMove(event) {
|
||||
autocompleteEventHandler.handleMouseMove(event);
|
||||
similarTagsEventHandler.handleMouseMove(event);
|
||||
relatedTagsEventHandler.handleMouseMove(event);
|
||||
}
|
||||
|
||||
// New event handler for click to show similar tags
|
||||
// New event handler for click to show related tags
|
||||
function handleClick(event) {
|
||||
autocompleteEventHandler.handleClick(event);
|
||||
similarTagsEventHandler.handleClick(event);
|
||||
relatedTagsEventHandler.handleClick(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,22 +166,22 @@ app.registerExtension({
|
||||
settingValues.maxSuggestions = newVal;
|
||||
}
|
||||
},
|
||||
// Similar Tags Settings
|
||||
// Related Tags Settings
|
||||
{
|
||||
id: id + ".similar_tags_enable",
|
||||
name: "Enable Similar Tags",
|
||||
description: "Enable or disable the similar tags feature.",
|
||||
id: id + ".related_tags_enable",
|
||||
name: "Enable Related Tags",
|
||||
description: "Enable or disable the related tags feature.",
|
||||
type: "boolean",
|
||||
defaultValue: true,
|
||||
category: [name, "Similar Tags", "Enable Similar Tags"],
|
||||
category: [name, "Related Tags", "Enable Related Tags"],
|
||||
onChange: (newVal, oldVal) => {
|
||||
settingValues.enableSimilarTags = newVal;
|
||||
settingValues.enableRelatedTags = newVal;
|
||||
}
|
||||
},
|
||||
{
|
||||
id: id + ".max_similar_tags",
|
||||
name: "Max similar tags",
|
||||
description: "Maximum number of similar tags to display",
|
||||
id: id + ".max_related_tags",
|
||||
name: "Max related tags",
|
||||
description: "Maximum number of related tags to display",
|
||||
type: "slider",
|
||||
attrs: {
|
||||
min: 5,
|
||||
@@ -189,21 +189,21 @@ app.registerExtension({
|
||||
step: 5,
|
||||
},
|
||||
defaultValue: 20,
|
||||
category: [name, "Similar Tags", "Max similar tags"],
|
||||
category: [name, "Related Tags", "Max related tags"],
|
||||
onChange: (newVal, oldVal) => {
|
||||
settingValues.maxSimilarTags = newVal;
|
||||
settingValues.maxRelatedTags = newVal;
|
||||
}
|
||||
},
|
||||
{
|
||||
id: id + ".similar_tags_position",
|
||||
name: "Similar Tags Display Position",
|
||||
description: "Position of similar tags display",
|
||||
id: id + ".related_tags_position",
|
||||
name: "Related Tags Display Position",
|
||||
description: "Position of related tags display",
|
||||
type: "combo",
|
||||
options: ["horizontal", "vertical"],
|
||||
defaultValue: "horizontal",
|
||||
category: [name, "Similar Tags", "Display Position"],
|
||||
category: [name, "Related Tags", "Display Position"],
|
||||
onChange: (newVal, oldVal) => {
|
||||
settingValues.similarTagsDisplayPosition = newVal;
|
||||
settingValues.relatedTagsDisplayPosition = newVal;
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// filepath: v:\Programs\StabilityMatrix-win-x64\Data\Packages\ComfyUI-New\custom_nodes\ComfyUI-Autocomplete-Plus\web\js\similar-tags.js
|
||||
// filepath: v:\Programs\StabilityMatrix-win-x64\Data\Packages\ComfyUI-New\custom_nodes\ComfyUI-Autocomplete-Plus\web\js\related-tags.js
|
||||
import { settingValues } from './settings.js';
|
||||
import { TagCategory, autoCompleteData } from './data.js';
|
||||
import {
|
||||
@@ -9,27 +9,27 @@ import {
|
||||
getViewportMargin
|
||||
} from './utils.js';
|
||||
|
||||
// --- SimilarTags UI Class ---
|
||||
// --- RelatedTags UI Class ---
|
||||
|
||||
/**
|
||||
* Class that manages the UI for displaying similar tags.
|
||||
* Shows a panel with tags similar to the current tag under cursor.
|
||||
* Class that manages the UI for displaying related tags.
|
||||
* Shows a panel with tags related to the current tag under cursor.
|
||||
*/
|
||||
class SimilarTagsUI {
|
||||
class RelatedTagsUI {
|
||||
constructor() {
|
||||
// Create the main container
|
||||
this.root = document.createElement('div');
|
||||
this.root.id = 'similar-tags-container';
|
||||
this.root.id = 'related-tags-container';
|
||||
|
||||
// Create header row
|
||||
this.header = document.createElement('div');
|
||||
this.header.id = 'similar-tags-header';
|
||||
this.header.textContent = 'Similar Tags';
|
||||
this.header.id = 'related-tags-header';
|
||||
this.header.textContent = 'Related Tags';
|
||||
this.root.appendChild(this.header);
|
||||
|
||||
// Create a tbody for the tags
|
||||
this.tagsContainer = document.createElement('div');
|
||||
this.tagsContainer.id = 'similar-tags-list';
|
||||
this.tagsContainer.id = 'related-tags-list';
|
||||
this.root.appendChild(this.tagsContainer);
|
||||
|
||||
// Add to DOM
|
||||
@@ -41,7 +41,7 @@ class SimilarTagsUI {
|
||||
|
||||
// Add click handler for tag selection
|
||||
this.tagsContainer.addEventListener('mousedown', (e) => {
|
||||
const row = e.target.closest('.similar-tag-item');
|
||||
const row = e.target.closest('.related-tag-item');
|
||||
if (row && row.dataset.tag) {
|
||||
this.selectTag(row.dataset.tag);
|
||||
e.preventDefault();
|
||||
@@ -54,13 +54,13 @@ class SimilarTagsUI {
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the similar tags UI for a specific tag and text input element.
|
||||
* Shows the related tags UI for a specific tag and text input element.
|
||||
* @param {HTMLTextAreaElement} inputElement The textarea being used
|
||||
* @param {string} tag The tag to find similarities for
|
||||
* @param {Array<{tag: string, similarity: number, count: number, alias?: string[]}>} similarTags List of similar tags
|
||||
* @param {string} tag The tag to find relatedities for
|
||||
* @param {Array<{tag: string, similarity: number, count: number, alias?: string[]}>} relatedTags List of related tags
|
||||
*/
|
||||
show(inputElement, tag, similarTags) {
|
||||
if (!settingValues.enableSimilarTags) {
|
||||
show(inputElement, tag, relatedTags) {
|
||||
if (!settingValues.enableRelatedTags) {
|
||||
this.hide();
|
||||
return;
|
||||
}
|
||||
@@ -68,8 +68,8 @@ class SimilarTagsUI {
|
||||
this.activeInput = inputElement;
|
||||
this.currentTag = tag;
|
||||
|
||||
// Update content (even if there are no similar tags, we'll show a message)
|
||||
this.updateContent(similarTags);
|
||||
// Update content (even if there are no related tags, we'll show a message)
|
||||
this.updateContent(relatedTags);
|
||||
|
||||
// Calculate and update position
|
||||
this.updatePosition(inputElement);
|
||||
@@ -82,13 +82,13 @@ class SimilarTagsUI {
|
||||
clearTimeout(this.autoRefreshTimerId);
|
||||
}
|
||||
this.autoRefreshTimerId = setTimeout(() => {
|
||||
similarTagsUI.show(inputElement, tag, similarTags);
|
||||
relatedTagsUI.show(inputElement, tag, relatedTags);
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the similar tags UI.
|
||||
* Hides the related tags UI.
|
||||
*/
|
||||
hide() {
|
||||
if(this.autoRefreshTimerId){
|
||||
@@ -101,10 +101,10 @@ class SimilarTagsUI {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the content of the similar tags panel with the provided tags.
|
||||
* @param {Array<{tag: string, similarity: number, count: number, alias?: string[]}>} similarTags
|
||||
* Updates the content of the related tags panel with the provided tags.
|
||||
* @param {Array<{tag: string, similarity: number, count: number, alias?: string[]}>} relatedTags
|
||||
*/
|
||||
updateContent(similarTags) {
|
||||
updateContent(relatedTags) {
|
||||
this.root.style.left = 0;
|
||||
this.root.style.top = 0;
|
||||
this.root.style.maxWidth = `${window.innerWidth / 2}px`;
|
||||
@@ -115,34 +115,34 @@ class SimilarTagsUI {
|
||||
this.header.innerHTML = ''; // Clear previous content
|
||||
this.header.textContent = 'Tags related to: ';
|
||||
const tagNameSpan = document.createElement('span');
|
||||
tagNameSpan.className = 'similar-tags-header-tag-name';
|
||||
tagNameSpan.className = 'related-tags-header-tag-name';
|
||||
tagNameSpan.textContent = this.currentTag;
|
||||
this.header.appendChild(tagNameSpan);
|
||||
|
||||
if (!autoCompleteData.cooccurrenceLoaded) {
|
||||
const messageDiv = document.createElement('div');
|
||||
messageDiv.className = 'similar-tags-loading-message';
|
||||
messageDiv.className = 'related-tags-loading-message';
|
||||
messageDiv.textContent = `Initializing cooccurrence data... [${autoCompleteData.cooccurrenceInitProgress}%]`;
|
||||
this.tagsContainer.appendChild(messageDiv);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!similarTags || similarTags.length === 0) {
|
||||
if (!relatedTags || relatedTags.length === 0) {
|
||||
const messageCell = document.createElement('div');
|
||||
messageCell.textContent = 'No similar tags found';
|
||||
messageCell.textContent = 'No related tags found';
|
||||
this.tagsContainer.appendChild(messageCell);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create tag rows
|
||||
similarTags.forEach(tagData => {
|
||||
relatedTags.forEach(tagData => {
|
||||
const tagRow = this.createTagElement(tagData);
|
||||
this.tagsContainer.appendChild(tagRow);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML table row for a similar tag.
|
||||
* Creates an HTML table row for a related tag.
|
||||
* @param {{tag: string, similarity: number, count: number, alias?: string[]}} tagData
|
||||
* @returns {HTMLTableRowElement} The tag row element
|
||||
*/
|
||||
@@ -150,18 +150,18 @@ class SimilarTagsUI {
|
||||
const categoryText = TagCategory[tagData.category] || "unknown";
|
||||
|
||||
const tagRow = document.createElement('div');
|
||||
tagRow.className = 'similar-tag-item';
|
||||
tagRow.className = 'related-tag-item';
|
||||
tagRow.dataset.tag = tagData.tag;
|
||||
tagRow.dataset.tagCategory = categoryText;
|
||||
|
||||
// Tag name cell
|
||||
const tagNameCell = document.createElement('span');
|
||||
tagNameCell.className = 'similar-tag-name';
|
||||
tagNameCell.className = 'related-tag-name';
|
||||
tagNameCell.textContent = tagData.tag;
|
||||
|
||||
// Alias cell (middle column)
|
||||
const aliasCell = document.createElement('span');
|
||||
aliasCell.className = 'similar-tag-alias';
|
||||
aliasCell.className = 'related-tag-alias';
|
||||
|
||||
// Display alias if available
|
||||
if (tagData.alias && tagData.alias.length > 0) {
|
||||
@@ -172,12 +172,12 @@ class SimilarTagsUI {
|
||||
|
||||
// Category cell
|
||||
const categoryCell = document.createElement('span');
|
||||
categoryCell.className = `similar-tag-category`;
|
||||
categoryCell.className = `related-tag-category`;
|
||||
categoryCell.textContent = `${categoryText.substring(0, 2)}`;
|
||||
|
||||
// Similarity cell
|
||||
const similarityCell = document.createElement('span');
|
||||
similarityCell.className = 'similar-tag-similarity';
|
||||
similarityCell.className = 'related-tag-similarity';
|
||||
similarityCell.textContent = `${(tagData.similarity * 100).toFixed(2)}%`;
|
||||
|
||||
// Create tooltip with more info
|
||||
@@ -197,9 +197,9 @@ class SimilarTagsUI {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the position of the similar tags panel.
|
||||
* Updates the position of the related tags panel.
|
||||
* Position is calculated based on the input element, available space,
|
||||
* and the setting `similarTagsDisplayPosition`.
|
||||
* and the setting `relatedTagsDisplayPosition`.
|
||||
* @param {HTMLElement} inputElement The input element to position
|
||||
*/
|
||||
updatePosition(inputElement) {
|
||||
@@ -241,7 +241,7 @@ class SimilarTagsUI {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the selection of a similar tag.
|
||||
* Handles the selection of a related tag.
|
||||
* Inserts the tag into the active input.
|
||||
* @param {string} tag
|
||||
*/
|
||||
@@ -256,7 +256,7 @@ class SimilarTagsUI {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the similar tags UI is currently visible.
|
||||
* Checks if the related tags UI is currently visible.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isVisible() {
|
||||
@@ -289,7 +289,7 @@ class SimilarTagsUI {
|
||||
height: Math.min(elemHeight, viewportHeight - margin.top - margin.bottom)
|
||||
};
|
||||
|
||||
if (settingValues.similarTagsDisplayPosition === 'vertical') {
|
||||
if (settingValues.relatedTagsDisplayPosition === 'vertical') {
|
||||
// Vertical placement
|
||||
const topSpace = inputRect.top - margin.top;
|
||||
const bottomSpace = viewportHeight - inputRect.bottom - margin.bottom;
|
||||
@@ -355,11 +355,11 @@ function calculateJaccardSimilarity(tagA, tagB) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds similar tags for a given tag.
|
||||
* @param {string} tag The tag to find similar tags for
|
||||
* Finds related tags for a given tag.
|
||||
* @param {string} tag The tag to find related tags for
|
||||
* @returns {Array<{tag: string, similarity: number, count: number, alias?: string[]}>}
|
||||
*/
|
||||
function findSimilarTags(tag) {
|
||||
function findRelatedTags(tag) {
|
||||
const startTime = performance.now(); // Record start time for performance measurement
|
||||
|
||||
if (!tag || !autoCompleteData.cooccurrenceMap.has(tag)) {
|
||||
@@ -367,7 +367,7 @@ function findSimilarTags(tag) {
|
||||
}
|
||||
|
||||
const cooccurrences = autoCompleteData.cooccurrenceMap.get(tag);
|
||||
const similarTags = [];
|
||||
const relatedTags = [];
|
||||
|
||||
// Convert to array for sorting
|
||||
cooccurrences.forEach((count, coTag) => {
|
||||
@@ -381,7 +381,7 @@ function findSimilarTags(tag) {
|
||||
// Calculate similarity
|
||||
const similarity = calculateJaccardSimilarity(tag, coTag);
|
||||
|
||||
similarTags.push({
|
||||
relatedTags.push({
|
||||
tag: coTag,
|
||||
similarity: similarity,
|
||||
alias: tagData.alias,
|
||||
@@ -391,10 +391,10 @@ function findSimilarTags(tag) {
|
||||
});
|
||||
|
||||
// Sort by similarity (highest first)
|
||||
similarTags.sort((a, b) => b.similarity - a.similarity);
|
||||
relatedTags.sort((a, b) => b.similarity - a.similarity);
|
||||
|
||||
// Limit to max number of suggestions
|
||||
const result = similarTags.slice(0, settingValues.maxSimilarTags);
|
||||
const result = relatedTags.slice(0, settingValues.maxRelatedTags);
|
||||
|
||||
const endTime = performance.now();
|
||||
const duration = endTime - startTime;
|
||||
@@ -555,27 +555,27 @@ function findAllTagPositions(text) {
|
||||
// --- Main Exports ---
|
||||
|
||||
// Create a singleton instance
|
||||
const similarTagsUI = new SimilarTagsUI();
|
||||
const relatedTagsUI = new RelatedTagsUI();
|
||||
|
||||
// Helper function to show similar tags based on cursor position
|
||||
function showSimilarTagsForCurrentPosition(textareaElement) {
|
||||
// Helper function to show related tags based on cursor position
|
||||
function showRelatedTagsForCurrentPosition(textareaElement) {
|
||||
// Get the tag at current cursor position
|
||||
const currentTag = normalizeTagToSearch(getCurrentTag(textareaElement));
|
||||
|
||||
// If no valid tag or tag is too short, hide the panel
|
||||
if (!isValidTag(currentTag)) {
|
||||
similarTagsUI.hide();
|
||||
relatedTagsUI.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
// Find similar tags
|
||||
const similarTagsResults = findSimilarTags(currentTag);
|
||||
// Find related tags
|
||||
const relatedTagsResults = findRelatedTags(currentTag);
|
||||
|
||||
// Always show the panel with current tag, even if there are no similar tags
|
||||
similarTagsUI.show(textareaElement, currentTag, similarTagsResults);
|
||||
// Always show the panel with current tag, even if there are no related tags
|
||||
relatedTagsUI.show(textareaElement, currentTag, relatedTagsResults);
|
||||
}
|
||||
|
||||
export class SimilarTagsEventHandler {
|
||||
export class RelatedTagsEventHandler {
|
||||
constructor() {
|
||||
|
||||
}
|
||||
@@ -585,9 +585,9 @@ export class SimilarTagsEventHandler {
|
||||
* @param {KeyboardEvent} event
|
||||
*/
|
||||
handleInput(event) {
|
||||
if (settingValues.enableSimilarTags) {
|
||||
if (similarTagsUI && similarTagsUI.isVisible()) {
|
||||
similarTagsUI.hide();
|
||||
if (settingValues.enableRelatedTags) {
|
||||
if (relatedTagsUI && relatedTagsUI.isVisible()) {
|
||||
relatedTagsUI.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -609,17 +609,17 @@ export class SimilarTagsEventHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use setTimeout to delay hiding. This allows clicks on the similar tags UI
|
||||
// Use setTimeout to delay hiding. This allows clicks on the related tags UI
|
||||
// to be processed before the UI is hidden.
|
||||
setTimeout(() => {
|
||||
// Check if the new focused element is part of the similar tags UI.
|
||||
// Check if the new focused element is part of the related tags UI.
|
||||
// document.activeElement refers to the currently focused element.
|
||||
const activeElement = document.activeElement;
|
||||
const similarTagsElement = similarTagsUI.root;
|
||||
const relatedTagsElement = relatedTagsUI.root;
|
||||
|
||||
// If the focus is not within the similar tags UI, hide it.
|
||||
if (similarTagsUI && !similarTagsElement.contains(activeElement)) {
|
||||
similarTagsUI.hide();
|
||||
// If the focus is not within the related tags UI, hide it.
|
||||
if (relatedTagsUI && !relatedTagsElement.contains(activeElement)) {
|
||||
relatedTagsUI.hide();
|
||||
}
|
||||
}, 150); // Delay in milliseconds (adjust if necessary)
|
||||
}
|
||||
@@ -631,19 +631,19 @@ export class SimilarTagsEventHandler {
|
||||
handleKeyDown(event) {
|
||||
const textareaElement = event.target;
|
||||
|
||||
// For similar tags panel, handle Escape key
|
||||
if (similarTagsUI && similarTagsUI.isVisible()) {
|
||||
// For related tags panel, handle Escape key
|
||||
if (relatedTagsUI && relatedTagsUI.isVisible()) {
|
||||
if (event.key === 'Escape') {
|
||||
event.preventDefault();
|
||||
similarTagsUI.hide();
|
||||
relatedTagsUI.hide();
|
||||
}
|
||||
}
|
||||
|
||||
// Show similar tags on Ctrl+Space
|
||||
if (settingValues.enableSimilarTags) {
|
||||
// Show related tags on Ctrl+Space
|
||||
if (settingValues.enableRelatedTags) {
|
||||
if (event.key === ' ' && event.ctrlKey && event.shiftKey ) {
|
||||
event.preventDefault();
|
||||
showSimilarTagsForCurrentPosition(textareaElement);
|
||||
showRelatedTagsForCurrentPosition(textareaElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -680,6 +680,6 @@ export class SimilarTagsEventHandler {
|
||||
*/
|
||||
handleClick(event) {
|
||||
const textareaElement = event.target;
|
||||
showSimilarTagsForCurrentPosition(textareaElement);
|
||||
showRelatedTagsForCurrentPosition(textareaElement);
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -3,10 +3,10 @@ export const settingValues = {
|
||||
enabled: true,
|
||||
maxSuggestions: 10,
|
||||
|
||||
// Similar tags feature settings
|
||||
enableSimilarTags: true,
|
||||
maxSimilarTags: 20,
|
||||
similarTagsDisplayPosition: 'horizontal', // 'horizontal' or 'vertical'
|
||||
// Related tags feature settings
|
||||
enableRelatedTags: true,
|
||||
maxRelatedTags: 20,
|
||||
relatedTagsDisplayPosition: 'horizontal', // 'horizontal' or 'vertical'
|
||||
|
||||
// Internal logic settings
|
||||
_useFallbackAttachmentForEventListener: false, // Fallback to attach event listener if not using jQuery
|
||||
|
||||
Reference in New Issue
Block a user