summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@serenityos.org>2022-09-20 18:23:04 +0100
committerSam Atkins <atkinssj@gmail.com>2022-09-21 20:03:49 +0100
commit7a2da4cabf5627941cf1fc6eb7c5fd068fcc75f9 (patch)
tree86a1edc37ed2f5fab1a7432d0f9b8ea3d93b2268
parenta875713f2e50994fb52ac9eb233f8d40440d6894 (diff)
downloadserenity-7a2da4cabf5627941cf1fc6eb7c5fd068fcc75f9.zip
Browser+WebContent+LibJS: Support `%c` specifiers in Console.log()
...and the other Console methods. This lets you apply styling to a log message or any other text that passes through the Console `Formatter` operation. We store the CSS on the ConsoleClient instead of passing it along with the rest of the message, since I couldn't figure out a nice way of doing that, as Formatter has to return JS::Values. This way isn't nice, and has a risk of forgetting to clear the style and having it apply to subsequent messages, but it works. This is only supported in the Browser for now. REPL support would require parsing the CSS and figuring out the relevant ANSI codes. We also don't filter this styling at all, so you can `position: absolute` and `transform: translate(...)` all you want, which is less than ideal.
-rw-r--r--Userland/Applications/Browser/ConsoleWidget.cpp2
-rw-r--r--Userland/Libraries/LibJS/Console.cpp3
-rw-r--r--Userland/Libraries/LibJS/Console.h2
-rw-r--r--Userland/Services/WebContent/WebContentConsoleClient.cpp19
-rw-r--r--Userland/Services/WebContent/WebContentConsoleClient.h8
5 files changed, 23 insertions, 11 deletions
diff --git a/Userland/Applications/Browser/ConsoleWidget.cpp b/Userland/Applications/Browser/ConsoleWidget.cpp
index 6a08ae5b66..7e02db847e 100644
--- a/Userland/Applications/Browser/ConsoleWidget.cpp
+++ b/Userland/Applications/Browser/ConsoleWidget.cpp
@@ -199,7 +199,7 @@ void ConsoleWidget::begin_group(StringView label, bool start_expanded)
var group = document.createElement("details");
group.id = "group_{}";
var label = document.createElement("summary");
- label.innerText = ")~~~",
+ label.innerHTML = ")~~~",
group.id);
builder.append_escaped_for_json(label);
builder.append(R"~~~(";
diff --git a/Userland/Libraries/LibJS/Console.cpp b/Userland/Libraries/LibJS/Console.cpp
index 8eab7ceddb..e7270d5681 100644
--- a/Userland/Libraries/LibJS/Console.cpp
+++ b/Userland/Libraries/LibJS/Console.cpp
@@ -615,8 +615,7 @@ ThrowCompletionOr<MarkedVector<Value>> ConsoleClient::formatter(MarkedVector<Val
// 6. TODO: process %c
else if (specifier == "%c"sv) {
// NOTE: This has no spec yet. `%c` specifiers treat the argument as CSS styling for the log message.
- // For now, we'll just consume the specifier and the argument.
- // FIXME: Actually style the message somehow.
+ add_css_style_to_current_message(TRY(current.to_string(vm)));
converted = js_string(vm, "");
}
diff --git a/Userland/Libraries/LibJS/Console.h b/Userland/Libraries/LibJS/Console.h
index e7165ace12..fcb20f043b 100644
--- a/Userland/Libraries/LibJS/Console.h
+++ b/Userland/Libraries/LibJS/Console.h
@@ -108,6 +108,8 @@ public:
ThrowCompletionOr<MarkedVector<Value>> formatter(MarkedVector<Value> const& args);
virtual ThrowCompletionOr<Value> printer(Console::LogLevel log_level, PrinterArguments) = 0;
+ virtual void add_css_style_to_current_message(StringView) {};
+
virtual void clear() = 0;
virtual void end_group() = 0;
diff --git a/Userland/Services/WebContent/WebContentConsoleClient.cpp b/Userland/Services/WebContent/WebContentConsoleClient.cpp
index 2724b38f2e..6b2d96a0fa 100644
--- a/Userland/Services/WebContent/WebContentConsoleClient.cpp
+++ b/Userland/Services/WebContent/WebContentConsoleClient.cpp
@@ -143,11 +143,14 @@ void WebContentConsoleClient::clear()
// 2.3. Printer(logLevel, args[, options]), https://console.spec.whatwg.org/#printer
JS::ThrowCompletionOr<JS::Value> WebContentConsoleClient::printer(JS::Console::LogLevel log_level, PrinterArguments arguments)
{
+ auto styling = escape_html_entities(m_current_message_style.string_view());
+ m_current_message_style.clear();
+
if (log_level == JS::Console::LogLevel::Trace) {
auto trace = arguments.get<JS::Console::Trace>();
StringBuilder html;
if (!trace.label.is_empty())
- html.appendff("<span class='title'>{}</span><br>", escape_html_entities(trace.label));
+ html.appendff("<span class='title' style='{}'>{}</span><br>", styling, escape_html_entities(trace.label));
html.append("<span class='trace'>"sv);
for (auto& function_name : trace.stack)
@@ -160,7 +163,7 @@ JS::ThrowCompletionOr<JS::Value> WebContentConsoleClient::printer(JS::Console::L
if (log_level == JS::Console::LogLevel::Group || log_level == JS::Console::LogLevel::GroupCollapsed) {
auto group = arguments.get<JS::Console::Group>();
- begin_group(group.label, log_level == JS::Console::LogLevel::Group);
+ begin_group(String::formatted("<span style='{}'>{}</span>", styling, escape_html_entities(group.label)), log_level == JS::Console::LogLevel::Group);
return JS::js_undefined();
}
@@ -170,23 +173,23 @@ JS::ThrowCompletionOr<JS::Value> WebContentConsoleClient::printer(JS::Console::L
StringBuilder html;
switch (log_level) {
case JS::Console::LogLevel::Debug:
- html.append("<span class=\"debug\">(d) "sv);
+ html.appendff("<span class=\"debug\" style=\"{}\">(d) "sv, styling);
break;
case JS::Console::LogLevel::Error:
- html.append("<span class=\"error\">(e) "sv);
+ html.appendff("<span class=\"error\" style=\"{}\">(e) "sv, styling);
break;
case JS::Console::LogLevel::Info:
- html.append("<span class=\"info\">(i) "sv);
+ html.appendff("<span class=\"info\" style=\"{}\">(i) "sv, styling);
break;
case JS::Console::LogLevel::Log:
- html.append("<span class=\"log\"> "sv);
+ html.appendff("<span class=\"log\" style=\"{}\"> "sv, styling);
break;
case JS::Console::LogLevel::Warn:
case JS::Console::LogLevel::CountReset:
- html.append("<span class=\"warn\">(w) "sv);
+ html.appendff("<span class=\"warn\" style=\"{}\">(w) "sv, styling);
break;
default:
- html.append("<span>"sv);
+ html.appendff("<span style=\"{}\">"sv, styling);
break;
}
diff --git a/Userland/Services/WebContent/WebContentConsoleClient.h b/Userland/Services/WebContent/WebContentConsoleClient.h
index a8dfc28a16..c234bb779d 100644
--- a/Userland/Services/WebContent/WebContentConsoleClient.h
+++ b/Userland/Services/WebContent/WebContentConsoleClient.h
@@ -27,6 +27,12 @@ private:
virtual void clear() override;
virtual JS::ThrowCompletionOr<JS::Value> printer(JS::Console::LogLevel log_level, PrinterArguments) override;
+ virtual void add_css_style_to_current_message(StringView style) override
+ {
+ m_current_message_style.append(style);
+ m_current_message_style.append(';');
+ }
+
ConnectionFromClient& m_client;
WeakPtr<JS::Realm> m_realm;
JS::Handle<ConsoleGlobalObject> m_console_global_object;
@@ -48,6 +54,8 @@ private:
String data;
};
Vector<ConsoleOutput> m_message_log;
+
+ StringBuilder m_current_message_style;
};
}