diff --git a/Userland/Libraries/LibWeb/Dump.cpp b/Userland/Libraries/LibWeb/Dump.cpp index 29e02858ac..2f5727da1a 100644 --- a/Userland/Libraries/LibWeb/Dump.cpp +++ b/Userland/Libraries/LibWeb/Dump.cpp @@ -53,7 +53,7 @@ static void indent(StringBuilder& builder, int levels) static ErrorOr dump_session_history_entry(StringBuilder& builder, HTML::SessionHistoryEntry const& session_history_entry, int indent_levels) { indent(builder, indent_levels); - auto const& document = session_history_entry.document_state()->document(); + auto const& document = session_history_entry.document(); TRY(builder.try_appendff("step=({}) url=({}) is-active=({})\n", session_history_entry.step().get(), session_history_entry.url(), document && document->is_active())); for (auto const& nested_history : session_history_entry.document_state()->nested_histories()) { for (auto const& nested_she : nested_history.entries) { diff --git a/Userland/Libraries/LibWeb/HTML/Navigable.cpp b/Userland/Libraries/LibWeb/HTML/Navigable.cpp index c5bf31480b..4de469945f 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigable.cpp +++ b/Userland/Libraries/LibWeb/HTML/Navigable.cpp @@ -183,7 +183,7 @@ void Navigable::activate_history_entry(JS::GCPtr entry) // FIXME: 1. Save persisted state to the navigable's active session history entry. // 2. Let newDocument be entry's document. - JS::GCPtr new_document = entry->document_state()->document().ptr(); + JS::GCPtr new_document = entry->document().ptr(); // 3. Assert: newDocument's is initial about:blank is false, i.e., we never traverse // back to the initial about:blank Document because it always gets replaced when we @@ -205,7 +205,7 @@ void Navigable::activate_history_entry(JS::GCPtr entry) JS::GCPtr Navigable::active_document() { // A navigable's active document is its active session history entry's document. - return m_active_session_history_entry->document_state()->document(); + return m_active_session_history_entry->document(); } // https://html.spec.whatwg.org/multipage/document-sequences.html#nav-bc @@ -1097,7 +1097,7 @@ WebIDL::ExceptionOr Navigable::populate_session_history_entry_document( // FIXME: https://github.com/whatwg/html/issues/9767 // We probably are expected to skip to steps 13 and 14 and return after doing this entry->document_state()->set_document(attempt_to_create_a_non_fetch_scheme_document(navigation_params.get())); - if (entry->document_state()->document()) { + if (entry->document()) { entry->document_state()->set_ever_populated(true); } completion_steps(); @@ -1131,7 +1131,7 @@ WebIDL::ExceptionOr Navigable::populate_session_history_entry_document( })); // 2. Set entry's document state's document's salvageable to false. - entry->document_state()->document()->set_salvageable(false); + entry->document()->set_salvageable(false); // FIXME: 3. If navigationParams is not null, then: if (!navigation_params.has()) { @@ -1174,7 +1174,7 @@ WebIDL::ExceptionOr Navigable::populate_session_history_entry_document( // What is "request" here? // 13. If entry's document state's document is not null, then set entry's document state's ever populated to true. - if (entry->document_state()->document()) { + if (entry->document()) { entry->document_state()->set_ever_populated(true); } @@ -1805,7 +1805,7 @@ void finalize_a_cross_document_navigation(JS::NonnullGCPtr navigable, navigable->set_delaying_load_events(false); // 3. If historyEntry's document is null, then return. - if (!history_entry->document_state()->document()) + if (!history_entry->document()) return; // 4. If all of the following are true: @@ -1813,7 +1813,7 @@ void finalize_a_cross_document_navigation(JS::NonnullGCPtr navigable, // - historyEntry's document's browsing context is not an auxiliary browsing context whose opener browsing context is non-null; and // - historyEntry's document's origin is not navigable's active document's origin // then set historyEntry's document state's navigable target name to the empty string. - if (navigable->parent() == nullptr && history_entry->document_state()->document()->browsing_context()->opener_browsing_context() != nullptr && history_entry->document_state()->document()->origin() != navigable->active_document()->origin()) + if (navigable->parent() == nullptr && history_entry->document()->browsing_context()->opener_browsing_context() != nullptr && history_entry->document()->origin() != navigable->active_document()->origin()) history_entry->document_state()->set_navigable_target_name(String {}); // 5. Let entryToReplace be navigable's active session history entry if historyHandling is "replace", otherwise null. diff --git a/Userland/Libraries/LibWeb/HTML/Navigation.cpp b/Userland/Libraries/LibWeb/HTML/Navigation.cpp index 75817aafda..cc216cb507 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigation.cpp +++ b/Userland/Libraries/LibWeb/HTML/Navigation.cpp @@ -1272,7 +1272,7 @@ bool Navigation::fire_a_traverse_navigate_event(JS::NonnullGCPtrset_is_same_document(destination_she->document_state()->document() == &verify_cast(relevant_global_object(*this)).associated_document()); + destination->set_is_same_document(destination_she->document() == &verify_cast(relevant_global_object(*this)).associated_document()); // 9. Return the result of performing the inner navigate event firing algorithm given navigation, "traverse", event, destination, userInvolvement, null, and null. // AD-HOC: We don't pass the event, but we do pass the classic_history_api state at the end to be set later diff --git a/Userland/Libraries/LibWeb/HTML/NavigationHistoryEntry.cpp b/Userland/Libraries/LibWeb/HTML/NavigationHistoryEntry.cpp index 653dd17c41..f1224dcef4 100644 --- a/Userland/Libraries/LibWeb/HTML/NavigationHistoryEntry.cpp +++ b/Userland/Libraries/LibWeb/HTML/NavigationHistoryEntry.cpp @@ -59,7 +59,7 @@ WebIDL::ExceptionOr> 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_state()->document() != &document) + if ((she->document() != &document) && (she->document_state()->request_referrer_policy() == ReferrerPolicy::ReferrerPolicy::NoReferrer || she->document_state()->request_referrer_policy() == ReferrerPolicy::ReferrerPolicy::Origin)) return OptionalNone {}; @@ -120,7 +120,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_state()->document() == &document; + return m_session_history_entry->document() == &document; } // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigationhistoryentry-getstate diff --git a/Userland/Libraries/LibWeb/HTML/SessionHistoryEntry.cpp b/Userland/Libraries/LibWeb/HTML/SessionHistoryEntry.cpp index 6df31acec4..363772d9f3 100644 --- a/Userland/Libraries/LibWeb/HTML/SessionHistoryEntry.cpp +++ b/Userland/Libraries/LibWeb/HTML/SessionHistoryEntry.cpp @@ -28,4 +28,13 @@ SessionHistoryEntry::SessionHistoryEntry() { } +// https://html.spec.whatwg.org/multipage/browsing-the-web.html#she-document +JS::GCPtr SessionHistoryEntry::document() const +{ + // To get a session history entry's document, return its document state's document. + if (!m_document_state) + return {}; + return m_document_state->document(); +} + } diff --git a/Userland/Libraries/LibWeb/HTML/SessionHistoryEntry.h b/Userland/Libraries/LibWeb/HTML/SessionHistoryEntry.h index eee322e5af..9cdcf6518a 100644 --- a/Userland/Libraries/LibWeb/HTML/SessionHistoryEntry.h +++ b/Userland/Libraries/LibWeb/HTML/SessionHistoryEntry.h @@ -37,6 +37,8 @@ public: void visit_edges(Cell::Visitor&) override; + JS::GCPtr document() const; + enum class Pending { Tag, }; diff --git a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp index 78e326e782..6ad4149679 100644 --- a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp +++ b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp @@ -249,7 +249,7 @@ Vector> TraversableNavigable::get_all_navigables_whose_cur } // 3. If targetEntry's document is navigable's document, and targetEntry's document state's reload pending is false, then extend navigablesToCheck with the child navigables of navigable. - if (target_entry->document_state()->document() == navigable->active_document() && !target_entry->document_state()->reload_pending()) { + if (target_entry->document() == navigable->active_document() && !target_entry->document_state()->reload_pending()) { navigables_to_check.extend(navigable->child_navigables()); } } @@ -318,7 +318,7 @@ Vector> TraversableNavigable::get_all_navigables_that_migh // 2. If targetEntry's document is not navigable's document or targetEntry's document state's reload pending is true, then append navigable to results. // NOTE: Although navigable's active history entry can change synchronously, the new entry will always have the same Document, // so accessing navigable's document is reliable. - if (target_entry->document_state()->document() != navigable->active_document() || target_entry->document_state()->reload_pending()) { + if (target_entry->document() != navigable->active_document() || target_entry->document_state()->reload_pending()) { results.append(navigable); } @@ -421,7 +421,7 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ // 3. Let changingNavigableContinuation be a changing navigable continuation state with: auto changing_navigable_continuation = ChangingNavigableContinuationState { - .displayed_document = displayed_entry->document_state()->document(), + .displayed_document = displayed_entry->document(), .target_entry = target_entry, .navigable = navigable, .update_only = false @@ -444,13 +444,13 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ auto after_document_populated = [old_origin, target_entry, changing_navigable_continuation, &changing_navigable_continuations, &vm, &navigable]() mutable { // 1. If targetEntry's document is null, then set changingNavigableContinuation's update-only to true. - if (!target_entry->document_state()->document()) { + if (!target_entry->document()) { changing_navigable_continuation.update_only = true; } else { // 2. If targetEntry's document's origin is not oldOrigin, then set targetEntry's classic history API state to StructuredSerializeForStorage(null). - if (target_entry->document_state()->document()->origin() != old_origin) { + if (target_entry->document()->origin() != old_origin) { target_entry->set_classic_history_api_state(MUST(structured_serialize_for_storage(vm, JS::js_null()))); } @@ -460,7 +460,7 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ // - targetEntry's document's origin is not oldOrigin, // then set targetEntry's document state's navigable target name to the empty string. if (navigable->parent() != nullptr - && target_entry->document_state()->document()->browsing_context()->opener_browsing_context() == nullptr + && target_entry->document()->browsing_context()->opener_browsing_context() == nullptr && target_entry->document_state()->origin() != old_origin) { target_entry->document_state()->set_navigable_target_name(String {}); } @@ -471,7 +471,7 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ }; // 6. If targetEntry's document is null, or targetEntry's document state's reload pending is true, then: - if (!target_entry->document_state()->document() || target_entry->document_state()->reload_pending()) { + if (!target_entry->document() || target_entry->document_state()->reload_pending()) { // FIXME: 1. Let navTimingType be "back_forward" if targetEntry's document is null; otherwise "reload". // 2. Let targetSnapshotParams be the result of snapshotting target snapshot params given navigable. @@ -593,9 +593,9 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ // 1. If changingNavigableContinuation's update-only is false, then: if (!update_only) { // 1. If targetEntry's document does not equal displayedDocument, then: - if (target_entry->document_state()->document().ptr() != displayed_document.ptr()) { + if (target_entry->document().ptr() != displayed_document.ptr()) { // 1. Unload displayedDocument given targetEntry's document. - displayed_document->unload(target_entry->document_state()->document()); + displayed_document->unload(target_entry->document()); // 2. For each childNavigable of displayedDocument's descendant navigables, queue a global task on the navigation and traversal task source given // childNavigable's active window to unload childNavigable's active document. @@ -624,16 +624,16 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ // 3. Let updateDocument be an algorithm step which performs update document for history step application given targetEntry's document, // targetEntry, changingNavigableContinuation's update-only, scriptHistoryLength, scriptHistoryIndex, and entriesForNavigationAPI. auto update_document = JS::SafeFunction([target_entry, update_only, script_history_length, script_history_index, entries_for_navigation_api = move(entries_for_navigation_api)] { - target_entry->document_state()->document()->update_for_history_step_application(*target_entry, update_only, script_history_length, script_history_index, entries_for_navigation_api); + target_entry->document()->update_for_history_step_application(*target_entry, update_only, script_history_length, script_history_index, entries_for_navigation_api); }); // 4. If targetEntry's document is equal to displayedDocument, then perform updateDocument. - if (target_entry->document_state()->document() == displayed_document.ptr()) { + if (target_entry->document() == displayed_document.ptr()) { update_document(); } // 5. Otherwise, queue a global task on the navigation and traversal task source given targetEntry's document's relevant global object to perform updateDocument else { - queue_global_task(Task::Source::NavigationAndTraversal, relevant_global_object(*target_entry->document_state()->document()), move(update_document)); + queue_global_task(Task::Source::NavigationAndTraversal, relevant_global_object(*target_entry->document()), move(update_document)); } // 6. Increment completedChangeJobs. @@ -898,7 +898,7 @@ void TraversableNavigable::destroy_top_level_traversable() // 2. For each historyEntry in traversable's session history entries: for (auto& history_entry : m_session_history_entries) { // 1. Let document be historyEntry's document. - auto document = history_entry->document_state()->document(); + auto document = history_entry->document(); // 2. If document is not null, then destroy document. if (document)