mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 04:09:13 +00:00
LibWebView+WebContent: Implement basic DevTools console support
This commit is contained in:
parent
c5a22a1a97
commit
ffdce78b7b
Notes:
github-actions[bot]
2025-03-04 20:34:44 +00:00
Author: https://github.com/trflynn89
Commit: ffdce78b7b
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3801
Reviewed-by: https://github.com/AtkinsSJ
13 changed files with 128 additions and 4 deletions
|
@ -433,4 +433,34 @@ void Application::evaluate_javascript(DevTools::TabDescription const& descriptio
|
||||||
view->js_console_input(move(script));
|
view->js_console_input(move(script));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::listen_for_console_messages(DevTools::TabDescription const& description, OnConsoleMessageAvailable on_console_message_available, OnReceivedConsoleMessages on_received_console_output) const
|
||||||
|
{
|
||||||
|
auto view = ViewImplementation::find_view_by_id(description.id);
|
||||||
|
if (!view.has_value())
|
||||||
|
return;
|
||||||
|
|
||||||
|
view->on_console_message_available = move(on_console_message_available);
|
||||||
|
view->on_received_unstyled_console_messages = move(on_received_console_output);
|
||||||
|
view->js_console_request_messages(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::stop_listening_for_console_messages(DevTools::TabDescription const& description) const
|
||||||
|
{
|
||||||
|
auto view = ViewImplementation::find_view_by_id(description.id);
|
||||||
|
if (!view.has_value())
|
||||||
|
return;
|
||||||
|
|
||||||
|
view->on_console_message_available = nullptr;
|
||||||
|
view->on_received_unstyled_console_messages = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::request_console_messages(DevTools::TabDescription const& description, i32 start_index) const
|
||||||
|
{
|
||||||
|
auto view = ViewImplementation::find_view_by_id(description.id);
|
||||||
|
if (!view.has_value())
|
||||||
|
return;
|
||||||
|
|
||||||
|
view->js_console_request_messages(start_index);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,9 @@ private:
|
||||||
virtual void highlight_dom_node(DevTools::TabDescription const&, Web::UniqueNodeID, Optional<Web::CSS::Selector::PseudoElement::Type>) const override;
|
virtual void highlight_dom_node(DevTools::TabDescription const&, Web::UniqueNodeID, Optional<Web::CSS::Selector::PseudoElement::Type>) const override;
|
||||||
virtual void clear_highlighted_dom_node(DevTools::TabDescription const&) const override;
|
virtual void clear_highlighted_dom_node(DevTools::TabDescription const&) const override;
|
||||||
virtual void evaluate_javascript(DevTools::TabDescription const&, String, OnScriptEvaluationComplete) const override;
|
virtual void evaluate_javascript(DevTools::TabDescription const&, String, OnScriptEvaluationComplete) const override;
|
||||||
|
virtual void listen_for_console_messages(DevTools::TabDescription const&, OnConsoleMessageAvailable, OnReceivedConsoleMessages) const override;
|
||||||
|
virtual void stop_listening_for_console_messages(DevTools::TabDescription const&) const override;
|
||||||
|
virtual void request_console_messages(DevTools::TabDescription const&, i32) const override;
|
||||||
|
|
||||||
static Application* s_the;
|
static Application* s_the;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ set(SOURCES
|
||||||
Application.cpp
|
Application.cpp
|
||||||
Attribute.cpp
|
Attribute.cpp
|
||||||
ChromeProcess.cpp
|
ChromeProcess.cpp
|
||||||
|
ConsoleOutput.cpp
|
||||||
CookieJar.cpp
|
CookieJar.cpp
|
||||||
Database.cpp
|
Database.cpp
|
||||||
HelperProcess.cpp
|
HelperProcess.cpp
|
||||||
|
|
29
Libraries/LibWebView/ConsoleOutput.cpp
Normal file
29
Libraries/LibWebView/ConsoleOutput.cpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibIPC/Decoder.h>
|
||||||
|
#include <LibIPC/Encoder.h>
|
||||||
|
#include <LibWebView/ConsoleOutput.h>
|
||||||
|
|
||||||
|
template<>
|
||||||
|
ErrorOr<void> IPC::encode(Encoder& encoder, WebView::ConsoleOutput const& console_output)
|
||||||
|
{
|
||||||
|
TRY(encoder.encode(console_output.level));
|
||||||
|
TRY(encoder.encode(console_output.timestamp));
|
||||||
|
TRY(encoder.encode(console_output.arguments));
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
ErrorOr<WebView::ConsoleOutput> IPC::decode(Decoder& decoder)
|
||||||
|
{
|
||||||
|
auto level = TRY(decoder.decode<JS::Console::LogLevel>());
|
||||||
|
auto timestamp = TRY(decoder.decode<UnixDateTime>());
|
||||||
|
auto arguments = TRY(decoder.decode<Vector<JsonValue>>());
|
||||||
|
|
||||||
|
return WebView::ConsoleOutput { level, timestamp, move(arguments) };
|
||||||
|
}
|
|
@ -9,6 +9,7 @@
|
||||||
#include <AK/JsonValue.h>
|
#include <AK/JsonValue.h>
|
||||||
#include <AK/Time.h>
|
#include <AK/Time.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
#include <LibIPC/Forward.h>
|
||||||
#include <LibJS/Console.h>
|
#include <LibJS/Console.h>
|
||||||
|
|
||||||
namespace WebView {
|
namespace WebView {
|
||||||
|
@ -20,3 +21,13 @@ struct ConsoleOutput {
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace IPC {
|
||||||
|
|
||||||
|
template<>
|
||||||
|
ErrorOr<void> encode(Encoder&, WebView::ConsoleOutput const&);
|
||||||
|
|
||||||
|
template<>
|
||||||
|
ErrorOr<WebView::ConsoleOutput> decode(Decoder&);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -218,6 +218,7 @@ public:
|
||||||
Function<void(JsonValue)> on_received_js_console_result;
|
Function<void(JsonValue)> on_received_js_console_result;
|
||||||
Function<void(i32 message_id)> on_console_message_available;
|
Function<void(i32 message_id)> on_console_message_available;
|
||||||
Function<void(i32 start_index, Vector<String> const& message_types, Vector<String> const& messages)> on_received_styled_console_messages;
|
Function<void(i32 start_index, Vector<String> const& message_types, Vector<String> const& messages)> on_received_styled_console_messages;
|
||||||
|
Function<void(i32 start_index, Vector<ConsoleOutput>)> on_received_unstyled_console_messages;
|
||||||
Function<void(i32 count_waiting)> on_resource_status_change;
|
Function<void(i32 count_waiting)> on_resource_status_change;
|
||||||
Function<void()> on_restore_window;
|
Function<void()> on_restore_window;
|
||||||
Function<void(Gfx::IntPoint)> on_reposition_window;
|
Function<void(Gfx::IntPoint)> on_reposition_window;
|
||||||
|
|
|
@ -385,6 +385,14 @@ void WebContentClient::did_get_styled_js_console_messages(u64 page_id, i32 start
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebContentClient::did_get_unstyled_js_console_messages(u64 page_id, i32 start_index, Vector<ConsoleOutput> const& console_output)
|
||||||
|
{
|
||||||
|
if (auto view = view_for_page_id(page_id); view.has_value()) {
|
||||||
|
if (view->on_received_unstyled_console_messages)
|
||||||
|
view->on_received_unstyled_console_messages(start_index, move(const_cast<Vector<ConsoleOutput>&>(console_output)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WebContentClient::did_request_alert(u64 page_id, String const& message)
|
void WebContentClient::did_request_alert(u64 page_id, String const& message)
|
||||||
{
|
{
|
||||||
if (auto view = view_for_page_id(page_id); view.has_value()) {
|
if (auto view = view_for_page_id(page_id); view.has_value()) {
|
||||||
|
|
|
@ -82,6 +82,7 @@ private:
|
||||||
virtual void did_execute_js_console_input(u64 page_id, JsonValue const&) override;
|
virtual void did_execute_js_console_input(u64 page_id, JsonValue const&) override;
|
||||||
virtual void did_output_js_console_message(u64 page_id, i32 message_index) override;
|
virtual void did_output_js_console_message(u64 page_id, i32 message_index) override;
|
||||||
virtual void did_get_styled_js_console_messages(u64 page_id, i32 start_index, Vector<String> const& message_types, Vector<String> const& messages) override;
|
virtual void did_get_styled_js_console_messages(u64 page_id, i32 start_index, Vector<String> const& message_types, Vector<String> const& messages) override;
|
||||||
|
virtual void did_get_unstyled_js_console_messages(u64 page_id, i32 start_index, Vector<ConsoleOutput> const&) override;
|
||||||
virtual void did_change_favicon(u64 page_id, Gfx::ShareableBitmap const&) override;
|
virtual void did_change_favicon(u64 page_id, Gfx::ShareableBitmap const&) override;
|
||||||
virtual void did_request_alert(u64 page_id, String const&) override;
|
virtual void did_request_alert(u64 page_id, String const&) override;
|
||||||
virtual void did_request_confirm(u64 page_id, String const&) override;
|
virtual void did_request_confirm(u64 page_id, String const&) override;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <AK/GenericShorthands.h>
|
||||||
#include <AK/JsonObject.h>
|
#include <AK/JsonObject.h>
|
||||||
#include <AK/JsonValue.h>
|
#include <AK/JsonValue.h>
|
||||||
#include <AK/MemoryStream.h>
|
#include <AK/MemoryStream.h>
|
||||||
|
@ -106,14 +107,39 @@ void DevToolsConsoleClient::report_exception(JS::Error const& exception, bool in
|
||||||
|
|
||||||
void DevToolsConsoleClient::send_messages(i32 start_index)
|
void DevToolsConsoleClient::send_messages(i32 start_index)
|
||||||
{
|
{
|
||||||
(void)start_index;
|
if (m_console_output.size() - start_index < 1) {
|
||||||
|
// When the console is first created, it requests any messages that happened before then, by requesting with
|
||||||
|
// start_index=0. If we don't have any messages at all, that is still a valid request, and we can just ignore it.
|
||||||
|
if (start_index != 0)
|
||||||
|
m_client->console_peer_did_misbehave("Requested non-existent console message index");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<WebView::ConsoleOutput> messages { m_console_output.span().slice(start_index) };
|
||||||
|
m_client->did_get_unstyled_js_console_messages(start_index, move(messages));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2.3. Printer(logLevel, args[, options]), https://console.spec.whatwg.org/#printer
|
// 2.3. Printer(logLevel, args[, options]), https://console.spec.whatwg.org/#printer
|
||||||
JS::ThrowCompletionOr<JS::Value> DevToolsConsoleClient::printer(JS::Console::LogLevel log_level, PrinterArguments arguments)
|
JS::ThrowCompletionOr<JS::Value> DevToolsConsoleClient::printer(JS::Console::LogLevel log_level, PrinterArguments arguments)
|
||||||
{
|
{
|
||||||
(void)log_level;
|
// FIXME: Implement these.
|
||||||
(void)arguments;
|
if (first_is_one_of(log_level, JS::Console::LogLevel::Table, JS::Console::LogLevel::Trace, JS::Console::LogLevel::Group, JS::Console::LogLevel::GroupCollapsed))
|
||||||
|
return JS::js_undefined();
|
||||||
|
|
||||||
|
auto const& argument_values = arguments.get<GC::RootVector<JS::Value>>();
|
||||||
|
|
||||||
|
auto output = TRY(generically_format_values(argument_values));
|
||||||
|
m_console->output_debug_message(log_level, output);
|
||||||
|
|
||||||
|
Vector<JsonValue> serialized_arguments;
|
||||||
|
serialized_arguments.ensure_capacity(argument_values.size());
|
||||||
|
|
||||||
|
for (auto value : argument_values)
|
||||||
|
serialized_arguments.unchecked_append(serialize_js_value(m_console->realm(), value));
|
||||||
|
|
||||||
|
m_console_output.empend(log_level, UnixDateTime::now(), move(serialized_arguments));
|
||||||
|
m_client->did_output_js_console_message(m_console_output.size() - 1);
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,12 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Time.h>
|
||||||
|
#include <LibIPC/Forward.h>
|
||||||
#include <LibJS/Console.h>
|
#include <LibJS/Console.h>
|
||||||
#include <LibJS/Forward.h>
|
#include <LibJS/Forward.h>
|
||||||
#include <LibWeb/Forward.h>
|
#include <LibWeb/Forward.h>
|
||||||
|
#include <LibWebView/ConsoleOutput.h>
|
||||||
#include <WebContent/Forward.h>
|
#include <WebContent/Forward.h>
|
||||||
#include <WebContent/WebContentConsoleClient.h>
|
#include <WebContent/WebContentConsoleClient.h>
|
||||||
|
|
||||||
|
@ -32,6 +35,8 @@ private:
|
||||||
|
|
||||||
virtual void send_messages(i32 start_index) override;
|
virtual void send_messages(i32 start_index) override;
|
||||||
virtual JS::ThrowCompletionOr<JS::Value> printer(JS::Console::LogLevel, PrinterArguments) override;
|
virtual JS::ThrowCompletionOr<JS::Value> printer(JS::Console::LogLevel, PrinterArguments) override;
|
||||||
|
|
||||||
|
Vector<WebView::ConsoleOutput> m_console_output;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -810,6 +810,11 @@ void PageClient::did_get_styled_js_console_messages(i32 start_index, Vector<Stri
|
||||||
client().async_did_get_styled_js_console_messages(m_id, start_index, move(message_types), move(messages));
|
client().async_did_get_styled_js_console_messages(m_id, start_index, move(message_types), move(messages));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PageClient::did_get_unstyled_js_console_messages(i32 start_index, Vector<WebView::ConsoleOutput> console_output)
|
||||||
|
{
|
||||||
|
client().async_did_get_unstyled_js_console_messages(m_id, start_index, move(console_output));
|
||||||
|
}
|
||||||
|
|
||||||
static void gather_style_sheets(Vector<Web::CSS::StyleSheetIdentifier>& results, Web::CSS::CSSStyleSheet& sheet)
|
static void gather_style_sheets(Vector<Web::CSS::StyleSheetIdentifier>& results, Web::CSS::CSSStyleSheet& sheet)
|
||||||
{
|
{
|
||||||
Web::CSS::StyleSheetIdentifier identifier {};
|
Web::CSS::StyleSheetIdentifier identifier {};
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <LibWeb/HTML/FileFilter.h>
|
#include <LibWeb/HTML/FileFilter.h>
|
||||||
#include <LibWeb/Page/Page.h>
|
#include <LibWeb/Page/Page.h>
|
||||||
#include <LibWeb/PixelUnits.h>
|
#include <LibWeb/PixelUnits.h>
|
||||||
|
#include <LibWebView/Forward.h>
|
||||||
#include <WebContent/BackingStoreManager.h>
|
#include <WebContent/BackingStoreManager.h>
|
||||||
#include <WebContent/Forward.h>
|
#include <WebContent/Forward.h>
|
||||||
|
|
||||||
|
@ -91,6 +92,7 @@ public:
|
||||||
void did_output_js_console_message(i32 message_index);
|
void did_output_js_console_message(i32 message_index);
|
||||||
void console_peer_did_misbehave(char const* reason);
|
void console_peer_did_misbehave(char const* reason);
|
||||||
void did_get_styled_js_console_messages(i32 start_index, Vector<String> message_types, Vector<String> messages);
|
void did_get_styled_js_console_messages(i32 start_index, Vector<String> message_types, Vector<String> messages);
|
||||||
|
void did_get_unstyled_js_console_messages(i32 start_index, Vector<WebView::ConsoleOutput> console_output);
|
||||||
|
|
||||||
Vector<Web::CSS::StyleSheetIdentifier> list_style_sheets() const;
|
Vector<Web::CSS::StyleSheetIdentifier> list_style_sheets() const;
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,9 @@
|
||||||
#include <LibWeb/Page/EventResult.h>
|
#include <LibWeb/Page/EventResult.h>
|
||||||
#include <LibWeb/Page/Page.h>
|
#include <LibWeb/Page/Page.h>
|
||||||
#include <LibWebView/Attribute.h>
|
#include <LibWebView/Attribute.h>
|
||||||
#include <LibWebView/ProcessHandle.h>
|
#include <LibWebView/ConsoleOutput.h>
|
||||||
#include <LibWebView/PageInfo.h>
|
#include <LibWebView/PageInfo.h>
|
||||||
|
#include <LibWebView/ProcessHandle.h>
|
||||||
|
|
||||||
endpoint WebContentClient
|
endpoint WebContentClient
|
||||||
{
|
{
|
||||||
|
@ -95,6 +96,7 @@ endpoint WebContentClient
|
||||||
did_execute_js_console_input(u64 page_id, JsonValue result) =|
|
did_execute_js_console_input(u64 page_id, JsonValue result) =|
|
||||||
did_output_js_console_message(u64 page_id, i32 message_index) =|
|
did_output_js_console_message(u64 page_id, i32 message_index) =|
|
||||||
did_get_styled_js_console_messages(u64 page_id, i32 start_index, Vector<String> message_types, Vector<String> messages) =|
|
did_get_styled_js_console_messages(u64 page_id, i32 start_index, Vector<String> message_types, Vector<String> messages) =|
|
||||||
|
did_get_unstyled_js_console_messages(u64 page_id, i32 start_index, Vector<WebView::ConsoleOutput> console_output) =|
|
||||||
|
|
||||||
did_finish_text_test(u64 page_id, String text) =|
|
did_finish_text_test(u64 page_id, String text) =|
|
||||||
did_set_test_timeout(u64 page_id, double milliseconds) =|
|
did_set_test_timeout(u64 page_id, double milliseconds) =|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue