From 4184d1fd0cbaebeee155d5947759da1ca206886e Mon Sep 17 00:00:00 2001 From: Jeremiah Johnson Date: Mon, 2 Jun 2025 11:19:11 -0600 Subject: [PATCH] fix(swap): apply swap delay in swap function instead of handleAjaxResponse (#2845) * fix(swap): apply swap delay in swap function instead of handleAjaxResponse * add swap delay test --- src/htmx.js | 35 ++++++++++++++++++++++++++--------- test/core/api.js | 11 +++++++++++ 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/htmx.js b/src/htmx.js index 0ae040d9..a1b1b0b5 100644 --- a/src/htmx.js +++ b/src/htmx.js @@ -1850,6 +1850,30 @@ var htmx = (function() { return oobElts.length > 0 } + /** + * Apply swapping class and then execute the swap with optional delay + * @param {string|Element} target + * @param {string} content + * @param {HtmxSwapSpecification} swapSpec + * @param {SwapOptions} [swapOptions] + */ + function swap(target, content, swapSpec, swapOptions) { + if (!swapOptions) { + swapOptions = {} + } + + target = resolveTarget(target) + target.classList.add(htmx.config.swappingClass) + const localSwap = function() { + runSwap(target, content, swapSpec, swapOptions) + } + if (swapSpec?.swapDelay && swapSpec.swapDelay > 0) { + getWindow().setTimeout(localSwap, swapSpec.swapDelay) + } else { + localSwap() + } + } + /** * Implements complete swapping pipeline, including: focus and selection preservation, * title updates, scroll, OOB swapping, normal swapping and settling @@ -1858,7 +1882,7 @@ var htmx = (function() { * @param {HtmxSwapSpecification} swapSpec * @param {SwapOptions} [swapOptions] */ - function swap(target, content, swapSpec, swapOptions) { + function runSwap(target, content, swapSpec, swapOptions) { if (!swapOptions) { swapOptions = {} } @@ -4790,8 +4814,6 @@ var htmx = (function() { swapSpec.ignoreTitle = ignoreTitle } - target.classList.add(htmx.config.swappingClass) - // optional transition API promise callbacks let settleResolve = null let settleReject = null @@ -4878,12 +4900,7 @@ var htmx = (function() { }) } } - - if (swapSpec.swapDelay > 0) { - getWindow().setTimeout(doSwap, swapSpec.swapDelay) - } else { - doSwap() - } + doSwap() } if (isError) { triggerErrorEvent(elt, 'htmx:responseError', mergeObjects({ error: 'Response Status Error Code ' + xhr.status + ' from ' + responseInfo.pathInfo.requestPath }, responseInfo)) diff --git a/test/core/api.js b/test/core/api.js index 707f262d..f566b8b1 100644 --- a/test/core/api.js +++ b/test/core/api.js @@ -483,6 +483,17 @@ describe('Core htmx API test', function() { output.innerHTML.should.be.equal('
Swapped!
') }) + it('swap works with a swap delay', function(done) { + var div = make("
") + div.innerText.should.equal('') + htmx.swap(div, 'jsswapped', { swapDelay: 10 }) + div.innerText.should.equal('') + setTimeout(function() { + div.innerText.should.equal('jsswapped') + done() + }, 30) + }) + it('swaps content properly (with select)', function() { var output = make('') htmx.swap('#output', '

Swapped!

', { swapStyle: 'innerHTML' }, { select: '#select-me' })