ui: focus scan name input and start scanning on Enter
'Profile from card' and 'New snapshot' now focus the name field when the dialog opens, and Enter in that field starts the scan (profilerScanNameKeydown, ignored while the Scan button is disabled). Tests for the key handler and the input wiring; SW cache v98 -> v99.
This commit is contained in:
+10
-1
@@ -956,7 +956,7 @@
|
|||||||
<div class="bg-white dark:bg-slate-800 rounded-lg p-6 max-w-sm w-full mx-4 max-h-[85vh] overflow-auto">
|
<div class="bg-white dark:bg-slate-800 rounded-lg p-6 max-w-sm w-full mx-4 max-h-[85vh] overflow-auto">
|
||||||
<h3 id="profiler-scan-title" class="text-lg font-semibold mb-4 text-gray-800 dark:text-slate-200" data-l10n="Profile from card">Profile from card</h3>
|
<h3 id="profiler-scan-title" class="text-lg font-semibold mb-4 text-gray-800 dark:text-slate-200" data-l10n="Profile from card">Profile from card</h3>
|
||||||
<label id="profiler-scan-name-label" class="block mb-1 text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="Profile name">Profile name</label>
|
<label id="profiler-scan-name-label" class="block mb-1 text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="Profile name">Profile name</label>
|
||||||
<input id="profiler-scan-name" class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-3 py-2 dark:bg-slate-800 mb-3" placeholder="Profile name">
|
<input id="profiler-scan-name" class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-3 py-2 dark:bg-slate-800 mb-3" placeholder="Profile name" onkeydown="profilerScanNameKeydown(event)">
|
||||||
<div id="profiler-scan-options">
|
<div id="profiler-scan-options">
|
||||||
<div class="flex items-center gap-2 mb-1">
|
<div class="flex items-center gap-2 mb-1">
|
||||||
<span class="text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="Ignore contents of files:">Ignore contents of files:</span>
|
<span class="text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="Ignore contents of files:">Ignore contents of files:</span>
|
||||||
@@ -7376,6 +7376,7 @@ function profilerFromCard() {
|
|||||||
document.getElementById('profiler-scan-btn').disabled = false;
|
document.getElementById('profiler-scan-btn').disabled = false;
|
||||||
document.getElementById('profiler-scan-btn').textContent = t('Scan');
|
document.getElementById('profiler-scan-btn').textContent = t('Scan');
|
||||||
document.getElementById('profiler-scan-modal').classList.remove('hidden');
|
document.getElementById('profiler-scan-modal').classList.remove('hidden');
|
||||||
|
document.getElementById('profiler-scan-name').focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
function profilerScanCancel() {
|
function profilerScanCancel() {
|
||||||
@@ -7394,6 +7395,14 @@ function snapshotNew() {
|
|||||||
document.getElementById('profiler-scan-btn').disabled = false;
|
document.getElementById('profiler-scan-btn').disabled = false;
|
||||||
document.getElementById('profiler-scan-btn').textContent = t('Scan');
|
document.getElementById('profiler-scan-btn').textContent = t('Scan');
|
||||||
document.getElementById('profiler-scan-modal').classList.remove('hidden');
|
document.getElementById('profiler-scan-modal').classList.remove('hidden');
|
||||||
|
nameEl.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function profilerScanNameKeydown(e) {
|
||||||
|
if (e.key !== 'Enter') return;
|
||||||
|
if (document.getElementById('profiler-scan-btn').disabled) return;
|
||||||
|
e.preventDefault();
|
||||||
|
profilerScanStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function profilerScanStart() {
|
async function profilerScanStart() {
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
const CACHE = 'otaman-v98';
|
const CACHE = 'otaman-v99';
|
||||||
const URLS = [
|
const URLS = [
|
||||||
'index.html',
|
'index.html',
|
||||||
'help.html',
|
'help.html',
|
||||||
|
|||||||
@@ -33,3 +33,7 @@ test('phone simulator has Phone / TR Config pills', () => {
|
|||||||
assert.ok(html.includes('id="phone-sub-phone"'));
|
assert.ok(html.includes('id="phone-sub-phone"'));
|
||||||
assert.ok(html.includes('id="phone-sub-tr"'));
|
assert.ok(html.includes('id="phone-sub-tr"'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('scan name input starts scanning on Enter', () => {
|
||||||
|
assert.match(html, /id="profiler-scan-name"[^>]*onkeydown="profilerScanNameKeydown\(event\)"/);
|
||||||
|
});
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ function extractFunc(src, name, asyncFn) {
|
|||||||
return (asyncFn ? 'async ' : '') + src.slice(m.index, i + 1);
|
return (asyncFn ? 'async ' : '') + src.slice(m.index, i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const FNS = ['profilerNormHex', 'profilerNormHexStrict', 'profilerMatch', 'profilerMatchMin', 'profilerMaskPrefix4', 'profilerFileFields', 'profilerContentKindForFileType', 'profilerEmptyRecordContent', 'profilerValidateProfile', 'profilerCustomNameForPath', 'profilerUpdateRulePath', 'profilerResultAspects', 'profilerAspectSummary', 'profilerNumRanges', 'esc', 'escHtml', 'profilerRawDataCheck', 'profilerRenderReport', 'parseBerLen', 'parseTlvList', 'fcpInt', 'fcpParseTlvs', 'fcpFileDescriptor', 'fcpLifeCycle', 'fcpSfi', 'fcpDo', 'fcpDecode', 'fcpDiffHtml', 'profilerFciPreviewItems', 'profilerUpdateFciPreview', 'profilerUpdateRule', 'profilerFciInput', 'profilerScanToggleAll', 'profilerScanIgnoreAllState', 'swapNibbles', 'decIccid', 'profilerSnapshotIccid', 'profilerValidateSnapshot', 'profilerListSwitch', 'profilerScanRefreshOptions', 'profilerLiveSource', 'profilerSnapshotSource', 'profilerVisibleResults', 'profilerMaskFidForFile', 'profilerRulesFromSnapshot', 'profilerExtraFileResults'];
|
const FNS = ['profilerNormHex', 'profilerNormHexStrict', 'profilerMatch', 'profilerMatchMin', 'profilerMaskPrefix4', 'profilerFileFields', 'profilerContentKindForFileType', 'profilerEmptyRecordContent', 'profilerValidateProfile', 'profilerCustomNameForPath', 'profilerUpdateRulePath', 'profilerResultAspects', 'profilerAspectSummary', 'profilerNumRanges', 'esc', 'escHtml', 'profilerRawDataCheck', 'profilerRenderReport', 'parseBerLen', 'parseTlvList', 'fcpInt', 'fcpParseTlvs', 'fcpFileDescriptor', 'fcpLifeCycle', 'fcpSfi', 'fcpDo', 'fcpDecode', 'fcpDiffHtml', 'profilerFciPreviewItems', 'profilerUpdateFciPreview', 'profilerUpdateRule', 'profilerFciInput', 'profilerScanToggleAll', 'profilerScanIgnoreAllState', 'swapNibbles', 'decIccid', 'profilerSnapshotIccid', 'profilerValidateSnapshot', 'profilerListSwitch', 'profilerScanRefreshOptions', 'profilerLiveSource', 'profilerSnapshotSource', 'profilerVisibleResults', 'profilerMaskFidForFile', 'profilerRulesFromSnapshot', 'profilerExtraFileResults', 'profilerScanNameKeydown'];
|
||||||
let code = '';
|
let code = '';
|
||||||
for (const f of FNS) code += extractFunc(html, f) + '\n';
|
for (const f of FNS) code += extractFunc(html, f) + '\n';
|
||||||
code += extractFunc(html, 'profilerBuildFileRule', true) + '\n';
|
code += extractFunc(html, 'profilerBuildFileRule', true) + '\n';
|
||||||
@@ -1112,3 +1112,21 @@ test('profilerExtraFileResults reports files missing from the master', () => {
|
|||||||
assert.strictEqual(extras[0].status, 'fail');
|
assert.strictEqual(extras[0].status, 'fail');
|
||||||
assert.deepStrictEqual(extras[0].checks, [{ label: 'extra file', expected: 'absent', actual: 'present', ok: false }]);
|
assert.deepStrictEqual(extras[0].checks, [{ label: 'extra file', expected: 'absent', actual: 'present', ok: false }]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('profilerScanNameKeydown starts the scan on Enter only', () => {
|
||||||
|
const btn = { disabled: false };
|
||||||
|
global.document = { getElementById: () => btn };
|
||||||
|
let started = 0;
|
||||||
|
global.profilerScanStart = () => { started++; };
|
||||||
|
let prevented = 0;
|
||||||
|
profilerScanNameKeydown({ key: 'Enter', preventDefault: () => prevented++ });
|
||||||
|
profilerScanNameKeydown({ key: 'a', preventDefault: () => prevented++ });
|
||||||
|
assert.strictEqual(started, 1);
|
||||||
|
assert.strictEqual(prevented, 1);
|
||||||
|
btn.disabled = true;
|
||||||
|
profilerScanNameKeydown({ key: 'Enter', preventDefault: () => prevented++ });
|
||||||
|
assert.strictEqual(started, 1);
|
||||||
|
assert.strictEqual(prevented, 1);
|
||||||
|
delete global.document;
|
||||||
|
delete global.profilerScanStart;
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user