Przeglądaj źródła

LibWeb: Support assigning to window.location

Assignments actually forward to window.location.href, as the spec
requires. Since the window object is implemented by hand, this looks a
little janky. Eventually we should move all this stuff to IDL.
Andreas Kling 3 lat temu
rodzic
commit
95e011e2a0

+ 17 - 2
Userland/Libraries/LibWeb/Bindings/WindowObject.cpp

@@ -133,7 +133,7 @@ void WindowObject::initialize_global_object()
     define_direct_property("clientInformation", m_navigator_object, JS::Attribute::Enumerable | JS::Attribute::Configurable);
 
     // NOTE: location is marked as [LegacyUnforgeable], meaning it isn't configurable.
-    define_direct_property("location", m_location_object, JS::Attribute::Enumerable);
+    define_native_accessor("location", location_getter, location_setter, JS::Attribute::Enumerable);
 
     // WebAssembly "namespace"
     define_direct_property("WebAssembly", heap().allocate<WebAssemblyObject>(*this, *this), JS::Attribute::Enumerable | JS::Attribute::Configurable);
@@ -184,7 +184,7 @@ static JS::ThrowCompletionOr<HTML::Window*> impl_from(JS::VM& vm, JS::GlobalObje
 
     auto* this_object = MUST(this_value.to_object(global_object));
 
-    if ("WindowObject"sv != this_object->class_name())
+    if (!is<WindowObject>(*this_object))
         return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WindowObject");
     return &static_cast<WindowObject*>(this_object)->impl();
 }
@@ -453,6 +453,21 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::event_setter)
     REPLACEABLE_PROPERTY_SETTER(WindowObject, event);
 }
 
+JS_DEFINE_NATIVE_FUNCTION(WindowObject::location_getter)
+{
+    auto* impl = TRY(impl_from(vm, global_object));
+    VERIFY(impl->wrapper());
+    return impl->wrapper()->m_location_object;
+}
+
+JS_DEFINE_NATIVE_FUNCTION(WindowObject::location_setter)
+{
+    auto* impl = TRY(impl_from(vm, global_object));
+    VERIFY(impl->wrapper());
+    TRY(impl->wrapper()->m_location_object->set(JS::PropertyKey("href"), vm.argument(0), JS::Object::ShouldThrowExceptions::Yes));
+    return JS::js_undefined();
+}
+
 JS_DEFINE_NATIVE_FUNCTION(WindowObject::crypto_getter)
 {
     auto* impl = TRY(impl_from(vm, global_object));

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

@@ -82,6 +82,9 @@ private:
 
     JS_DECLARE_NATIVE_FUNCTION(document_getter);
 
+    JS_DECLARE_NATIVE_FUNCTION(location_getter);
+    JS_DECLARE_NATIVE_FUNCTION(location_setter);
+
     JS_DECLARE_NATIVE_FUNCTION(name_getter);
     JS_DECLARE_NATIVE_FUNCTION(name_setter);