diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c index 90ff31303c8..9c287c99014 100644 --- a/dlls/jscript/array.c +++ b/dlls/jscript/array.c @@ -47,6 +47,7 @@ static const WCHAR spliceW[] = {'s','p','l','i','c','e',0}; static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0}; static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0}; static const WCHAR unshiftW[] = {'u','n','s','h','i','f','t',0}; +static const WCHAR indexOfW[] = {'i','n','d','e','x','O','f',0}; static const WCHAR default_separatorW[] = {',',0}; @@ -946,6 +947,61 @@ static HRESULT Array_toLocaleString(script_ctx_t *ctx, vdisp_t *vthis, WORD flag return E_NOTIMPL; } +static HRESULT Array_indexOf(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, + jsval_t *r) +{ + jsdisp_t *jsthis; + unsigned length, i, from = 0; + jsval_t search, value; + BOOL eq; + HRESULT hres; + + TRACE("\n"); + + hres = get_length(ctx, vthis, &jsthis, &length); + if(FAILED(hres)) + return hres; + if(!length) { + if(r) *r = jsval_number(-1); + return S_OK; + } + + search = argc ? argv[0] : jsval_undefined(); + + if(argc > 1) { + double from_arg; + + hres = to_integer(ctx, argv[1], &from_arg); + if(FAILED(hres)) + return hres; + + if(from_arg >= 0) + from = min(from_arg, length); + else + from = max(from_arg + length, 0); + } + + for(i = from; i < length; i++) { + hres = jsdisp_get_idx(jsthis, i, &value); + if(hres == DISP_E_UNKNOWNNAME) + continue; + if(FAILED(hres)) + return hres; + + hres = jsval_strict_equal(value, search, &eq); + jsval_release(value); + if(FAILED(hres)) + return hres; + if(eq) { + if(r) *r = jsval_number(i); + return S_OK; + } + } + + if(r) *r = jsval_number(-1); + return S_OK; +} + /* ECMA-262 3rd Edition 15.4.4.13 */ static HRESULT Array_unshift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) @@ -1044,6 +1100,7 @@ static void Array_on_put(jsdisp_t *dispex, const WCHAR *name) static const builtin_prop_t Array_props[] = { {concatW, Array_concat, PROPF_METHOD|1}, + {indexOfW, Array_indexOf, PROPF_ES5|PROPF_METHOD|1}, {joinW, Array_join, PROPF_METHOD|1}, {lengthW, NULL,0, Array_get_length, Array_set_length}, {popW, Array_pop, PROPF_METHOD}, diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index bd14a355f60..d7a5a46b457 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -520,7 +520,7 @@ static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret) } /* ECMA-262 3rd Edition 11.9.6 */ -static HRESULT jsval_strict_equal(jsval_t lval, jsval_t rval, BOOL *ret) +HRESULT jsval_strict_equal(jsval_t lval, jsval_t rval, BOOL *ret) { jsval_type_t type = jsval_type(lval); diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 119d4168d12..86786192489 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -341,6 +341,8 @@ HRESULT to_string(script_ctx_t*,jsval_t,jsstr_t**) DECLSPEC_HIDDEN; HRESULT to_flat_string(script_ctx_t*,jsval_t,jsstr_t**,const WCHAR**) DECLSPEC_HIDDEN; HRESULT to_object(script_ctx_t*,jsval_t,IDispatch**) DECLSPEC_HIDDEN; +HRESULT jsval_strict_equal(jsval_t,jsval_t,BOOL*) DECLSPEC_HIDDEN; + HRESULT variant_change_type(script_ctx_t*,VARIANT*,VARIANT*,VARTYPE) DECLSPEC_HIDDEN; HRESULT decode_source(WCHAR*) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index a506a169a67..b9ac40ede9a 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -123,6 +123,7 @@ function test_javascript() { test_exposed("JSON", g, v >= 8); test_exposed("now", Date, true); test_exposed("isArray", Array, v >= 9); + test_exposed("indexOf", Array.prototype, v >= 9); next_test(); } diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 29af64e465d..9f87e995b79 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -27,6 +27,34 @@ function test_date_now() { next_test(); } +function test_indexOf() { + function expect(array, args, exr) { + var r = Array.prototype.indexOf.apply(array, args); + ok(r == exr, "indexOf returned " + r + " expected " + exr); + } + + ok(Array.prototype.indexOf.length == 1, "indexOf.length = " + Array.prototype.indexOf.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,2,3,4,5,6], [2, 2], -1); + expect([1,2,3,4,5,6], [5, -1], -1); + expect([1,2,3,4,5,6], [5, -2], 4); + expect([1,2,3,4,5,6], [5, -20], 4); + expect([1,2,3,4,5,6], [5, 20], -1); + expect("abc", ["b"], 1); + 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); + + next_test(); +} + function test_isArray() { function expect_array(a, exr) { var r = Array.isArray(a); @@ -47,5 +75,6 @@ function test_isArray() { var tests = [ test_date_now, + test_indexOf, test_isArray ];