mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-02-03 04:37:40 +01:00
Merge pull request #2520 from SillyTavern/popup-onclosing-fix
Fix popup onClosing handling not working correctly
This commit is contained in:
commit
ecceeec62a
@ -135,6 +135,7 @@ export class Popup {
|
||||
|
||||
/** @type {Promise<any>} */ #promise;
|
||||
/** @type {(result: any) => any} */ #resolver;
|
||||
/** @type {boolean} */ #isClosingPrevented;
|
||||
|
||||
/**
|
||||
* Constructs a new Popup object with the given text content, type, inputValue, and options
|
||||
@ -334,10 +335,21 @@ export class Popup {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
await this.complete(POPUP_RESULT.CANCELLED);
|
||||
window.removeEventListener('cancel', cancelListenerBound);
|
||||
};
|
||||
const cancelListenerBound = cancelListener.bind(this);
|
||||
this.dlg.addEventListener('cancel', cancelListenerBound);
|
||||
this.dlg.addEventListener('cancel', cancelListener.bind(this));
|
||||
|
||||
// Don't ask me why this is needed. I don't get it. But we have to keep it.
|
||||
// We make sure that the modal on it's own doesn't hide. Dunno why, if onClosing is triggered multiple times through the cancel event, and stopped
|
||||
// It seems to just call 'close' on the dialog even if the 'cancel' event was prevented.
|
||||
// Here, we just say that close should not happen if the dalog has no result.
|
||||
const closeListener = async (evt) => {
|
||||
if (this.#isClosingPrevented) {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
this.dlg.showModal();
|
||||
}
|
||||
};
|
||||
this.dlg.addEventListener('close', closeListener.bind(this));
|
||||
|
||||
const keyListener = async (evt) => {
|
||||
switch (evt.key) {
|
||||
@ -366,16 +378,16 @@ export class Popup {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
const result = Number(document.activeElement.getAttribute('data-result') ?? this.defaultResult);
|
||||
|
||||
// Call complete on the popup. Make sure that we handle `onClosing` cancels correctly and don't remove the listener then.
|
||||
await this.complete(result);
|
||||
window.removeEventListener('keydown', keyListenerBound);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
const keyListenerBound = keyListener.bind(this);
|
||||
this.dlg.addEventListener('keydown', keyListenerBound);
|
||||
this.dlg.addEventListener('keydown', keyListener.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -445,9 +457,11 @@ export class Popup {
|
||||
* - popup with `POPUP_TYPE.INPUT` will return the input value - or `false` on negative and `null` on cancelled
|
||||
* - All other will return the result value as provided as `POPUP_RESULT` or a custom number value
|
||||
*
|
||||
* <b>IMPORTANT:</b> If the popup closing was cancelled via the `onClosing` handler, the return value will be `Promise<undefined>`.
|
||||
*
|
||||
* @param {POPUP_RESULT|number} result - The result of the popup (either an existing `POPUP_RESULT` or a custom result value)
|
||||
*
|
||||
* @returns {Promise<string|number|boolean?>} A promise that resolves with the value of the popup when it is completed.
|
||||
* @returns {Promise<string|number|boolean|undefined?>} A promise that resolves with the value of the popup when it is completed. <b>Returns `undefined` if the closing action was cancelled.</b>
|
||||
*/
|
||||
async complete(result) {
|
||||
// In all cases besides INPUT the popup value should be the result
|
||||
@ -481,8 +495,16 @@ export class Popup {
|
||||
|
||||
if (this.onClosing) {
|
||||
const shouldClose = this.onClosing(this);
|
||||
if (!shouldClose) return;
|
||||
if (!shouldClose) {
|
||||
this.#isClosingPrevented = true;
|
||||
// Set values back if we cancel out of closing the popup
|
||||
this.value = undefined;
|
||||
this.result = undefined;
|
||||
this.inputResults = undefined;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
this.#isClosingPrevented = false;
|
||||
|
||||
Popup.util.lastResult = { value, result, inputResults: this.inputResults };
|
||||
this.#hide();
|
||||
|
Loading…
x
Reference in New Issue
Block a user