feat: Add keyup and keypress event handlers for autocomplete and similar tags more natural behaviour

This commit is contained in:
newtextdoc1111
2025-05-08 15:26:08 +09:00
parent ce3cc9594d
commit 12b782ec02
3 changed files with 111 additions and 23 deletions
+56 -22
View File
@@ -733,7 +733,6 @@ function insertTag(inputElement, tagToInsert) {
const needsSuffixAfter = text[replaceEnd] !== ','
const suffix = needsSuffixAfter ? ', ' : '';
// Text to insert (including prefix and suffix)
const textToInsertWithAffixes = prefix + normalizedTag + suffix;
// --- Use execCommand for Undo support ---
@@ -757,28 +756,22 @@ function insertTag(inputElement, tagToInsert) {
// Trigger input event manually as a fallback
inputElement.dispatchEvent(new Event('input', { bubbles: true }));
}
// Note: execCommand usually triggers the necessary events,
// so explicitly dispatching 'input' might be redundant or cause issues.
// Test carefully. If ComfyUI doesn't update, uncomment the dispatchEvent line in the fallback.
// inputElement.dispatchEvent(new Event('input', { bubbles: true })); // Keep commented unless needed
}
export class AutocompleteEventHandler {
/**
*
* @param {InputEvent} event
* @returns
*/
handleInput(event) {
if (!settingValues.enabled || !autocompleteUI) return;
if(!event.isTrusted) return; // ignore synthetic events
const ESCAPE_SEQUENCE = ["#", "/"]; // prevent autocomplete for these sequences
const textareaElement = event.target;
const partialTag = getCurrentPartialTag(textareaElement);
if (partialTag.length > 0 && !ESCAPE_SEQUENCE.some(seq => partialTag.startsWith(seq))) {
const candidates = findCompletionCandidates(partialTag);
autocompleteUI.show(textareaElement, candidates);
// console.debug(`[Autocomplete-Plus] InputEvent: ${candidates.length} candidates for "${partialTag}"`);
} else {
if (partialTag.length <= 0){
autocompleteUI.hide();
}
}
@@ -800,6 +793,11 @@ export class AutocompleteEventHandler {
}, 150);
}
/**
*
* @param {KeyboardEvent} event
* @returns
*/
handleKeyDown(event) {
if (!settingValues.enabled) return;
@@ -821,10 +819,8 @@ export class AutocompleteEventHandler {
if (autocompleteUI.getSelectedTag() !== null) {
event.preventDefault();
insertTag(textareaElement, autocompleteUI.getSelectedTag());
} else {
// Allow default Tab/Enter if no item is selected
autocompleteUI.hide();
}
autocompleteUI.hide();
break;
case 'Escape':
event.preventDefault();
@@ -832,17 +828,55 @@ export class AutocompleteEventHandler {
break;
}
}
// Debug print
const partialTag = getCurrentPartialTag(textareaElement);
console.debug(`[Autocomplete-Plus] KeyDownEvent: ${event.key}, PartialTag: "${partialTag}"`);
// const partialTag = getCurrentPartialTag(textareaElement);
// console.debug(`[Autocomplete-Plus] KeyDownEvent: ${event.key}, PartialTag: "${partialTag}"`);
}
// New event handler for mousemove to show similar tags on hover
/**
*
* @param {KeyboardEvent} event
* @returns
*/
handleKeyUp(event){
}
/**
*
* @param {KeyboardEvent} event
* @returns
*/
handleKeyPress(event){
if (!settingValues.enabled || !autocompleteUI) return;
if (event.defaultPrevented) return; // Ignore if default action is prevented
const textareaElement = event.target;
const ESCAPE_SEQUENCE = ["#", "/"]; // If the first string is that character, autocomplete will not be displayed.
const partialTag = getCurrentPartialTag(textareaElement);
if (partialTag.length > 0 && !ESCAPE_SEQUENCE.some(seq => partialTag.startsWith(seq))) {
const candidates = findCompletionCandidates(partialTag);
autocompleteUI.show(textareaElement, candidates);
// console.debug(`[Autocomplete-Plus] KeyPressEvent: ${candidates.length} candidates for "${partialTag}"`);
}
}
/**
*
* @param {MouseEvent} event
* @returns
*/
handleMouseMove(event) {
}
// New event handler for click to show similar tags
/**
*
* @param {MouseEvent} event
* @returns
*/
handleClick(event) {
if (!settingValues.enabled || !settingValues.enableSimilarTags ||
settingValues.similarTagsDisplayMode !== 'click') return;
+12
View File
@@ -19,6 +19,8 @@ function initializeEventHandlers() {
element.addEventListener('focus', handleFocus);
element.addEventListener('blur', handleBlur);
element.addEventListener('keydown', handleKeyDown);
element.addEventListener('keyup', handleKeyUp);
element.addEventListener('keypress', handleKeyPress);
// Add new event listeners for similar tags feature
element.addEventListener('mousemove', handleMouseMove);
@@ -100,6 +102,16 @@ function initializeEventHandlers() {
autocompleteEventHandler.handleKeyDown(event);
similarTagsEventHandler.handleKeyDown(event);
}
function handleKeyUp(event) {
autocompleteEventHandler.handleKeyUp(event);
similarTagsEventHandler.handleKeyUp(event);
}
function handleKeyPress(event) {
autocompleteEventHandler.handleKeyPress(event);
similarTagsEventHandler.handleKeyPress(event);
}
// New event handler for mousemove to show similar tags on hover
function handleMouseMove(event) {
+43 -1
View File
@@ -580,6 +580,10 @@ export class SimilarTagsEventHandler {
}
/**
*
* @param {KeyboardEvent} event
*/
handleInput(event) {
if (settingValues.enableSimilarTags) {
if (similarTagsUI && similarTagsUI.isVisible()) {
@@ -588,10 +592,18 @@ export class SimilarTagsEventHandler {
}
}
/**
*
* @param {KeyboardEvent} event
*/
handleFocus(event) {
// Handle focus event
}
/**
*
* @param {KeyboardEvent} event
*/
handleBlur(event) {
if (!settingValues._hideWhenOutofFocus) {
return;
@@ -612,6 +624,10 @@ export class SimilarTagsEventHandler {
}, 150); // Delay in milliseconds (adjust if necessary)
}
/**
*
* @param {KeyboardEvent} event
*/
handleKeyDown(event) {
const textareaElement = event.target;
@@ -625,17 +641,43 @@ export class SimilarTagsEventHandler {
// Show similar tags on Ctrl+Space
if (settingValues.enableSimilarTags) {
if (event.key === ' ' && event.ctrlKey) {
if (event.key === ' ' && event.ctrlKey && event.shiftKey ) {
event.preventDefault();
showSimilarTagsForCurrentPosition(textareaElement);
}
}
}
/**
*
* @param {KeyboardEvent} event
*/
handleKeyUp(event){
}
/**
*
* @param {KeyboardEvent} event
*/
handleKeyPress(event){
}
/**
*
* @param {MouseEvent} event
* @returns
*/
handleMouseMove(event) {
}
/**
*
* @param {MouseEvent} event
* @returns
*/
handleClick(event) {
const textareaElement = event.target;
showSimilarTagsForCurrentPosition(textareaElement);