Die Stelle bleibt -- auch wenn die Seite dazwischen neu laedt

Filipe, zum vierten Mal: "wenn ich in eine kategorie rein gehe und dan
zurueck geh die hauptseite immer wieder ganz hoch ... ohne dass die
seite hoch scrollt ODER NEU LAEDT."

DAS "ODER NEU LAEDT" WAR DER HINWEIS, und ich habe ihn zweimal
ueberlesen. kopf.js laedt die Seite selbst neu, sobald der Browser sie
aus seinem Rueckwaerts-Speicher holt -- damit keine veralteten Zahlen
dastehen. Nach einem Neuladen heisst die Navigationsart aber "reload",
nicht "back_forward".

UND DIE EIGENTLICHE BOSHEIT stand in einer Zeile, die ich selbst
geschrieben habe: Wurde eine Ankunft nicht als Zurueck erkannt, wurde
die gemerkte Stelle GELOESCHT. Ein einziges Neuladen reichte -- danach
half auch das naechste Zurueckgehen nicht mehr. Deshalb "geht es immer
noch nicht", obwohl ich es dreimal fuer behoben hielt.

WARUM ES IN JEDER MESSUNG FUNKTIONIERT HAT: kopf.js haelt einen
Ereignisstrom offen, und der sperrt den Rueckwaerts-Speicher aus.
`persisted` bleibt hier immer false, die Neulade-Zeile lief nie. Auf
einem echten Handy greift er sehr wohl. Man muss den Weg gehen, den der
Mensch geht -- und wenn man ihn nicht nachstellen kann, baut man gegen
ALLE Wege robust statt gegen einen.

FUENF AENDERUNGEN:

  Die Stelle wird LAUFEND gemerkt (gedrosselt auf 250 ms), nicht nur
  beim Klicken und Verlassen. Deckt auch die Glocke, eine
  Benachrichtigung und einen Absturz des Reiters ab.

  Nichts wird mehr geloescht. Die Stelle verfaellt von selbst nach
  einer Stunde.

  Wiederhergestellt wird jetzt auch bei "reload" und bei "navigate mit
  Herkunft aus diesem Haus" -- nicht nur bei "back_forward".

  Vor dem Neuladen aus dem Rueckwaerts-Speicher wird die Stelle samt
  Merker festgehalten.

  Der Pfeil in der Kopfleiste setzt den Merker jetzt fuer BEIDE seiner
  Wege. Er nimmt history.back() nur, wenn `document.referrer` da ist --
  sonst location.assign(), und das ist fuer den Browser ein Hingehen.
  Hier stand "der braucht nichts"; fuer den zweiten Weg stimmte das nie.

Ein Neuanfang faengt weiterhin oben an: keine Herkunft, kein Merker --
also vom Startbildschirm, aus einer Benachrichtigung, ueber die
Adresszeile.

Beim Bauen fast hineingelaufen: `START` steht in einem anderen Block
derselben Datei und waere an der neuen Stelle ein Absturz gewesen --
dieselbe Falle wie bei `$` am 21.09. Jetzt gibt der erste Block ihn
einmal bekannt, statt ihn abzuschreiben.

