fix: new session input stays open when clicking device select dropdown
blur handler on the name input was closing the entire new-session UI when focus moved to the device select. Fixed: check if activeElement is the sibling select before running cleanup. Same guard added to the select's blur handler (check if focus returned to input). Also adds Escape keydown handler on the select to allow cancelling without returning focus to the input first. Applied to both showNewSessionInput() and showFabSessionInput().
This commit is contained in:
+37
-3
@@ -1975,10 +1975,27 @@ function showNewSessionInput(btn) {
|
||||
}
|
||||
});
|
||||
|
||||
input.addEventListener('blur', function () {
|
||||
setTimeout(cleanup, 150);
|
||||
input.addEventListener('blur', function() {
|
||||
setTimeout(function() {
|
||||
// Don't close if focus moved to the device select dropdown
|
||||
if (select && document.activeElement === select) return;
|
||||
cleanup();
|
||||
}, 150);
|
||||
});
|
||||
|
||||
if (select) {
|
||||
select.addEventListener('blur', function() {
|
||||
setTimeout(function() {
|
||||
// Don't close if focus moved back to the name input
|
||||
if (document.activeElement === input) return;
|
||||
cleanup();
|
||||
}, 150);
|
||||
});
|
||||
select.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') { cleanup(); }
|
||||
});
|
||||
}
|
||||
|
||||
btn.style.display = 'none';
|
||||
if (select) btn.parentNode.insertBefore(select, btn);
|
||||
btn.parentNode.insertBefore(input, btn);
|
||||
@@ -2022,9 +2039,26 @@ function showFabSessionInput() {
|
||||
});
|
||||
|
||||
input.addEventListener('blur', function() {
|
||||
setTimeout(cleanup, 150);
|
||||
setTimeout(function() {
|
||||
// Don't close if focus moved to the device select dropdown
|
||||
if (select && document.activeElement === select) return;
|
||||
cleanup();
|
||||
}, 150);
|
||||
});
|
||||
|
||||
if (select) {
|
||||
select.addEventListener('blur', function() {
|
||||
setTimeout(function() {
|
||||
// Don't close if focus moved back to the name input
|
||||
if (document.activeElement === input) return;
|
||||
cleanup();
|
||||
}, 150);
|
||||
});
|
||||
select.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') { cleanup(); }
|
||||
});
|
||||
}
|
||||
|
||||
if (fab) fab.style.display = 'none';
|
||||
document.body.appendChild(overlay);
|
||||
input.focus();
|
||||
|
||||
@@ -4299,3 +4299,39 @@ test('CSS has new-session-device-select styling', () => {
|
||||
'style.css must have .new-session-device-select rule',
|
||||
);
|
||||
});
|
||||
|
||||
// --- Fix: blur handler guards against closing when clicking device select ---
|
||||
|
||||
test('showNewSessionInput blur does not close when clicking device select', () => {
|
||||
const source = fs.readFileSync(new URL('../app.js', import.meta.url), 'utf8');
|
||||
// Find the blur handler in showNewSessionInput
|
||||
const fnStart = source.indexOf('function showNewSessionInput');
|
||||
const fnBody = source.substring(fnStart, fnStart + 2000);
|
||||
// Must check activeElement before cleanup
|
||||
assert.ok(fnBody.includes('activeElement'), 'blur handler must check activeElement before cleanup');
|
||||
});
|
||||
|
||||
test('showFabSessionInput blur does not close when clicking device select', () => {
|
||||
const source = fs.readFileSync(new URL('../app.js', import.meta.url), 'utf8');
|
||||
const fnStart = source.indexOf('function showFabSessionInput');
|
||||
const fnBody = source.substring(fnStart, fnStart + 2000);
|
||||
assert.ok(fnBody.includes('activeElement'), 'FAB blur handler must check activeElement before cleanup');
|
||||
});
|
||||
|
||||
test('showNewSessionInput device select has blur handler that guards against closing when focus returns to input', () => {
|
||||
const source = fs.readFileSync(new URL('../app.js', import.meta.url), 'utf8');
|
||||
const fnStart = source.indexOf('function showNewSessionInput');
|
||||
const fnBody = source.substring(fnStart, fnStart + 2000);
|
||||
// The select element should also have a blur handler
|
||||
// We check that there's a blur listener added to the select element
|
||||
const selectBlurIdx = fnBody.indexOf("select.addEventListener('blur'");
|
||||
assert.ok(selectBlurIdx !== -1, 'select element must have a blur handler in showNewSessionInput');
|
||||
});
|
||||
|
||||
test('showNewSessionInput device select has keydown handler for Escape', () => {
|
||||
const source = fs.readFileSync(new URL('../app.js', import.meta.url), 'utf8');
|
||||
const fnStart = source.indexOf('function showNewSessionInput');
|
||||
const fnBody = source.substring(fnStart, fnStart + 2000);
|
||||
const selectKeydownIdx = fnBody.indexOf("select.addEventListener('keydown'");
|
||||
assert.ok(selectKeydownIdx !== -1, 'select element must have a keydown handler in showNewSessionInput');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user