WebContentConsoleClient.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Copyright (c) 2021, Brandon Scott <xeon.productions@gmail.com>
  3. * Copyright (c) 2020, Hunter Salyer <thefalsehonesty@gmail.com>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include "WebContentConsoleClient.h"
  8. #include <LibJS/Interpreter.h>
  9. #include <LibJS/MarkupGenerator.h>
  10. #include <LibJS/Parser.h>
  11. #include <LibWeb/Bindings/DOMExceptionWrapper.h>
  12. namespace WebContent {
  13. void WebContentConsoleClient::handle_input(const String& js_source)
  14. {
  15. auto parser = JS::Parser(JS::Lexer(js_source));
  16. auto program = parser.parse_program();
  17. StringBuilder output_html;
  18. if (parser.has_errors()) {
  19. auto error = parser.errors()[0];
  20. auto hint = error.source_location_hint(js_source);
  21. if (!hint.is_empty())
  22. output_html.append(String::formatted("<pre>{}</pre>", escape_html_entities(hint)));
  23. m_interpreter->vm().throw_exception<JS::SyntaxError>(m_interpreter->global_object(), error.to_string());
  24. } else {
  25. m_interpreter->run(m_interpreter->global_object(), *program);
  26. }
  27. if (m_interpreter->exception()) {
  28. auto* exception = m_interpreter->exception();
  29. m_interpreter->vm().clear_exception();
  30. output_html.append("Uncaught exception: ");
  31. auto error = exception->value();
  32. if (error.is_object())
  33. output_html.append(JS::MarkupGenerator::html_from_error(error.as_object()));
  34. else
  35. output_html.append(JS::MarkupGenerator::html_from_value(error));
  36. print_html(output_html.string_view());
  37. return;
  38. }
  39. print_html(JS::MarkupGenerator::html_from_value(m_interpreter->vm().last_value()));
  40. }
  41. void WebContentConsoleClient::print_html(const String& line)
  42. {
  43. m_client.async_did_js_console_output("html", line);
  44. }
  45. void WebContentConsoleClient::clear_output()
  46. {
  47. m_client.async_did_js_console_output("clear_output", {});
  48. }
  49. JS::Value WebContentConsoleClient::log()
  50. {
  51. print_html(escape_html_entities(vm().join_arguments()));
  52. return JS::js_undefined();
  53. }
  54. JS::Value WebContentConsoleClient::info()
  55. {
  56. StringBuilder html;
  57. html.append("<span class=\"info\">");
  58. html.append("(i) ");
  59. html.append(escape_html_entities(vm().join_arguments()));
  60. html.append("</span>");
  61. print_html(html.string_view());
  62. return JS::js_undefined();
  63. }
  64. JS::Value WebContentConsoleClient::debug()
  65. {
  66. StringBuilder html;
  67. html.append("<span class=\"debug\">");
  68. html.append("(d) ");
  69. html.append(escape_html_entities(vm().join_arguments()));
  70. html.append("</span>");
  71. print_html(html.string_view());
  72. return JS::js_undefined();
  73. }
  74. JS::Value WebContentConsoleClient::warn()
  75. {
  76. StringBuilder html;
  77. html.append("<span class=\"warn\">");
  78. html.append("(w) ");
  79. html.append(escape_html_entities(vm().join_arguments()));
  80. html.append("</span>");
  81. print_html(html.string_view());
  82. return JS::js_undefined();
  83. }
  84. JS::Value WebContentConsoleClient::error()
  85. {
  86. StringBuilder html;
  87. html.append("<span class=\"error\">");
  88. html.append("(e) ");
  89. html.append(escape_html_entities(vm().join_arguments()));
  90. html.append("</span>");
  91. print_html(html.string_view());
  92. return JS::js_undefined();
  93. }
  94. JS::Value WebContentConsoleClient::clear()
  95. {
  96. clear_output();
  97. return JS::js_undefined();
  98. }
  99. JS::Value WebContentConsoleClient::trace()
  100. {
  101. StringBuilder html;
  102. html.append(escape_html_entities(vm().join_arguments()));
  103. auto trace = get_trace();
  104. for (auto& function_name : trace) {
  105. if (function_name.is_empty())
  106. function_name = "&lt;anonymous&gt;";
  107. html.appendff(" -> {}<br>", function_name);
  108. }
  109. print_html(html.string_view());
  110. return JS::js_undefined();
  111. }
  112. JS::Value WebContentConsoleClient::count()
  113. {
  114. auto label = vm().argument_count() ? vm().argument(0).to_string_without_side_effects() : "default";
  115. auto counter_value = m_console.counter_increment(label);
  116. print_html(String::formatted("{}: {}", label, counter_value));
  117. return JS::js_undefined();
  118. }
  119. JS::Value WebContentConsoleClient::count_reset()
  120. {
  121. auto label = vm().argument_count() ? vm().argument(0).to_string_without_side_effects() : "default";
  122. if (m_console.counter_reset(label)) {
  123. print_html(String::formatted("{}: 0", label));
  124. } else {
  125. print_html(String::formatted("\"{}\" doesn't have a count", label));
  126. }
  127. return JS::js_undefined();
  128. }
  129. JS::Value WebContentConsoleClient::assert_()
  130. {
  131. auto& vm = this->vm();
  132. if (!vm.argument(0).to_boolean()) {
  133. StringBuilder html;
  134. if (vm.argument_count() > 1) {
  135. html.append("<span class=\"error\">");
  136. html.append("Assertion failed:");
  137. html.append("</span>");
  138. html.append(" ");
  139. html.append(escape_html_entities(vm.join_arguments(1)));
  140. } else {
  141. html.append("<span class=\"error\">");
  142. html.append("Assertion failed");
  143. html.append("</span>");
  144. }
  145. print_html(html.string_view());
  146. }
  147. return JS::js_undefined();
  148. }
  149. }