diff --git a/public/index.html b/public/index.html index 960c1b750..faa25f4f5 100644 --- a/public/index.html +++ b/public/index.html @@ -3310,7 +3310,7 @@ Active World(s) for all chats
-
diff --git a/public/scripts/utils.js b/public/scripts/utils.js index ac63fdbcc..aef6d33f5 100644 --- a/public/scripts/utils.js +++ b/public/scripts/utils.js @@ -1459,7 +1459,7 @@ export function includesIgnoreCaseAndAccents(text, searchTerm) { /** * Returns a unique hash as ID for a select2 option text - * + * * @param {string} option - The option * @returns {string} A hashed version of that option */ @@ -1500,7 +1500,7 @@ export function select2ModifyOptions(element, items, { select = false, changeEve /** * Returns the ajax settings that can be used on the select2 ajax property to dynamically get the data. * Can be used on a single global array, querying data from the server or anything similar. - * + * * @param {function():Select2Option[]} dataProvider - The provider/function to retrieve the data - can be as simple as "() => myData" for arrays * @return {{transport: function}} The ajax object with the transport function to use on the select2 ajax property */ @@ -1525,9 +1525,39 @@ export function dynamicSelect2DataViaAjax(dataProvider) { return ajax; } +/** + * Subscribes a 'click' event handler to the choice elements of a select2 multi-select control + * + * @param {JQuery} control The original control the select2 was applied to + * @param {function(EventTarget):void} action - The action to execute when a choice element is clicked + * @param {object} options - Optional parameters + * @param {boolean} [options.closeDrawer=false] - Whether the drawer should be closed and focus removed after the choice item was clicked + */ +export function select2ChoiceClickSubscribe(control, action, { closeDrawer = false } = {}) { + // Add class for styling (hover color, changed cursor, etc) + control.addClass('select2_choice_clickable'); + + // Get the real container below and create a click handler on that one + const select2Container = control.next('span.select2-container'); + select2Container.on('click', function (event) { + if ($(event.target).hasClass('select2-selection__choice__display')) { + event.preventDefault(); + + // select2 still bubbles the event to open the dropdown. So we close it here and remove focus if we want that + if (closeDrawer) { + control.select2('close'); + setTimeout(() => select2Container.find('textarea').trigger('blur'), debounce_timeout.quick); + } + + // Now execute the actual action that was subscribed + action(event.target); + } + }); +} + /** * Applies syntax highlighting to a given regex string by generating HTML with classes - * + * * @param {string} regexStr - The javascript compatible regex string * @returns {string} The html representation of the highlighted regex */ @@ -1564,4 +1594,4 @@ export function highlightRegex(regexStr) { wrapPattern(patterns.delimiters, 'regex-delimiter'); return `${regexStr}`; -} \ No newline at end of file +} diff --git a/public/scripts/world-info.js b/public/scripts/world-info.js index 00a6d3d3b..23224bffa 100644 --- a/public/scripts/world-info.js +++ b/public/scripts/world-info.js @@ -1,5 +1,5 @@ import { saveSettings, callPopup, substituteParams, getRequestHeaders, chat_metadata, this_chid, characters, saveCharacterDebounced, menu_type, eventSource, event_types, getExtensionPromptByName, saveMetadata, getCurrentChatId, extension_prompt_roles } from '../script.js'; -import { download, debounce, initScrollHeight, resetScrollHeight, parseJsonFile, extractDataFromPng, getFileBuffer, getCharaFilename, getSortableDelay, escapeRegex, PAGINATION_TEMPLATE, navigation_option, waitUntilCondition, isTrueBoolean, setValueByPath, flashHighlight, select2ModifyOptions, getStringHash, getSelect2OptionId, dynamicSelect2DataViaAjax, highlightRegex } from './utils.js'; +import { download, debounce, initScrollHeight, resetScrollHeight, parseJsonFile, extractDataFromPng, getFileBuffer, getCharaFilename, getSortableDelay, escapeRegex, PAGINATION_TEMPLATE, navigation_option, waitUntilCondition, isTrueBoolean, setValueByPath, flashHighlight, select2ModifyOptions, getStringHash, getSelect2OptionId, dynamicSelect2DataViaAjax, highlightRegex, select2ChoiceClickSubscribe } from './utils.js'; import { extension_settings, getContext } from './extensions.js'; import { NOTE_MODULE_NAME, metadata_keys, shouldWIAddPrompt } from './authors-note.js'; import { registerSlashCommand } from './slash-commands.js'; @@ -1220,7 +1220,7 @@ function splitKeywordsAndRegexes(input) { /** * Tokenizer parsing input and splitting it into keywords and regexes - * + * * @param {{_type: string, term: string}} input - The typed input * @param {{options: object}} _selection - The selection even object (?) * @param {function(Select2Option):void} callback - The original callback function to call if an item should be inserted @@ -3525,22 +3525,14 @@ jQuery(() => { }); // Subscribe world loading to the select2 multiselect items (We need to target the specific select2 control) - $('#world_info + span.select2-container').on('click', function (event) { - if ($(event.target).hasClass('select2-selection__choice__display')) { - event.preventDefault(); - - // select2 still bubbles the event to open the dropdown. So we close it here and remove focus - $('#world_info').select2('close'); - setTimeout(() => $('#world_info + span.select2-container textarea').trigger('blur'), debounce_timeout.quick); - - const name = $(event.target).text(); - const selectedIndex = world_names.indexOf(name); - if (selectedIndex !== -1) { - $('#world_editor_select').val(selectedIndex).trigger('change'); - console.log('Quick selection of world', name); - } + select2ChoiceClickSubscribe($('#world_info'), (target) => { + const name = $(target).text(); + const selectedIndex = world_names.indexOf(name); + if (selectedIndex !== -1) { + $('#world_editor_select').val(selectedIndex).trigger('change'); + console.log('Quick selection of world', name); } - }); + }, { closeDrawer: true }); } $('#WorldInfo').on('scroll', () => {