@@ -82,6 +82,7 @@ void StringPrototype::initialize(GlobalObject& global_object)
82
82
define_native_function (vm.names .match , match, 1 , attr);
83
83
define_native_function (vm.names .matchAll , match_all, 1 , attr);
84
84
define_native_function (vm.names .replace , replace, 2 , attr);
85
+ define_native_function (vm.names .replaceAll , replace_all, 2 , attr);
85
86
define_native_function (vm.names .search , search, 1 , attr);
86
87
define_native_function (vm.names .anchor , anchor, 1 , attr);
87
88
define_native_function (vm.names .big , big, 0 , attr);
@@ -765,7 +766,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match_all)
765
766
if (vm.exception ())
766
767
return {};
767
768
if (!flags_string.contains (" g" )) {
768
- vm.throw_exception <TypeError>(global_object, ErrorType::StringMatchAllNonGlobalRegExp );
769
+ vm.throw_exception <TypeError>(global_object, ErrorType::StringNonGlobalRegExp );
769
770
return {};
770
771
}
771
772
}
@@ -835,6 +836,90 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace)
835
836
return js_string (vm, builder.build ());
836
837
}
837
838
839
+ // 22.1.3.18 String.prototype.replaceAll ( searchValue, replaceValue ), https://tc39.es/ecma262/#sec-string.prototype.replaceall
840
+ JS_DEFINE_NATIVE_FUNCTION (StringPrototype::replace_all)
841
+ {
842
+ auto this_object = require_object_coercible (global_object, vm.this_value (global_object));
843
+ if (vm.exception ())
844
+ return {};
845
+ auto search_value = vm.argument (0 );
846
+ auto replace_value = vm.argument (1 );
847
+
848
+ if (!search_value.is_nullish ()) {
849
+ bool is_regexp = search_value.is_regexp (global_object);
850
+ if (vm.exception ())
851
+ return {};
852
+
853
+ if (is_regexp) {
854
+ auto flags = search_value.as_object ().get (vm.names .flags );
855
+ if (vm.exception ())
856
+ return {};
857
+ auto flags_object = require_object_coercible (global_object, flags);
858
+ if (vm.exception ())
859
+ return {};
860
+ auto flags_string = flags_object.to_string (global_object);
861
+ if (vm.exception ())
862
+ return {};
863
+ if (!flags_string.contains (" g" )) {
864
+ vm.throw_exception <TypeError>(global_object, ErrorType::StringNonGlobalRegExp);
865
+ return {};
866
+ }
867
+ }
868
+
869
+ auto * replacer = search_value.get_method (global_object, *vm.well_known_symbol_replace ());
870
+ if (vm.exception ())
871
+ return {};
872
+ if (replacer) {
873
+ auto result = vm.call (*replacer, search_value, this_object, replace_value);
874
+ if (vm.exception ())
875
+ return {};
876
+ return result;
877
+ }
878
+ }
879
+
880
+ auto string = this_object.to_string (global_object);
881
+ if (vm.exception ())
882
+ return {};
883
+ auto search_string = search_value.to_string (global_object);
884
+ if (vm.exception ())
885
+ return {};
886
+
887
+ Vector<size_t > match_positions = string.find_all (search_string);
888
+ size_t end_of_last_match = 0 ;
889
+
890
+ StringBuilder result;
891
+
892
+ for (auto position : match_positions) {
893
+ auto preserved = string.substring_view (end_of_last_match, position - end_of_last_match);
894
+ String replacement;
895
+
896
+ if (replace_value.is_function ()) {
897
+ auto result = vm.call (replace_value.as_function (), js_undefined (), search_value, Value (position), js_string (vm, string));
898
+ if (vm.exception ())
899
+ return {};
900
+
901
+ replacement = result.to_string (global_object);
902
+ if (vm.exception ())
903
+ return {};
904
+ } else {
905
+ // FIXME: Implement the GetSubstituion algorithm for substituting placeholder '$' characters - https://tc39.es/ecma262/#sec-getsubstitution
906
+ replacement = replace_value.to_string (global_object);
907
+ if (vm.exception ())
908
+ return {};
909
+ }
910
+
911
+ result.append (preserved);
912
+ result.append (replacement);
913
+
914
+ end_of_last_match = position + search_string.length ();
915
+ }
916
+
917
+ if (end_of_last_match < string.length ())
918
+ result.append (string.substring_view (end_of_last_match));
919
+
920
+ return js_string (vm, result.build ());
921
+ }
922
+
838
923
// 22.1.3.19 String.prototype.search ( regexp ), https://tc39.es/ecma262/#sec-string.prototype.search
839
924
JS_DEFINE_NATIVE_FUNCTION (StringPrototype::search)
840
925
{
0 commit comments