mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 21:47:43 +00:00
LibWeb: Make SessionHistoryEntry GC-allocated
These will need to float around more than they're currently able to. Put them on the GC heap to prepare for that. Co-authored-by: Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
This commit is contained in:
parent
32557be930
commit
3b0e5a87db
7 changed files with 60 additions and 33 deletions
|
@ -337,6 +337,7 @@ set(SOURCES
|
||||||
HTML/Scripting/ModuleScript.cpp
|
HTML/Scripting/ModuleScript.cpp
|
||||||
HTML/Scripting/Script.cpp
|
HTML/Scripting/Script.cpp
|
||||||
HTML/Scripting/WindowEnvironmentSettingsObject.cpp
|
HTML/Scripting/WindowEnvironmentSettingsObject.cpp
|
||||||
|
HTML/SessionHistoryEntry.cpp
|
||||||
HTML/Storage.cpp
|
HTML/Storage.cpp
|
||||||
HTML/StructuredSerialize.cpp
|
HTML/StructuredSerialize.cpp
|
||||||
HTML/SubmitEvent.cpp
|
HTML/SubmitEvent.cpp
|
||||||
|
|
|
@ -351,6 +351,7 @@ class PromiseRejectionEvent;
|
||||||
class WorkerDebugConsoleClient;
|
class WorkerDebugConsoleClient;
|
||||||
struct SandboxingFlagSet;
|
struct SandboxingFlagSet;
|
||||||
struct SerializedFormData;
|
struct SerializedFormData;
|
||||||
|
struct SessionHistoryEntry;
|
||||||
class Storage;
|
class Storage;
|
||||||
class SubmitEvent;
|
class SubmitEvent;
|
||||||
class TextMetrics;
|
class TextMetrics;
|
||||||
|
|
|
@ -209,15 +209,15 @@ JS::NonnullGCPtr<BrowsingContext> BrowsingContext::create_a_new_browsing_context
|
||||||
// FIXME: 21. If creator is non-null, then set document's policy container to a clone of creator's policy container.
|
// FIXME: 21. If creator is non-null, then set document's policy container to a clone of creator's policy container.
|
||||||
|
|
||||||
// 22. Append a new session history entry to browsingContext's session history whose URL is about:blank and document is document.
|
// 22. Append a new session history entry to browsingContext's session history whose URL is about:blank and document is document.
|
||||||
browsing_context->m_session_history.append(HTML::SessionHistoryEntry {
|
auto new_entry = browsing_context->heap().allocate_without_realm<SessionHistoryEntry>();
|
||||||
.url = AK::URL("about:blank"),
|
new_entry->url = AK::URL("about:blank");
|
||||||
.document = document.ptr(),
|
new_entry->document = document.ptr();
|
||||||
.serialized_state = {},
|
new_entry->serialized_state = {};
|
||||||
.policy_container = {},
|
new_entry->policy_container = {};
|
||||||
.scroll_restoration_mode = {},
|
new_entry->scroll_restoration_mode = {};
|
||||||
.browsing_context_name = {},
|
new_entry->browsing_context_name = {};
|
||||||
.original_source_browsing_context = {},
|
new_entry->original_source_browsing_context = {};
|
||||||
});
|
browsing_context->m_session_history.append(*new_entry);
|
||||||
|
|
||||||
// 23. Completely finish loading document.
|
// 23. Completely finish loading document.
|
||||||
document->completely_finish_loading();
|
document->completely_finish_loading();
|
||||||
|
@ -249,7 +249,7 @@ void BrowsingContext::visit_edges(Cell::Visitor& visitor)
|
||||||
Base::visit_edges(visitor);
|
Base::visit_edges(visitor);
|
||||||
|
|
||||||
for (auto& entry : m_session_history)
|
for (auto& entry : m_session_history)
|
||||||
visitor.visit(entry.document);
|
visitor.visit(entry);
|
||||||
visitor.visit(m_container);
|
visitor.visit(m_container);
|
||||||
visitor.visit(m_window_proxy);
|
visitor.visit(m_window_proxy);
|
||||||
visitor.visit(m_opener_browsing_context);
|
visitor.visit(m_opener_browsing_context);
|
||||||
|
@ -774,8 +774,8 @@ bool BrowsingContext::still_on_its_initial_about_blank_document() const
|
||||||
// if browsingContext's session history's size is 1
|
// if browsingContext's session history's size is 1
|
||||||
// and browsingContext's session history[0]'s document's is initial about:blank is true.
|
// and browsingContext's session history[0]'s document's is initial about:blank is true.
|
||||||
return m_session_history.size() == 1
|
return m_session_history.size() == 1
|
||||||
&& m_session_history[0].document
|
&& m_session_history[0]->document
|
||||||
&& m_session_history[0].document->is_initial_about_blank();
|
&& m_session_history[0]->document->is_initial_about_blank();
|
||||||
}
|
}
|
||||||
|
|
||||||
DOM::Document const* BrowsingContext::active_document() const
|
DOM::Document const* BrowsingContext::active_document() const
|
||||||
|
@ -1009,15 +1009,15 @@ WebIDL::ExceptionOr<void> BrowsingContext::navigate_to_a_fragment(AK::URL const&
|
||||||
// document is the current entry's document,
|
// document is the current entry's document,
|
||||||
// policy container is the current entry's policy-container
|
// policy container is the current entry's policy-container
|
||||||
// and scroll restoration mode is the current entry's scroll restoration mode.
|
// and scroll restoration mode is the current entry's scroll restoration mode.
|
||||||
m_session_history.append(SessionHistoryEntry {
|
auto new_entry = heap().allocate_without_realm<SessionHistoryEntry>();
|
||||||
.url = url,
|
new_entry->url = url;
|
||||||
.document = current_entry().document,
|
new_entry->document = current_entry().document;
|
||||||
.serialized_state = {},
|
new_entry->serialized_state = {};
|
||||||
.policy_container = current_entry().policy_container,
|
new_entry->policy_container = current_entry().policy_container;
|
||||||
.scroll_restoration_mode = current_entry().scroll_restoration_mode,
|
new_entry->scroll_restoration_mode = current_entry().scroll_restoration_mode;
|
||||||
.browsing_context_name = {},
|
new_entry->browsing_context_name = {};
|
||||||
.original_source_browsing_context = {},
|
new_entry->original_source_browsing_context = {};
|
||||||
});
|
m_session_history.append(*new_entry);
|
||||||
|
|
||||||
// 4. Traverse the history to the new entry, with historyHandling set to historyHandling.
|
// 4. Traverse the history to the new entry, with historyHandling set to historyHandling.
|
||||||
// This will scroll to the fragment given in what is now the document's URL.
|
// This will scroll to the fragment given in what is now the document's URL.
|
||||||
|
@ -1033,7 +1033,7 @@ WebIDL::ExceptionOr<void> BrowsingContext::navigate_to_a_fragment(AK::URL const&
|
||||||
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#traverse-the-history
|
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#traverse-the-history
|
||||||
WebIDL::ExceptionOr<void> BrowsingContext::traverse_the_history(size_t entry_index, HistoryHandlingBehavior history_handling, bool explicit_history_navigation)
|
WebIDL::ExceptionOr<void> BrowsingContext::traverse_the_history(size_t entry_index, HistoryHandlingBehavior history_handling, bool explicit_history_navigation)
|
||||||
{
|
{
|
||||||
auto* entry = &m_session_history[entry_index];
|
auto entry = m_session_history[entry_index];
|
||||||
|
|
||||||
// 1. If entry's document is null, then:
|
// 1. If entry's document is null, then:
|
||||||
if (!entry->document) {
|
if (!entry->document) {
|
||||||
|
@ -1152,7 +1152,7 @@ WebIDL::ExceptionOr<void> BrowsingContext::traverse_the_history(size_t entry_ind
|
||||||
// FIXME: This is gnarly.
|
// FIXME: This is gnarly.
|
||||||
m_session_history.remove(entry_index - 1);
|
m_session_history.remove(entry_index - 1);
|
||||||
entry_index--;
|
entry_index--;
|
||||||
entry = &m_session_history[entry_index];
|
entry = m_session_history[entry_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10. If entry's persisted user state is null, and its URL's fragment is non-null, then scroll to the fragment.
|
// 10. If entry's persisted user state is null, and its URL's fragment is non-null, then scroll to the fragment.
|
||||||
|
@ -1260,11 +1260,11 @@ Vector<JS::Handle<DOM::Document>> BrowsingContext::document_family() const
|
||||||
{
|
{
|
||||||
HashTable<DOM::Document*> documents;
|
HashTable<DOM::Document*> documents;
|
||||||
for (auto& entry : m_session_history) {
|
for (auto& entry : m_session_history) {
|
||||||
if (!entry.document)
|
if (!entry->document)
|
||||||
continue;
|
continue;
|
||||||
if (documents.set(const_cast<DOM::Document*>(entry.document.ptr())) == AK::HashSetResult::ReplacedExistingEntry)
|
if (documents.set(const_cast<DOM::Document*>(entry->document.ptr())) == AK::HashSetResult::ReplacedExistingEntry)
|
||||||
continue;
|
continue;
|
||||||
for (auto& context : entry.document->list_of_descendant_browsing_contexts()) {
|
for (auto& context : entry->document->list_of_descendant_browsing_contexts()) {
|
||||||
for (auto& document : context->document_family()) {
|
for (auto& document : context->document_family()) {
|
||||||
documents.set(document.ptr());
|
documents.set(document.ptr());
|
||||||
}
|
}
|
||||||
|
@ -1320,8 +1320,8 @@ void BrowsingContext::discard()
|
||||||
|
|
||||||
// 1. Discard all Document objects for all the entries in browsingContext's session history.
|
// 1. Discard all Document objects for all the entries in browsingContext's session history.
|
||||||
for (auto& entry : m_session_history) {
|
for (auto& entry : m_session_history) {
|
||||||
if (entry.document)
|
if (entry->document)
|
||||||
entry.document->discard();
|
entry->document->discard();
|
||||||
}
|
}
|
||||||
|
|
||||||
// AD-HOC:
|
// AD-HOC:
|
||||||
|
|
|
@ -210,8 +210,9 @@ public:
|
||||||
|
|
||||||
JS::GCPtr<DOM::Node> currently_focused_area();
|
JS::GCPtr<DOM::Node> currently_focused_area();
|
||||||
|
|
||||||
Vector<SessionHistoryEntry>& session_history() { return m_session_history; }
|
Vector<JS::NonnullGCPtr<SessionHistoryEntry>>& session_history() { return m_session_history; }
|
||||||
Vector<SessionHistoryEntry> const& session_history() const { return m_session_history; }
|
Vector<JS::NonnullGCPtr<SessionHistoryEntry>> const& session_history() const { return m_session_history; }
|
||||||
|
|
||||||
size_t session_history_index() const { return *m_session_history_index; }
|
size_t session_history_index() const { return *m_session_history_index; }
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/dom.html#still-on-its-initial-about:blank-document
|
// https://html.spec.whatwg.org/multipage/dom.html#still-on-its-initial-about:blank-document
|
||||||
|
@ -284,7 +285,7 @@ private:
|
||||||
Optional<size_t> m_session_history_index { 0 };
|
Optional<size_t> m_session_history_index { 0 };
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/history.html#session-history
|
// https://html.spec.whatwg.org/multipage/history.html#session-history
|
||||||
Vector<SessionHistoryEntry> m_session_history;
|
Vector<JS::NonnullGCPtr<SessionHistoryEntry>> m_session_history;
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/browsers.html#creator-url
|
// https://html.spec.whatwg.org/multipage/browsers.html#creator-url
|
||||||
Optional<AK::URL> m_creator_url;
|
Optional<AK::URL> m_creator_url;
|
||||||
|
|
|
@ -83,7 +83,7 @@ WebIDL::ExceptionOr<void> History::go(long delta = 0)
|
||||||
if (next_entry_index < sessions.size()) {
|
if (next_entry_index < sessions.size()) {
|
||||||
auto const& next_entry = sessions.at(next_entry_index);
|
auto const& next_entry = sessions.at(next_entry_index);
|
||||||
// FIXME: 4. Traverse the history by a delta with delta and document's browsing context.
|
// FIXME: 4. Traverse the history by a delta with delta and document's browsing context.
|
||||||
browsing_context->loader().load(next_entry.url, FrameLoader::Type::Reload);
|
browsing_context->loader().load(next_entry->url, FrameLoader::Type::Reload);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|
19
Userland/Libraries/LibWeb/HTML/SessionHistoryEntry.cpp
Normal file
19
Userland/Libraries/LibWeb/HTML/SessionHistoryEntry.cpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibWeb/DOM/Document.h>
|
||||||
|
#include <LibWeb/HTML/SessionHistoryEntry.h>
|
||||||
|
|
||||||
|
namespace Web::HTML {
|
||||||
|
|
||||||
|
void SessionHistoryEntry::visit_edges(Cell::Visitor& visitor)
|
||||||
|
{
|
||||||
|
Base::visit_edges(visitor);
|
||||||
|
visitor.visit(document);
|
||||||
|
visitor.visit(original_source_browsing_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <AK/URL.h>
|
#include <AK/URL.h>
|
||||||
#include <AK/WeakPtr.h>
|
#include <AK/WeakPtr.h>
|
||||||
|
#include <LibJS/Heap/Cell.h>
|
||||||
#include <LibJS/Heap/GCPtr.h>
|
#include <LibJS/Heap/GCPtr.h>
|
||||||
#include <LibWeb/Forward.h>
|
#include <LibWeb/Forward.h>
|
||||||
#include <LibWeb/HTML/PolicyContainers.h>
|
#include <LibWeb/HTML/PolicyContainers.h>
|
||||||
|
@ -26,7 +27,11 @@ enum class ScrollRestorationMode {
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/history.html#session-history-entry
|
// https://html.spec.whatwg.org/multipage/history.html#session-history-entry
|
||||||
struct SessionHistoryEntry {
|
struct SessionHistoryEntry final : public JS::Cell {
|
||||||
|
JS_CELL(SessionHistoryEntry, JS::Cell);
|
||||||
|
|
||||||
|
void visit_edges(Cell::Visitor&) override;
|
||||||
|
|
||||||
// URL, a URL
|
// URL, a URL
|
||||||
AK::URL url;
|
AK::URL url;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue