Add Entry Preview to World Info Deletion Confirmation Dialog (#5423) * feat: add entry preview to world info deletion confirmation dialog Displays entry comment or first two lines of content in the deletion confirmation popup to help users verify they're deleting the correct entry. * fix: sanitize world info entry preview text in deletion confirmation dialog Adds DOMPurify sanitization to the entry preview text displayed in the deletion confirmation popup to prevent potential XSS vulnerabilities from unsanitized user content. * DOMPurify -> escapeHtml --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>

5e68410d4eede1fad17f31aa3c202b074b7346e8

Wolfsblvt <wolfsblvt@gmail.com>

Signed
1 files changed, +20 -2Ignore whitespace
public/scripts/world-info.js+20 -2
@@ -1,7 +1,7 @@
1import { Fuse } from '../lib.js';1import { Fuse } from '../lib.js';
22
3import { saveSettings, substituteParams, getRequestHeaders, chat_metadata, this_chid, characters, saveCharacterDebounced, menu_type, eventSource, event_types, getExtensionPromptByName, saveMetadata, getCurrentChatId, extension_prompt_roles, create_save, createOrEditCharacter, name1, getOneCharacter, select_selected_character } from '../script.js';3import { saveSettings, substituteParams, getRequestHeaders, chat_metadata, this_chid, characters, saveCharacterDebounced, menu_type, eventSource, event_types, getExtensionPromptByName, saveMetadata, getCurrentChatId, extension_prompt_roles, create_save, createOrEditCharacter, name1, getOneCharacter, select_selected_character } from '../script.js';
4import { download, debounce, initScrollHeight, resetScrollHeight, parseJsonFile, extractDataFromPng, getFileBuffer, getCharaFilename, getSortableDelay, escapeRegex, PAGINATION_TEMPLATE, navigation_option, waitUntilCondition, isTrueBoolean, setValueByPath, flashHighlight, select2ModifyOptions, getSelect2OptionId, dynamicSelect2DataViaAjax, highlightRegex, select2ChoiceClickSubscribe, isFalseBoolean, getSanitizedFilename, checkOverwriteExistingData, getStringHash, parseStringArray, cancelDebounce, findChar, onlyUnique, equalsIgnoreCaseAndAccents, uuidv4, normalizeArray, getUniqueName, logSlashCommandWarn, addLongPressEvent } from './utils.js';4import { download, debounce, initScrollHeight, resetScrollHeight, parseJsonFile, extractDataFromPng, getFileBuffer, getCharaFilename, getSortableDelay, escapeRegex, PAGINATION_TEMPLATE, navigation_option, waitUntilCondition, isTrueBoolean, setValueByPath, flashHighlight, select2ModifyOptions, getSelect2OptionId, dynamicSelect2DataViaAjax, highlightRegex, select2ChoiceClickSubscribe, isFalseBoolean, getSanitizedFilename, checkOverwriteExistingData, getStringHash, parseStringArray, cancelDebounce, findChar, onlyUnique, equalsIgnoreCaseAndAccents, uuidv4, normalizeArray, getUniqueName, logSlashCommandWarn, addLongPressEvent, escapeHtml } from './utils.js';
5import { extension_settings, getContext } from './extensions.js';5import { extension_settings, getContext } from './extensions.js';
6import { NOTE_MODULE_NAME, metadata_keys, shouldWIAddPrompt } from './authors-note.js';6import { NOTE_MODULE_NAME, metadata_keys, shouldWIAddPrompt } from './authors-note.js';
7import { isMobile } from './RossAscends-mods.js';7import { isMobile } from './RossAscends-mods.js';
@@ -3965,7 +3965,25 @@ export async function deleteWorldInfoEntry(data, uid, { silent = false } = {}) {
3965 return;3965 return;
3966 }3966 }
39673967
3968 const confirmation = silent || await Popup.show.confirm(t`Delete the entry with UID: ${uid}?`, t`This action is irreversible!`);3968 const entry = data.entries[uid];
3969 if (!entry) {
3970 return false;
3971 }
3972
3973 let previewText = '';
3974 if (entry.comment && entry.comment.trim()) {
3975 previewText = entry.comment.trim();
3976 } else if (entry.content) {
3977 const lines = entry.content.split(/\r?\n/).filter(line => line.trim());
3978 previewText = lines.slice(0, 2).join('\n');
3979 }
3980
3981 const popupHeader = t`Delete world info entry with UID: ${uid}?`;
3982 const popupText = previewText
3983 ? `<strong>${t`Entry`}:</strong><br>${escapeHtml(previewText).replace(/\n/g, '<br>')}<br><br>${t`This action is irreversible!`}`
3984 : t`This action is irreversible!`;
3985
3986 const confirmation = silent || await Popup.show.confirm(popupHeader, popupText);
3969 if (!confirmation) {3987 if (!confirmation) {
3970 return false;3988 return false;
3971 }3989 }