ladybird/Libraries/LibDevTools/Actors/TabActor.cpp
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

88 lines
2.6 KiB
C++

/*
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/JsonObject.h>
#include <LibDevTools/Actors/TabActor.h>
#include <LibDevTools/Actors/WatcherActor.h>
#include <LibDevTools/DevToolsDelegate.h>
#include <LibDevTools/DevToolsServer.h>
namespace DevTools {
NonnullRefPtr<TabActor> TabActor::create(DevToolsServer& devtools, String name, TabDescription description)
{
return adopt_ref(*new TabActor(devtools, move(name), move(description)));
}
TabActor::TabActor(DevToolsServer& devtools, String name, TabDescription description)
: Actor(devtools, move(name))
, m_description(move(description))
{
}
TabActor::~TabActor()
{
reset_selected_node();
}
void TabActor::handle_message(Message const& message)
{
JsonObject response;
if (message.type == "getFavicon"sv) {
// FIXME: Firefox DevTools wants a favicon URL here, but supplying a URL seems to prevent this tab from being
// listed on the about:debugging page. Both Servo and Firefox itself supply `null` here.
response.set("favicon"sv, JsonValue {});
send_response(message, move(response));
return;
}
if (message.type == "getWatcher"sv) {
if (!m_watcher)
m_watcher = devtools().register_actor<WatcherActor>(this);
response.set("actor"sv, m_watcher->name());
response.set("traits"sv, m_watcher->serialize_description());
send_response(message, move(response));
return;
}
send_unrecognized_packet_type_error(message);
}
JsonObject TabActor::serialize_description() const
{
JsonObject traits;
traits.set("watcher"sv, true);
traits.set("supportsReloadDescriptor"sv, true);
// FIXME: We are using the tab's ID multiple times here. This is likely not correct, as both Firefox and Servo
// provide different IDs for browserId, browsingContextID, and outerWindowID.
JsonObject description;
description.set("actor"sv, name());
description.set("title"sv, m_description.title);
description.set("url"sv, m_description.url);
description.set("browserId"sv, m_description.id);
description.set("browsingContextID"sv, m_description.id);
description.set("outerWindowID"sv, m_description.id);
description.set("traits"sv, move(traits));
return description;
}
void TabActor::reset_selected_node()
{
devtools().delegate().clear_highlighted_dom_node(description());
devtools().delegate().clear_inspected_dom_node(description());
}
void TabActor::navigate_to(String url, String title)
{
m_description.url = move(url);
m_description.title = move(title);
++m_inner_window_id;
}
}