diff options
author | FalseHonesty <thefalsehonesty@gmail.com> | 2020-05-25 15:24:46 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-26 10:17:50 +0200 |
commit | 941b028ca3287574aeaec470d66ce085a9ccb100 (patch) | |
tree | 76fb44e9e4631fc3a380a40a6ef4814082f67340 /Applications/Browser | |
parent | b352a6b59d5deb10fb1a29b0b521439b3823e7e3 (diff) | |
download | serenity-941b028ca3287574aeaec470d66ce085a9ccb100.zip |
LibJS: Create JS to HTML markup generator
The new JS::MarkupGenerator class can convert both a JS source string
and a JS Runtime Value into properly formatted HTML using the new
LibWeb System Palette css color values.
It makes more sense for this JS -> HTML process to occur in LibJS
so that it can be used elsewhere, namely Markdown code block syntax
highlighting. It also means the Browser can worry less about LibJS
implementation details.
Diffstat (limited to 'Applications/Browser')
-rw-r--r-- | Applications/Browser/ConsoleWidget.cpp | 156 | ||||
-rw-r--r-- | Applications/Browser/ConsoleWidget.h | 7 |
2 files changed, 3 insertions, 160 deletions
diff --git a/Applications/Browser/ConsoleWidget.cpp b/Applications/Browser/ConsoleWidget.cpp index 9743e87bc9..a5ae9e61aa 100644 --- a/Applications/Browser/ConsoleWidget.cpp +++ b/Applications/Browser/ConsoleWidget.cpp @@ -30,6 +30,7 @@ #include <LibGUI/JSSyntaxHighlighter.h> #include <LibGUI/TextBox.h> #include <LibJS/Interpreter.h> +#include <LibJS/MarkupGenerator.h> #include <LibJS/Parser.h> #include <LibJS/Runtime/Array.h> #include <LibJS/Runtime/Date.h> @@ -93,16 +94,14 @@ ConsoleWidget::ConsoleWidget() if (m_interpreter->exception()) { StringBuilder output_html; output_html.append("Uncaught exception: "); - print_value(m_interpreter->exception()->value(), output_html); + output_html.append(JS::MarkupGenerator::html_from_value(m_interpreter->exception()->value())); print_html(output_html.string_view()); m_interpreter->clear_exception(); return; } - StringBuilder output_html; - print_value(m_interpreter->last_value(), output_html); - print_html(output_html.string_view()); + print_html(JS::MarkupGenerator::html_from_value(m_interpreter->last_value())); }; } @@ -174,155 +173,6 @@ void ConsoleWidget::print_source_line(const StringView& source) print_html(html.string_view()); } -void ConsoleWidget::print_value(JS::Value value, StringBuilder& output_html, HashTable<JS::Object*> seen_objects) -{ - // FIXME: Support output highlighting - - if (value.is_empty()) { - output_html.append("<span class=\"empty-object\">"); - output_html.append("<empty>"); - output_html.append("</span>"); - return; - } - - if (value.is_object()) { - if (seen_objects.contains(&value.as_object())) { - // FIXME: Maybe we should only do this for circular references, - // not for all reoccurring objects. - output_html.append("<span class=\"already-printed\">"); - output_html.appendf("<already printed Object %p>", &value.as_object()); - output_html.append("</span>"); - return; - } - seen_objects.set(&value.as_object()); - } - - if (value.is_array()) - return print_array(static_cast<const JS::Array&>(value.as_object()), output_html, seen_objects); - - if (value.is_object()) { - auto& object = value.as_object(); - if (object.is_function()) - return print_function(object, output_html, seen_objects); - if (object.is_date()) - return print_date(object, output_html, seen_objects); - if (object.is_error()) - return print_error(object, output_html, seen_objects); - return print_object(object, output_html, seen_objects); - } - - if (value.is_string()) - output_html.append("<span class=\"js-string\">"); - else if (value.is_number()) - output_html.append("<span class=\"js-number\">"); - else if (value.is_boolean()) - output_html.append("<span class=\"js-boolean\">"); - else if (value.is_null()) - output_html.append("<span class=\"js-null\">"); - else if (value.is_undefined()) - output_html.append("<span class=\"js-undefined\">"); - - if (value.is_string()) - output_html.append('"'); - output_html.append(value.to_string_without_side_effects()); - if (value.is_string()) - output_html.append('"'); - - output_html.append("</span>"); -} - -void ConsoleWidget::print_array(const JS::Array& array, StringBuilder& html_output, HashTable<JS::Object*>& seen_objects) -{ - html_output.append("<span class=\"js-array-open\">"); - html_output.append("[ "); - html_output.append("</span>"); - for (size_t i = 0; i < array.elements().size(); ++i) { - print_value(array.elements()[i], html_output, seen_objects); - if (i != array.elements().size() - 1) { - html_output.append("<span class=\"js-array-element-separator\">"); - html_output.append(", "); - html_output.append("</span>"); - } - } - html_output.append("<span class=\"js-array-close\">"); - html_output.append(" ]"); - html_output.append("</span>"); -} - -void ConsoleWidget::print_object(const JS::Object& object, StringBuilder& html_output, HashTable<JS::Object*>& seen_objects) -{ - html_output.append("<span class=\"js-object-open\">"); - html_output.append("{ "); - html_output.append("</span>"); - - for (size_t i = 0; i < object.elements().size(); ++i) { - if (object.elements()[i].is_empty()) - continue; - html_output.append("<span class=\"js-object-element-index\">"); - html_output.appendf("%zu", i); - html_output.append("</span>"); - html_output.append(": "); - print_value(object.elements()[i], html_output, seen_objects); - if (i != object.elements().size() - 1) { - html_output.append("<span class=\"js-object-element-separator\">"); - html_output.append(", "); - html_output.append("</span>"); - } - } - - if (!object.elements().is_empty() && object.shape().property_count()) { - html_output.append("<span class=\"js-object-element-separator\">"); - html_output.append(", "); - html_output.append("</span>"); - } - - size_t index = 0; - for (auto& it : object.shape().property_table_ordered()) { - html_output.append("<span class=\"js-object-element-key\">"); - html_output.appendf("\"%s\"", it.key.characters()); - html_output.append("</span>"); - html_output.append(": "); - print_value(object.get_direct(it.value.offset), html_output, seen_objects); - if (index != object.shape().property_count() - 1) { - html_output.append("<span class=\"js-object-element-separator\">"); - html_output.append(", "); - html_output.append("</span>"); - } - ++index; - } - - html_output.append("<span class=\"js-object-close\">"); - html_output.append(" }"); - html_output.append("</span>"); -} - -void ConsoleWidget::print_function(const JS::Object& function, StringBuilder& html_output, HashTable<JS::Object*>&) -{ - html_output.append("<span class=\"js-function\">"); - html_output.appendf("[%s]", function.class_name()); - html_output.append("</span>"); -} - -void ConsoleWidget::print_date(const JS::Object& date, StringBuilder& html_output, HashTable<JS::Object*>&) -{ - html_output.append("<span class=\"js-date\">"); - html_output.appendf("Date %s", static_cast<const JS::Date&>(date).string().characters()); - html_output.append("</span>"); -} - -void ConsoleWidget::print_error(const JS::Object& object, StringBuilder& html_output, HashTable<JS::Object*>&) -{ - auto& error = static_cast<const JS::Error&>(object); - html_output.append("<span class=\"js-error-name\">"); - html_output.appendf("[%s]", error.name().characters()); - html_output.append("</span>"); - if (!error.message().is_empty()) { - html_output.append("<span class=\"js-error-message\">"); - html_output.appendf(": %s", error.message().characters()); - html_output.append("</span>"); - } -} - void ConsoleWidget::print_html(const StringView& line) { auto paragraph = create_element(m_console_output_container->document(), "p"); diff --git a/Applications/Browser/ConsoleWidget.h b/Applications/Browser/ConsoleWidget.h index 5a0d0d7412..50516ed5e6 100644 --- a/Applications/Browser/ConsoleWidget.h +++ b/Applications/Browser/ConsoleWidget.h @@ -47,13 +47,6 @@ private: String create_document_style(); - void print_value(JS::Value, StringBuilder& output_html, HashTable<JS::Object*> seen_objects = {}); - void print_array(const JS::Array&, StringBuilder& output_html, HashTable<JS::Object*>&); - void print_object(const JS::Object&, StringBuilder& output_html, HashTable<JS::Object*>&); - void print_function(const JS::Object&, StringBuilder& output_html, HashTable<JS::Object*>&); - void print_date(const JS::Object&, StringBuilder& output_html, HashTable<JS::Object*>&); - void print_error(const JS::Object&, StringBuilder& output_html, HashTable<JS::Object*>&); - RefPtr<GUI::TextBox> m_console_input; RefPtr<Web::HtmlView> m_console_output_view; RefPtr<Web::Element> m_console_output_container; |