@@ -12,6 +12,9 @@ export default async ({ params, resolve, root }, config) => {
1212 const spaUrlAttribute = `${ spaAttribute } ${ params . attributeSeparator } url` ;
1313 const spaIgnoreAttribute = `${ spaAttribute } ${ params . attributeSeparator } ignore` ;
1414 const spaStateActionAttribute = `${ spaAttribute } ${ params . attributeSeparator } state-action` ;
15+ const spaProcessingLabelAttribute = `${ spaAttribute } ${ params . attributeSeparator } processing-label` ;
16+ const spaConfirmAttribute = `${ spaAttribute } ${ params . attributeSeparator } confirm-message` ;
17+ const spaHttpMethodAttribute = `${ spaAttribute } ${ params . attributeSeparator } http-method` ;
1518 const spaMetaCacheNameAttribute = `${ spaAttribute } ${ params . attributeSeparator } cache-control` ;
1619 const spaHeaderPrefix = 'X-Spa-' ;
1720 const spaCacheHeader = config ?. cacheHeader ?? `${ spaHeaderPrefix } Cache-Control` ;
@@ -76,6 +79,7 @@ export default async ({ params, resolve, root }, config) => {
7679 /** @type {import('../../types/modules/spa').navigate } */
7780 const navigate = async ( data ) => {
7881 updateCurrentState ( ) ;
82+
7983 if ( typeof data === 'string' ) {
8084 data = { url : data } ;
8185 }
@@ -104,7 +108,7 @@ export default async ({ params, resolve, root }, config) => {
104108 }
105109
106110 abortNavigationRequestController = new AbortController ( ) ;
107- const { stateAction = defaultStateAction } = data ;
111+ const { stateAction = defaultStateAction , httpMethod } = data ;
108112 const url = data . url instanceof URL ? data . url : createUrl ( data . url ) ;
109113
110114 if ( url === null ) {
@@ -114,7 +118,7 @@ export default async ({ params, resolve, root }, config) => {
114118 const currentLocation = getCurrentLocation ( ) ;
115119 const onlyHashChanged = url . pathname === currentLocation . pathname && url . hash !== currentLocation . hash ;
116120 const shouldTriggerNavigation = ! onlyHashChanged ;
117- const urlString = url . toString ( ) ;
121+ let urlString = url . toString ( ) ;
118122
119123 /** @type {import('../../types/modules/ajax.d.ts').AjaxReturn } */
120124 let navigationResponse ;
@@ -133,6 +137,7 @@ export default async ({ params, resolve, root }, config) => {
133137
134138 navigationRequestIsRunning = true ;
135139 navigationResponse = await ajax ( urlString , {
140+ method : httpMethod ?? 'GET' ,
136141 signal : abortNavigationRequestController . signal ,
137142 headers : {
138143 Accept : 'text/html, application/xhtml+xml'
@@ -145,8 +150,7 @@ export default async ({ params, resolve, root }, config) => {
145150
146151 if ( requestIsWithoutErroor ) {
147152 if ( navigationResponse . response . redirected ) {
148- window . location = navigationRequestIsRunning . response . url ;
149- return ;
153+ urlString = navigationResponse . response . url ;
150154 }
151155
152156 try {
@@ -366,10 +370,28 @@ export default async ({ params, resolve, root }, config) => {
366370 stateAction = stateActionAttribute ;
367371 }
368372
369- void navigate ( {
373+ const confirmMessage = element . getAttribute ( spaConfirmAttribute ) ;
374+ if ( confirmMessage && ! confirm ( confirmMessage ) ) {
375+ return ;
376+ }
377+
378+ const processingLabel = element . getAttribute ( spaProcessingLabelAttribute ) ;
379+ let previousLabel = null ;
380+
381+ if ( processingLabel ) {
382+ previousLabel = element . innerHTML ;
383+ element . innerHTML = processingLabel ;
384+ }
385+
386+ await navigate ( {
387+ httpMethod : element . getAttribute ( spaHttpMethodAttribute ) ,
370388 url,
371389 stateAction
372390 } ) ;
391+
392+ if ( previousLabel !== null ) {
393+ element . innerHTML = previousLabel ;
394+ }
373395 } ;
374396
375397 const updateCurrentState = ( ) => {
0 commit comments