@@ -1901,7 +1901,11 @@ var htmx = (function() {
19011901 } else {
19021902 let fragment = makeFragment ( content )
19031903
1904- settleInfo . title = fragment . title
1904+ settleInfo . title = swapOptions . title || fragment . title
1905+ if ( swapOptions . historyRequest ) {
1906+ // @ts -ignore fragment can be a parentNode Element
1907+ fragment = fragment . querySelector ( '[hx-history-elt],[data-hx-history-elt]' ) || fragment
1908+ }
19051909
19061910 // select-oob swaps
19071911 if ( swapOptions . selectOOB ) {
@@ -3271,8 +3275,8 @@ var htmx = (function() {
32713275 */
32723276 function loadHistoryFromServer ( path ) {
32733277 const request = new XMLHttpRequest ( )
3274- const details = { path , xhr : request }
3275- triggerEvent ( getDocument ( ) . body , 'htmx:historyCacheMiss' , details )
3278+ const swapSpec = { swapStyle : 'innerHTML' , swapDelay : 0 , settleDelay : 0 }
3279+ const details = { path , xhr : request , historyElt : getHistoryElement ( ) , swapSpec }
32763280 request . open ( 'GET' , path , true )
32773281 if ( htmx . config . historyRestoreAsHxRequest ) {
32783282 request . setRequestHeader ( 'HX-Request' , 'true' )
@@ -3281,25 +3285,21 @@ var htmx = (function() {
32813285 request . setRequestHeader ( 'HX-Current-URL' , location . href )
32823286 request . onload = function ( ) {
32833287 if ( this . status >= 200 && this . status < 400 ) {
3288+ details . response = this . response
32843289 triggerEvent ( getDocument ( ) . body , 'htmx:historyCacheMissLoad' , details )
3285- const fragment = makeFragment ( this . response )
3286- /** @type ParentNode */
3287- const content = fragment . querySelector ( '[hx-history-elt],[data-hx-history-elt]' ) || fragment
3288- const historyElement = getHistoryElement ( )
3289- const settleInfo = makeSettleInfo ( historyElement )
3290- handleTitle ( fragment . title )
3291-
3292- handlePreservedElements ( fragment )
3293- swapInnerHTML ( historyElement , content , settleInfo )
3294- restorePreservedElements ( )
3295- settleImmediately ( settleInfo . tasks )
3296- currentPathForHistory = path
3297- triggerEvent ( getDocument ( ) . body , 'htmx:historyRestore' , { path, cacheMiss : true , serverResponse : this . response } )
3290+ swap ( details . historyElt , details . response , swapSpec , {
3291+ contextElement : details . historyElt ,
3292+ historyRequest : true
3293+ } )
3294+ currentPathForHistory = details . path
3295+ triggerEvent ( getDocument ( ) . body , 'htmx:historyRestore' , { path, cacheMiss : true , serverResponse : details . response } )
32983296 } else {
32993297 triggerErrorEvent ( getDocument ( ) . body , 'htmx:historyCacheMissLoadError' , details )
33003298 }
33013299 }
3302- request . send ( )
3300+ if ( triggerEvent ( getDocument ( ) . body , 'htmx:historyCacheMiss' , details ) ) {
3301+ request . send ( ) // only send request if event not prevented
3302+ }
33033303 }
33043304
33053305 /**
@@ -3310,19 +3310,16 @@ var htmx = (function() {
33103310 path = path || location . pathname + location . search
33113311 const cached = getCachedHistory ( path )
33123312 if ( cached ) {
3313- const fragment = makeFragment ( cached . content )
3314- const historyElement = getHistoryElement ( )
3315- const settleInfo = makeSettleInfo ( historyElement )
3316- handleTitle ( cached . title )
3317- handlePreservedElements ( fragment )
3318- swapInnerHTML ( historyElement , fragment , settleInfo )
3319- restorePreservedElements ( )
3320- settleImmediately ( settleInfo . tasks )
3321- getWindow ( ) . setTimeout ( function ( ) {
3322- window . scrollTo ( 0 , cached . scroll )
3323- } , 0 ) // next 'tick', so browser has time to render layout
3324- currentPathForHistory = path
3325- triggerEvent ( getDocument ( ) . body , 'htmx:historyRestore' , { path, item : cached } )
3313+ const swapSpec = { swapStyle : 'innerHTML' , swapDelay : 0 , settleDelay : 0 , scroll : cached . scroll }
3314+ const details = { path, item : cached , historyElt : getHistoryElement ( ) , swapSpec }
3315+ if ( triggerEvent ( getDocument ( ) . body , 'htmx:historyCacheHit' , details ) ) {
3316+ swap ( details . historyElt , cached . content , swapSpec , {
3317+ contextElement : details . historyElt ,
3318+ title : cached . title
3319+ } )
3320+ currentPathForHistory = details . path
3321+ triggerEvent ( getDocument ( ) . body , 'htmx:historyRestore' , details )
3322+ }
33263323 } else {
33273324 if ( htmx . config . refreshOnHistoryMiss ) {
33283325 // @ts -ignore: optional parameter in reload() function throws error
@@ -3837,6 +3834,11 @@ var htmx = (function() {
38373834 target = target || last
38383835 target . scrollTop = target . scrollHeight
38393836 }
3837+ if ( typeof swapSpec . scroll === 'number' ) {
3838+ getWindow ( ) . setTimeout ( function ( ) {
3839+ window . scrollTo ( 0 , /** @type number */ ( swapSpec . scroll ) )
3840+ } , 0 ) // next 'tick', so browser has time to render layout
3841+ }
38403842 }
38413843 if ( swapSpec . show ) {
38423844 var target = null
@@ -5121,6 +5123,8 @@ var htmx = (function() {
51215123 * @property {swapCallback } [afterSwapCallback]
51225124 * @property {swapCallback } [afterSettleCallback]
51235125 * @property {swapCallback } [beforeSwapCallback]
5126+ * @property {string } [title]
5127+ * @property {boolean } [historyRequest]
51245128 */
51255129
51265130/**
@@ -5139,7 +5143,7 @@ var htmx = (function() {
51395143 * @property {boolean } [transition]
51405144 * @property {boolean } [ignoreTitle]
51415145 * @property {string } [head]
5142- * @property {'top' | 'bottom' } [scroll]
5146+ * @property {'top' | 'bottom' | number } [scroll]
51435147 * @property {string } [scrollTarget]
51445148 * @property {string } [show]
51455149 * @property {string } [showTarget]
@@ -5184,7 +5188,8 @@ var htmx = (function() {
51845188 * @property {'true' } [HX-History-Restore-Request]
51855189 */
51865190
5187- /** @typedef HtmxAjaxHelperContext
5191+ /**
5192+ * @typedef HtmxAjaxHelperContext
51885193 * @property {Element|string } [source]
51895194 * @property {Event } [event]
51905195 * @property {HtmxAjaxHandler } [handler]
0 commit comments