Geprueft: pruef-stelle 15/0 (war 9) -- Brotkrume (navigate),
Browser-Zurueck (back_forward), NEULADEN (reload), Neuanfang oben, und
dass eine fremde Ankunft die Stelle nicht wegwirft. Dazu pruef-sprung
43/0, pruef-start-ansicht 153/0, pruef-css-klassen 30/0.
This commit is contained in:
2026-09-22 00:54:28 +02:00
parent 66789aabcd
commit 2b6c2be1ad
40 changed files with 725 additions and 531 deletions
+74 -1
View File
@@ -168,8 +168,24 @@ async function hinUndZurueck(wieZurueck) {
await seite.waitForNavigation({ waitUntil: "networkidle" }).catch(() => {});
} else {
await seite.goBack({ waitUntil: "load" });
if (wieZurueck === "neuladen") {
/* WARUM AUSGERECHNET DAS (21.09.2026): kopf.js laedt die Seite
selbst neu, sobald der Browser sie aus seinem Rueckwaerts-
Speicher holt -- damit keine veralteten Zahlen dastehen. Nach
einem Neuladen heisst die Navigationsart aber "reload", nicht
"back_forward". Die Wiederherstellung sprang deshalb nicht an
und LOESCHTE die gemerkte Stelle sogar.
Hier wird nie `persisted` erreicht, weil kopf.js einen
Ereignisstrom offenhaelt und der den Rueckwaerts-Speicher
aussperrt -- genau deshalb war jede Messung gruen und Filipes
Handy nicht. Das Neuladen wird deshalb von Hand ausgeloest:
Der ZUSTAND danach ist derselbe, und nur auf den kommt es an. */
await seite.waitForTimeout(2200);
await seite.reload({ waitUntil: "load" });
}
}
await seite.waitForTimeout(3000);
await seite.waitForTimeout(3600);
const nach = await seite.evaluate(() => ({
y: Math.round(window.scrollY),
art: performance.getEntriesByType("navigation")[0]?.type,
@@ -237,6 +253,63 @@ try {
await ctx.close();
}
}
melde("\n=== 4. Zurueck, und dann laedt die Seite neu ===");
{
const r = await hinUndZurueck("neuladen");
ok(!r.zuKurz, r.zuKurz ? `zu kurz (${r.zuKurz}px)` : "die Seite ist hoch genug");
if (!r.zuKurz) {
ok(r.art === "reload",
`die Navigationsart ist wirklich ein Neuladen (${r.art}) -- sonst `
+ "pruefte dieser Abschnitt denselben Weg wie Abschnitt 2");
ok(r.y >= r.vor - 80,
`und die Stelle ueberlebt es: ${r.vor}px hin, ${r.y}px zurueck`);
}
}
melde("\n=== 5. Eine fremde Ankunft darf die Stelle nicht wegwerfen ===");
{
/* DER EIGENTLICHE FEHLER war nicht, dass nicht wiederhergestellt
wurde -- sondern dass die gemerkte Stelle dabei GELOESCHT wurde.
Ein einziges Neuladen reichte, und danach half auch das naechste
Zurueckgehen nicht mehr. Genau das wird hier gemessen. */
const ctx = await browser.newContext({ viewport: { width: 1280, height: 800 } });
await ctx.addCookies(keks.split("; ").filter(Boolean).map((z) => {
const [name, ...rest] = z.split("=");
return { name, value: rest.join("="), domain: "127.0.0.1", path: "/" };
}));
try {
const seite = await ctx.newPage();
await seite.goto(`http://127.0.0.1:${PORT}/workspace/start.html`,
{ waitUntil: "networkidle" });
await seite.waitForTimeout(1800);
const hoch = await seite.evaluate(() => document.documentElement.scrollHeight);
const ziel = Math.min(900, Math.max(200, hoch - 700));
await seite.evaluate((y) => window.scrollTo(0, y), ziel);
await seite.waitForTimeout(700);
const gemerkt = await seite.evaluate(() => {
try { return sessionStorage.getItem("ws-stelle:/workspace/start.html"); }
catch (e) { return null; }
});
ok(!!gemerkt, `beim Scrollen wird laufend gemerkt (${gemerkt})`);
/* Eine Ankunft OHNE Herkunft -- der Neuanfang. */
await seite.goto(`http://127.0.0.1:${PORT}/workspace/start.html`,
{ waitUntil: "load" });
await seite.waitForTimeout(2600);
const oben = await seite.evaluate(() => Math.round(window.scrollY));
ok(oben <= 80, `ein Neuanfang faengt oben an (${oben}px)`);
const nochDa = await seite.evaluate(() => {
try { return sessionStorage.getItem("ws-stelle:/workspace/start.html"); }
catch (e) { return null; }
});
ok(!!nochDa, nochDa
? "und die gemerkte Stelle ist trotzdem noch da"
: "GELOESCHT -- das naechste Zurueckgehen haette nichts mehr");
} finally {
await ctx.close();
}
}
} finally {
await browser.close();
}