Skip to content

Commit 712c718

Browse files
committed
fix from review / remove redundant namespaces info
1 parent 5e1bb43 commit 712c718

2 files changed

Lines changed: 66 additions & 114 deletions

File tree

css/style.css

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,26 +1200,29 @@ div.clear {
12001200
padding: 25px;
12011201
overflow-y: auto;
12021202
flex: 1;
1203+
color: #333;
12031204
}
12041205

12051206
.nvs-dialog-body h4 {
1206-
margin: 0 0 10px 0;
1207-
font-size: 14px;
1208-
color: #666;
1207+
margin: 0 0 12px 0;
1208+
font-size: 15px;
1209+
color: #333;
12091210
text-transform: uppercase;
1210-
font-weight: 600;
1211+
font-weight: 700;
1212+
letter-spacing: 0.5px;
12111213
}
12121214

12131215
.nvs-dialog-body pre {
1214-
background-color: #f8f8f8;
1215-
padding: 10px;
1216-
border-radius: 5px;
1217-
margin: 0 0 15px 0;
1218-
font-family: "SF Mono", "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace;
1219-
font-size: 13px;
1220-
line-height: 1.5;
1216+
background-color: #f5f5f5;
1217+
padding: 12px 15px;
1218+
border-radius: 6px;
1219+
margin: 0 0 18px 0;
1220+
font-family: "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
1221+
font-size: 14px;
1222+
line-height: 1.6;
12211223
white-space: pre-wrap;
1222-
word-wrap: break-word;
1224+
overflow-wrap: break-word;
1225+
border: 1px solid #e0e0e0;
12231226
}
12241227

