Kaynağa Gözat

LibWeb: Make window.performance replaceable and configurable

Required by Discord, which polyfills it by taking the existing native
object, polyfilling missing functions and setting window.performance to
it.

This is a hard requirement as this is done in strict mode with no
try/catch and thus causes their JavaScript to stop progressing.
Luke Wilde 2 yıl önce
ebeveyn
işleme
5ebf444199

+ 19 - 1
Userland/Libraries/LibWeb/Bindings/WindowObject.cpp

@@ -72,7 +72,7 @@ void WindowObject::initialize_global_object()
     define_native_accessor("document", document_getter, {}, JS::Attribute::Enumerable);
     define_native_accessor("name", name_getter, name_setter, JS::Attribute::Enumerable);
     define_native_accessor("history", history_getter, {}, JS::Attribute::Enumerable);
-    define_native_accessor("performance", performance_getter, {}, JS::Attribute::Enumerable);
+    define_native_accessor("performance", performance_getter, performance_setter, JS::Attribute::Enumerable | JS::Attribute::Configurable);
     define_native_accessor("crypto", crypto_getter, {}, JS::Attribute::Enumerable);
     define_native_accessor("screen", screen_getter, {}, JS::Attribute::Enumerable);
     define_native_accessor("innerWidth", inner_width_getter, {}, JS::Attribute::Enumerable);
@@ -434,6 +434,24 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::performance_getter)
     return wrap(global_object, impl->performance());
 }
 
+JS_DEFINE_NATIVE_FUNCTION(WindowObject::performance_setter)
+{
+    // https://webidl.spec.whatwg.org/#dfn-attribute-setter
+    // 4.1. If no arguments were passed, then throw a TypeError.
+    if (vm.argument_count() == 0)
+        return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::BadArgCountOne, "set performance");
+
+    auto* impl = TRY(impl_from(vm, global_object));
+
+    // 5. If attribute is declared with the [Replaceable] extended attribute, then:
+    // 1. Perform ? CreateDataProperty(esValue, id, V).
+    VERIFY(impl->wrapper());
+    TRY(impl->wrapper()->create_data_property("performance", vm.argument(0)));
+
+    // 2. Return undefined.
+    return JS::js_undefined();
+}
+
 JS_DEFINE_NATIVE_FUNCTION(WindowObject::screen_getter)
 {
     auto* impl = TRY(impl_from(vm, global_object));

+ 2 - 0
Userland/Libraries/LibWeb/Bindings/WindowObject.h

@@ -89,6 +89,8 @@ private:
     JS_DECLARE_NATIVE_FUNCTION(name_setter);
 
     JS_DECLARE_NATIVE_FUNCTION(performance_getter);
+    JS_DECLARE_NATIVE_FUNCTION(performance_setter);
+
     JS_DECLARE_NATIVE_FUNCTION(history_getter);
     JS_DECLARE_NATIVE_FUNCTION(screen_getter);