diff options
Diffstat (limited to 'Userland/Applications')
-rw-r--r-- | Userland/Applications/Browser/ConsoleWidget.cpp | 71 | ||||
-rw-r--r-- | Userland/Applications/Browser/ConsoleWidget.h | 14 | ||||
-rw-r--r-- | Userland/Applications/Browser/Tab.cpp | 14 |
3 files changed, 88 insertions, 11 deletions
diff --git a/Userland/Applications/Browser/ConsoleWidget.cpp b/Userland/Applications/Browser/ConsoleWidget.cpp index 500d1dabdb..5c0f961ef7 100644 --- a/Userland/Applications/Browser/ConsoleWidget.cpp +++ b/Userland/Applications/Browser/ConsoleWidget.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2020, Hunter Salyer <thefalsehonesty@gmail.com> * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -23,6 +24,11 @@ ConsoleWidget::ConsoleWidget() m_output_view = add<Web::OutOfProcessWebView>(); m_output_view->load("data:text/html,<html></html>"); + // Wait until our output WebView is loaded, and then request any messages that occurred before we existed + m_output_view->on_load_finish = [this](auto&) { + if (on_request_messages) + on_request_messages(0); + }; auto& bottom_container = add<GUI::Widget>(); bottom_container.set_layout<GUI::HorizontalBoxLayout>(); @@ -65,13 +71,56 @@ ConsoleWidget::~ConsoleWidget() { } -void ConsoleWidget::handle_js_console_output(const String& method, const String& line) +void ConsoleWidget::request_console_messages() { - if (method == "html") { - print_html(line); - } else if (method == "clear") { - clear_output(); + VERIFY(!m_waiting_for_messages); + VERIFY(on_request_messages); + on_request_messages(m_highest_received_message_index + 1); + m_waiting_for_messages = true; +} + +void ConsoleWidget::notify_about_new_console_message(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 ConsoleWidget::handle_console_messages(i32 start_index, const Vector<String>& message_types, const Vector<String>& messages) +{ + i32 end_index = start_index + message_types.size() - 1; + if (end_index <= m_highest_received_message_index) { + dbgln("Received old console messages"); + return; } + + for (size_t i = 0; i < message_types.size(); i++) { + auto& type = message_types[i]; + auto& message = messages[i]; + + if (type == "html") { + print_html(message); + } else if (type == "clear") { + clear_output(); + } else { + VERIFY_NOT_REACHED(); + } + } + + 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 ConsoleWidget::print_source_line(const StringView& source) @@ -97,7 +146,9 @@ void ConsoleWidget::print_html(StringView const& line) document.body.appendChild(p); )~~~"); m_output_view->run_javascript(builder.string_view()); - m_output_view->scroll_to_bottom(); + // FIXME: Make it scroll to the bottom, using `window.scrollTo()` in the JS above. + // We used to call `m_output_view->scroll_to_bottom();` here, but that does not work because + // it runs synchronously, meaning it happens before the HTML is output via IPC above. } void ConsoleWidget::clear_output() @@ -107,4 +158,12 @@ void ConsoleWidget::clear_output() )~~~"); } +void ConsoleWidget::reset() +{ + clear_output(); + m_highest_notified_message_index = -1; + m_highest_received_message_index = -1; + m_waiting_for_messages = false; +} + } diff --git a/Userland/Applications/Browser/ConsoleWidget.h b/Userland/Applications/Browser/ConsoleWidget.h index 0610865aa7..23276bea94 100644 --- a/Userland/Applications/Browser/ConsoleWidget.h +++ b/Userland/Applications/Browser/ConsoleWidget.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2020, Hunter Salyer <thefalsehonesty@gmail.com> * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -18,18 +19,27 @@ class ConsoleWidget final : public GUI::Widget { public: virtual ~ConsoleWidget(); - void handle_js_console_output(const String& method, const String& line); + void notify_about_new_console_message(i32 message_index); + void handle_console_messages(i32 start_index, Vector<String> const& message_types, Vector<String> const& messages); void print_source_line(const StringView&); void print_html(const StringView&); - void clear_output(); + void reset(); Function<void(const String&)> on_js_input; + Function<void(i32)> on_request_messages; private: ConsoleWidget(); + void request_console_messages(); + void clear_output(); + RefPtr<GUI::TextBox> m_input; RefPtr<Web::OutOfProcessWebView> m_output_view; + + i32 m_highest_notified_message_index { -1 }; + i32 m_highest_received_message_index { -1 }; + bool m_waiting_for_messages { false }; }; } diff --git a/Userland/Applications/Browser/Tab.cpp b/Userland/Applications/Browser/Tab.cpp index 13deed226b..4b997720e1 100644 --- a/Userland/Applications/Browser/Tab.cpp +++ b/Userland/Applications/Browser/Tab.cpp @@ -180,7 +180,7 @@ Tab::Tab(BrowserWindow& window) m_dom_inspector_widget->clear_dom_json(); if (m_console_widget) - m_console_widget->clear_output(); + m_console_widget->reset(); }; hooks().on_load_finish = [this](auto&) { @@ -301,9 +301,14 @@ Tab::Tab(BrowserWindow& window) m_dom_inspector_widget->set_dom_node_properties_json(node_id, specified, computed); }; - hooks().on_js_console_output = [this](auto& method, auto& line) { + hooks().on_js_console_new_message = [this](auto message_index) { if (m_console_widget) - m_console_widget->handle_js_console_output(method, line); + m_console_widget->notify_about_new_console_message(message_index); + }; + + hooks().on_get_js_console_messages = [this](auto start_index, auto& message_types, auto& messages) { + if (m_console_widget) + m_console_widget->handle_console_messages(start_index, message_types, messages); }; auto focus_location_box_action = GUI::Action::create( @@ -520,6 +525,9 @@ void Tab::show_console_window() m_console_widget->on_js_input = [this](String const& js_source) { m_web_content_view->js_console_input(js_source); }; + m_console_widget->on_request_messages = [this](i32 start_index) { + m_web_content_view->js_console_request_messages(start_index); + }; m_web_content_view->js_console_initialize(); } |