diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index 7a037d09b2d..9148451f1cb 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -483,6 +483,11 @@ static void decrease_state(JScript *This, SCRIPTSTATE state) This->ctx->site = NULL; } + if(This->ctx->map_prototype) { + jsdisp_release(This->ctx->map_prototype); + This->ctx->map_prototype = NULL; + } + if(This->ctx->set_prototype) { jsdisp_release(This->ctx->set_prototype); This->ctx->set_prototype = NULL; diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index d64d927c227..e4137855430 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -131,6 +131,7 @@ typedef enum { JSCLASS_ARGUMENTS, JSCLASS_VBARRAY, JSCLASS_JSON, + JSCLASS_MAP, JSCLASS_SET, } jsclass_t; @@ -467,6 +468,7 @@ struct _script_ctx_t { jsdisp_t *regexp_constr; jsdisp_t *string_constr; jsdisp_t *vbarray_constr; + jsdisp_t *map_prototype; jsdisp_t *set_prototype; }; diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c index 46d50000cc3..c8c0572c839 100644 --- a/dlls/jscript/object.c +++ b/dlls/jscript/object.c @@ -48,6 +48,7 @@ static HRESULT Object_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u L"[object Object]", L"[object Object]", L"[object Object]", + L"[object Object]", L"[object Object]" }; diff --git a/dlls/jscript/set.c b/dlls/jscript/set.c index ec22b69eb91..8ac2475ff90 100644 --- a/dlls/jscript/set.c +++ b/dlls/jscript/set.c @@ -26,6 +26,10 @@ typedef struct { jsdisp_t dispex; } SetInstance; +typedef struct { + jsdisp_t dispex; +} MapInstance; + static HRESULT Set_add(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { @@ -119,6 +123,107 @@ static HRESULT Set_constructor(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u } } +static HRESULT Map_clear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, + jsval_t *r) +{ + FIXME("%p\n", jsthis); + return E_NOTIMPL; +} + +static HRESULT Map_delete(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, + jsval_t *r) +{ + FIXME("%p\n", jsthis); + return E_NOTIMPL; +} + +static HRESULT Map_forEach(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, + jsval_t *r) +{ + FIXME("%p\n", jsthis); + return E_NOTIMPL; +} + +static HRESULT Map_get(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, + jsval_t *r) +{ + FIXME("%p\n", jsthis); + return E_NOTIMPL; +} + +static HRESULT Map_set(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, + jsval_t *r) +{ + FIXME("%p\n", jsthis); + return E_NOTIMPL; +} + +static HRESULT Map_has(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, + jsval_t *r) +{ + FIXME("%p\n", jsthis); + return E_NOTIMPL; +} + +static HRESULT Map_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, + jsval_t *r) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static const builtin_prop_t Map_prototype_props[] = { + {L"clear", Map_clear, PROPF_METHOD}, + {L"delete" , Map_delete, PROPF_METHOD|1}, + {L"forEach", Map_forEach, PROPF_METHOD|1}, + {L"get", Map_get, PROPF_METHOD|1}, + {L"has", Map_has, PROPF_METHOD|1}, + {L"set", Map_set, PROPF_METHOD|2}, +}; + +static const builtin_info_t Map_prototype_info = { + JSCLASS_OBJECT, + {NULL, Map_value, 0}, + ARRAY_SIZE(Map_prototype_props), + Map_prototype_props, + NULL, + NULL +}; + +static const builtin_info_t Map_info = { + JSCLASS_MAP, + {NULL, Map_value, 0}, + 0, NULL, + NULL, + NULL +}; + +static HRESULT Map_constructor(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, + jsval_t *r) +{ + MapInstance *map; + HRESULT hres; + + switch(flags) { + case DISPATCH_CONSTRUCT: + TRACE("\n"); + + if(!(map = heap_alloc_zero(sizeof(*map)))) + return E_OUTOFMEMORY; + + hres = init_dispex(&map->dispex, ctx, &Map_info, ctx->map_prototype); + if(FAILED(hres)) + return hres; + + *r = jsval_obj(&map->dispex); + return S_OK; + + default: + FIXME("unimplemented flags %x\n", flags); + return E_NOTIMPL; + } +} + HRESULT init_set_constructor(script_ctx_t *ctx) { jsdisp_t *constructor; @@ -139,5 +244,20 @@ HRESULT init_set_constructor(script_ctx_t *ctx) hres = jsdisp_define_data_property(ctx->global, L"Set", PROPF_WRITABLE, jsval_obj(constructor)); jsdisp_release(constructor); + if(FAILED(hres)) + return hres; + + hres = create_dispex(ctx, &Map_prototype_info, ctx->object_prototype, &ctx->map_prototype); + if(FAILED(hres)) + return hres; + + hres = create_builtin_constructor(ctx, Map_constructor, L"Map", NULL, + PROPF_CONSTR, ctx->map_prototype, &constructor); + if(FAILED(hres)) + return hres; + + hres = jsdisp_define_data_property(ctx->global, L"Map", PROPF_WRITABLE, + jsval_obj(constructor)); + jsdisp_release(constructor); return hres; } diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index d46da5d44a0..d4394e011ce 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -117,6 +117,7 @@ sync_test("window_props", function() { test_exposed("onfocusout", v >= 9); test_exposed("getComputedStyle", v >= 9); test_exposed("requestAnimationFrame", v >= 10); + test_exposed("Map", v >= 11); test_exposed("Set", v >= 11); if(v >= 9) /* FIXME: native exposes it in all compat modes */ test_exposed("performance", true); @@ -623,6 +624,29 @@ sync_test("set_obj", function() { ok(r === "[object Object]", "toString returned " + r); }); +sync_test("map_obj", function() { + if(!("Map" in window)) return; + + var s = new Map, r; + ok(Object.getPrototypeOf(s) === Map.prototype, "unexpected Map prototype"); + + function test_length(name, len) { + ok(Map.prototype[name].length === len, "Map.prototype." + name + " = " + Map.prototype[name].length); + } + test_length("clear", 0); + test_length("delete", 1); + test_length("forEach", 1); + test_length("get", 1); + test_length("has", 1); + test_length("set", 2); + ok(!("entries" in s), "entries are in Map"); + ok(!("keys" in s), "keys are in Map"); + ok(!("values" in s), "values are in Map"); + + r = Object.prototype.toString.call(s); + ok(r === "[object Object]", "toString returned " + r); +}); + sync_test("elem_attr", function() { var v = document.documentMode; var elem = document.createElement("div"), r;