Refactor chid/grid attributes to data attributes - We don't believe in imaginary HTML attributes that we make up, right?
| @@ -1342,6 +1342,14 @@ export function resultCheckStatus() { | |||
| 1342 | stopStatusLoading(); | 1342 | stopStatusLoading(); |
| 1343 | } | 1343 | } |
| 1344 | 1344 | ||
| 1345 | |||
| 1346 | /** | ||
| 1347 | * Switches the currently selected character to the one with the given ID. (character index, not the character key!) | ||
| 1348 | * | ||
| 1349 | * If the character ID doesn't exist, if the chat is being saved, or if a group is being generated, this function does nothing. | ||
| 1350 | * If the character is different from the currently selected one, it will clear the chat and reset any selected character or group. | ||
| 1351 | * @param {number} id The ID of the character to switch to. | ||
| 1352 | */ | ||
| 1345 | export async function selectCharacterById(id) { | 1353 | export async function selectCharacterById(id) { |
| 1346 | if (characters[id] === undefined) { | 1354 | if (characters[id] === undefined) { |
| 1347 | return; | 1355 | return; |
| @@ -1415,7 +1423,7 @@ function getCharacterBlock(item, id) { | |||
| 1415 | } | 1423 | } |
| 1416 | // Populate the template | 1424 | // Populate the template |
| 1417 | const template = $('#character_template .character_select').clone(); | 1425 | const template = $('#character_template .character_select').clone(); |
| 1418 | template.attr({ 'chid': id, 'id': `CharID${id}` }); | 1426 | template.attr({ 'data-chid': id, 'id': `CharID${id}` }); |
| 1419 | template.find('img').attr('src', this_avatar).attr('alt', item.name); | 1427 | template.find('img').attr('src', this_avatar).attr('alt', item.name); |
| 1420 | template.find('.avatar').attr('title', `[Character] ${item.name}\nFile: ${item.avatar}`); | 1428 | template.find('.avatar').attr('title', `[Character] ${item.name}\nFile: ${item.avatar}`); |
| 1421 | template.find('.ch_name').text(item.name).attr('title', `[Character] ${item.name}`); | 1429 | 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 | |||
| 6191 | if (newChId !== -1) { | 6199 | if (newChId !== -1) { |
| 6192 | // Select the character after the renaming | 6200 | // Select the character after the renaming |
| 6193 | this_chid = -1; | 6201 | this_chid = -1; |
| 6194 | await selectCharacterById(String(newChId)); | 6202 | await selectCharacterById(newChId); |
| 6195 | 6203 | ||
| 6196 | // Async delay to update UI | 6204 | // Async delay to update UI |
| 6197 | await delay(1); | 6205 | await delay(1); |
| @@ -9878,7 +9886,7 @@ jQuery(async function () { | |||
| 9878 | }); | 9886 | }); |
| 9879 | 9887 | ||
| 9880 | $(document).on('click', '.character_select', async function () { | 9888 | $(document).on('click', '.character_select', async function () { |
| 9881 | const id = $(this).attr('chid'); | 9889 | const id = Number($(this).attr('data-chid')); |
| 9882 | await selectCharacterById(id); | 9890 | await selectCharacterById(id); |
| 9883 | }); | 9891 | }); |
| 9884 | 9892 | ||
| @@ -672,7 +672,7 @@ class BulkEditOverlay { | |||
| 672 | * @param {HTMLElement} currentCharacter - The html element of the currently toggled character | 672 | * @param {HTMLElement} currentCharacter - The html element of the currently toggled character |
| 673 | */ | 673 | */ |
| 674 | handleShiftClick = (currentCharacter) => { | 674 | handleShiftClick = (currentCharacter) => { |
| 675 | const characterId = currentCharacter.getAttribute('chid'); | 675 | const characterId = Number(currentCharacter.getAttribute('data-chid')); |
| 676 | const select = !this.selectedCharacters.includes(characterId); | 676 | const select = !this.selectedCharacters.includes(characterId); |
| 677 | 677 | ||
| 678 | if (this.lastSelected.characterId && this.lastSelected.select !== undefined) { | 678 | if (this.lastSelected.characterId && this.lastSelected.select !== undefined) { |
| @@ -691,7 +691,7 @@ class BulkEditOverlay { | |||
| 691 | * @param {boolean} [param1.markState] - Whether the toggle of this character should be remembered as the last done toggle | 691 | * @param {boolean} [param1.markState] - Whether the toggle of this character should be remembered as the last done toggle |
| 692 | */ | 692 | */ |
| 693 | toggleSingleCharacter = (character, { markState = true } = {}) => { | 693 | toggleSingleCharacter = (character, { markState = true } = {}) => { |
| 694 | const characterId = character.getAttribute('chid'); | 694 | const characterId = Number(character.getAttribute('data-chid')); |
| 695 | 695 | ||
| 696 | const select = !this.selectedCharacters.includes(characterId); | 696 | const select = !this.selectedCharacters.includes(characterId); |
| 697 | const legacyBulkEditCheckbox = character.querySelector('.' + BulkEditOverlay.legacySelectedClass); | 697 | const legacyBulkEditCheckbox = character.querySelector('.' + BulkEditOverlay.legacySelectedClass); |
| @@ -699,11 +699,11 @@ class BulkEditOverlay { | |||
| 699 | if (select) { | 699 | if (select) { |
| 700 | character.classList.add(BulkEditOverlay.selectedClass); | 700 | character.classList.add(BulkEditOverlay.selectedClass); |
| 701 | if (legacyBulkEditCheckbox) legacyBulkEditCheckbox.checked = true; | 701 | if (legacyBulkEditCheckbox) legacyBulkEditCheckbox.checked = true; |
| 702 | this.#selectedCharacters.push(String(characterId)); | 702 | this.#selectedCharacters.push(characterId); |
| 703 | } else { | 703 | } else { |
| 704 | character.classList.remove(BulkEditOverlay.selectedClass); | 704 | character.classList.remove(BulkEditOverlay.selectedClass); |
| 705 | if (legacyBulkEditCheckbox) legacyBulkEditCheckbox.checked = false; | 705 | if (legacyBulkEditCheckbox) legacyBulkEditCheckbox.checked = false; |
| 706 | this.#selectedCharacters = this.#selectedCharacters.filter(item => String(characterId) !== item); | 706 | this.#selectedCharacters = this.#selectedCharacters.filter(item => characterId !== item); |
| 707 | } | 707 | } |
| 708 | 708 | ||
| 709 | this.updateSelectedCount(); | 709 | this.updateSelectedCount(); |
| @@ -732,15 +732,15 @@ class BulkEditOverlay { | |||
| 732 | * @param {boolean} select - <c>true</c> if the characters in the range are to be selected, <c>false</c> if deselected | 732 | * @param {boolean} select - <c>true</c> if the characters in the range are to be selected, <c>false</c> if deselected |
| 733 | */ | 733 | */ |
| 734 | toggleCharactersInRange = (currentCharacter, select) => { | 734 | toggleCharactersInRange = (currentCharacter, select) => { |
| 735 | const currentCharacterId = currentCharacter.getAttribute('chid'); | 735 | const currentCharacterId = Number(currentCharacter.getAttribute('data-chid')); |
| 736 | const characters = Array.from(document.querySelectorAll('#' + BulkEditOverlay.containerId + ' .' + BulkEditOverlay.characterClass)); | 736 | const characters = Array.from(document.querySelectorAll('#' + BulkEditOverlay.containerId + ' .' + BulkEditOverlay.characterClass)); |
| 737 | 737 | ||
| 738 | const startIndex = characters.findIndex(c => c.getAttribute('chid') === this.lastSelected.characterId); | 738 | const startIndex = characters.findIndex(c => Number(c.getAttribute('data-chid')) === Number(this.lastSelected.characterId)); |
| 739 | const endIndex = characters.findIndex(c => c.getAttribute('chid') === currentCharacterId); | 739 | const endIndex = characters.findIndex(c => Number(c.getAttribute('data-chid')) === currentCharacterId); |
| 740 | 740 | ||
| 741 | for (let i = Math.min(startIndex, endIndex); i <= Math.max(startIndex, endIndex); i++) { | 741 | for (let i = Math.min(startIndex, endIndex); i <= Math.max(startIndex, endIndex); i++) { |
| 742 | const character = characters[i]; | 742 | const character = characters[i]; |
| 743 | const characterId = character.getAttribute('chid'); | 743 | const characterId = Number(character.getAttribute('data-chid')); |
| 744 | const isCharacterSelected = this.selectedCharacters.includes(characterId); | 744 | const isCharacterSelected = this.selectedCharacters.includes(characterId); |
| 745 | 745 | ||
| 746 | // Only toggle the character if it wasn't on the state we have are toggling towards. | 746 | // Only toggle the character if it wasn't on the state we have are toggling towards. |
| @@ -280,7 +280,7 @@ async function RA_autoloadchat() { | |||
| 280 | if (active_character !== null && active_character !== undefined) { | 280 | if (active_character !== null && active_character !== undefined) { |
| 281 | const active_character_id = characters.findIndex(x => getTagKeyForEntity(x) === active_character); | 281 | const active_character_id = characters.findIndex(x => getTagKeyForEntity(x) === active_character); |
| 282 | if (active_character_id !== null) { | 282 | if (active_character_id !== null) { |
| 283 | await selectCharacterById(String(active_character_id)); | 283 | await selectCharacterById(active_character_id); |
| 284 | 284 | ||
| 285 | // Do a little tomfoolery to spoof the tag selector | 285 | // Do a little tomfoolery to spoof the tag selector |
| 286 | const selectedCharElement = $(`#rm_print_characters_block .character_select[chid="${active_character_id}"]`); | 286 | const selectedCharElement = $(`#rm_print_characters_block .character_select[chid="${active_character_id}"]`); |
| @@ -875,14 +875,14 @@ export function initRossMods() { | |||
| 875 | 875 | ||
| 876 | // when a char is selected from the list, save their name as the auto-load character for next page load | 876 | // when a char is selected from the list, save their name as the auto-load character for next page load |
| 877 | $(document).on('click', '.character_select', function () { | 877 | $(document).on('click', '.character_select', function () { |
| 878 | const characterId = $(this).attr('chid') || $(this).data('id'); | 878 | const characterId = $(this).attr('data-chid'); |
| 879 | setActiveCharacter(characterId); | 879 | setActiveCharacter(characterId); |
| 880 | setActiveGroup(null); | 880 | setActiveGroup(null); |
| 881 | saveSettingsDebounced(); | 881 | saveSettingsDebounced(); |
| 882 | }); | 882 | }); |
| 883 | 883 | ||
| 884 | $(document).on('click', '.group_select', function () { | 884 | $(document).on('click', '.group_select', function () { |
| 885 | const groupId = $(this).attr('chid') || $(this).attr('grid') || $(this).data('id'); | 885 | const groupId = $(this).attr('data-chid') || $(this).attr('data-grid'); |
| 886 | setActiveCharacter(null); | 886 | setActiveCharacter(null); |
| 887 | setActiveGroup(groupId); | 887 | setActiveGroup(groupId); |
| 888 | saveSettingsDebounced(); | 888 | saveSettingsDebounced(); |
| @@ -677,7 +677,7 @@ export function getGroupBlock(group) { | |||
| 677 | 677 | ||
| 678 | const template = $('#group_list_template .group_select').clone(); | 678 | const template = $('#group_list_template .group_select').clone(); |
| 679 | template.data('id', group.id); | 679 | template.data('id', group.id); |
| 680 | template.attr('grid', group.id); | 680 | template.attr('data-grid', group.id); |
| 681 | template.find('.ch_name').text(group.name).attr('title', `[Group] ${group.name}`); | 681 | template.find('.ch_name').text(group.name).attr('title', `[Group] ${group.name}`); |
| 682 | template.find('.group_fav_icon').css('display', 'none'); | 682 | template.find('.group_fav_icon').css('display', 'none'); |
| 683 | template.addClass(group.fav ? 'is_fav' : ''); | 683 | template.addClass(group.fav ? 'is_fav' : ''); |
| @@ -1364,7 +1364,7 @@ function getGroupCharacterBlock(character) { | |||
| 1364 | template.data('id', character.avatar); | 1364 | template.data('id', character.avatar); |
| 1365 | template.find('.avatar img').attr({ 'src': avatar, 'title': character.avatar }); | 1365 | template.find('.avatar img').attr({ 'src': avatar, 'title': character.avatar }); |
| 1366 | template.find('.ch_name').text(character.name); | 1366 | template.find('.ch_name').text(character.name); |
| 1367 | template.attr('chid', characters.indexOf(character)); | 1367 | template.attr('data-chid', characters.indexOf(character)); |
| 1368 | template.find('.ch_fav').val(isFav); | 1368 | template.find('.ch_fav').val(isFav); |
| 1369 | template.toggleClass('is_fav', isFav); | 1369 | template.toggleClass('is_fav', isFav); |
| 1370 | 1370 | ||
| @@ -1641,7 +1641,7 @@ async function onGroupActionClick(event) { | |||
| 1641 | } | 1641 | } |
| 1642 | 1642 | ||
| 1643 | if (action === 'speak') { | 1643 | if (action === 'speak') { |
| 1644 | const chid = Number(member.attr('chid')); | 1644 | const chid = Number(member.attr('data-chid')); |
| 1645 | if (Number.isInteger(chid)) { | 1645 | if (Number.isInteger(chid)) { |
| 1646 | Generate('normal', { force_chid: chid }); | 1646 | Generate('normal', { force_chid: chid }); |
| 1647 | } | 1647 | } |
| @@ -1693,7 +1693,7 @@ function openCharacterDefinition(characterSelect) { | |||
| 1693 | return; | 1693 | return; |
| 1694 | } | 1694 | } |
| 1695 | 1695 | ||
| 1696 | const chid = characterSelect.attr('chid'); | 1696 | const chid = characterSelect.attr('data-chid'); |
| 1697 | 1697 | ||
| 1698 | if (chid === null || chid === undefined) { | 1698 | if (chid === null || chid === undefined) { |
| 1699 | return; | 1699 | return; |
| @@ -2011,7 +2011,7 @@ jQuery(() => { | |||
| 2011 | } | 2011 | } |
| 2012 | 2012 | ||
| 2013 | $(document).on('click', '.group_select', function () { | 2013 | $(document).on('click', '.group_select', function () { |
| 2014 | const groupId = $(this).attr('chid') || $(this).attr('grid') || $(this).data('id'); | 2014 | const groupId = $(this).attr('data-chid') || $(this).attr('data-grid'); |
| 2015 | openGroupById(groupId); | 2015 | openGroupById(groupId); |
| 2016 | }); | 2016 | }); |
| 2017 | $('#rm_group_filter').on('input', filterGroupMembers); | 2017 | $('#rm_group_filter').on('input', filterGroupMembers); |
| @@ -1163,7 +1163,7 @@ function updatePersonaLockIcons() { | |||
| 1163 | $('#lock_persona_to_char i.icon').toggleClass('fa-unlock', !hasCharLock); | 1163 | $('#lock_persona_to_char i.icon').toggleClass('fa-unlock', !hasCharLock); |
| 1164 | } | 1164 | } |
| 1165 | 1165 | ||
| 1166 | async function setChatLockedPersona() { | 1166 | async function loadPersonaForCurrentChat() { |
| 1167 | // Cache persona list to check if they exist | 1167 | // Cache persona list to check if they exist |
| 1168 | const userAvatars = await getUserAvatars(false); | 1168 | const userAvatars = await getUserAvatars(false); |
| 1169 | 1169 | ||
| @@ -1484,6 +1484,6 @@ export function initPersonas() { | |||
| 1484 | convertCharacterToPersona(); | 1484 | convertCharacterToPersona(); |
| 1485 | } | 1485 | } |
| 1486 | }); | 1486 | }); |
| 1487 | eventSource.on(event_types.CHAT_CHANGED, setChatLockedPersona); | 1487 | eventSource.on(event_types.CHAT_CHANGED, loadPersonaForCurrentChat); |
| 1488 | switchPersonaGridView(); | 1488 | switchPersonaGridView(); |
| 1489 | } | 1489 | } |
| @@ -485,8 +485,8 @@ export function getTagKeyForEntityElement(element) { | |||
| 485 | } | 485 | } |
| 486 | // Start with the given element and traverse up the DOM tree | 486 | // Start with the given element and traverse up the DOM tree |
| 487 | while (element.length && element.parent().length) { | 487 | while (element.length && element.parent().length) { |
| 488 | const grid = element.attr('grid'); | 488 | const grid = element.attr('data-grid'); |
| 489 | const chid = element.attr('chid'); | 489 | const chid = element.attr('data-chid'); |
| 490 | if (grid || chid) { | 490 | if (grid || chid) { |
| 491 | const id = grid || chid; | 491 | const id = grid || chid; |
| 492 | return getTagKeyForEntity(id); | 492 | return getTagKeyForEntity(id); |
| @@ -4731,7 +4731,7 @@ export function checkEmbeddedWorld(chid) { | |||
| 4731 | } | 4731 | } |
| 4732 | 4732 | ||
| 4733 | if (characters[chid]?.data?.character_book) { | 4733 | if (characters[chid]?.data?.character_book) { |
| 4734 | $('#import_character_info').data('chid', chid).show(); | 4734 | $('#import_character_info').data('data-chid', chid).show(); |
| 4735 | 4735 | ||
| 4736 | // Only show the alert once per character | 4736 | // Only show the alert once per character |
| 4737 | const checkKey = `AlertWI_${characters[chid].avatar}`; | 4737 | const checkKey = `AlertWI_${characters[chid].avatar}`; |
| @@ -4765,7 +4765,7 @@ export function checkEmbeddedWorld(chid) { | |||
| 4765 | } | 4765 | } |
| 4766 | 4766 | ||
| 4767 | export async function importEmbeddedWorldInfo(skipPopup = false) { | 4767 | export async function importEmbeddedWorldInfo(skipPopup = false) { |
| 4768 | const chid = $('#import_character_info').data('chid'); | 4768 | const chid = $('#import_character_info').data('data-chid'); |
| 4769 | 4769 | ||
| 4770 | if (chid === undefined) { | 4770 | if (chid === undefined) { |
| 4771 | return; | 4771 | return; |
| @@ -5149,7 +5149,7 @@ jQuery(() => { | |||
| 5149 | }); | 5149 | }); |
| 5150 | 5150 | ||
| 5151 | $('#world_button').on('click', async function (event) { | 5151 | $('#world_button').on('click', async function (event) { |
| 5152 | const chid = $('#set_character_world').data('chid'); | 5152 | const chid = $('#set_character_world').data('data-chid'); |
| 5153 | 5153 | ||
| 5154 | if (chid) { | 5154 | if (chid) { |
| 5155 | const worldName = characters[chid]?.data?.extensions?.world; | 5155 | const worldName = characters[chid]?.data?.extensions?.world; |