diff --git a/packages/signalizejs/src/modules/spa.js b/packages/signalizejs/src/modules/spa.js index ace9b17..521c7a5 100755 --- a/packages/signalizejs/src/modules/spa.js +++ b/packages/signalizejs/src/modules/spa.js @@ -12,6 +12,9 @@ export default async ({ params, resolve, root }, config) => { const spaUrlAttribute = `${spaAttribute}${params.attributeSeparator}url`; const spaIgnoreAttribute = `${spaAttribute}${params.attributeSeparator}ignore`; const spaStateActionAttribute = `${spaAttribute}${params.attributeSeparator}state-action`; + const spaProcessingLabelAttribute = `${spaAttribute}${params.attributeSeparator}processing-label`; + const spaConfirmAttribute = `${spaAttribute}${params.attributeSeparator}confirm-message`; + const spaHttpMethodAttribute = `${spaAttribute}${params.attributeSeparator}http-method`; const spaMetaCacheNameAttribute = `${spaAttribute}${params.attributeSeparator}cache-control`; const spaHeaderPrefix = 'X-Spa-'; const spaCacheHeader = config?.cacheHeader ?? `${spaHeaderPrefix}Cache-Control`; @@ -76,9 +79,6 @@ export default async ({ params, resolve, root }, config) => { /** @type {import('../../types/modules/spa').navigate} */ const navigate = async (data) => { updateCurrentState(); - if (typeof data === 'string') { - data = { url: data }; - } firstNavigationTriggered = true; /** @type {import('../../types/modules/spa.d.ts').NavigationEventData} */ @@ -104,7 +104,7 @@ export default async ({ params, resolve, root }, config) => { } abortNavigationRequestController = new AbortController(); - const { stateAction = defaultStateAction } = data; + const { stateAction = defaultStateAction, httpMethod } = data; const url = data.url instanceof URL ? data.url : createUrl(data.url); if (url === null) { @@ -114,7 +114,7 @@ export default async ({ params, resolve, root }, config) => { const currentLocation = getCurrentLocation(); const onlyHashChanged = url.pathname === currentLocation.pathname && url.hash !== currentLocation.hash; const shouldTriggerNavigation = !onlyHashChanged; - const urlString = url.toString(); + let urlString = url.toString(); /** @type {import('../../types/modules/ajax.d.ts').AjaxReturn} */ let navigationResponse; @@ -133,6 +133,7 @@ export default async ({ params, resolve, root }, config) => { navigationRequestIsRunning = true; navigationResponse = await ajax(urlString, { + method: httpMethod ?? 'GET', signal: abortNavigationRequestController.signal, headers: { Accept: 'text/html, application/xhtml+xml' @@ -144,9 +145,9 @@ export default async ({ params, resolve, root }, config) => { const requestIsWithoutErroor = navigationResponse.error === null; if (requestIsWithoutErroor) { + console.log(navigationResponse); if (navigationResponse.response.redirected) { - window.location = navigationRequestIsRunning.response.url; - return; + urlString = navigationResponse.response.url; } try { @@ -211,6 +212,7 @@ export default async ({ params, resolve, root }, config) => { scrollX: data.scrollX ?? window.scrollX, scrollY: data.scrollY ?? window.scrollY }; + console.log(urlString); window.history.pushState(currentState, '', urlString); } @@ -366,10 +368,28 @@ export default async ({ params, resolve, root }, config) => { stateAction = stateActionAttribute; } - void navigate({ + const confirmMessage = element.getAttribute(spaConfirmAttribute); + if (confirmMessage && !confirm(confirmMessage)) { + return; + } + + const processingLabel = element.getAttribute(spaProcessingLabelAttribute); + let previousLabel = null; + + if (processingLabel) { + previousLabel = element.innerHTML; + element.innerHTML = processingLabel; + } + + await navigate({ + httpMethod: element.getAttribute(spaHttpMethodAttribute), url, stateAction }); + + if (previousLabel !== null) { + element.innerHTML = previousLabel; + } }; const updateCurrentState = () => { diff --git a/packages/signalizejs/types/modules/spa.d.ts b/packages/signalizejs/types/modules/spa.d.ts index b2584eb..35decdd 100644 --- a/packages/signalizejs/types/modules/spa.d.ts +++ b/packages/signalizejs/types/modules/spa.d.ts @@ -2,6 +2,7 @@ export type StateAction = 'push' | 'replace'; export interface NavigationData { + httpMethod?: string|null /** The URL for navigation. */ url: string|URL; /** The scroll position on the X-axis. */ @@ -37,6 +38,7 @@ export interface SpaConfig { } export interface HistoryState { + httpMethod?: string /** Current state url. */ url: string; /** If the state is triggered by spa */