12251228
.nvs-ok {
@@ -1260,15 +1263,6 @@ div.clear {
12601263
border-radius: 12px;
12611264
}
12621265

1263-
.nvs-namespace-item {
1264-
background-color: #f8f8f8;
1265-
border: 1px solid #e0e0e0;
1266-
border-radius: 5px;
1267-
padding: 10px 15px;
1268-
margin-bottom: 8px;
1269-
font-size: 13px;
1270-
}
1271-
12721266
/* Mobile Optimizations */
12731267
@media (max-width: 768px) {
12741268
/* Larger touch targets and better readability */

js/nvs-editor.js

Lines changed: 51 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ export class NVSEditor {
148148
// ─────── Integrity checking and statistics (from Berry nvs.be) ───────
149149

150150
getStatistics() {
151+
const MAX_ENTRY_COUNT = 126;
151152
const stats = {
152153
pages_total: this.pages.length,
153154
pages_active: 0,
@@ -166,8 +167,6 @@ export class NVSEditor {
166167
};
167168

168169
for (const page of this.pages) {
169-
stats.pages_total++;
170-
171170
if (page.state === 'ACTIVE') stats.pages_active++;
172171
else if (page.state === 'FULL') stats.pages_full++;
173172
else if (page.state === 'UNINIT') stats.pages_empty++;
@@ -180,20 +179,20 @@ export class NVSEditor {
180179
stats.pages_bad_header_crc++;
181180
}
182181

182+
// Iterate ALL slots in the page bitmap to count erased/empty/written
183+
const stateBitmap = this.data.slice(page.offset + 32, page.offset + 64);
184+
for (let slotIndex = 0; slotIndex < MAX_ENTRY_COUNT; slotIndex++) {
185+
const slotState = this._getNVSItemState(stateBitmap, slotIndex);
186+
if (slotState === 0) stats.entries_erased++;
187+
else if (slotState === 1) stats.entries_empty++;
188+
else if (slotState === 2) stats.entries_written++;
189+
}
190+
191+
// Check entry header / data CRC for parsed (WRITTEN) items
183192
for (const item of page.items) {
184-
const itemState = this._getNVSItemState(this.data.slice(page.offset + 32, page.offset + 64),
185-
(item.offset - page.offset - 64) / 32);
186-
187-
if (itemState === 2) stats.entries_written++;
188-
else if (itemState === 0) stats.entries_erased++;
189-
else stats.entries_empty++;
190-
191-
// Check entry header CRC
192193
if (!item.headerCrcValid) {
193194
stats.entries_bad_header_crc++;
194195
}
195-
196-
// Check data CRC for string/blob types
197196
if (item.dataCrcValid !== undefined && !item.dataCrcValid) {
198197
stats.entries_bad_data_crc++;
199198
}
@@ -203,18 +202,6 @@ export class NVSEditor {
203202
return stats;
204203
}
205204

206-
getNamespaces() {
207-
const namespaces = new Map();
208-
for (const page of this.pages) {
209-
for (const item of page.items) {
210-
if (item.nsIndex === 0 && item.namespace) {
211-
namespaces.set(item.value, item.namespace);
212-
}
213-
}
214-
}
215-
return namespaces;
216-
}
217-
218205
// ─────── Blob integrity checking (from Berry nvs.be) ───────
219206

220207
getBlobs() {
@@ -263,7 +250,7 @@ export class NVSEditor {
263250

264251
// For inline blob (small blobs stored in header)
265252
if (item.datatype === 0x42 && item.size > 0 && item.span === 1) {
266-
const inlineOff = item.offset + 24;
253+
const inlineOff = item.offset + 32;
267254
blob.chunks.push({
268255
offset: inlineOff,
269256
length: item.size,
@@ -650,7 +637,6 @@ export class NVSEditor {
650637
</div>
651638
<button id="nvsStats" title="Show statistics and integrity report">📊 Stats</button>
652639
<button id="nvsBlobs" title="Show blob information">📦 Blobs</button>
653-
<button id="nvsNamespaces" title="Show namespaces">📁 Namespaces</button>
654640
<button id="nvsRefresh" title="Re-parse data">Refresh</button>
655641
<button id="nvsWrite" class="primary" disabled>Write to Flash</button>
656642
<button id="nvsClose">Close</button>
@@ -717,34 +703,14 @@ export class NVSEditor {
717703
});
718704

719705
// Stats button
720-
const statsBtn = this.container.querySelector('#nvsStats');
721-
if (statsBtn) {
722-
statsBtn.addEventListener('click', () => {
723-
this._showStats();
724-
});
725-
} else {
726-
console.error('Stats button not found');
727-
}
706+
this.container.querySelector('#nvsStats').addEventListener('click', () => {
707+
this._showStats();
708+
});
728709

729710
// Blobs button
730-
const blobsBtn = this.container.querySelector('#nvsBlobs');
731-
if (blobsBtn) {
732-
blobsBtn.addEventListener('click', () => {
733-
this._showBlobs();
734-
});
735-
} else {
736-
console.error('Blobs button not found');
737-
}
738-
739-
// Namespaces button
740-
const nsBtn = this.container.querySelector('#nvsNamespaces');
741-
if (nsBtn) {
742-
nsBtn.addEventListener('click', () => {
743-
this._showNamespaces();
744-
});
745-
} else {
746-
console.error('Namespaces button not found');
747-
}
711+
this.container.querySelector('#nvsBlobs').addEventListener('click', () => {
712+
this._showBlobs();
713+
});
748714

749715
this._renderContent();
750716
}
@@ -1118,7 +1084,32 @@ export class NVSEditor {
11181084
const blob = blobs.get(key);
11191085
const blobData = this.getBlobData(blob);
11201086
const hexDump = NVSEditor.hexDump(blobData);
1121-
alert(`Hex dump for ${key}:\n\n${hexDump}`);
1087+
1088+
const dialogBody = dialogContainer.querySelector('.nvs-dialog-body');
1089+
if (!dialogBody) return;
1090+
1091+
// Reuse a single hex-dump pane per key inside this dialog
1092+
const paneId = `nvs-hex-dump-${key}`;
1093+
let pre = dialogBody.querySelector(`#${CSS.escape(paneId)}`);
1094+
if (!pre) {
1095+
pre = document.createElement('pre');
1096+
pre.id = paneId;
1097+
pre.className = 'nvs-hex-dump';
1098+
pre.style.fontFamily = '"SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace';
1099+
pre.style.fontSize = '12px';
1100+
pre.style.background = '#f5f5f5';
1101+
pre.style.border = '1px solid #e0e0e0';
1102+
pre.style.borderRadius = '6px';
1103+
pre.style.padding = '10px';
1104+
pre.style.maxHeight = '400px';
1105+
pre.style.overflow = 'auto';
1106+
pre.style.whiteSpace = 'pre';
1107+
pre.style.margin = '8px 0 18px 0';
1108+
dialogBody.appendChild(pre);
1109+
}
1110+
// textContent escapes HTML by default
1111+
pre.textContent = `Hex dump for ${key}:\n\n${hexDump}`;
1112+
pre.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
11221113
});
11231114
});
11241115

@@ -1133,49 +1124,16 @@ export class NVSEditor {
11331124
const a = document.createElement('a');
11341125
a.href = url;
11351126
a.download = `${key}.bin`;
1127+
a.style.display = 'none';
1128+
document.body.appendChild(a);
11361129
a.click();
1137-
URL.revokeObjectURL(url);
1130+
// Defer cleanup so the download has time to start before the URL is revoked
1131+
setTimeout(() => {
1132+
URL.revokeObjectURL(url);
1133+
a.remove();
1134+
}, 0);
11381135
});
11391136
});
11401137
}
11411138

1142-
_showNamespaces() {
1143-
const namespaces = this.getNamespaces();
1144-
1145-
let html = '';
1146-
if (namespaces.size > 0) {
1147-
for (const [index, name] of namespaces) {
1148-
html += `<div class="nvs-namespace-item"><strong>Index ${index}:</strong> ${this._esc(name)}</div>`;
1149-
}
1150-
} else {
1151-
html = '<div class="nvs-empty">No namespace entries found.</div>';
1152-
}
1153-
1154-
const dialogHtml = `
1155-
<div class="nvs-dialog-overlay" id="nvsNamespacesDialog">
1156-
<div class="nvs-dialog">
1157-
<div class="nvs-dialog-header">
1158-
<h3>📁 Namespaces Found (${namespaces.size})</h3>
1159-
<button class="nvs-dialog-close">×</button>
1160-
</div>
1161-
<div class="nvs-dialog-body">
1162-
${html}
1163-
</div>
1164-
</div>
1165-
</div>`;
1166-
1167-
const dialogContainer = document.createElement('div');
1168-
dialogContainer.innerHTML = dialogHtml;
1169-
document.body.appendChild(dialogContainer);
1170-
1171-
dialogContainer.querySelector('.nvs-dialog-close').addEventListener('click', () => {
1172-
dialogContainer.remove();
1173-
});
1174-
1175-
dialogContainer.querySelector('.nvs-dialog-overlay').addEventListener('click', (e) => {
1176-
if (e.target === dialogContainer.querySelector('.nvs-dialog-overlay')) {
1177-
dialogContainer.remove();
1178-
}
1179-
});
1180-
}
11811139
}

0 commit comments

Comments
 (0)