|
1 | 1 | /* eslint-disable dci-lint/atomic-role-binding */
|
2 | 2 | import type { TaintedFields, SuperFormValidated, SuperValidated } from '$lib/superValidate.js';
|
3 |
| -import type { ActionResult, Page, SubmitFunction } from '@sveltejs/kit'; |
| 3 | +import type { ActionResult, BeforeNavigate, Page, SubmitFunction } from '@sveltejs/kit'; |
4 | 4 | import {
|
5 | 5 | derived,
|
6 | 6 | get,
|
@@ -1353,50 +1353,53 @@ export function superForm<
|
1353 | 1353 |
|
1354 | 1354 | ///// Store subscriptions ///////////////////////////////////////////////////
|
1355 | 1355 |
|
1356 |
| - if (browser) { |
1357 |
| - // Tainted check |
1358 |
| - const defaultMessage = 'Leave page? Changes that you made may not be saved.'; |
1359 |
| - let forceRedirection = false; |
1360 |
| - beforeNavigate(async (nav) => { |
1361 |
| - if (options.taintedMessage && !Data.submitting && !forceRedirection) { |
1362 |
| - if (Tainted_isTainted()) { |
1363 |
| - const { taintedMessage } = options; |
1364 |
| - const isTaintedFunction = typeof taintedMessage === 'function'; |
1365 |
| - |
1366 |
| - // As beforeNavigate does not support Promise, we cancel the redirection until the promise resolve |
1367 |
| - // if it's a custom function |
1368 |
| - if (isTaintedFunction) nav.cancel(); |
1369 |
| - // Does not display any dialog on page refresh or closing tab, will use default browser behaviour |
1370 |
| - if (nav.type === 'leave') return; |
1371 |
| - |
1372 |
| - const message = |
1373 |
| - isTaintedFunction || taintedMessage === true ? defaultMessage : taintedMessage; |
1374 |
| - |
1375 |
| - let shouldRedirect; |
1376 |
| - try { |
1377 |
| - // - rejected => shouldRedirect = false |
1378 |
| - // - resolved with false => shouldRedirect = false |
1379 |
| - // - resolved with true => shouldRedirect = true |
1380 |
| - shouldRedirect = isTaintedFunction ? await taintedMessage() : window.confirm(message); |
1381 |
| - } catch { |
1382 |
| - shouldRedirect = false; |
1383 |
| - } |
| 1356 | + // Tainted check |
| 1357 | + const defaultMessage = 'Leave page? Changes that you made may not be saved.'; |
| 1358 | + let forceRedirection = false; |
| 1359 | + |
| 1360 | + async function taintedCheck(nav: BeforeNavigate) { |
| 1361 | + if (options.taintedMessage && !Data.submitting && !forceRedirection) { |
| 1362 | + if (Tainted_isTainted()) { |
| 1363 | + const { taintedMessage } = options; |
| 1364 | + const isTaintedFunction = typeof taintedMessage === 'function'; |
| 1365 | + |
| 1366 | + // As beforeNavigate does not support Promise, we cancel the redirection until the promise resolve |
| 1367 | + // if it's a custom function |
| 1368 | + if (isTaintedFunction) nav.cancel(); |
| 1369 | + // Does not display any dialog on page refresh or closing tab, will use default browser behaviour |
| 1370 | + if (nav.type === 'leave') return; |
| 1371 | + |
| 1372 | + const message = |
| 1373 | + isTaintedFunction || taintedMessage === true ? defaultMessage : taintedMessage; |
| 1374 | + |
| 1375 | + let shouldRedirect; |
| 1376 | + try { |
| 1377 | + // - rejected => shouldRedirect = false |
| 1378 | + // - resolved with false => shouldRedirect = false |
| 1379 | + // - resolved with true => shouldRedirect = true |
| 1380 | + shouldRedirect = isTaintedFunction ? await taintedMessage() : window.confirm(message); |
| 1381 | + } catch { |
| 1382 | + shouldRedirect = false; |
| 1383 | + } |
1384 | 1384 |
|
1385 |
| - if (shouldRedirect && nav.to) { |
1386 |
| - try { |
1387 |
| - forceRedirection = true; |
1388 |
| - await goto(nav.to.url, { ...nav.to.params }); |
1389 |
| - return; |
1390 |
| - } finally { |
1391 |
| - // Reset forceRedirection for multiple-tainted purpose |
1392 |
| - forceRedirection = false; |
1393 |
| - } |
1394 |
| - } else if (!shouldRedirect && !isTaintedFunction) { |
1395 |
| - nav.cancel(); |
| 1385 | + if (shouldRedirect && nav.to) { |
| 1386 | + try { |
| 1387 | + forceRedirection = true; |
| 1388 | + await goto(nav.to.url, { ...nav.to.params }); |
| 1389 | + return; |
| 1390 | + } finally { |
| 1391 | + // Reset forceRedirection for multiple-tainted purpose |
| 1392 | + forceRedirection = false; |
1396 | 1393 | }
|
| 1394 | + } else if (!shouldRedirect && !isTaintedFunction) { |
| 1395 | + nav.cancel(); |
1397 | 1396 | }
|
1398 | 1397 | }
|
1399 |
| - }); |
| 1398 | + } |
| 1399 | + } |
| 1400 | + |
| 1401 | + if (browser) { |
| 1402 | + beforeNavigate(taintedCheck); |
1400 | 1403 |
|
1401 | 1404 | // Need to subscribe to catch page invalidation.
|
1402 | 1405 | Unsubscriptions_add(
|
|
0 commit comments