LibWeb: Make Navigable directly own its active document

Previously, the active document's lifecycle was bound to
SessionHistoryEntry via DocumentState. The ownership chain was:
  Navigable → SessionHistoryEntry → DocumentState → Document

This made it impossible to move SessionHistoryEntry to the UI process
(which cannot own DOM::Document). This commit decouples the two by
giving Navigable a direct m_active_document field that serves as the
authoritative source for active_document().

- Navigable owns m_active_document directly; active_document() reads
  from it instead of going through the active session history entry.

- DocumentState no longer holds a Document pointer. Instead, it stores
  a document_id for "same document?" checks. Same-document navigations
  share a DocumentState and thus the same document_id, while
  cross-document navigations create a new DocumentState with a new ID.

- A pending_document parameter is threaded through
  finalize_a_cross_document_navigation → apply_the_push_or_replace →
  apply_the_history_step so the newly created document reaches
  activation without being stored on DocumentState.

- For traversal, the population output delivers the document.
  A resolved_document is computed per continuation from either the
  pending document, the population output, or the current active
  document (for same-document traversals).
This commit is contained in:
Aliaksandr Kalenik
2026-03-31 16:56:18 +02:00
committed by Alexander Kalenik
parent 1467127d35
commit 2645695fdd
Notes: github-actions[bot] 2026-04-01 09:52:51 +00:00
14 changed files with 137 additions and 94 deletions

View File

@@ -10,6 +10,7 @@
#include <LibWeb/Bindings/NavigationHistoryEntryPrototype.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/HTML/DocumentState.h>
#include <LibWeb/HTML/Navigable.h>
#include <LibWeb/HTML/Navigation.h>
#include <LibWeb/HTML/NavigationHistoryEntry.h>
#include <LibWeb/HTML/SessionHistoryEntry.h>
@@ -61,7 +62,7 @@ Optional<String> NavigationHistoryEntry::url() const
// 4. If she's document does not equal document, and she's document state's request referrer policy
// is "no-referrer" or "origin", then return null.
if ((she->document() != &document)
if ((she->document_state()->document_id() != document.unique_id())
&& (she->document_state()->request_referrer_policy() == ReferrerPolicy::ReferrerPolicy::NoReferrer
|| she->document_state()->request_referrer_policy() == ReferrerPolicy::ReferrerPolicy::Origin))
return OptionalNone {};
@@ -122,7 +123,7 @@ bool NavigationHistoryEntry::same_document() const
return false;
// 3. Return true if this's session history entry's document equals document, and false otherwise.
return m_session_history_entry->document() == &document;
return m_session_history_entry->document_state()->document_id() == document.unique_id();
}
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigationhistoryentry-getstate