Refactor chid/grid attributes to data attributes

- We don't believe in imaginary HTML attributes that we make up, right?
This commit is contained in:
Wolfsblvt
2025-01-24 21:12:49 +01:00
parent a611a3ac59
commit 7c9b347116
7 changed files with 34 additions and 26 deletions

View File

@@ -1342,6 +1342,14 @@ export function resultCheckStatus() {
stopStatusLoading(); stopStatusLoading();
} }
/**
* Switches the currently selected character to the one with the given ID. (character index, not the character key!)
*
* If the character ID doesn't exist, if the chat is being saved, or if a group is being generated, this function does nothing.
* If the character is different from the currently selected one, it will clear the chat and reset any selected character or group.
* @param {number} id The ID of the character to switch to.
*/
export async function selectCharacterById(id) { export async function selectCharacterById(id) {
if (characters[id] === undefined) { if (characters[id] === undefined) {
return; return;
@@ -1415,7 +1423,7 @@ function getCharacterBlock(item, id) {
} }
// Populate the template // Populate the template
const template = $('#character_template .character_select').clone(); const template = $('#character_template .character_select').clone();
template.attr({ 'chid': id, 'id': `CharID${id}` }); template.attr({ 'data-chid': id, 'id': `CharID${id}` });
template.find('img').attr('src', this_avatar).attr('alt', item.name); template.find('img').attr('src', this_avatar).attr('alt', item.name);
template.find('.avatar').attr('title', `[Character] ${item.name}\nFile: ${item.avatar}`); template.find('.avatar').attr('title', `[Character] ${item.name}\nFile: ${item.avatar}`);
template.find('.ch_name').text(item.name).attr('title', `[Character] ${item.name}`); template.find('.ch_name').text(item.name).attr('title', `[Character] ${item.name}`);
@@ -6191,7 +6199,7 @@ export async function renameCharacter(name = null, { silent = false, renameChats
if (newChId !== -1) { if (newChId !== -1) {
// Select the character after the renaming // Select the character after the renaming
this_chid = -1; this_chid = -1;
await selectCharacterById(String(newChId)); await selectCharacterById(newChId);
// Async delay to update UI // Async delay to update UI
await delay(1); await delay(1);
@@ -9878,7 +9886,7 @@ jQuery(async function () {
}); });
$(document).on('click', '.character_select', async function () { $(document).on('click', '.character_select', async function () {
const id = $(this).attr('chid'); const id = Number($(this).attr('data-chid'));
await selectCharacterById(id); await selectCharacterById(id);
}); });

View File

@@ -672,7 +672,7 @@ class BulkEditOverlay {
* @param {HTMLElement} currentCharacter - The html element of the currently toggled character * @param {HTMLElement} currentCharacter - The html element of the currently toggled character
*/ */
handleShiftClick = (currentCharacter) => { handleShiftClick = (currentCharacter) => {
const characterId = currentCharacter.getAttribute('chid'); const characterId = Number(currentCharacter.getAttribute('data-chid'));
const select = !this.selectedCharacters.includes(characterId); const select = !this.selectedCharacters.includes(characterId);
if (this.lastSelected.characterId && this.lastSelected.select !== undefined) { if (this.lastSelected.characterId && this.lastSelected.select !== undefined) {
@@ -691,7 +691,7 @@ class BulkEditOverlay {
* @param {boolean} [param1.markState] - Whether the toggle of this character should be remembered as the last done toggle * @param {boolean} [param1.markState] - Whether the toggle of this character should be remembered as the last done toggle
*/ */
toggleSingleCharacter = (character, { markState = true } = {}) => { toggleSingleCharacter = (character, { markState = true } = {}) => {
const characterId = character.getAttribute('chid'); const characterId = Number(character.getAttribute('data-chid'));
const select = !this.selectedCharacters.includes(characterId); const select = !this.selectedCharacters.includes(characterId);
const legacyBulkEditCheckbox = character.querySelector('.' + BulkEditOverlay.legacySelectedClass); const legacyBulkEditCheckbox = character.querySelector('.' + BulkEditOverlay.legacySelectedClass);
@@ -699,11 +699,11 @@ class BulkEditOverlay {
if (select) { if (select) {
character.classList.add(BulkEditOverlay.selectedClass); character.classList.add(BulkEditOverlay.selectedClass);
if (legacyBulkEditCheckbox) legacyBulkEditCheckbox.checked = true; if (legacyBulkEditCheckbox) legacyBulkEditCheckbox.checked = true;
this.#selectedCharacters.push(String(characterId)); this.#selectedCharacters.push(characterId);
} else { } else {
character.classList.remove(BulkEditOverlay.selectedClass); character.classList.remove(BulkEditOverlay.selectedClass);
if (legacyBulkEditCheckbox) legacyBulkEditCheckbox.checked = false; if (legacyBulkEditCheckbox) legacyBulkEditCheckbox.checked = false;
this.#selectedCharacters = this.#selectedCharacters.filter(item => String(characterId) !== item); this.#selectedCharacters = this.#selectedCharacters.filter(item => characterId !== item);
} }
this.updateSelectedCount(); this.updateSelectedCount();
@@ -732,15 +732,15 @@ class BulkEditOverlay {
* @param {boolean} select - <c>true</c> if the characters in the range are to be selected, <c>false</c> if deselected * @param {boolean} select - <c>true</c> if the characters in the range are to be selected, <c>false</c> if deselected
*/ */
toggleCharactersInRange = (currentCharacter, select) => { toggleCharactersInRange = (currentCharacter, select) => {
const currentCharacterId = currentCharacter.getAttribute('chid'); const currentCharacterId = Number(currentCharacter.getAttribute('data-chid'));
const characters = Array.from(document.querySelectorAll('#' + BulkEditOverlay.containerId + ' .' + BulkEditOverlay.characterClass)); const characters = Array.from(document.querySelectorAll('#' + BulkEditOverlay.containerId + ' .' + BulkEditOverlay.characterClass));
const startIndex = characters.findIndex(c => c.getAttribute('chid') === this.lastSelected.characterId); const startIndex = characters.findIndex(c => Number(c.getAttribute('data-chid')) === Number(this.lastSelected.characterId));
const endIndex = characters.findIndex(c => c.getAttribute('chid') === currentCharacterId); const endIndex = characters.findIndex(c => Number(c.getAttribute('data-chid')) === currentCharacterId);
for (let i = Math.min(startIndex, endIndex); i <= Math.max(startIndex, endIndex); i++) { for (let i = Math.min(startIndex, endIndex); i <= Math.max(startIndex, endIndex); i++) {
const character = characters[i]; const character = characters[i];
const characterId = character.getAttribute('chid'); const characterId = Number(character.getAttribute('data-chid'));
const isCharacterSelected = this.selectedCharacters.includes(characterId); const isCharacterSelected = this.selectedCharacters.includes(characterId);
// Only toggle the character if it wasn't on the state we have are toggling towards. // Only toggle the character if it wasn't on the state we have are toggling towards.

View File

@@ -280,7 +280,7 @@ async function RA_autoloadchat() {
if (active_character !== null && active_character !== undefined) { if (active_character !== null && active_character !== undefined) {
const active_character_id = characters.findIndex(x => getTagKeyForEntity(x) === active_character); const active_character_id = characters.findIndex(x => getTagKeyForEntity(x) === active_character);
if (active_character_id !== null) { if (active_character_id !== null) {
await selectCharacterById(String(active_character_id)); await selectCharacterById(active_character_id);
// Do a little tomfoolery to spoof the tag selector // Do a little tomfoolery to spoof the tag selector
const selectedCharElement = $(`#rm_print_characters_block .character_select[chid="${active_character_id}"]`); const selectedCharElement = $(`#rm_print_characters_block .character_select[chid="${active_character_id}"]`);
@@ -875,14 +875,14 @@ export function initRossMods() {
// when a char is selected from the list, save their name as the auto-load character for next page load // when a char is selected from the list, save their name as the auto-load character for next page load
$(document).on('click', '.character_select', function () { $(document).on('click', '.character_select', function () {
const characterId = $(this).attr('chid') || $(this).data('id'); const characterId = $(this).attr('data-chid');
setActiveCharacter(characterId); setActiveCharacter(characterId);
setActiveGroup(null); setActiveGroup(null);
saveSettingsDebounced(); saveSettingsDebounced();
}); });
$(document).on('click', '.group_select', function () { $(document).on('click', '.group_select', function () {
const groupId = $(this).attr('chid') || $(this).attr('grid') || $(this).data('id'); const groupId = $(this).attr('data-chid') || $(this).attr('data-grid');
setActiveCharacter(null); setActiveCharacter(null);
setActiveGroup(groupId); setActiveGroup(groupId);
saveSettingsDebounced(); saveSettingsDebounced();

View File

@@ -677,7 +677,7 @@ export function getGroupBlock(group) {
const template = $('#group_list_template .group_select').clone(); const template = $('#group_list_template .group_select').clone();
template.data('id', group.id); template.data('id', group.id);
template.attr('grid', group.id); template.attr('data-grid', group.id);
template.find('.ch_name').text(group.name).attr('title', `[Group] ${group.name}`); template.find('.ch_name').text(group.name).attr('title', `[Group] ${group.name}`);
template.find('.group_fav_icon').css('display', 'none'); template.find('.group_fav_icon').css('display', 'none');
template.addClass(group.fav ? 'is_fav' : ''); template.addClass(group.fav ? 'is_fav' : '');
@@ -1364,7 +1364,7 @@ function getGroupCharacterBlock(character) {
template.data('id', character.avatar); template.data('id', character.avatar);
template.find('.avatar img').attr({ 'src': avatar, 'title': character.avatar }); template.find('.avatar img').attr({ 'src': avatar, 'title': character.avatar });
template.find('.ch_name').text(character.name); template.find('.ch_name').text(character.name);
template.attr('chid', characters.indexOf(character)); template.attr('data-chid', characters.indexOf(character));
template.find('.ch_fav').val(isFav); template.find('.ch_fav').val(isFav);
template.toggleClass('is_fav', isFav); template.toggleClass('is_fav', isFav);
@@ -1641,7 +1641,7 @@ async function onGroupActionClick(event) {
} }
if (action === 'speak') { if (action === 'speak') {
const chid = Number(member.attr('chid')); const chid = Number(member.attr('data-chid'));
if (Number.isInteger(chid)) { if (Number.isInteger(chid)) {
Generate('normal', { force_chid: chid }); Generate('normal', { force_chid: chid });
} }
@@ -1693,7 +1693,7 @@ function openCharacterDefinition(characterSelect) {
return; return;
} }
const chid = characterSelect.attr('chid'); const chid = characterSelect.attr('data-chid');
if (chid === null || chid === undefined) { if (chid === null || chid === undefined) {
return; return;
@@ -2011,7 +2011,7 @@ jQuery(() => {
} }
$(document).on('click', '.group_select', function () { $(document).on('click', '.group_select', function () {
const groupId = $(this).attr('chid') || $(this).attr('grid') || $(this).data('id'); const groupId = $(this).attr('data-chid') || $(this).attr('data-grid');
openGroupById(groupId); openGroupById(groupId);
}); });
$('#rm_group_filter').on('input', filterGroupMembers); $('#rm_group_filter').on('input', filterGroupMembers);

View File

@@ -1163,7 +1163,7 @@ function updatePersonaLockIcons() {
$('#lock_persona_to_char i.icon').toggleClass('fa-unlock', !hasCharLock); $('#lock_persona_to_char i.icon').toggleClass('fa-unlock', !hasCharLock);
} }
async function setChatLockedPersona() { async function loadPersonaForCurrentChat() {
// Cache persona list to check if they exist // Cache persona list to check if they exist
const userAvatars = await getUserAvatars(false); const userAvatars = await getUserAvatars(false);
@@ -1484,6 +1484,6 @@ export function initPersonas() {
convertCharacterToPersona(); convertCharacterToPersona();
} }
}); });
eventSource.on(event_types.CHAT_CHANGED, setChatLockedPersona); eventSource.on(event_types.CHAT_CHANGED, loadPersonaForCurrentChat);
switchPersonaGridView(); switchPersonaGridView();
} }

View File

@@ -485,8 +485,8 @@ export function getTagKeyForEntityElement(element) {
} }
// Start with the given element and traverse up the DOM tree // Start with the given element and traverse up the DOM tree
while (element.length && element.parent().length) { while (element.length && element.parent().length) {
const grid = element.attr('grid'); const grid = element.attr('data-grid');
const chid = element.attr('chid'); const chid = element.attr('data-chid');
if (grid || chid) { if (grid || chid) {
const id = grid || chid; const id = grid || chid;
return getTagKeyForEntity(id); return getTagKeyForEntity(id);

View File

@@ -4731,7 +4731,7 @@ export function checkEmbeddedWorld(chid) {
} }
if (characters[chid]?.data?.character_book) { if (characters[chid]?.data?.character_book) {
$('#import_character_info').data('chid', chid).show(); $('#import_character_info').data('data-chid', chid).show();
// Only show the alert once per character // Only show the alert once per character
const checkKey = `AlertWI_${characters[chid].avatar}`; const checkKey = `AlertWI_${characters[chid].avatar}`;
@@ -4765,7 +4765,7 @@ export function checkEmbeddedWorld(chid) {
} }
export async function importEmbeddedWorldInfo(skipPopup = false) { export async function importEmbeddedWorldInfo(skipPopup = false) {
const chid = $('#import_character_info').data('chid'); const chid = $('#import_character_info').data('data-chid');
if (chid === undefined) { if (chid === undefined) {
return; return;
@@ -5149,7 +5149,7 @@ jQuery(() => {
}); });
$('#world_button').on('click', async function (event) { $('#world_button').on('click', async function (event) {
const chid = $('#set_character_world').data('chid'); const chid = $('#set_character_world').data('data-chid');
if (chid) { if (chid) {
const worldName = characters[chid]?.data?.extensions?.world; const worldName = characters[chid]?.data?.extensions?.world;