From a05d3ca8314b013342f1c0194650c4c73ce0648e Mon Sep 17 00:00:00 2001 From: LeRatierBretonnier Date: Sun, 24 May 2026 13:56:31 +0200 Subject: [PATCH] Fix ApplicationV2 jQuery parameter handling in _onRender methods - Fixed TypeError in PlayerPrivacyPanel._onRender: element.querySelector is not a function - Root cause: FoundryVTT v14 ApplicationV2 passes jQuery objects to _onRender, not plain HTMLElements - Solution: Normalize parameter to element with querySelector method: - If HTMLElement, use directly - If jQuery (has [0]), use html[0] - Otherwise, use as-is (for test mocks) - Applied fix to: - PlayerPrivacyPanel._onRender - PresetSaveDialog._onRender - PresetLoadDialog._onRender - All 900 unit tests passing Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe --- src/ui/gm/PresetLoadDialog.js | 11 +++++++++-- src/ui/gm/PresetSaveDialog.js | 11 +++++++++-- src/ui/player/PlayerPrivacyPanel.js | 11 +++++++++-- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/ui/gm/PresetLoadDialog.js b/src/ui/gm/PresetLoadDialog.js index 27f121b..e7e9aef 100644 --- a/src/ui/gm/PresetLoadDialog.js +++ b/src/ui/gm/PresetLoadDialog.js @@ -89,9 +89,16 @@ export class PresetLoadDialog extends _AppBase { /** * Sets up event handlers after rendering. - * @param {HTMLElement} element - The dialog element. + * @param {HTMLElement|JQuery|object} html - The dialog element, jQuery object, or plain object with querySelector. */ - _onRender(element) { + _onRender(html) { + // Normalize html to element with querySelector + // FoundryVTT ApplicationV2 passes jQuery object, tests pass plain objects + const element = html instanceof HTMLElement + ? html + : (html?.[0] ?? html); + if (!element || typeof element.querySelector !== 'function') return; + // Set up load button handlers for each preset const loadButtons = element.querySelectorAll('[data-action="load"]'); loadButtons.forEach((btn) => { diff --git a/src/ui/gm/PresetSaveDialog.js b/src/ui/gm/PresetSaveDialog.js index 3ebfc04..a7b91a0 100644 --- a/src/ui/gm/PresetSaveDialog.js +++ b/src/ui/gm/PresetSaveDialog.js @@ -86,9 +86,16 @@ export class PresetSaveDialog extends _AppBase { /** * Sets up event handlers after rendering. - * @param {HTMLElement} element - The dialog element. + * @param {HTMLElement|JQuery|object} html - The dialog element, jQuery object, or plain object with querySelector. */ - _onRender(element) { + _onRender(html) { + // Normalize html to element with querySelector + // FoundryVTT ApplicationV2 passes jQuery object, tests pass plain objects + const element = html instanceof HTMLElement + ? html + : (html?.[0] ?? html); + if (!element || typeof element.querySelector !== 'function') return; + // Cache the name input this._nameInput = element.querySelector('[name="presetName"]'); diff --git a/src/ui/player/PlayerPrivacyPanel.js b/src/ui/player/PlayerPrivacyPanel.js index f63387d..c4fe5b5 100644 --- a/src/ui/player/PlayerPrivacyPanel.js +++ b/src/ui/player/PlayerPrivacyPanel.js @@ -187,9 +187,16 @@ export class PlayerPrivacyPanel extends _AppBase { /** * Sets up event handlers after rendering. - * @param {HTMLElement} element - The dialog element. + * @param {HTMLElement|JQuery|object} html - The dialog element, jQuery object, or plain object with querySelector. */ - _onRender(element) { + _onRender(html) { + // Normalize html to element with querySelector + // FoundryVTT ApplicationV2 passes jQuery object, tests pass plain objects + const element = html instanceof HTMLElement + ? html + : (html?.[0] ?? html); + if (!element || typeof element.querySelector !== 'function') return; + // Cache toggle elements this._reactionCamToggle = element.querySelector('[data-setting="reactionCamEnabled"]'); this._hpReactiveCamToggle = element.querySelector('[data-setting="hpReactiveCamStylingEnabled"]');