diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 00b5dc7523..dc8b5c4c12 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -1012,7 +1012,7 @@ void Document::update_layout() browsing_context()->set_needs_display(); - if (browsing_context()->is_top_level() && browsing_context()->active_document() == this) { + if (navigable()->is_traversable()) { if (auto* page = this->page()) page->client().page_did_layout(); } diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp index f82716945a..40c23d3c1e 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.cpp +++ b/Userland/Libraries/LibWeb/DOM/Element.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -1514,8 +1515,9 @@ static ErrorOr scroll_an_element_into_view(DOM::Element& element, Bindings if (!layout_node) return Error::from_string_view("Element has no parent layout node that is a box."sv); - if (element.document().browsing_context() == &page->top_level_browsing_context()) - page->client().page_did_request_scroll_into_view(verify_cast(*layout_node).paintable_box()->absolute_padding_box_rect()); + if (auto navigable = element.document().navigable()) { + element.document().navigable()->traversable_navigable()->page()->client().page_did_request_scroll_into_view(verify_cast(*layout_node).paintable_box()->absolute_padding_box_rect()); + } return {}; } diff --git a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp index 0054282e72..d8fa224571 100644 --- a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp +++ b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp @@ -531,7 +531,7 @@ void BrowsingContext::set_active_document(JS::NonnullGCPtr docume // AD-HOC: document->set_browsing_context(this); - if (m_page && m_page->top_level_browsing_context_is_initialized() && this == &m_page->top_level_browsing_context()) + if (m_page && m_page->top_level_traversable_is_initialized() && this == &m_page->top_level_browsing_context()) m_page->client().page_did_change_title(document->title()); if (previously_active_document && previously_active_document != document.ptr()) diff --git a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp index 489d25ab85..b824305a7d 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -458,11 +459,9 @@ bool HTMLLinkElement::load_favicon_and_use_if_window_is_active() if (!page) return favicon_bitmap; - if (document().browsing_context() == &page->top_level_browsing_context()) - if (favicon_bitmap) { - page->client().page_did_change_favicon(*favicon_bitmap); - return true; - } + if (navigable() && navigable()->is_traversable()) { + navigable()->traversable_navigable()->page()->client().page_did_change_favicon(*favicon_bitmap); + } return false; } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTitleElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLTitleElement.cpp index 998a4b5b24..89a8e2b633 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLTitleElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLTitleElement.cpp @@ -6,6 +6,7 @@ #include #include +#include #include namespace Web::HTML { @@ -26,9 +27,8 @@ void HTMLTitleElement::initialize(JS::Realm& realm) void HTMLTitleElement::children_changed() { HTMLElement::children_changed(); - if (auto* page = document().page()) { - if (document().browsing_context() == &page->top_level_browsing_context()) - page->client().page_did_change_title(document().title()); + if (navigable() && navigable()->is_traversable()) { + navigable()->traversable_navigable()->page()->client().page_did_change_title(document().title()); } } diff --git a/Userland/Libraries/LibWeb/HTML/Navigable.cpp b/Userland/Libraries/LibWeb/HTML/Navigable.cpp index 21a1f85cbb..aa43989120 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigable.cpp +++ b/Userland/Libraries/LibWeb/HTML/Navigable.cpp @@ -71,6 +71,11 @@ Vector> Navigable::child_navigables() const return results; } +bool Navigable::is_traversable() const +{ + return is(*this); +} + Navigable::Navigable() { all_navigables().set(this); diff --git a/Userland/Libraries/LibWeb/HTML/Navigable.h b/Userland/Libraries/LibWeb/HTML/Navigable.h index b5ccf02d59..edd549c580 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigable.h +++ b/Userland/Libraries/LibWeb/HTML/Navigable.h @@ -51,6 +51,8 @@ public: Vector> child_navigables() const; + bool is_traversable() const; + String const& id() const { return m_id; } JS::GCPtr parent() const { return m_parent; } diff --git a/Userland/Libraries/LibWeb/Page/Page.cpp b/Userland/Libraries/LibWeb/Page/Page.cpp index 15f1fcc8a2..581f7ba254 100644 --- a/Userland/Libraries/LibWeb/Page/Page.cpp +++ b/Userland/Libraries/LibWeb/Page/Page.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -24,7 +25,7 @@ namespace Web { Page::Page(PageClient& client) : m_client(client) { - m_top_level_browsing_context = JS::make_handle(*HTML::BrowsingContext::create_a_new_top_level_browsing_context(*this)); + m_top_level_traversable = JS::make_handle(HTML::TraversableNavigable::create_a_fresh_top_level_traversable(*this, AK::URL("about:blank")).release_value_but_fixme_should_propagate_errors()); } Page::~Page() = default; @@ -43,17 +44,16 @@ void Page::set_focused_browsing_context(Badge, HTML::BrowsingConte void Page::load(const AK::URL& url) { - top_level_browsing_context().loader().load(url, FrameLoader::Type::Navigation); + (void)top_level_traversable()->navigate(url, *top_level_traversable()->active_document()); } -void Page::load(LoadRequest& request) +void Page::load(LoadRequest&) { - top_level_browsing_context().loader().load(request, FrameLoader::Type::Navigation); } void Page::load_html(StringView html, const AK::URL& url) { - top_level_browsing_context().loader().load_html(html, url); + (void)top_level_traversable()->navigate(url, *top_level_traversable()->active_document(), String::from_utf8(html).release_value_but_fixme_should_propagate_errors()); } bool Page::has_ongoing_navigation() const @@ -167,19 +167,24 @@ bool Page::handle_keyup(KeyCode key, unsigned modifiers, u32 code_point) return focused_context().event_handler().handle_keyup(key, modifiers, code_point); } -bool Page::top_level_browsing_context_is_initialized() const +bool Page::top_level_traversable_is_initialized() const { - return m_top_level_browsing_context; + return m_top_level_traversable; } HTML::BrowsingContext& Page::top_level_browsing_context() { - return *m_top_level_browsing_context; + return *m_top_level_traversable->active_browsing_context(); } HTML::BrowsingContext const& Page::top_level_browsing_context() const { - return *m_top_level_browsing_context; + return *m_top_level_traversable->active_browsing_context(); +} + +JS::NonnullGCPtr Page::top_level_traversable() const +{ + return *m_top_level_traversable; } template @@ -376,8 +381,8 @@ JS::GCPtr Page::media_context_menu_element() void Page::set_user_style(String source) { m_user_style_sheet_source = source; - if (top_level_browsing_context_is_initialized() && top_level_browsing_context().active_document()) { - top_level_browsing_context().active_document()->style_computer().invalidate_rule_cache(); + if (top_level_traversable_is_initialized() && top_level_traversable()->active_document()) { + top_level_traversable()->active_document()->style_computer().invalidate_rule_cache(); } } diff --git a/Userland/Libraries/LibWeb/Page/Page.h b/Userland/Libraries/LibWeb/Page/Page.h index 2e6d06482d..2d6878414a 100644 --- a/Userland/Libraries/LibWeb/Page/Page.h +++ b/Userland/Libraries/LibWeb/Page/Page.h @@ -46,11 +46,13 @@ public: PageClient const& client() const { return m_client; } // FIXME: This is a hack. - bool top_level_browsing_context_is_initialized() const; + bool top_level_traversable_is_initialized() const; HTML::BrowsingContext& top_level_browsing_context(); HTML::BrowsingContext const& top_level_browsing_context() const; + JS::NonnullGCPtr top_level_traversable() const; + HTML::BrowsingContext& focused_context(); HTML::BrowsingContext const& focused_context() const { return const_cast(this)->focused_context(); } @@ -145,9 +147,10 @@ private: PageClient& m_client; - JS::Handle m_top_level_browsing_context; WeakPtr m_focused_context; + JS::Handle m_top_level_traversable; + // FIXME: Enable this by default once CORS preflight checks are supported. bool m_same_origin_policy_enabled { false };