Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/array.c | 63 ++++++++++++++++++++++++++++++++++++++++ dlls/mshtml/tests/es5.js | 29 ++++++++++++++++++ 2 files changed, 92 insertions(+)
diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c index 525b3a3..6aa1a69 100644 --- a/dlls/jscript/array.c +++ b/dlls/jscript/array.c @@ -1311,6 +1311,68 @@ done: return hres; }
+static HRESULT Array_lastIndexOf(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, + jsval_t *r) +{ + jsval_t search, value; + unsigned i, length; + jsdisp_t *jsthis; + HRESULT hres; + BOOL eq; + + TRACE("\n"); + + hres = get_length(ctx, vthis, &jsthis, &length); + if(FAILED(hres)) + return hres; + if(!length) + goto notfound; + + search = argc ? argv[0] : jsval_undefined(); + + i = length - 1; + if(argc > 1) { + double from_arg; + + hres = to_integer(ctx, argv[1], &from_arg); + if(FAILED(hres)) + goto done; + + if(from_arg >= 0.0) + i = min(from_arg, i); + else { + from_arg += length; + if(from_arg < 0.0) + goto notfound; + i = from_arg; + } + } + + do { + hres = jsdisp_get_idx(jsthis, i, &value); + if(hres == DISP_E_UNKNOWNNAME) + continue; + if(FAILED(hres)) + goto done; + + hres = jsval_strict_equal(value, search, &eq); + jsval_release(value); + if(FAILED(hres)) + goto done; + if(eq) { + if(r) *r = jsval_number(i); + goto done; + } + } while(i--); + +notfound: + if(r) *r = jsval_number(-1); + hres = S_OK; +done: + jsdisp_release(jsthis); + return hres; +} + static HRESULT Array_map(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { IDispatch *context_this = NULL, *callback; @@ -1610,6 +1672,7 @@ static const builtin_prop_t Array_props[] = { {L"forEach", Array_forEach, PROPF_METHOD|PROPF_ES5|1}, {L"indexOf", Array_indexOf, PROPF_METHOD|PROPF_ES5|1}, {L"join", Array_join, PROPF_METHOD|1}, + {L"lastIndexOf", Array_lastIndexOf, PROPF_METHOD|PROPF_ES5|1}, {L"length", NULL,0, Array_get_length, Array_set_length}, {L"map", Array_map, PROPF_METHOD|PROPF_ES5|1}, {L"pop", Array_pop, PROPF_METHOD}, diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index ceb9c4a..d77c69c 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -147,6 +147,35 @@ sync_test("indexOf", function() { expect([1,2,3], [2, 1.9], 1); });
+sync_test("lastIndexOf", function() { + function expect(array, args, exr) { + var r = Array.prototype.lastIndexOf.apply(array, args); + ok(r == exr, "lastIndexOf returned " + r + " expected " + exr); + } + + ok(Array.prototype.lastIndexOf.length == 1, "lastIndexOf.length = " + Array.prototype.lastIndexOf.length); + + expect([1,2,3], [2], 1); + expect([1,undefined,3], [undefined], 1); + expect([1,undefined,3], [], 1); + expect([1,,3], [undefined], -1); + expect([1,undefined,undefined], [undefined], 2); + expect([1,2,3,2,5,6], [2, 2], 1); + expect([1,2,3,2,5,6], [2], 3); + expect([1,2,3,2,5,6], [2, -3], 3); + expect([1,2,3,2,5,6], [2, -4], 1); + expect([1,2,3,2,5,6], [1, -100], -1); + expect([1,2,3,2,5,6], [2, 100], 3); + expect("abcba", ["b"], 3); + expect(true, [true], -1); + expect({"4": 4, length: 5}, [4], 4); + expect({"4": 4, length: 5}, [undefined], -1); + expect({"4": 4, length: 3}, [4], -1); + expect({"test": true}, [true], -1); + expect([1,2,3], [2, 1.9], 1); + expect([1,2,3], [2, 0.9], -1); +}); + sync_test("filter", function() { ok(Array.prototype.filter.length === 1, "filter.length = " + Array.prototype.filter.length);