v3.28.8: the batch panel's scroll preservation
The attempts box's content is replaced on every render (the batch panel is static markup; the render fills the dynamic bits) and replacing a scrollable element's content resets its scroll. That was harmless while the render ran once per attempt, but v3.28.7 made it run on every 2 s poll, so scrolling back through the attempts during a run snapped to the top each poll. The render now captures the box's scrollTop before refilling it and restores it afterwards. Test: the stub box resets its scroll on an innerHTML write (like a browser) and the render must keep the reader's position - verified to fail without the restore. 920 frontend + 928 Python; sw cache simple-v446.
This commit is contained in:
+8
-2
@@ -1910,7 +1910,7 @@
|
||||
// ===== Version =====
|
||||
// Single source of truth for the PWA version: shown in the header and used
|
||||
// by the server version check in pysimConnect().
|
||||
const SIMPLE_VERSION = '3.28.7';
|
||||
const SIMPLE_VERSION = '3.28.8';
|
||||
document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION;
|
||||
|
||||
// ===== view history (the browser Back/Forward buttons) =====
|
||||
@@ -10267,7 +10267,13 @@ function ramBatchRender() {
|
||||
counts.textContent = text;
|
||||
}
|
||||
const box = document.getElementById('ram-batch-attempts');
|
||||
if (box) box.innerHTML = ramBatchAttemptsHtml(st.attempts || []);
|
||||
if (box) {
|
||||
// Replacing the box's content resets its scroll: the render now runs on
|
||||
// every 2 s poll, so keep the reader's position (v3.28.8).
|
||||
const prevScroll = box.scrollTop;
|
||||
box.innerHTML = ramBatchAttemptsHtml(st.attempts || []);
|
||||
if (prevScroll) box.scrollTop = prevScroll;
|
||||
}
|
||||
}
|
||||
|
||||
function ramBatchAttemptsHtml(attempts) {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
const CACHE = 'simple-v445';
|
||||
const CACHE = 'simple-v446';
|
||||
const URLS = [
|
||||
'index.html',
|
||||
'help.html',
|
||||
|
||||
@@ -45,6 +45,13 @@ function setEl(id, value) {
|
||||
contains(c) { return !!els[id].classes[c]; },
|
||||
},
|
||||
};
|
||||
if (id === 'ram-batch-attempts') {
|
||||
// like a browser: replacing the content resets the scroll position
|
||||
Object.defineProperty(els[id], 'innerHTML', {
|
||||
get() { return this._html || ''; },
|
||||
set(v) { this._html = v; this.scrollTop = 0; },
|
||||
});
|
||||
}
|
||||
return els[id];
|
||||
}
|
||||
function clearEls() {
|
||||
@@ -302,6 +309,27 @@ test('a hung detailed fetch does not freeze the counts (v3.28.7)', async () => {
|
||||
app.hangs = false;
|
||||
});
|
||||
|
||||
test('the attempts table keeps its scroll position across a poll render (v3.28.8)', () => {
|
||||
clearEls();
|
||||
setEl('ram-op', 'batch');
|
||||
setEl('ram-batch-panel', '');
|
||||
setEl('ram-batch-start', '');
|
||||
setEl('ram-batch-stop', '');
|
||||
setEl('ram-batch-clear', '');
|
||||
setEl('ram-batch-spin', '');
|
||||
setEl('ram-batch-state', '');
|
||||
setEl('ram-batch-notice', '');
|
||||
setEl('ram-batch-counts', '');
|
||||
setEl('ram-batch-attempts', '');
|
||||
app.setLast({ active: true, phase: 'waiting_card', attempts: [
|
||||
{ ts: 1, iccid: '8970119000004600098', preset: 'p', result: 'installed', duration_ms: 1 }],
|
||||
counts: { installed: 1, failed: 0, skipped: 0 }, attempts_total: 1 });
|
||||
app.ramBatchRender();
|
||||
els['ram-batch-attempts'].scrollTop = 120; // the reader scrolled back
|
||||
app.ramBatchRender(); // the next 2 s poll render
|
||||
assert.strictEqual(els['ram-batch-attempts'].scrollTop, 120);
|
||||
});
|
||||
|
||||
test('a stale fetch guard is released so the report recovers (v3.28.7)', async () => {
|
||||
clearEls();
|
||||
setEl('ram-op', 'batch');
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "pysim-simple-server"
|
||||
version = "3.28.7"
|
||||
version = "3.28.8"
|
||||
description = "HTTP REST server wrapping pysim for the SIMple PWA"
|
||||
requires-python = ">=3.8"
|
||||
# pysim is a git-only dependency installed explicitly by setup.bat/setup.sh.
|
||||
|
||||
@@ -37,7 +37,7 @@ from osmocom.tlv import BER_TLV_IE
|
||||
from osmocom.utils import rpad
|
||||
|
||||
|
||||
VERSION = '3.28.7'
|
||||
VERSION = '3.28.8'
|
||||
|
||||
MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE
|
||||
|
||||
|
||||
Reference in New Issue
Block a user