Skip to content

Commit 073900a

Browse files
committed
Skip hidden [autofocus] and [x-autofocus] elements
1 parent 24075e7 commit 073900a

File tree

2 files changed

+27
-11
lines changed

2 files changed

+27
-11
lines changed

src/index.js

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -372,16 +372,15 @@ async function render(request, targets, el, config) {
372372
if (merged) {
373373
merged.dataset.source = response.url
374374
merged.removeAttribute('aria-busy')
375-
if (!focused) {
376-
['[x-autofocus]', '[autofocus]'].forEach(selector => {
377-
if (focused) return
378-
let autofocus = merged.matches(selector) ? merged : merged.querySelector(selector)
379-
if (autofocus) {
380-
focusOn(autofocus)
381-
focused = true
382-
}
383-
})
384-
}
375+
let focusables = ['[x-autofocus]', '[autofocus]']
376+
focusables.some(selector => {
377+
if (focused) return true
378+
if (merged.matches(selector)) {
379+
focused = focusOn(merged)
380+
}
381+
382+
return focused || Array.from(merged.querySelectorAll(selector)).some(focusable => focusOn(focusable))
383+
})
385384
}
386385

387386
dispatch(merged, 'ajax:merged')
@@ -453,11 +452,14 @@ async function merge(strategy, from, to) {
453452
}
454453

455454
function focusOn(el) {
456-
if (!el) return
455+
if (!el) return false
456+
if (!el.getClientRects().length) return false
457457
setTimeout(() => {
458458
if (!el.hasAttribute('tabindex')) el.setAttribute('tabindex', '0')
459459
el.focus()
460460
}, 0)
461+
462+
return true
461463
}
462464

463465
function updateHistory(strategy, url) {

tests/focus.cy.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,20 @@ test('first listed target is focused when multiple [autofocus] are merged',
5656
}
5757
)
5858

59+
test('hidden [autofocus] elements are ignored',
60+
html`<form x-init x-target id="replace" method="post"><button>First</button><a href="#">Second</a></form>`,
61+
({ intercept, get, wait }) => {
62+
intercept('POST', '/tests', {
63+
statusCode: 200,
64+
body: '<form x-init x-target id="replace" method="post"><button hidden autofocus>First</button><a href="#" autofocus>Second</a></form>'
65+
}).as('response')
66+
get('button').focus().click()
67+
wait('@response').then(() => {
68+
get('a').should('have.focus')
69+
})
70+
}
71+
)
72+
5973
test('[x-autofocus] overrides [autofocus]',
6074
html`<form x-init x-target id="replace" method="post"><button>First</button><a href="#">Second</a></form>`,
6175
({ intercept, get, wait }) => {

0 commit comments

Comments
 (0)