summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Applications/Browser/ConsoleWidget.cpp71
-rw-r--r--Userland/Applications/Browser/ConsoleWidget.h14
-rw-r--r--Userland/Applications/Browser/Tab.cpp14
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();
}