summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS/MarkupGenerator.cpp
diff options
context:
space:
mode:
authorLinus Groh <mail@linusgroh.de>2021-04-12 00:08:28 +0200
committerAndreas Kling <kling@serenityos.org>2021-04-12 09:38:57 +0200
commitda177c6517ab0ba77facfe4ff5a078562f887e96 (patch)
tree33123a6ad6e98f09b4390796dc20f26458c0800e /Userland/Libraries/LibJS/MarkupGenerator.cpp
parent6e9eb0a284661803d634ce0bd8c1656a156878bb (diff)
downloadserenity-da177c6517ab0ba77facfe4ff5a078562f887e96.zip
LibJS: Make Errors fully spec compliant
The previous handling of the name and message properties specifically was breaking websites that created their own error types and relied on the error prototype working correctly - not assuming an JS::Error this object, that is. The way it works now, and it is supposed to work, is: - Error.prototype.name and Error.prototype.message just have initial string values and are no longer getters/setters - When constructing an error with a message, we create a regular property on the newly created object, so a lookup of the message property will either get it from the object directly or go though the prototype chain - Internal m_name/m_message properties are no longer needed and removed This makes printing errors slightly more complicated, as we can no longer rely on the (safe) internal properties, and cannot trust a property lookup either - get_without_side_effects() is used to solve this, it's not perfect but something we can revisit later. I did some refactoring along the way, there was some really old stuff in there - accessing vm.call_frame().arguments[0] is not something we (have to) do anymore :^) Fixes #6245.
Diffstat (limited to 'Userland/Libraries/LibJS/MarkupGenerator.cpp')
-rw-r--r--Userland/Libraries/LibJS/MarkupGenerator.cpp22
1 files changed, 18 insertions, 4 deletions
diff --git a/Userland/Libraries/LibJS/MarkupGenerator.cpp b/Userland/Libraries/LibJS/MarkupGenerator.cpp
index 6766b1b858..fb8e8fb6e5 100644
--- a/Userland/Libraries/LibJS/MarkupGenerator.cpp
+++ b/Userland/Libraries/LibJS/MarkupGenerator.cpp
@@ -53,6 +53,14 @@ String MarkupGenerator::html_from_value(Value value)
return output_html.to_string();
}
+String MarkupGenerator::html_from_error(Object& object)
+{
+ StringBuilder output_html;
+ HashTable<Object*> seen_objects;
+ error_to_html(object, output_html, seen_objects);
+ return output_html.to_string();
+}
+
void MarkupGenerator::value_to_html(Value value, StringBuilder& output_html, HashTable<Object*> seen_objects)
{
if (value.is_empty()) {
@@ -156,10 +164,16 @@ void MarkupGenerator::date_to_html(const Object& date, StringBuilder& html_outpu
void MarkupGenerator::error_to_html(const Object& object, StringBuilder& html_output, HashTable<Object*>&)
{
- auto& error = static_cast<const Error&>(object);
- html_output.append(wrap_string_in_style(String::formatted("[{}]", error.name()), StyleType::Invalid));
- if (!error.message().is_empty()) {
- html_output.appendff(": {}", escape_html_entities(error.message()));
+ auto name = object.get_without_side_effects("name").value_or(JS::js_undefined());
+ auto message = object.get_without_side_effects("message").value_or(JS::js_undefined());
+ if (name.is_accessor() || name.is_native_property() || message.is_accessor() || message.is_native_property()) {
+ html_output.append(wrap_string_in_style(JS::Value(&object).to_string_without_side_effects(), StyleType::Invalid));
+ } else {
+ auto name_string = name.to_string_without_side_effects();
+ auto message_string = message.to_string_without_side_effects();
+ html_output.append(wrap_string_in_style(String::formatted("[{}]", name_string), StyleType::Invalid));
+ if (!message_string.is_empty())
+ html_output.appendff(": {}", escape_html_entities(message_string));
}
}