diff options
author | Kesse Jones <kjonesfc@outlook.com> | 2020-04-29 08:42:00 -0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-04-29 18:35:18 +0200 |
commit | 58f6f50de48965a6bf0113c7e9ba79889dba09ac (patch) | |
tree | 64b910fe3884fface6b4a8269cc9f6570bededc0 | |
parent | bf727eb44cfde732886a434e5c4587702c5fec28 (diff) | |
download | serenity-58f6f50de48965a6bf0113c7e9ba79889dba09ac.zip |
LibJS: Add String.prototype.slice
-rw-r--r-- | Libraries/LibJS/Runtime/StringPrototype.cpp | 42 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/StringPrototype.h | 1 | ||||
-rw-r--r-- | Libraries/LibJS/Tests/String.prototype.slice.js | 22 |
3 files changed, 65 insertions, 0 deletions
diff --git a/Libraries/LibJS/Runtime/StringPrototype.cpp b/Libraries/LibJS/Runtime/StringPrototype.cpp index 91787a9fac..3e2deb9c2b 100644 --- a/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -60,6 +60,7 @@ StringPrototype::StringPrototype() put_native_function("concat", concat, 1, attr); put_native_function("substring", substring, 2, attr); put_native_function("includes", includes, 1, attr); + put_native_function("slice", slice, 2, attr); } StringPrototype::~StringPrototype() @@ -399,4 +400,45 @@ Value StringPrototype::includes(Interpreter& interpreter) return Value(substring_search.contains(search_string)); } +Value StringPrototype::slice(Interpreter& interpreter) +{ + auto* string_object = string_object_from(interpreter); + if (!string_object) + return {}; + + auto& string = string_object->primitive_string().string(); + + if (interpreter.argument_count() == 0) + return js_string(interpreter, string); + + i32 string_length = static_cast<i32>(string.length()); + i32 index_start = interpreter.argument(0).to_i32(); + i32 index_end = string_length; + + auto negative_min_index = -(string_length - 1); + if (index_start < negative_min_index) + index_start = 0; + else if (index_start < 0) + index_start = string_length + index_start; + + if (interpreter.argument_count() >= 2) { + index_end = interpreter.argument(1).to_i32(); + + if (index_end < negative_min_index) + return js_string(interpreter, String::empty()); + + if (index_end > string_length) + index_end = string_length; + else if (index_end < 0) + index_end = string_length + index_end; + } + + if (index_start >= index_end) + return js_string(interpreter, String::empty()); + + auto part_length = index_end - index_start; + auto string_part = string.substring(index_start, part_length); + return js_string(interpreter, string_part); +} + } diff --git a/Libraries/LibJS/Runtime/StringPrototype.h b/Libraries/LibJS/Runtime/StringPrototype.h index 0b0f54ffb1..df5221df75 100644 --- a/Libraries/LibJS/Runtime/StringPrototype.h +++ b/Libraries/LibJS/Runtime/StringPrototype.h @@ -56,6 +56,7 @@ private: static Value trim_end(Interpreter&); static Value concat(Interpreter&); static Value includes(Interpreter&); + static Value slice(Interpreter&); }; } diff --git a/Libraries/LibJS/Tests/String.prototype.slice.js b/Libraries/LibJS/Tests/String.prototype.slice.js new file mode 100644 index 0000000000..a6500ed9d8 --- /dev/null +++ b/Libraries/LibJS/Tests/String.prototype.slice.js @@ -0,0 +1,22 @@ +load("test-common.js"); + +try { + assert(String.prototype.slice.length === 2); + assert("hello friends".slice() === "hello friends"); + assert("hello friends".slice(1) === "ello friends"); + assert("hello friends".slice(0, 5) === "hello"); + assert("hello friends".slice(13, 6) === ""); + assert("hello friends".slice('', 5) === "hello"); + assert("hello friends".slice(3, 3) === ""); + assert("hello friends".slice(-1, 13) === "s"); + assert("hello friends".slice(0, 50) === "hello friends"); + assert("hello friends".slice(0, "5") === "hello"); + assert("hello friends".slice("6", "13") === "friends"); + assert("hello friends".slice(-7) === "friends"); + assert("hello friends".slice(1000) === ""); + assert("hello friends".slice(-1000) === "hello friends"); + + console.log("PASS"); +} catch (err) { + console.log("FAIL: " + err); +} |