handle bad scroll selectors gracefully

This commit is contained in:
Carson Gross
2026-02-22 10:11:38 -07:00
parent 5ef73e4348
commit 93fda88ed1
2 changed files with 41 additions and 5 deletions

View File

@@ -1128,15 +1128,17 @@ var htmx = (() => {
__handleScroll(swapSpec, target) {
if (swapSpec.scroll) {
let scrollTarget = swapSpec.scrollTarget ? this.__findExt(swapSpec.scrollTarget) : target;
if (swapSpec.scroll === 'top') {
scrollTarget.scrollTop = 0;
} else if (swapSpec.scroll === 'bottom'){
scrollTarget.scrollTop = scrollTarget.scrollHeight;
if (scrollTarget) {
if (swapSpec.scroll === 'top') {
scrollTarget.scrollTop = 0;
} else if (swapSpec.scroll === 'bottom'){
scrollTarget.scrollTop = scrollTarget.scrollHeight;
}
}
}
if (swapSpec.show) {
let showTarget = swapSpec.showTarget ? this.__findExt(swapSpec.showTarget) : target;
showTarget.scrollIntoView(swapSpec.show === 'top')
showTarget?.scrollIntoView(swapSpec.show === 'top')
}
}

View File

@@ -258,6 +258,40 @@ describe('__issueRequest unit tests', function() {
assert.isTrue(ctx.request.signal.aborted)
})
it('does not crash when scroll target selector matches nothing', async function () {
let div = createProcessedHTML('<div hx-get="/test" hx-swap="innerHTML scroll:top scrollTarget:#nonexistent"></div>')
let ctx = htmx.__createRequestContext(div, new Event('click'))
ctx.fetch = async () => ({
status: 200,
headers: new Headers(),
text: async () => '<div>Response</div>'
})
let errorFired = false
div.addEventListener('htmx:error', () => errorFired = true)
await htmx.__issueRequest(ctx)
assert.isFalse(errorFired)
})
it('does not crash when show target selector matches nothing', async function () {
let div = createProcessedHTML('<div hx-get="/test" hx-swap="innerHTML show:top showTarget:#nonexistent"></div>')
let ctx = htmx.__createRequestContext(div, new Event('click'))
ctx.fetch = async () => ({
status: 200,
headers: new Headers(),
text: async () => '<div>Response</div>'
})
let errorFired = false
div.addEventListener('htmx:error', () => errorFired = true)
await htmx.__issueRequest(ctx)
assert.isFalse(errorFired)
})
it('throws clean error for unknown swap style with no extensions', async function () {
let div = createProcessedHTML('<div hx-get="/test" hx-swap="foobar"></div>')
let ctx = htmx.__createRequestContext(div, new Event('click'))