diff --git a/Libraries/LibJS/Runtime/StringPrototype.cpp b/Libraries/LibJS/Runtime/StringPrototype.cpp index c9d729414e..73cfd2f921 100644 --- a/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -33,6 +33,7 @@ #include #include #include +#include namespace JS { @@ -42,6 +43,7 @@ StringPrototype::StringPrototype() put_native_function("charAt", char_at, 1); put_native_function("repeat", repeat, 1); put_native_function("startsWith", starts_with, 1); + put_native_function("indexOf", index_of, 1); } StringPrototype::~StringPrototype() @@ -110,6 +112,27 @@ Value StringPrototype::starts_with(Interpreter& interpreter) return Value(underlying_string.substring(start, search_string_length) == search_string); } +Value StringPrototype::index_of(Interpreter& interpreter) +{ + auto* this_object = interpreter.this_value().to_object(interpreter.heap()); + if (!this_object) + return {}; + if (!this_object->is_string_object()) + return interpreter.throw_exception("TypeError", "Not a String object"); + + Value needle_value = js_undefined(); + if (interpreter.argument_count() >= 1) + needle_value = interpreter.argument(0); + auto needle = needle_value.to_string(); + auto haystack = static_cast(this_object)->primitive_string()->string(); + + // FIXME: We should have a helper in AK::String for this. + auto* ptr = strstr(haystack.characters(), needle.characters()); + if (!ptr) + return Value(-1); + return Value((i32)(ptr - haystack.characters())); +} + Value StringPrototype::length_getter(Interpreter& interpreter) { auto* this_object = interpreter.this_value().to_object(interpreter.heap()); diff --git a/Libraries/LibJS/Runtime/StringPrototype.h b/Libraries/LibJS/Runtime/StringPrototype.h index 000f373fb6..3a2f749aa2 100644 --- a/Libraries/LibJS/Runtime/StringPrototype.h +++ b/Libraries/LibJS/Runtime/StringPrototype.h @@ -41,6 +41,7 @@ private: static Value char_at(Interpreter&); static Value repeat(Interpreter&); static Value starts_with(Interpreter&); + static Value index_of(Interpreter&); static Value length_getter(Interpreter&); }; diff --git a/Libraries/LibJS/Tests/String.prototype.indexOf.js b/Libraries/LibJS/Tests/String.prototype.indexOf.js new file mode 100644 index 0000000000..3c84a4ece8 --- /dev/null +++ b/Libraries/LibJS/Tests/String.prototype.indexOf.js @@ -0,0 +1,12 @@ +function assert(x) { if (!x) throw 1; } + +try { + var s = "hello friends" + + assert(s.indexOf("friends") === 6); + assert(s.indexOf("enemies") === -1); + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +}