feat: clean up the Explore UX (v3.6.45)
- Explore runs inline: no blocking modal (that stays for the install operations, which can leave a half-loaded package; Explore leaves the card consistent). A test guards that ramExplore never calls the modal. - Minimal success line: just OK - the details live in the explorer below; error runs keep the detailed 'Partial - ...' line. - Counts moved into the section headings (Applications / Applet Instances (n), Executable Load Files (ELFs) / Packages (n)); the redundant '1 ISD' count is gone (P1=80 returns the ISD as a single occurrence, GP 11.4.2.1). - The RAM command format line gained a tooltip: compact = TS 102 226 5.2.1 command string, expanded = the AA/22 scripting template (5.2.1.0), detected per operation with a read-only GET STATUS probe. - The expanded-registry checkbox is relabelled 'Fetch expanded registry details (load-file / SD associations)' with a tooltip (extra secured packets, card support varies, the fallback is automatic) and is now a sticky per-browser preference (simple_ram_expanded). sw cache simple-v318; tests: 531 Python / 681 Node.
This commit is contained in:
@@ -22,7 +22,7 @@ function extractFunc(src, name) {
|
||||
}
|
||||
|
||||
// Extract chain builder functions and dependencies
|
||||
const FNS = ['berLenStr', 'buildApdu', 'escHtml', 'esc', 'chainInit', 'chainRamBuildRowHex', 'ramFmtLifecycle', 'ramFmtPrivileges', 'ramRenderExploreHtml', 'ramStepLine', 'ramStepComponents', 'ramInstallFailHint', 'ramProbeParse', 'ramGetStatusApdu', 'ramDeleteApdu',
|
||||
const FNS = ['berLenStr', 'buildApdu', 'escHtml', 'esc', 'chainInit', 'chainRamBuildRowHex', 'ramFmtLifecycle', 'ramFmtPrivileges', 'ramRenderExploreHtml', 'ramStepLine', 'ramStepComponents', 'ramInstallFailHint', 'ramProbeParse', 'ramExpandedDetailsInit', 'ramExpandedDetailsChanged', 'ramGetStatusApdu', 'ramDeleteApdu',
|
||||
'stkParamsBuild', 'ramRemoteSwOk', 'spPorAccepted', 'ramIncrementCntr', 'ramDeleteFromExplorer', 'ramListingSpi2', 'ramRemoveFromExplorer', 'ramHasInstance', 'ramExpandedQueryApdu',
|
||||
'_parseRawElfEntry', '_parseRawAppEntry', 'ramParseElfStatus', 'ramParseAppStatus', 'parseTLV', '_parseE3Entry',
|
||||
'ramCardIdxAfterRemove', 'ramClearResults', 'ramHideProgress', 'ramOpChanged', 'ramRender', 'ramApplyCard', 'ramExecute', 'decodePrivileges', 'ramActionBtn', 'ramCapToolkitMode', 'ramOpProgressText',
|
||||
@@ -788,3 +788,49 @@ test('ramProbeParse reads AID=version lines', () => {
|
||||
assert.ok(ramProbeParse('').error);
|
||||
assert.ok(ramProbeParse(' \n# only comments\n').error);
|
||||
});
|
||||
|
||||
test('ramRenderExploreHtml counts apps and ELFs in the section headings', () => {
|
||||
global.t = s => s;
|
||||
const out = ramRenderExploreHtml(null,
|
||||
[{ aid: 'A1', lifecycle: '07' }],
|
||||
[{ aid: 'A2', lifecycle: '07' }],
|
||||
[{ aid: 'E1', lifecycle: '01', moduleAids: [] }]);
|
||||
delete global.t;
|
||||
assert.ok(out.includes('Applications / Applet Instances (1)'), out);
|
||||
assert.ok(out.includes('Executable Load Files (ELFs) / Packages (1)'), out);
|
||||
// the ISD is a single occurrence (GP 11.4.2.1): no count in its heading
|
||||
assert.ok(out.includes('ISD (Issuer Security Domain)'), out);
|
||||
assert.ok(!out.includes('ISD (Issuer Security Domain) ('), out);
|
||||
});
|
||||
|
||||
test('the RAM command format line explains compact vs expanded', () => {
|
||||
global.t = s => s;
|
||||
const out = ramRenderExploreHtml({ appCount: 1, freeNV: 1, freeV: 1 }, [], [], [], 'compact');
|
||||
delete global.t;
|
||||
assert.ok(out.includes('title="compact = the TS 102 226 5.2.1 command string'), out);
|
||||
});
|
||||
|
||||
test('ramExplore runs inline, without the blocking modal', () => {
|
||||
const src = extractFunc(html, 'ramExplore');
|
||||
assert.ok(!/ramOpModal(Begin|Finish|Status)/.test(src),
|
||||
'Explore must not use the RAM modal (installs only)');
|
||||
});
|
||||
|
||||
test('the expanded-details checkbox is a sticky preference', () => {
|
||||
const els = fakeRamDocument(['ram-expanded-details']);
|
||||
const store = {};
|
||||
globalThis.localStorage = {
|
||||
getItem: k => (k in store ? store[k] : null),
|
||||
setItem: (k, v) => { store[k] = String(v); },
|
||||
};
|
||||
els['ram-expanded-details'].checked = false;
|
||||
ramExpandedDetailsInit();
|
||||
assert.strictEqual(els['ram-expanded-details'].checked, false); // default: off
|
||||
store['simple_ram_expanded'] = '1';
|
||||
ramExpandedDetailsInit();
|
||||
assert.strictEqual(els['ram-expanded-details'].checked, true); // stored choice applied
|
||||
els['ram-expanded-details'].checked = false;
|
||||
ramExpandedDetailsChanged();
|
||||
assert.strictEqual(store['simple_ram_expanded'], '0'); // ticking stores it
|
||||
delete globalThis.localStorage;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user