ladybird/Libraries/LibDevTools/Actors/FrameActor.h
Sam Atkins 5283f669a1 LibDevTools: Reload inspector roots after navigation
Firefox keeps using the same walker after navigation and expects it to
publish the new document root.

Normal tab debugging also relies on target switching. Re-inspect the tab
when navigation finishes, replace the walker DOM data, and notify the
watcher that the previous top-level frame target was destroyed before a
fresh target becomes available.

Send target availability as a watcher event, not as the watchTargets
response, and give each navigation a new inner window id so Firefox can
associate the new target with the new document.
2026-06-01 15:09:25 +01:00

73 lines
2.7 KiB
C++

/*
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/HashMap.h>
#include <AK/NonnullRefPtr.h>
#include <AK/Types.h>
#include <AK/Vector.h>
#include <LibDevTools/Actor.h>
#include <LibDevTools/DevToolsDelegate.h>
#include <LibDevTools/Forward.h>
#include <LibWeb/Forward.h>
#include <LibWebView/Forward.h>
namespace DevTools {
class DEVTOOLS_API FrameActor final : public Actor {
public:
static constexpr auto base_name = "frame"sv;
static NonnullRefPtr<FrameActor> create(DevToolsServer&, String name, WeakPtr<TabActor>, WeakPtr<WatcherActor>, WeakPtr<CSSPropertiesActor>, WeakPtr<ConsoleActor>, WeakPtr<InspectorActor>, WeakPtr<StyleSheetsActor>, WeakPtr<ThreadActor>, WeakPtr<AccessibilityActor>);
virtual ~FrameActor() override;
void send_frame_update_message();
void set_pending_navigation_document_events_after_target_switch(String const& url, String const& title);
void stop_listening();
JsonObject serialize_target() const;
private:
FrameActor(DevToolsServer&, String name, WeakPtr<TabActor>, WeakPtr<WatcherActor>, WeakPtr<CSSPropertiesActor>, WeakPtr<ConsoleActor>, WeakPtr<InspectorActor>, WeakPtr<StyleSheetsActor>, WeakPtr<ThreadActor>, WeakPtr<AccessibilityActor>);
void style_sheets_available(JsonObject& response, Vector<Web::CSS::StyleSheetIdentifier> style_sheets);
virtual void handle_message(Message const&) override;
void on_console_message(WebView::ConsoleOutput);
void on_network_request_started(DevToolsDelegate::NetworkRequestData);
void on_network_response_headers_received(DevToolsDelegate::NetworkResponseData);
void on_network_response_body_received(u64 request_id, ByteBuffer data);
void on_network_request_finished(DevToolsDelegate::NetworkRequestCompleteData);
void on_navigation_started(String url);
void on_navigation_finished(String url, String title);
void send_document_event(StringView name, String const& url, Optional<StringView> title = {});
void send_pending_navigation_document_events_after_target_switch();
struct PendingNavigationDocumentEvents {
String url;
String title;
};
WeakPtr<TabActor> m_tab;
WeakPtr<WatcherActor> m_watcher;
WeakPtr<CSSPropertiesActor> m_css_properties;
WeakPtr<ConsoleActor> m_console;
WeakPtr<InspectorActor> m_inspector;
WeakPtr<StyleSheetsActor> m_style_sheets;
WeakPtr<ThreadActor> m_thread;
WeakPtr<AccessibilityActor> m_accessibility;
Optional<PendingNavigationDocumentEvents> m_pending_navigation_document_events_after_target_switch;
HashMap<u64, NonnullRefPtr<NetworkEventActor>> m_network_events;
bool m_is_listening { false };
};
}