diff --git a/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp index aa6e39a6e8..440cc8a05e 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp @@ -80,6 +80,7 @@ void ArrayPrototype::initialize(GlobalObject& global_object) define_native_function(vm.names.splice, splice, 2, attr); define_native_function(vm.names.fill, fill, 1, attr); define_native_function(vm.names.values, values, 0, attr); + define_native_function(vm.names.flat, flat, 0, attr); define_property(vm.names.length, Value(0), Attribute::Configurable); // Use define_property here instead of define_native_function so that @@ -1034,4 +1035,51 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::values) return ArrayIterator::create(global_object, this_object, Object::PropertyKind::Value); } +static void recursive_array_flat(VM& vm, GlobalObject& global_object, Array& new_array, Object& array, double depth) +{ + auto array_length = length_of_array_like(global_object, array); + if (vm.exception()) + return; + + for (size_t j = 0; j < array_length; ++j) { + auto value = array.get(j); + if (vm.exception()) + return; + + if (depth > 0 && value.is_array()) { + recursive_array_flat(vm, global_object, new_array, value.as_array(), depth - 1); + continue; + } + if (!value.is_empty()) { + new_array.indexed_properties().append(value); + if (vm.exception()) + return; + } + } +} + +JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::flat) +{ + auto* this_object = vm.this_value(global_object).to_object(global_object); + if (!this_object) + return {}; + + auto* new_array = Array::create(global_object); + + double depth = 1; + if (vm.argument_count() > 0) { + auto depth_argument = vm.argument(0); + if (!depth_argument.is_undefined()) { + auto depth_num = depth_argument.to_integer_or_infinity(global_object); + if (vm.exception()) + return {}; + depth = max(depth_num, 0.0); + } + } + + recursive_array_flat(vm, global_object, *new_array, *this_object, depth); + if (vm.exception()) + return {}; + return new_array; +} } diff --git a/Userland/Libraries/LibJS/Runtime/ArrayPrototype.h b/Userland/Libraries/LibJS/Runtime/ArrayPrototype.h index bbdb82903e..92ffafe957 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayPrototype.h +++ b/Userland/Libraries/LibJS/Runtime/ArrayPrototype.h @@ -66,6 +66,7 @@ private: JS_DECLARE_NATIVE_FUNCTION(splice); JS_DECLARE_NATIVE_FUNCTION(fill); JS_DECLARE_NATIVE_FUNCTION(values); + JS_DECLARE_NATIVE_FUNCTION(flat); }; } diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h index 2d1d4d1d2e..af471bab5e 100644 --- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h +++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h @@ -108,6 +108,7 @@ namespace JS { P(find) \ P(findIndex) \ P(flags) \ + P(flat) \ P(floor) \ P(forEach) \ P(from) \