Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4066f58d25 | ||
|
|
ce07964a68 | ||
|
|
d39a915888 | ||
|
|
5aa72379e8 | ||
|
|
8257ad5109 | ||
|
|
b8c250e836 | ||
|
|
4be66d7132 | ||
|
|
7f089527c5 |
@@ -28,7 +28,17 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- name: Checkout code
|
||||||
- uses: actions-hub/stylelint@master
|
uses: actions/checkout@v4
|
||||||
env:
|
|
||||||
PATTERN : 'web/css/*.css'
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v6
|
||||||
|
with:
|
||||||
|
node-version: '22'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Run stylelint
|
||||||
|
run: npx stylelint "web/css/*.css"
|
||||||
@@ -169,6 +169,7 @@ For example, by preparing the following CSV, you can quickly insert correspondin
|
|||||||
- **Max suggestions**: Maximum number of autocomplete suggestions to display.
|
- **Max suggestions**: Maximum number of autocomplete suggestions to display.
|
||||||
- **Auto-Insert Comma**: Automatically insert a comma after tags when inserting from autocomplete.
|
- **Auto-Insert Comma**: Automatically insert a comma after tags when inserting from autocomplete.
|
||||||
- **Replace '_' with 'Space'**: Replaces underscores with spaces when inserting tags. This setting also affects related tag display.
|
- **Replace '_' with 'Space'**: Replaces underscores with spaces when inserting tags. This setting also affects related tag display.
|
||||||
|
- **String to add before artist tags**: Text to prepend when inserting an artist tag. For Anima models, specify `@`.
|
||||||
- **Enable Loras and Embeddings**: Display Lora and Embedding in the suggestions.
|
- **Enable Loras and Embeddings**: Display Lora and Embedding in the suggestions.
|
||||||
- **Use Fast Search**: Switch autocomplete suggestions search to fast processing (see [About Fast Search for Autocomplete](#about-fast-search-for-autocomplete) for details).
|
- **Use Fast Search**: Switch autocomplete suggestions search to fast processing (see [About Fast Search for Autocomplete](#about-fast-search-for-autocomplete) for details).
|
||||||
|
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ worst_quality,5,9999999,
|
|||||||
- **Max Suggestions**: オートコンプリート候補の最大表示件数
|
- **Max Suggestions**: オートコンプリート候補の最大表示件数
|
||||||
- **Auto-Insert Comma**: タグの挿入時、末尾にカンマを追加する
|
- **Auto-Insert Comma**: タグの挿入時、末尾にカンマを追加する
|
||||||
- **Replace '_' with 'Space'**: タグ挿入時にアンダースコアをスペースに置き換えます。この設定は関連タグ表示にも影響します
|
- **Replace '_' with 'Space'**: タグ挿入時にアンダースコアをスペースに置き換えます。この設定は関連タグ表示にも影響します
|
||||||
|
- **String to add before artist tags**: アーティストタグを挿入する際に付加する文字列。 Anima モデルの場合は「@」を指定します
|
||||||
- **Enable Loras and Embeddings**: LoraとEmbeddingを候補に表示する
|
- **Enable Loras and Embeddings**: LoraとEmbeddingを候補に表示する
|
||||||
- **Use Fast Search**: オートコンプリート候補の検索を高速な処理に切り替える(詳細は [オートコンプリートの高速検索について](#オートコンプリートの高速検索について) を確認してください)
|
- **Use Fast Search**: オートコンプリート候補の検索を高速な処理に切り替える(詳細は [オートコンプリートの高速検索について](#オートコンプリートの高速検索について) を確認してください)
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,10 @@
|
|||||||
"AutocompletePlus_Autocompletion_EnableModels": {
|
"AutocompletePlus_Autocompletion_EnableModels": {
|
||||||
"name": "Enable Loras and Embeddings"
|
"name": "Enable Loras and Embeddings"
|
||||||
},
|
},
|
||||||
|
"AutocompletePlus_Autocompletion_PrefixArtist": {
|
||||||
|
"name": "String to add before artist tags",
|
||||||
|
"tooltip": "Text to prepend when inserting an artist tag via autocomplete.\ne.g. '@' -> '@artist_name'."
|
||||||
|
},
|
||||||
"AutocompletePlus_Autocompletion_ReplaceUnderscoreWithSpace": {
|
"AutocompletePlus_Autocompletion_ReplaceUnderscoreWithSpace": {
|
||||||
"name": "Replace '_' with 'Space'",
|
"name": "Replace '_' with 'Space'",
|
||||||
"tooltip": "This setting also affects related tags display."
|
"tooltip": "This setting also affects related tags display."
|
||||||
|
|||||||
@@ -31,6 +31,10 @@
|
|||||||
"AutocompletePlus_Autocompletion_EnableModels": {
|
"AutocompletePlus_Autocompletion_EnableModels": {
|
||||||
"name": "LoraとEmbeddingを候補に表示する"
|
"name": "LoraとEmbeddingを候補に表示する"
|
||||||
},
|
},
|
||||||
|
"AutocompletePlus_Autocompletion_PrefixArtist": {
|
||||||
|
"name": "アーティストタグの前に追加する文字列",
|
||||||
|
"tooltip": "オートコンプリートからアーティストタグを挿入する際に付加する文字列。\n例: '@' -> '@artist_name'"
|
||||||
|
},
|
||||||
"AutocompletePlus_Autocompletion_ReplaceUnderscoreWithSpace": {
|
"AutocompletePlus_Autocompletion_ReplaceUnderscoreWithSpace": {
|
||||||
"name": "'_' を 'スペース' に置き換える",
|
"name": "'_' を 'スペース' に置き換える",
|
||||||
"tooltip": "この設定は関連タグ表示にも影響します"
|
"tooltip": "この設定は関連タグ表示にも影響します"
|
||||||
|
|||||||
@@ -31,6 +31,10 @@
|
|||||||
"AutocompletePlus_Autocompletion_EnableModels": {
|
"AutocompletePlus_Autocompletion_EnableModels": {
|
||||||
"name": "顯示Lora和Embedding"
|
"name": "顯示Lora和Embedding"
|
||||||
},
|
},
|
||||||
|
"AutocompletePlus_Autocompletion_PrefixArtist": {
|
||||||
|
"name": "在藝術家標籤前添加的字串",
|
||||||
|
"tooltip": "透過自動完成插入藝術家標籤時,在標籤前添加的文字。\n例: '@' -> '@artist_name'"
|
||||||
|
},
|
||||||
"AutocompletePlus_Autocompletion_ReplaceUnderscoreWithSpace": {
|
"AutocompletePlus_Autocompletion_ReplaceUnderscoreWithSpace": {
|
||||||
"name": "將'_'替換為'空格'",
|
"name": "將'_'替換為'空格'",
|
||||||
"tooltip": "此設定也會影響相關標籤顯示"
|
"tooltip": "此設定也會影響相關標籤顯示"
|
||||||
|
|||||||
@@ -31,6 +31,10 @@
|
|||||||
"AutocompletePlus_Autocompletion_EnableModels": {
|
"AutocompletePlus_Autocompletion_EnableModels": {
|
||||||
"name": "显示Lora和Embedding"
|
"name": "显示Lora和Embedding"
|
||||||
},
|
},
|
||||||
|
"AutocompletePlus_Autocompletion_PrefixArtist": {
|
||||||
|
"name": "在艺术家标签前添加的字符串",
|
||||||
|
"tooltip": "通过自动完成插入艺术家标签时,在标签前添加的文本。\n例: '@' -> '@artist_name'"
|
||||||
|
},
|
||||||
"AutocompletePlus_Autocompletion_ReplaceUnderscoreWithSpace": {
|
"AutocompletePlus_Autocompletion_ReplaceUnderscoreWithSpace": {
|
||||||
"name": "将'_'替换为'空格'",
|
"name": "将'_'替换为'空格'",
|
||||||
"tooltip": "此设置也会影响相关标签显示"
|
"tooltip": "此设置也会影响相关标签显示"
|
||||||
|
|||||||
+24
-2
@@ -351,11 +351,13 @@ function insertTagToTextArea(inputElement, tagDataToInsert) {
|
|||||||
const needsSpaceBefore = text[replaceStart - 1] === ',';
|
const needsSpaceBefore = text[replaceStart - 1] === ',';
|
||||||
const prefix = needsSpaceBefore ? ' ' : '';
|
const prefix = needsSpaceBefore ? ' ' : '';
|
||||||
|
|
||||||
|
const prefixArtist = tagDataToInsert.categoryText == 'artist' ? settingValues.prefixArtist : '';
|
||||||
|
|
||||||
// Standard separator (comma + space, or empty if autoInsertComma is disabled)
|
// Standard separator (comma + space, or empty if autoInsertComma is disabled)
|
||||||
const needsSuffixAfter = !",:".includes(text[replaceEnd]); // TODO: If ":" is part of the emoticon, a suffix is required (e.g. ":o")
|
const needsSuffixAfter = !",:".includes(text[replaceEnd]); // TODO: If ":" is part of the emoticon, a suffix is required (e.g. ":o")
|
||||||
const suffix = (needsSuffixAfter && settingValues.autoInsertComma) ? ', ' : '';
|
const suffix = (needsSuffixAfter && settingValues.autoInsertComma) ? ', ' : '';
|
||||||
|
|
||||||
const textToInsertWithAffixes = prefix + normalizedTag + suffix;
|
const textToInsertWithAffixes = prefix + prefixArtist + normalizedTag + suffix;
|
||||||
|
|
||||||
// --- Use execCommand for Undo support ---
|
// --- Use execCommand for Undo support ---
|
||||||
// 1. Select the text range to be replaced
|
// 1. Select the text range to be replaced
|
||||||
@@ -939,6 +941,25 @@ export class AutocompleteEventHandler {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.autocompleteUI = new AutocompleteUI();
|
this.autocompleteUI = new AutocompleteUI();
|
||||||
this.keyDownWithModifier = new Map(); // Keep track of keydown events with modifiers
|
this.keyDownWithModifier = new Map(); // Keep track of keydown events with modifiers
|
||||||
|
this._debounceTimer = null; // Timer ID for debounced search
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls autocompleteUI.updateDisplay() with debounce for sequential search, or immediately for fast search.
|
||||||
|
* @param {HTMLTextAreaElement} target
|
||||||
|
*/
|
||||||
|
_triggerUpdateDisplay(target) {
|
||||||
|
if (settingValues.useFastSearch || settingValues.searchDebounceTime <= 0) {
|
||||||
|
// FastSearch or debounce disabled: immediate update
|
||||||
|
this.autocompleteUI.updateDisplay(target);
|
||||||
|
} else {
|
||||||
|
// Sequential search: debounced update
|
||||||
|
clearTimeout(this._debounceTimer);
|
||||||
|
this._debounceTimer = setTimeout(() => {
|
||||||
|
this.autocompleteUI.updateDisplay(target);
|
||||||
|
this._debounceTimer = null;
|
||||||
|
}, settingValues.searchDebounceTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -952,6 +973,7 @@ export class AutocompleteEventHandler {
|
|||||||
|
|
||||||
const partialTag = getCurrentPartialTag(event.target);
|
const partialTag = getCurrentPartialTag(event.target);
|
||||||
if (partialTag.length <= 0) {
|
if (partialTag.length <= 0) {
|
||||||
|
clearTimeout(this._debounceTimer); // Cancel pending debounced search
|
||||||
this.autocompleteUI.hide();
|
this.autocompleteUI.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1062,7 +1084,7 @@ export class AutocompleteEventHandler {
|
|||||||
// and default action is not prevented, update the display.
|
// and default action is not prevented, update the display.
|
||||||
// This will typically be for character inputs, Delete, Backspace or IME composition.
|
// This will typically be for character inputs, Delete, Backspace or IME composition.
|
||||||
if (!event.defaultPrevented) {
|
if (!event.defaultPrevented) {
|
||||||
this.autocompleteUI.updateDisplay(event.target);
|
this._triggerUpdateDisplay(event.target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+23
-9
@@ -50,16 +50,19 @@ function initializeEventHandlers() {
|
|||||||
ComfyWidgets.STRING = function (node, inputName, inputData, appInstance) { // Use appInstance to avoid conflict with global app
|
ComfyWidgets.STRING = function (node, inputName, inputData, appInstance) { // Use appInstance to avoid conflict with global app
|
||||||
const result = originalStringWidget.apply(this, arguments);
|
const result = originalStringWidget.apply(this, arguments);
|
||||||
|
|
||||||
// Check if the widget has an inputEl and if it's a TEXTAREA
|
// Check if the widget has an element and if it's a TEXTAREA
|
||||||
// This is to ensure we are targeting multiline text inputs, related to '.comfy-multiline-input'
|
// This is to ensure we are targeting multiline text inputs, related to '.comfy-multiline-input'
|
||||||
if (result && result.widget
|
if (result && result.widget) {
|
||||||
&& result.widget.inputEl && result.widget.inputEl.tagName === 'TEXTAREA' && !result.widget.inputEl.readOnly) {
|
// fallback for older Comfyui frontend versions
|
||||||
const widgetConfig = inputData && inputData[1] ? inputData[1] : {};
|
const inputEl = result.widget.element ?? result.widget.inputEl;
|
||||||
// Future: Add checks for Autocomplete Plus specific configurations if needed
|
if (inputEl && inputEl.tagName === 'TEXTAREA' && !inputEl.readOnly) {
|
||||||
// e.g., if (widgetConfig["AutocompletePlus.enabled"] === false) return result;
|
const widgetConfig = inputData && inputData[1] ? inputData[1] : {};
|
||||||
|
// Future: Add checks for Autocomplete Plus specific configurations if needed
|
||||||
|
// e.g., if (widgetConfig["AutocompletePlus.enabled"] === false) return result;
|
||||||
|
|
||||||
const nodeInfo = new NodeInfo(node.comfyClass || node.constructor.name, inputName);
|
const nodeInfo = new NodeInfo(node.comfyClass || node.constructor.name, inputName);
|
||||||
attachListeners(result.widget.inputEl, nodeInfo);
|
attachListeners(inputEl, nodeInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
@@ -377,6 +380,17 @@ app.registerExtension({
|
|||||||
settingValues.enableModels = newVal;
|
settingValues.enableModels = newVal;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: id + ".Autocompletion.PrefixArtist",
|
||||||
|
name: "String to add before artist tags",
|
||||||
|
tooltip: "Text to prepend when inserting an artist tag via autocomplete.\ne.g. '@' -> '@artist_name'.",
|
||||||
|
type: "text",
|
||||||
|
defaultValue: '',
|
||||||
|
category: [name, "Autocompletion", "String to add before artist tags"],
|
||||||
|
onChange: (newVal, oldVal) => {
|
||||||
|
settingValues.prefixArtist = newVal;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: id + ".Autocompletion.ReplaceUnderscoreWithSpace",
|
id: id + ".Autocompletion.ReplaceUnderscoreWithSpace",
|
||||||
name: "Replace '_' with 'Space'",
|
name: "Replace '_' with 'Space'",
|
||||||
@@ -535,4 +549,4 @@ app.registerExtension({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ export const settingValues = {
|
|||||||
enableModels: true, // Enable Lora and Embedding suggestions
|
enableModels: true, // Enable Lora and Embedding suggestions
|
||||||
useFastSearch: false,
|
useFastSearch: false,
|
||||||
replaceUnderscoreWithSpace: true, // Replace underscores with spaces in tag insertion
|
replaceUnderscoreWithSpace: true, // Replace underscores with spaces in tag insertion
|
||||||
|
prefixArtist: '', // Prefix to be attached before artist tags
|
||||||
autoInsertComma: true,
|
autoInsertComma: true,
|
||||||
|
searchDebounceTime: 100, // Sequential search debounce time in milliseconds
|
||||||
|
|
||||||
// Related tags feature settings
|
// Related tags feature settings
|
||||||
enableRelatedTags: true,
|
enableRelatedTags: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user