diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index eefe3109af..decc4891d4 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -2178,7 +2178,7 @@ static void generate_prototype_or_global_mixin_declarations(IDL::Interface const JS_DECLARE_NATIVE_FUNCTION(@attribute.name:snakecase@_getter); )~~~"); - if (!attribute.readonly || attribute.extended_attributes.contains("Replaceable"sv)) { + if (!attribute.readonly || attribute.extended_attributes.contains("Replaceable"sv) || attribute.extended_attributes.contains("PutForwards"sv)) { attribute_generator.append(R"~~~( JS_DECLARE_NATIVE_FUNCTION(@attribute.name:snakecase@_setter); )~~~"); @@ -2300,7 +2300,7 @@ JS::ThrowCompletionOr @class_name@::initialize(JS::Realm& realm) attribute_generator.set("attribute.name", attribute.name); attribute_generator.set("attribute.getter_callback", attribute.getter_callback_name); - if (!attribute.readonly || attribute.extended_attributes.contains("Replaceable"sv)) + if (!attribute.readonly || attribute.extended_attributes.contains("Replaceable"sv) || attribute.extended_attributes.contains("PutForwards"sv)) attribute_generator.set("attribute.setter_callback", attribute.setter_callback_name); else attribute_generator.set("attribute.setter_callback", "nullptr"); @@ -2540,6 +2540,22 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@) TRY(this_value.as_object().internal_define_own_property("@attribute.name@", JS::PropertyDescriptor { .value = vm.argument(0), .writable = true })); return JS::js_undefined(); } +)~~~"); + } else if (auto put_forwards_identifier = attribute.extended_attributes.get("PutForwards"sv); put_forwards_identifier.has_value()) { + attribute_generator.set("attribute.name", attribute.name.to_snakecase()); + attribute_generator.set("put_forwards_identifier"sv, *put_forwards_identifier); + + attribute_generator.append(R"~~~( +JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@) +{ + auto* impl = TRY(impl_from(vm)); + auto value = vm.argument(0); + + auto receiver = TRY(throw_dom_exception_if_needed(vm, [&]() { return impl->@attribute.name@(); })); + TRY(receiver->set(JS::PropertyKey { "@put_forwards_identifier@" }, value, JS::Object::ShouldThrowExceptions::Yes)); + + return JS::js_undefined(); +} )~~~"); } } diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp index 5f09f0cddc..fa4276e807 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.cpp +++ b/Userland/Libraries/LibWeb/HTML/Window.cpp @@ -756,10 +756,6 @@ WebIDL::ExceptionOr Window::initialize_web_interfaces(Badge(realm, realm))); create_method_property("WebAssembly", MUST_OR_THROW_OOM(heap().allocate(realm, realm))); - // FIXME: Implement codegen for readonly properties with [PutForwards] - auto& location_accessor = storage_get("location")->value.as_accessor(); - location_accessor.set_setter(JS::NativeFunction::create(realm, location_setter, 1, "location", &realm, {}, "set"sv)); - return {}; } @@ -770,29 +766,6 @@ JS::ThrowCompletionOr Window::internal_set_prototype_of(JS::Object* protot return set_immutable_prototype(prototype); } -static JS::ThrowCompletionOr impl_from(JS::VM& vm) -{ - // Since this is a non built-in function we must treat it as non-strict mode - // this means that a nullish this_value should be converted to the - // global_object. Generally this does not matter as we try to convert the - // this_value to a specific object type in the bindings. But since window is - // the global object we make an exception here. - // This allows calls like `setTimeout(f, 10)` to work. - auto this_value = vm.this_value(); - if (this_value.is_nullish()) - this_value = &vm.current_realm()->global_object(); - - auto* this_object = MUST(this_value.to_object(vm)); - - if (is(*this_object)) - return static_cast(this_object)->window().ptr(); - - if (is(*this_object)) - return static_cast(this_object); - - return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "Window"); -} - // https://html.spec.whatwg.org/multipage/window-object.html#dom-window JS::NonnullGCPtr Window::window() const { @@ -1371,12 +1344,4 @@ size_t Window::document_tree_child_browsing_context_count() const return this_browsing_context->document_tree_child_browsing_context_count(); } -JS_DEFINE_NATIVE_FUNCTION(Window::location_setter) -{ - auto* impl = TRY(impl_from(vm)); - auto location = TRY(Bindings::throw_dom_exception_if_needed(vm, [&] { return impl->location(); })); - TRY(location->set(JS::PropertyKey("href"), vm.argument(0), JS::Object::ShouldThrowExceptions::Yes)); - return JS::js_undefined(); -} - } diff --git a/Userland/Libraries/LibWeb/HTML/Window.h b/Userland/Libraries/LibWeb/HTML/Window.h index f61e39099a..96f6599826 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.h +++ b/Userland/Libraries/LibWeb/HTML/Window.h @@ -233,8 +233,6 @@ private: // [[CrossOriginPropertyDescriptorMap]], https://html.spec.whatwg.org/multipage/browsers.html#crossoriginpropertydescriptormap CrossOriginPropertyDescriptorMap m_cross_origin_property_descriptor_map; - - JS_DECLARE_NATIVE_FUNCTION(location_setter); }; void run_animation_frame_callbacks(DOM::Document&, double now);