diff --git a/frontend/index.html b/frontend/index.html index 90d12d6..2946c32 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -6731,6 +6731,19 @@ function profilerMaskPrefix4(hex) { return h.slice(0, 8) + '?'.repeat(h.length - 8); } +// Which size/record fields apply to a given file type. +function profilerFileFields(ft) { + if (ft === 'linear_fixed' || ft === 'cyclic') return { size: false, records: true }; + if (ft === 'df') return { size: false, records: false }; + if (ft === 'transparent' || ft === 'ber_tlv') return { size: true, records: false }; + return { size: true, records: true }; +} + +// Content representation ('record' vs 'transparent') for a given file type. +function profilerContentKindForFileType(ft) { + return (ft === 'linear_fixed' || ft === 'cyclic') ? 'record' : 'transparent'; +} + function profilerValidateProfile(obj) { if (!obj || typeof obj !== 'object') return 'Not an object'; if (!obj.name) return 'Missing name'; @@ -7014,17 +7027,24 @@ function profilerRenderRule(i, r) { html += '
' + '
'; html += ''; + const vis = profilerFileFields(r.fileType); html += '
'; html += '
' + - '
'; - html += '
' + - '
'; - html += '
' + - '
'; - html += '
' + - '
'; + '
'; + if (vis.size) { + html += '
' + + '
'; + } + if (vis.records) { + html += '
' + + '
'; + html += '
' + + '
'; + } html += ''; - html += profilerRenderContentEditor(i, r); + if (r.fileType !== 'df') { + html += profilerRenderContentEditor(i, r); + } html += ''; return html; } @@ -7059,6 +7079,24 @@ function profilerUpdateRule(i, field, value) { profilerDraft.rules[i][field] = value; } +function profilerUpdateRuleFileType(i, value) { + if (!profilerDraft) return; + const r = profilerDraft.rules[i]; + r.fileType = value; + const vis = profilerFileFields(value); + if (!vis.size) r.fileSize = null; + if (!vis.records) { r.recordLen = null; r.numRecords = null; } + if (r.content) { + const kind = profilerContentKindForFileType(value); + if (r.content.kind !== kind) { + r.content = kind === 'record' + ? { mode: r.content.mode, kind: 'record', records: [] } + : { mode: r.content.mode, kind: 'transparent', expected: '' }; + } + } + profilerRenderEditor(); +} + function profilerSetContent(i, mode) { if (!profilerDraft) return; const r = profilerDraft.rules[i]; @@ -7067,7 +7105,10 @@ function profilerSetContent(i, mode) { } else if (r.content) { r.content.mode = mode; } else { - r.content = { mode: mode, kind: 'transparent', expected: '' }; + const kind = profilerContentKindForFileType(r.fileType); + r.content = kind === 'record' + ? { mode: mode, kind: 'record', records: [] } + : { mode: mode, kind: 'transparent', expected: '' }; } profilerRenderEditor(); } diff --git a/frontend/sw.js b/frontend/sw.js index a87b9ca..89814fa 100644 --- a/frontend/sw.js +++ b/frontend/sw.js @@ -1,4 +1,4 @@ -const CACHE = 'otaman-v44'; +const CACHE = 'otaman-v45'; const URLS = [ 'index.html', 'help.html', diff --git a/frontend/tests/profiler.test.js b/frontend/tests/profiler.test.js index 75f63f7..1a33af4 100644 --- a/frontend/tests/profiler.test.js +++ b/frontend/tests/profiler.test.js @@ -21,7 +21,7 @@ function extractFunc(src, name) { return src.slice(m.index, i + 1); } -const FNS = ['profilerNormHex', 'profilerMatch', 'profilerMatchMin', 'profilerMaskPrefix4', 'profilerValidateProfile']; +const FNS = ['profilerNormHex', 'profilerMatch', 'profilerMatchMin', 'profilerMaskPrefix4', 'profilerFileFields', 'profilerContentKindForFileType', 'profilerValidateProfile']; let code = ''; for (const f of FNS) code += extractFunc(html, f) + '\n'; eval(code); @@ -74,6 +74,24 @@ test('profilerMaskPrefix4 keeps first 4 bytes and masks the rest', () => { assert.strictEqual(profilerMaskPrefix4('1234'), '1234'); }); +test('profilerFileFields maps file type to applicable fields', () => { + assert.deepStrictEqual(profilerFileFields('transparent'), { size: true, records: false }); + assert.deepStrictEqual(profilerFileFields('ber_tlv'), { size: true, records: false }); + assert.deepStrictEqual(profilerFileFields('linear_fixed'), { size: false, records: true }); + assert.deepStrictEqual(profilerFileFields('cyclic'), { size: false, records: true }); + assert.deepStrictEqual(profilerFileFields('df'), { size: false, records: false }); + assert.deepStrictEqual(profilerFileFields(null), { size: true, records: true }); + assert.deepStrictEqual(profilerFileFields(''), { size: true, records: true }); +}); + +test('profilerContentKindForFileType', () => { + assert.strictEqual(profilerContentKindForFileType('linear_fixed'), 'record'); + assert.strictEqual(profilerContentKindForFileType('cyclic'), 'record'); + assert.strictEqual(profilerContentKindForFileType('transparent'), 'transparent'); + assert.strictEqual(profilerContentKindForFileType('ber_tlv'), 'transparent'); + assert.strictEqual(profilerContentKindForFileType('df'), 'transparent'); +}); + test('profile validation', () => { assert.strictEqual(profilerValidateProfile(null), 'Not an object'); assert.strictEqual(profilerValidateProfile({ name: 'x' }), 'Missing rules array');