From 269ec8b1f979cd082b59860c1a76cbba20c2df7b Mon Sep 17 00:00:00 2001 From: Brandon Scott Date: Sat, 27 Feb 2021 21:53:20 -0600 Subject: [PATCH] Browser: Implemented out of process JS console Added input hook into console widget to allow input to be captured and sent to the external JS console via IPC. Output from the external JS console is fed into the console widget via handle_js_console_output(). --- .../Applications/Browser/ConsoleWidget.cpp | 16 +++++++++++++ Userland/Applications/Browser/ConsoleWidget.h | 3 +++ Userland/Applications/Browser/Tab.cpp | 23 ++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/Userland/Applications/Browser/ConsoleWidget.cpp b/Userland/Applications/Browser/ConsoleWidget.cpp index 7af99bff3e..1cba4760e6 100644 --- a/Userland/Applications/Browser/ConsoleWidget.cpp +++ b/Userland/Applications/Browser/ConsoleWidget.cpp @@ -84,6 +84,13 @@ ConsoleWidget::ConsoleWidget() print_source_line(js_source); + if (on_js_input) + on_js_input(js_source); + + // no interpreter being set means we are running in multi-process mode + if (!m_interpreter) + return; + auto parser = JS::Parser(JS::Lexer(js_source)); auto program = parser.parse_program(); @@ -130,6 +137,15 @@ ConsoleWidget::~ConsoleWidget() { } +void ConsoleWidget::handle_js_console_output(const String& method, const String& line) +{ + if (method == "html") { + print_html(line); + } else if (method == "clear") { + clear_output(); + } +} + void ConsoleWidget::set_interpreter(WeakPtr interpreter) { if (m_interpreter.ptr() == interpreter.ptr()) diff --git a/Userland/Applications/Browser/ConsoleWidget.h b/Userland/Applications/Browser/ConsoleWidget.h index 813ceed2ed..0f6b731062 100644 --- a/Userland/Applications/Browser/ConsoleWidget.h +++ b/Userland/Applications/Browser/ConsoleWidget.h @@ -40,10 +40,13 @@ public: virtual ~ConsoleWidget(); void set_interpreter(WeakPtr); + void handle_js_console_output(const String& method, const String& line); void print_source_line(const StringView&); void print_html(const StringView&); void clear_output(); + Function on_js_input; + private: ConsoleWidget(); diff --git a/Userland/Applications/Browser/Tab.cpp b/Userland/Applications/Browser/Tab.cpp index 0d9b0e66eb..aaf3bd7209 100644 --- a/Userland/Applications/Browser/Tab.cpp +++ b/Userland/Applications/Browser/Tab.cpp @@ -251,6 +251,13 @@ Tab::Tab(Type type) view_source(url.to_string(), source); }; + hooks().on_js_console_output = [this](auto& method, auto& line) { + if (m_console_window) { + auto* console_widget = static_cast(m_console_window->main_widget()); + console_widget->handle_js_console_output(method, line); + } + }; + // FIXME: Support JS console in multi-process mode. if (m_type == Type::InProcessWebView) { hooks().on_set_document = [this](auto* document) { @@ -376,7 +383,21 @@ Tab::Tab(Type type) m_console_window->show(); m_console_window->move_to_front(); } else { - TODO(); + if (!m_console_window) { + m_console_window = GUI::Window::construct(); + m_console_window->resize(500, 300); + m_console_window->set_title("JS Console"); + m_console_window->set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/filetype-javascript.png")); + m_console_window->set_main_widget(); + } + auto* console_widget = static_cast(m_console_window->main_widget()); + console_widget->on_js_input = [this](const String& js_source) { + m_web_content_view->js_console_input(js_source); + }; + console_widget->clear_output(); + m_web_content_view->js_console_initialize(); + m_console_window->show(); + m_console_window->move_to_front(); } }, this));