Repository navigation
Implement same-document History state and URL mutation #392
Description
Parent: #267
Top-level epics: #264, #227
Reproduction
The pinned unchanged Code OSS Markdown fixture prepares its packaged file: URL with:
const prepared = new URL(location.href);
prepared.searchParams.set('id', 'markdown-preview');
history.replaceState(null, '', prepared);At WebScene d4dc4fc1, history.pushState and history.replaceState are inert no-ops. location.href therefore remains unchanged, the fixture falls through to location.replace(next), and the native focused runtime rejects that host navigation before the ServiceWorker/resource and nested-document phases can run. Chrome updates the current entry and live Location/Document URL without performing a document navigation.
Scope and proposed fix
Implement reusable same-document History state/URL mutation for the top-level realm and every fully created same-origin realm. Actual iframe navigation/WindowProxy construction remains in #267 and will provide the end-to-end nested-frame exercise:
- real
pushState(state, unused, url?)andreplaceState(state, unused, url?)argument, URL resolution, same-origin and bounded-input behavior; - live
history.state,history.length, and Location/Document URL/base reflection without a host navigation or realm replacement; - browser-compatible
SecurityErrorandDataCloneErrorbehavior for invalid/cross-origin URLs and uncloneable state; - stable Location/History identity and stale-realm rejection;
- retain strict separation from
Location.assign/replace, full-document navigation, native host authority, CSP, ServiceWorker, resource admission, filesystem, and network permissions.
History traversal (back/forward/go) should be implemented here only if the selected reference tests require it for correctness; otherwise keep it as the next focused #267 child with explicit coverage.
Acceptance
- Checked-in Chromium/WPT-derived contract covers omitted/relative/absolute same-origin URLs, query/fragment updates,
state,length, stable object identity, invalid/cross-origin rejection, receiver branding, and nopopstateon the initiating call. - Native top-level and exact pinned
file:URL-object contracts match the oracle, updatelocation.href/search/hash,document.URL/documentURI/baseURI, and resolve subsequent relative resources against the updated document URL. History is installed for frame realms when Enforce secure nested-document lifecycle for Code OSS webviews #267 constructs them; end-to-end iframe navigation remains there. - The unchanged pinned Markdown fixture advances past its
id=markdown-previewpreparation without a host navigation request. - 10,000 replace operations and 1,000 bounded push operations publish no layout/scene work, meet p95 <= 0.25 ms, keep queues bounded, and retain <= 2 MiB RSS after warm-up.
- Repeated mutation and adjacent 31-cycle navigation-realm teardown retain stable heap/listener counts; full nested-frame retirement stays with Enforce secure nested-document lifecycle for Code OSS webviews #267.
- Linux, macOS, portable V8, native document, sanitizer, and selected Chrome/WPT gates pass.
Collision audit
This owns the History bindings, same-document URL/base update helpers, and focused contracts. It does not overlap active #382 IndexedDB/File System paths, #386 CSSOM paths, #388 resource-only tests, or consolidation #76. The broader #267 stack retains iframe navigation, WindowProxy, document open/write/close, CSP/Permissions Policy, replacement, traversal if deferred, and teardown acceptance.
Activity
wieslawsoltes commentedon Sep 18, 2026
Implementation is open in #396 at
bd3a927e.Focused evidence before opening the PR:
replaceState+ 1,000 boundedpushState: p95 about 0.01 ms, zero layout/scene publicationsfile:URL-object path updates in place and emits no host navigation requestThe issue body now separates this same-document primitive from #267's remaining iframe navigation/WindowProxy construction and traversal work. Direct PR runners are pending; the package publication workflow is intentionally canceled for this focused runtime change.