mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-30 12:49:19 +00:00
LibDevTools+LibWebView: Implement basic support for console logging
This implements support for basic usage of console.log and friends. It does not implement console.assert, console.trace, console.group, etc.
This commit is contained in:
parent
848ac11495
commit
c5a22a1a97
Notes:
github-actions[bot]
2025-03-04 20:34:51 +00:00
Author: https://github.com/trflynn89
Commit: c5a22a1a97
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3801
Reviewed-by: https://github.com/AtkinsSJ
5 changed files with 155 additions and 2 deletions
|
@ -12,6 +12,9 @@
|
|||
#include <LibDevTools/Actors/InspectorActor.h>
|
||||
#include <LibDevTools/Actors/TabActor.h>
|
||||
#include <LibDevTools/Actors/ThreadActor.h>
|
||||
#include <LibDevTools/DevToolsDelegate.h>
|
||||
#include <LibDevTools/DevToolsServer.h>
|
||||
#include <LibWebView/ConsoleOutput.h>
|
||||
|
||||
namespace DevTools {
|
||||
|
||||
|
@ -28,9 +31,25 @@ FrameActor::FrameActor(DevToolsServer& devtools, String name, WeakPtr<TabActor>
|
|||
, m_inspector(move(inspector))
|
||||
, m_thread(move(thread))
|
||||
{
|
||||
if (auto tab = m_tab.strong_ref()) {
|
||||
devtools.delegate().listen_for_console_messages(
|
||||
tab->description(),
|
||||
[weak_self = make_weak_ptr<FrameActor>()](i32 message_index) {
|
||||
if (auto self = weak_self.strong_ref())
|
||||
self->console_message_available(message_index);
|
||||
},
|
||||
[weak_self = make_weak_ptr<FrameActor>()](i32 start_index, Vector<WebView::ConsoleOutput> console_output) {
|
||||
if (auto self = weak_self.strong_ref())
|
||||
self->console_messages_received(start_index, move(console_output));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
FrameActor::~FrameActor() = default;
|
||||
FrameActor::~FrameActor()
|
||||
{
|
||||
if (auto tab = m_tab.strong_ref())
|
||||
devtools().delegate().stop_listening_for_console_messages(tab->description());
|
||||
}
|
||||
|
||||
void FrameActor::handle_message(StringView type, JsonObject const&)
|
||||
{
|
||||
|
@ -38,8 +57,10 @@ void FrameActor::handle_message(StringView type, JsonObject const&)
|
|||
response.set("from"sv, name());
|
||||
|
||||
if (type == "detach"sv) {
|
||||
if (auto tab = m_tab.strong_ref())
|
||||
if (auto tab = m_tab.strong_ref()) {
|
||||
devtools().delegate().stop_listening_for_console_messages(tab->description());
|
||||
tab->reset_selected_node();
|
||||
}
|
||||
|
||||
send_message(move(response));
|
||||
return;
|
||||
|
@ -107,4 +128,95 @@ JsonObject FrameActor::serialize_target() const
|
|||
return target;
|
||||
}
|
||||
|
||||
void FrameActor::console_message_available(i32 message_index)
|
||||
{
|
||||
if (message_index <= m_highest_received_message_index) {
|
||||
dbgln("Notified about console message we already have");
|
||||
return;
|
||||
}
|
||||
if (message_index <= m_highest_notified_message_index) {
|
||||
dbgln("Notified about console message we're already aware of");
|
||||
return;
|
||||
}
|
||||
|
||||
m_highest_notified_message_index = message_index;
|
||||
|
||||
if (!m_waiting_for_messages)
|
||||
request_console_messages();
|
||||
}
|
||||
|
||||
void FrameActor::console_messages_received(i32 start_index, Vector<WebView::ConsoleOutput> console_output)
|
||||
{
|
||||
auto end_index = start_index + static_cast<i32>(console_output.size()) - 1;
|
||||
if (end_index <= m_highest_received_message_index) {
|
||||
dbgln("Received old console messages");
|
||||
return;
|
||||
}
|
||||
|
||||
JsonArray messages;
|
||||
messages.ensure_capacity(console_output.size());
|
||||
|
||||
for (auto& output : console_output) {
|
||||
JsonObject message;
|
||||
|
||||
switch (output.level) {
|
||||
case JS::Console::LogLevel::Debug:
|
||||
message.set("level"sv, "debug"sv);
|
||||
break;
|
||||
case JS::Console::LogLevel::Error:
|
||||
message.set("level"sv, "error"sv);
|
||||
break;
|
||||
case JS::Console::LogLevel::Info:
|
||||
message.set("level"sv, "info"sv);
|
||||
break;
|
||||
case JS::Console::LogLevel::Log:
|
||||
message.set("level"sv, "log"sv);
|
||||
break;
|
||||
case JS::Console::LogLevel::Warn:
|
||||
message.set("level"sv, "warn"sv);
|
||||
break;
|
||||
default:
|
||||
// FIXME: Implement remaining console levels.
|
||||
continue;
|
||||
}
|
||||
|
||||
message.set("filename"sv, "<eval>"sv);
|
||||
message.set("line_number"sv, 1);
|
||||
message.set("column_number"sv, 1);
|
||||
message.set("time_stamp"sv, output.timestamp.milliseconds_since_epoch());
|
||||
message.set("arguments"sv, JsonArray { move(output.arguments) });
|
||||
|
||||
messages.must_append(move(message));
|
||||
}
|
||||
|
||||
JsonArray console_message;
|
||||
console_message.must_append("console-message"sv);
|
||||
console_message.must_append(move(messages));
|
||||
|
||||
JsonArray array;
|
||||
array.must_append(move(console_message));
|
||||
|
||||
JsonObject message;
|
||||
message.set("from"sv, name());
|
||||
message.set("type"sv, "resources-available-array"sv);
|
||||
message.set("array"sv, move(array));
|
||||
send_message(move(message));
|
||||
|
||||
m_highest_received_message_index = end_index;
|
||||
m_waiting_for_messages = false;
|
||||
|
||||
if (m_highest_received_message_index < m_highest_notified_message_index)
|
||||
request_console_messages();
|
||||
}
|
||||
|
||||
void FrameActor::request_console_messages()
|
||||
{
|
||||
VERIFY(!m_waiting_for_messages);
|
||||
|
||||
if (auto tab = m_tab.strong_ref()) {
|
||||
devtools().delegate().request_console_messages(m_tab->description(), m_highest_received_message_index + 1);
|
||||
m_waiting_for_messages = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <AK/Types.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibDevTools/Actor.h>
|
||||
#include <LibWebView/Forward.h>
|
||||
|
||||
namespace DevTools {
|
||||
|
||||
|
@ -26,12 +29,20 @@ public:
|
|||
private:
|
||||
FrameActor(DevToolsServer&, String name, WeakPtr<TabActor>, WeakPtr<CSSPropertiesActor>, WeakPtr<ConsoleActor>, WeakPtr<InspectorActor>, WeakPtr<ThreadActor>);
|
||||
|
||||
void console_message_available(i32 message_index);
|
||||
void console_messages_received(i32 start_index, Vector<WebView::ConsoleOutput>);
|
||||
void request_console_messages();
|
||||
|
||||
WeakPtr<TabActor> m_tab;
|
||||
|
||||
WeakPtr<CSSPropertiesActor> m_css_properties;
|
||||
WeakPtr<ConsoleActor> m_console;
|
||||
WeakPtr<InspectorActor> m_inspector;
|
||||
WeakPtr<ThreadActor> m_thread;
|
||||
|
||||
i32 m_highest_notified_message_index { -1 };
|
||||
i32 m_highest_received_message_index { -1 };
|
||||
bool m_waiting_for_messages { false };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <LibDevTools/Forward.h>
|
||||
#include <LibWeb/CSS/Selector.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWebView/Forward.h>
|
||||
|
||||
namespace DevTools {
|
||||
|
||||
|
@ -38,6 +39,12 @@ public:
|
|||
|
||||
using OnScriptEvaluationComplete = Function<void(ErrorOr<JsonValue>)>;
|
||||
virtual void evaluate_javascript(TabDescription const&, String, OnScriptEvaluationComplete) const { }
|
||||
|
||||
using OnConsoleMessageAvailable = Function<void(i32 message_id)>;
|
||||
using OnReceivedConsoleMessages = Function<void(i32 start_index, Vector<WebView::ConsoleOutput>)>;
|
||||
virtual void listen_for_console_messages(TabDescription const&, OnConsoleMessageAvailable, OnReceivedConsoleMessages) const { }
|
||||
virtual void stop_listening_for_console_messages(TabDescription const&) const { }
|
||||
virtual void request_console_messages(TabDescription const&, i32) const { }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
22
Libraries/LibWebView/ConsoleOutput.h
Normal file
22
Libraries/LibWebView/ConsoleOutput.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/JsonValue.h>
|
||||
#include <AK/Time.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibJS/Console.h>
|
||||
|
||||
namespace WebView {
|
||||
|
||||
struct ConsoleOutput {
|
||||
JS::Console::LogLevel level;
|
||||
UnixDateTime timestamp;
|
||||
Vector<JsonValue> arguments;
|
||||
};
|
||||
|
||||
}
|
|
@ -19,6 +19,7 @@ class ViewImplementation;
|
|||
class WebContentClient;
|
||||
|
||||
struct Attribute;
|
||||
struct ConsoleOutput;
|
||||
struct CookieStorageKey;
|
||||
struct ProcessHandle;
|
||||
struct SearchEngine;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue