diff options
author | Andreas Kling <kling@serenityos.org> | 2021-08-24 16:57:57 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-24 16:59:11 +0200 |
commit | fe09f854142aaabf51371efb3e2e046ae98181ff (patch) | |
tree | 63a123b26b9b6ba551b0ed26c47f3fa5ec47f4fc /Userland/Applications | |
parent | fd922cf92fc68624fda5de037274e112decb2640 (diff) | |
download | serenity-fe09f854142aaabf51371efb3e2e046ae98181ff.zip |
Browser: Use OutOfProcessWebView for the Browser JavaScript console
Instead of building the web DOM by hand, we now load an empty document
into an OutOfProcessWebView, and then append things to it by sending
little snippets of JavaScript to the host process. :^)
Diffstat (limited to 'Userland/Applications')
-rw-r--r-- | Userland/Applications/Browser/ConsoleWidget.cpp | 90 | ||||
-rw-r--r-- | Userland/Applications/Browser/ConsoleWidget.h | 11 |
2 files changed, 19 insertions, 82 deletions
diff --git a/Userland/Applications/Browser/ConsoleWidget.cpp b/Userland/Applications/Browser/ConsoleWidget.cpp index c5e7d61ba6..500d1dabdb 100644 --- a/Userland/Applications/Browser/ConsoleWidget.cpp +++ b/Userland/Applications/Browser/ConsoleWidget.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, Hunter Salyer <thefalsehonesty@gmail.com> + * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -10,15 +11,8 @@ #include <LibGUI/Button.h> #include <LibGUI/TextBox.h> #include <LibGfx/FontDatabase.h> -#include <LibJS/Interpreter.h> #include <LibJS/MarkupGenerator.h> -#include <LibJS/Parser.h> -#include <LibJS/Runtime/Error.h> #include <LibJS/SyntaxHighlighter.h> -#include <LibWeb/Bindings/DOMExceptionWrapper.h> -#include <LibWeb/DOM/DocumentType.h> -#include <LibWeb/DOM/Text.h> -#include <LibWeb/DOMTreeModel.h> namespace Browser { @@ -27,18 +21,8 @@ ConsoleWidget::ConsoleWidget() set_layout<GUI::VerticalBoxLayout>(); set_fill_with_background_color(true); - auto base_document = Web::DOM::Document::create(); - base_document->append_child(adopt_ref(*new Web::DOM::DocumentType(base_document))); - auto html_element = base_document->create_element("html"); - base_document->append_child(html_element); - auto head_element = base_document->create_element("head"); - html_element->append_child(head_element); - auto body_element = base_document->create_element("body"); - html_element->append_child(body_element); - m_output_container = body_element; - - m_output_view = add<Web::InProcessWebView>(); - m_output_view->set_document(base_document); + m_output_view = add<Web::OutOfProcessWebView>(); + m_output_view->load("data:text/html,<html></html>"); auto& bottom_container = add<GUI::Widget>(); bottom_container.set_layout<GUI::HorizontalBoxLayout>(); @@ -64,39 +48,6 @@ ConsoleWidget::ConsoleWidget() 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(); - - StringBuilder output_html; - if (parser.has_errors()) { - auto error = parser.errors()[0]; - auto hint = error.source_location_hint(js_source); - if (!hint.is_empty()) - output_html.append(String::formatted("<pre>{}</pre>", escape_html_entities(hint))); - m_interpreter->vm().throw_exception<JS::SyntaxError>(m_interpreter->global_object(), error.to_string()); - } else { - m_interpreter->run(m_interpreter->global_object(), *program); - } - - if (m_interpreter->exception()) { - auto* exception = m_interpreter->exception(); - m_interpreter->vm().clear_exception(); - output_html.append("Uncaught exception: "); - auto error = exception->value(); - if (error.is_object()) - output_html.append(JS::MarkupGenerator::html_from_error(error.as_object())); - else - output_html.append(JS::MarkupGenerator::html_from_value(error)); - print_html(output_html.string_view()); - return; - } - - print_html(JS::MarkupGenerator::html_from_value(m_interpreter->vm().last_value())); }; set_focus_proxy(m_input); @@ -123,18 +74,6 @@ void ConsoleWidget::handle_js_console_output(const String& method, const String& } } -void ConsoleWidget::set_interpreter(WeakPtr<JS::Interpreter> interpreter) -{ - if (m_interpreter.ptr() == interpreter.ptr()) - return; - - m_interpreter = interpreter; - m_console_client = make<BrowserConsoleClient>(interpreter->global_object().console(), *this); - interpreter->global_object().console().set_client(*m_console_client.ptr()); - - clear_output(); -} - void ConsoleWidget::print_source_line(const StringView& source) { StringBuilder html; @@ -147,22 +86,25 @@ void ConsoleWidget::print_source_line(const StringView& source) print_html(html.string_view()); } -void ConsoleWidget::print_html(const StringView& line) +void ConsoleWidget::print_html(StringView const& line) { - auto paragraph = m_output_container->document().create_element("p"); - paragraph->set_inner_html(line); - - m_output_container->append_child(paragraph); - m_output_container->document().invalidate_layout(); - m_output_container->document().update_layout(); - + StringBuilder builder; + builder.append(R"~~~( + var p = document.createElement("p"); + p.innerHTML = ")~~~"); + builder.append_escaped_for_json(line); + builder.append(R"~~~(" + document.body.appendChild(p); +)~~~"); + m_output_view->run_javascript(builder.string_view()); m_output_view->scroll_to_bottom(); } void ConsoleWidget::clear_output() { - m_output_container->remove_all_children(); - m_output_view->update(); + m_output_view->run_javascript(R"~~~( + document.body.innerHTML = ""; + )~~~"); } } diff --git a/Userland/Applications/Browser/ConsoleWidget.h b/Userland/Applications/Browser/ConsoleWidget.h index d357b39bd5..0610865aa7 100644 --- a/Userland/Applications/Browser/ConsoleWidget.h +++ b/Userland/Applications/Browser/ConsoleWidget.h @@ -1,16 +1,15 @@ /* * Copyright (c) 2020, Hunter Salyer <thefalsehonesty@gmail.com> + * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once -#include "BrowserConsoleClient.h" #include "History.h" #include <LibGUI/Widget.h> -#include <LibJS/Forward.h> -#include <LibWeb/InProcessWebView.h> +#include <LibWeb/OutOfProcessWebView.h> namespace Browser { @@ -19,7 +18,6 @@ class ConsoleWidget final : public GUI::Widget { public: virtual ~ConsoleWidget(); - void set_interpreter(WeakPtr<JS::Interpreter>); void handle_js_console_output(const String& method, const String& line); void print_source_line(const StringView&); void print_html(const StringView&); @@ -31,10 +29,7 @@ private: ConsoleWidget(); RefPtr<GUI::TextBox> m_input; - RefPtr<Web::InProcessWebView> m_output_view; - RefPtr<Web::DOM::Element> m_output_container; - WeakPtr<JS::Interpreter> m_interpreter; - OwnPtr<BrowserConsoleClient> m_console_client; + RefPtr<Web::OutOfProcessWebView> m_output_view; }; } |