Alexandre Julliard pushed to branch master at wine / wine
Commits:
-
a76b5021
by Jacek Caban at 2024-07-24T20:14:45+02:00
-
0ca77e91
by Jacek Caban at 2024-07-24T20:14:47+02:00
-
7c2b85a6
by Jacek Caban at 2024-07-24T20:14:49+02:00
-
a0319211
by Jacek Caban at 2024-07-24T20:14:49+02:00
-
99189c31
by Jacek Caban at 2024-07-24T20:14:50+02:00
-
262ad357
by Jacek Caban at 2024-07-24T20:14:51+02:00
8 changed files:
- dlls/jscript/dispex.c
- dlls/jscript/jscript.h
- dlls/jscript/object.c
- dlls/mshtml/dispex.c
- dlls/mshtml/htmlelem.c
- dlls/mshtml/mshtml_private.h
- dlls/mshtml/tests/documentmode.js
- dlls/mshtml/tests/dom.js
Changes:
| ... | ... | @@ -318,13 +318,14 @@ static HRESULT find_external_prop(jsdisp_t *This, const WCHAR *name, BOOL case_i |
| 318 | 318 | return S_OK;
|
| 319 | 319 | }
|
| 320 | 320 | |
| 321 | -static HRESULT find_prop_name(jsdisp_t *This, unsigned hash, const WCHAR *name, BOOL case_insens, dispex_prop_t **ret)
|
|
| 321 | +static HRESULT find_prop_name(jsdisp_t *This, unsigned hash, const WCHAR *name, BOOL case_insens,
|
|
| 322 | + dispex_prop_t *prop, dispex_prop_t **ret)
|
|
| 322 | 323 | {
|
| 323 | 324 | const builtin_prop_t *builtin;
|
| 324 | - dispex_prop_t *prop;
|
|
| 325 | 325 | HRESULT hres;
|
| 326 | 326 | |
| 327 | - prop = lookup_dispex_prop(This, hash, name, case_insens);
|
|
| 327 | + if(!prop)
|
|
| 328 | + prop = lookup_dispex_prop(This, hash, name, case_insens);
|
|
| 328 | 329 | if(prop && prop->type != PROP_DELETED) {
|
| 329 | 330 | *ret = prop;
|
| 330 | 331 | return S_OK;
|
| ... | ... | @@ -367,43 +368,52 @@ static HRESULT find_prop_name(jsdisp_t *This, unsigned hash, const WCHAR *name, |
| 367 | 368 | return hres;
|
| 368 | 369 | }
|
| 369 | 370 | |
| 370 | -static HRESULT find_prop_name_prot(jsdisp_t *This, unsigned hash, const WCHAR *name, BOOL case_insens, dispex_prop_t **ret)
|
|
| 371 | +static HRESULT find_prop_name_prot(jsdisp_t *This, unsigned hash, const WCHAR *name, BOOL case_insens,
|
|
| 372 | + dispex_prop_t *own_prop, dispex_prop_t **ret)
|
|
| 371 | 373 | {
|
| 372 | - dispex_prop_t *prop, *del=NULL;
|
|
| 374 | + dispex_prop_t *prot_prop = NULL;
|
|
| 373 | 375 | HRESULT hres;
|
| 374 | 376 | |
| 375 | - hres = find_prop_name(This, hash, name, case_insens, &prop);
|
|
| 377 | + hres = find_prop_name(This, hash, name, case_insens, own_prop, &own_prop);
|
|
| 376 | 378 | if(FAILED(hres))
|
| 377 | 379 | return hres;
|
| 378 | - if(prop && prop->type==PROP_DELETED) {
|
|
| 379 | - del = prop;
|
|
| 380 | - } else if(prop) {
|
|
| 381 | - fix_protref_prop(This, prop);
|
|
| 382 | - *ret = prop;
|
|
| 383 | - return S_OK;
|
|
| 380 | + if(own_prop) {
|
|
| 381 | + if(own_prop->type == PROP_PROTREF) {
|
|
| 382 | + prot_prop = &This->prototype->props[own_prop->u.ref];
|
|
| 383 | + }else if(own_prop->type != PROP_DELETED) {
|
|
| 384 | + *ret = own_prop;
|
|
| 385 | + return S_OK;
|
|
| 386 | + }
|
|
| 384 | 387 | }
|
| 385 | 388 | |
| 386 | 389 | if(This->prototype) {
|
| 387 | - hres = find_prop_name_prot(This->prototype, hash, name, case_insens, &prop);
|
|
| 390 | + hres = find_prop_name_prot(This->prototype, hash, name, case_insens, prot_prop, &prot_prop);
|
|
| 388 | 391 | if(FAILED(hres))
|
| 389 | 392 | return hres;
|
| 390 | - if(prop && prop->type != PROP_DELETED) {
|
|
| 391 | - if(del) {
|
|
| 392 | - del->type = PROP_PROTREF;
|
|
| 393 | - del->u.ref = prop - This->prototype->props;
|
|
| 394 | - prop = del;
|
|
| 393 | + if(prot_prop && prot_prop->type != PROP_DELETED) {
|
|
| 394 | + if(own_prop && case_insens && wcscmp(prot_prop->name, own_prop->name)) {
|
|
| 395 | + hres = find_prop_name(This, prot_prop->hash, prot_prop->name, FALSE, NULL, &own_prop);
|
|
| 396 | + if(FAILED(hres))
|
|
| 397 | + return hres;
|
|
| 398 | + if(own_prop && own_prop->type != PROP_DELETED) {
|
|
| 399 | + *ret = own_prop;
|
|
| 400 | + return S_OK;
|
|
| 401 | + }
|
|
| 402 | + }
|
|
| 403 | + if(own_prop) {
|
|
| 404 | + own_prop->type = PROP_PROTREF;
|
|
| 405 | + own_prop->u.ref = prot_prop - This->prototype->props;
|
|
| 395 | 406 | }else {
|
| 396 | - prop = alloc_protref(This, prop->name, prop - This->prototype->props);
|
|
| 397 | - if(!prop)
|
|
| 407 | + own_prop = alloc_protref(This, prot_prop->name, prot_prop - This->prototype->props);
|
|
| 408 | + if(!own_prop)
|
|
| 398 | 409 | return E_OUTOFMEMORY;
|
| 399 | 410 | }
|
| 400 | - |
|
| 401 | - *ret = prop;
|
|
| 402 | - return S_OK;
|
|
| 411 | + }else if(own_prop) {
|
|
| 412 | + own_prop->type = PROP_DELETED;
|
|
| 403 | 413 | }
|
| 404 | 414 | }
|
| 405 | 415 | |
| 406 | - *ret = del;
|
|
| 416 | + *ret = own_prop;
|
|
| 407 | 417 | return S_OK;
|
| 408 | 418 | }
|
| 409 | 419 | |
| ... | ... | @@ -412,7 +422,7 @@ static HRESULT ensure_prop_name(jsdisp_t *This, const WCHAR *name, DWORD create_ |
| 412 | 422 | dispex_prop_t *prop;
|
| 413 | 423 | HRESULT hres;
|
| 414 | 424 | |
| 415 | - hres = find_prop_name_prot(This, string_hash(name), name, case_insens, &prop);
|
|
| 425 | + hres = find_prop_name_prot(This, string_hash(name), name, case_insens, NULL, &prop);
|
|
| 416 | 426 | if(SUCCEEDED(hres) && (!prop || prop->type == PROP_DELETED)) {
|
| 417 | 427 | TRACE("creating prop %s flags %lx\n", debugstr_w(name), create_flags);
|
| 418 | 428 | |
| ... | ... | @@ -742,7 +752,7 @@ static HRESULT fill_protrefs(jsdisp_t *This) |
| 742 | 752 | return hres;
|
| 743 | 753 | |
| 744 | 754 | for(iter = This->prototype->props; iter < This->prototype->props+This->prototype->prop_cnt; iter++) {
|
| 745 | - hres = find_prop_name(This, iter->hash, iter->name, FALSE, &prop);
|
|
| 755 | + hres = find_prop_name(This, iter->hash, iter->name, FALSE, NULL, &prop);
|
|
| 746 | 756 | if(FAILED(hres))
|
| 747 | 757 | return hres;
|
| 748 | 758 | if(!prop || prop->type==PROP_DELETED) {
|
| ... | ... | @@ -2230,7 +2240,7 @@ static HRESULT WINAPI DispatchEx_DeleteMemberByName(IWineJSDispatch *iface, BSTR |
| 2230 | 2240 | if(grfdex & ~(fdexNameCaseSensitive|fdexNameCaseInsensitive|fdexNameEnsure|fdexNameImplicit|FDEX_VERSION_MASK))
|
| 2231 | 2241 | FIXME("Unsupported grfdex %lx\n", grfdex);
|
| 2232 | 2242 | |
| 2233 | - hres = find_prop_name(This, string_hash(bstrName), bstrName, grfdex & fdexNameCaseInsensitive, &prop);
|
|
| 2243 | + hres = find_prop_name(This, string_hash(bstrName), bstrName, grfdex & fdexNameCaseInsensitive, NULL, &prop);
|
|
| 2234 | 2244 | if(FAILED(hres))
|
| 2235 | 2245 | return hres;
|
| 2236 | 2246 | if(!prop) {
|
| ... | ... | @@ -2420,7 +2430,7 @@ HRESULT init_dispex_from_constr(jsdisp_t *dispex, script_ctx_t *ctx, const built |
| 2420 | 2430 | dispex_prop_t *prop;
|
| 2421 | 2431 | HRESULT hres;
|
| 2422 | 2432 | |
| 2423 | - hres = find_prop_name_prot(constr, string_hash(L"prototype"), L"prototype", FALSE, &prop);
|
|
| 2433 | + hres = find_prop_name_prot(constr, string_hash(L"prototype"), L"prototype", FALSE, NULL, &prop);
|
|
| 2424 | 2434 | if(SUCCEEDED(hres) && prop && prop->type!=PROP_DELETED) {
|
| 2425 | 2435 | jsval_t val;
|
| 2426 | 2436 | |
| ... | ... | @@ -2461,7 +2471,7 @@ HRESULT jsdisp_get_id(jsdisp_t *jsdisp, const WCHAR *name, DWORD flags, DISPID * |
| 2461 | 2471 | hres = ensure_prop_name(jsdisp, name, PROPF_ENUMERABLE | PROPF_CONFIGURABLE | PROPF_WRITABLE,
|
| 2462 | 2472 | flags & fdexNameCaseInsensitive, &prop);
|
| 2463 | 2473 | else
|
| 2464 | - hres = find_prop_name_prot(jsdisp, string_hash(name), name, flags & fdexNameCaseInsensitive, &prop);
|
|
| 2474 | + hres = find_prop_name_prot(jsdisp, string_hash(name), name, flags & fdexNameCaseInsensitive, NULL, &prop);
|
|
| 2465 | 2475 | if(FAILED(hres))
|
| 2466 | 2476 | return hres;
|
| 2467 | 2477 | |
| ... | ... | @@ -2522,7 +2532,7 @@ HRESULT jsdisp_call_name(jsdisp_t *disp, const WCHAR *name, WORD flags, unsigned |
| 2522 | 2532 | dispex_prop_t *prop;
|
| 2523 | 2533 | HRESULT hres;
|
| 2524 | 2534 | |
| 2525 | - hres = find_prop_name_prot(disp, string_hash(name), name, FALSE, &prop);
|
|
| 2535 | + hres = find_prop_name_prot(disp, string_hash(name), name, FALSE, NULL, &prop);
|
|
| 2526 | 2536 | if(FAILED(hres))
|
| 2527 | 2537 | return hres;
|
| 2528 | 2538 | |
| ... | ... | @@ -2752,7 +2762,7 @@ HRESULT jsdisp_propput(jsdisp_t *obj, const WCHAR *name, DWORD flags, BOOL throw |
| 2752 | 2762 | if(obj->extensible)
|
| 2753 | 2763 | hres = ensure_prop_name(obj, name, flags, FALSE, &prop);
|
| 2754 | 2764 | else
|
| 2755 | - hres = find_prop_name(obj, string_hash(name), name, FALSE, &prop);
|
|
| 2765 | + hres = find_prop_name(obj, string_hash(name), name, FALSE, NULL, &prop);
|
|
| 2756 | 2766 | if(FAILED(hres))
|
| 2757 | 2767 | return hres;
|
| 2758 | 2768 | if(!prop || (prop->type == PROP_DELETED && !obj->extensible))
|
| ... | ... | @@ -2853,7 +2863,7 @@ HRESULT jsdisp_propget_name(jsdisp_t *obj, const WCHAR *name, jsval_t *val) |
| 2853 | 2863 | dispex_prop_t *prop;
|
| 2854 | 2864 | HRESULT hres;
|
| 2855 | 2865 | |
| 2856 | - hres = find_prop_name_prot(obj, string_hash(name), name, FALSE, &prop);
|
|
| 2866 | + hres = find_prop_name_prot(obj, string_hash(name), name, FALSE, NULL, &prop);
|
|
| 2857 | 2867 | if(FAILED(hres))
|
| 2858 | 2868 | return hres;
|
| 2859 | 2869 | |
| ... | ... | @@ -2873,7 +2883,7 @@ HRESULT jsdisp_get_idx(jsdisp_t *obj, DWORD idx, jsval_t *r) |
| 2873 | 2883 | |
| 2874 | 2884 | swprintf(name, ARRAY_SIZE(name), L"%d", idx);
|
| 2875 | 2885 | |
| 2876 | - hres = find_prop_name_prot(obj, string_hash(name), name, FALSE, &prop);
|
|
| 2886 | + hres = find_prop_name_prot(obj, string_hash(name), name, FALSE, NULL, &prop);
|
|
| 2877 | 2887 | if(FAILED(hres))
|
| 2878 | 2888 | return hres;
|
| 2879 | 2889 | |
| ... | ... | @@ -2930,7 +2940,7 @@ HRESULT jsdisp_delete_idx(jsdisp_t *obj, DWORD idx) |
| 2930 | 2940 | |
| 2931 | 2941 | swprintf(buf, ARRAY_SIZE(buf), L"%d", idx);
|
| 2932 | 2942 | |
| 2933 | - hres = find_prop_name(obj, string_hash(buf), buf, FALSE, &prop);
|
|
| 2943 | + hres = find_prop_name(obj, string_hash(buf), buf, FALSE, NULL, &prop);
|
|
| 2934 | 2944 | if(FAILED(hres) || !prop)
|
| 2935 | 2945 | return hres;
|
| 2936 | 2946 | |
| ... | ... | @@ -3026,7 +3036,7 @@ HRESULT disp_delete_name(script_ctx_t *ctx, IDispatch *disp, jsstr_t *name, BOOL |
| 3026 | 3036 | return E_OUTOFMEMORY;
|
| 3027 | 3037 | }
|
| 3028 | 3038 | |
| 3029 | - hres = find_prop_name(jsdisp, string_hash(ptr), ptr, FALSE, &prop);
|
|
| 3039 | + hres = find_prop_name(jsdisp, string_hash(ptr), ptr, FALSE, NULL, &prop);
|
|
| 3030 | 3040 | if(prop) {
|
| 3031 | 3041 | hres = delete_prop(prop, ret);
|
| 3032 | 3042 | }else {
|
| ... | ... | @@ -3073,7 +3083,7 @@ HRESULT jsdisp_get_own_property(jsdisp_t *obj, const WCHAR *name, BOOL flags_onl |
| 3073 | 3083 | dispex_prop_t *prop;
|
| 3074 | 3084 | HRESULT hres;
|
| 3075 | 3085 | |
| 3076 | - hres = find_prop_name(obj, string_hash(name), name, FALSE, &prop);
|
|
| 3086 | + hres = find_prop_name(obj, string_hash(name), name, FALSE, NULL, &prop);
|
|
| 3077 | 3087 | if(FAILED(hres))
|
| 3078 | 3088 | return hres;
|
| 3079 | 3089 | |
| ... | ... | @@ -3117,7 +3127,7 @@ HRESULT jsdisp_define_property(jsdisp_t *obj, const WCHAR *name, property_desc_t |
| 3117 | 3127 | dispex_prop_t *prop;
|
| 3118 | 3128 | HRESULT hres;
|
| 3119 | 3129 | |
| 3120 | - hres = find_prop_name(obj, string_hash(name), name, FALSE, &prop);
|
|
| 3130 | + hres = find_prop_name(obj, string_hash(name), name, FALSE, NULL, &prop);
|
|
| 3121 | 3131 | if(FAILED(hres))
|
| 3122 | 3132 | return hres;
|
| 3123 | 3133 | |
| ... | ... | @@ -3408,7 +3418,7 @@ static HRESULT HostObject_to_string(jsdisp_t *jsdisp, jsstr_t **ret) |
| 3408 | 3418 | }
|
| 3409 | 3419 | |
| 3410 | 3420 | static const builtin_info_t HostObject_info = {
|
| 3411 | - .class = JSCLASS_OBJECT,
|
|
| 3421 | + .class = JSCLASS_HOST,
|
|
| 3412 | 3422 | .addref = HostObject_addref,
|
| 3413 | 3423 | .release = HostObject_release,
|
| 3414 | 3424 | .lookup_prop = HostObject_lookup_prop,
|
| ... | ... | @@ -119,6 +119,7 @@ typedef enum { |
| 119 | 119 | JSCLASS_MAP,
|
| 120 | 120 | JSCLASS_SET,
|
| 121 | 121 | JSCLASS_WEAKMAP,
|
| 122 | + JSCLASS_HOST,
|
|
| 122 | 123 | } jsclass_t;
|
| 123 | 124 | |
| 124 | 125 | jsdisp_t *iface_to_jsdisp(IDispatch*);
|
| ... | ... | @@ -55,7 +55,8 @@ static HRESULT Object_toString(script_ctx_t *ctx, jsval_t vthis, WORD flags, uns |
| 55 | 55 | L"[object Object]",
|
| 56 | 56 | L"[object Object]",
|
| 57 | 57 | L"[object Object]",
|
| 58 | - L"[object Object]"
|
|
| 58 | + L"[object Object]",
|
|
| 59 | + NULL
|
|
| 59 | 60 | };
|
| 60 | 61 | |
| 61 | 62 | TRACE("\n");
|
| ... | ... | @@ -2169,6 +2169,20 @@ HRESULT dispex_prop_name(DispatchEx *dispex, DISPID id, BSTR *ret) |
| 2169 | 2169 | HRESULT hres;
|
| 2170 | 2170 | |
| 2171 | 2171 | if(is_custom_dispid(id)) {
|
| 2172 | + if(dispex->info->desc->vtbl->get_prop_desc) {
|
|
| 2173 | + struct property_info desc;
|
|
| 2174 | + WCHAR buf[12];
|
|
| 2175 | + |
|
| 2176 | + hres = dispex->info->desc->vtbl->get_prop_desc(dispex, id, &desc);
|
|
| 2177 | + if(FAILED(hres))
|
|
| 2178 | + return hres;
|
|
| 2179 | + if(!desc.name) {
|
|
| 2180 | + swprintf(buf, ARRAYSIZE(buf), L"%u", desc.index);
|
|
| 2181 | + desc.name = buf;
|
|
| 2182 | + }
|
|
| 2183 | + *ret = SysAllocString(desc.name);
|
|
| 2184 | + return *ret ? S_OK : E_OUTOFMEMORY;
|
|
| 2185 | + }
|
|
| 2172 | 2186 | if(dispex->info->desc->vtbl->get_name)
|
| 2173 | 2187 | return dispex->info->desc->vtbl->get_name(dispex, id, ret);
|
| 2174 | 2188 | return DISP_E_MEMBERNOTFOUND;
|
| ... | ... | @@ -2299,33 +2313,67 @@ static HRESULT WINAPI JSDispatchHost_GetJSDispatch(IWineJSDispatchHost *iface, I |
| 2299 | 2313 | return S_OK;
|
| 2300 | 2314 | }
|
| 2301 | 2315 | |
| 2316 | +HRESULT dispex_index_prop_desc(DispatchEx *dispex, DISPID id, struct property_info *desc)
|
|
| 2317 | +{
|
|
| 2318 | + desc->id = id;
|
|
| 2319 | + desc->flags = PROPF_WRITABLE | PROPF_CONFIGURABLE;
|
|
| 2320 | + if(dispex->info->desc->vtbl->next_dispid)
|
|
| 2321 | + desc->flags |= PROPF_ENUMERABLE;
|
|
| 2322 | + desc->name = NULL;
|
|
| 2323 | + desc->index = id - MSHTML_DISPID_CUSTOM_MIN;
|
|
| 2324 | + desc->func_iid = 0;
|
|
| 2325 | + return S_OK;
|
|
| 2326 | +}
|
|
| 2327 | + |
|
| 2328 | +static HRESULT get_host_property_descriptor(DispatchEx *This, DISPID id, struct property_info *desc)
|
|
| 2329 | +{
|
|
| 2330 | + HRESULT hres;
|
|
| 2331 | + |
|
| 2332 | + desc->id = id;
|
|
| 2333 | + |
|
| 2334 | + switch(get_dispid_type(id)) {
|
|
| 2335 | + case DISPEXPROP_BUILTIN: {
|
|
| 2336 | + func_info_t *func;
|
|
| 2337 | + |
|
| 2338 | + hres = get_builtin_func(This->info, id, &func);
|
|
| 2339 | + if(FAILED(hres))
|
|
| 2340 | + return hres;
|
|
| 2341 | + desc->flags = PROPF_WRITABLE | PROPF_CONFIGURABLE;
|
|
| 2342 | + desc->name = func->name;
|
|
| 2343 | + if(func->func_disp_idx < 0) {
|
|
| 2344 | + desc->flags |= PROPF_ENUMERABLE;
|
|
| 2345 | + desc->func_iid = 0;
|
|
| 2346 | + }else {
|
|
| 2347 | + desc->func_iid = func->tid;
|
|
| 2348 | + }
|
|
| 2349 | + break;
|
|
| 2350 | + }
|
|
| 2351 | + case DISPEXPROP_DYNAMIC:
|
|
| 2352 | + desc->flags = PROPF_WRITABLE | PROPF_CONFIGURABLE | PROPF_ENUMERABLE;
|
|
| 2353 | + desc->name = This->dynamic_data->props[id - DISPID_DYNPROP_0].name;
|
|
| 2354 | + desc->func_iid = 0;
|
|
| 2355 | + break;
|
|
| 2356 | + case DISPEXPROP_CUSTOM:
|
|
| 2357 | + return This->info->desc->vtbl->get_prop_desc(This, id, desc);
|
|
| 2358 | + }
|
|
| 2359 | + |
|
| 2360 | + return S_OK;
|
|
| 2361 | +}
|
|
| 2362 | + |
|
| 2302 | 2363 | static HRESULT WINAPI JSDispatchHost_LookupProperty(IWineJSDispatchHost *iface, const WCHAR *name, DWORD flags,
|
| 2303 | 2364 | struct property_info *desc)
|
| 2304 | 2365 | {
|
| 2305 | 2366 | DispatchEx *This = impl_from_IWineJSDispatchHost(iface);
|
| 2306 | - func_info_t *func;
|
|
| 2307 | 2367 | DISPID id;
|
| 2308 | 2368 | HRESULT hres;
|
| 2309 | 2369 | |
| 2310 | 2370 | TRACE("%s (%p)->(%s)\n", This->info->desc->name, This, debugstr_w(name));
|
| 2311 | 2371 | |
| 2312 | - hres = get_builtin_id(This, name, flags, &id);
|
|
| 2372 | + hres = dispex_get_id(This, name, flags, &id);
|
|
| 2313 | 2373 | if(FAILED(hres))
|
| 2314 | 2374 | return hres;
|
| 2315 | 2375 | |
| 2316 | - hres = get_builtin_func(This->info, id, &func);
|
|
| 2317 | - if(FAILED(hres))
|
|
| 2318 | - return hres;
|
|
| 2319 | - desc->id = id;
|
|
| 2320 | - desc->flags = PROPF_WRITABLE | PROPF_CONFIGURABLE;
|
|
| 2321 | - if(func->func_disp_idx < 0) {
|
|
| 2322 | - desc->flags |= PROPF_ENUMERABLE;
|
|
| 2323 | - desc->func_iid = 0;
|
|
| 2324 | - }else {
|
|
| 2325 | - desc->func_iid = func->tid;
|
|
| 2326 | - }
|
|
| 2327 | - desc->name = func->name;
|
|
| 2328 | - return S_OK;
|
|
| 2376 | + return get_host_property_descriptor(This, id, desc);
|
|
| 2329 | 2377 | }
|
| 2330 | 2378 | |
| 2331 | 2379 | static HRESULT WINAPI JSDispatchHost_NextProperty(IWineJSDispatchHost *iface, DISPID id, struct property_info *desc)
|
| ... | ... | @@ -1073,21 +1073,6 @@ static HRESULT HTMLRectCollection_get_dispid(DispatchEx *dispex, const WCHAR *na |
| 1073 | 1073 | return S_OK;
|
| 1074 | 1074 | }
|
| 1075 | 1075 | |
| 1076 | -static HRESULT HTMLRectCollection_get_name(DispatchEx *dispex, DISPID id, BSTR *name)
|
|
| 1077 | -{
|
|
| 1078 | - HTMLRectCollection *This = HTMLRectCollection_from_DispatchEx(dispex);
|
|
| 1079 | - DWORD idx = id - MSHTML_DISPID_CUSTOM_MIN;
|
|
| 1080 | - UINT32 len = 0;
|
|
| 1081 | - WCHAR buf[11];
|
|
| 1082 | - |
|
| 1083 | - nsIDOMClientRectList_GetLength(This->rect_list, &len);
|
|
| 1084 | - if(idx >= len)
|
|
| 1085 | - return DISP_E_MEMBERNOTFOUND;
|
|
| 1086 | - |
|
| 1087 | - len = swprintf(buf, ARRAY_SIZE(buf), L"%u", idx);
|
|
| 1088 | - return (*name = SysAllocStringLen(buf, len)) ? S_OK : E_OUTOFMEMORY;
|
|
| 1089 | -}
|
|
| 1090 | - |
|
| 1091 | 1076 | static HRESULT HTMLRectCollection_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
|
| 1092 | 1077 | VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
|
| 1093 | 1078 | {
|
| ... | ... | @@ -1132,7 +1117,7 @@ static const dispex_static_data_vtbl_t HTMLRectCollection_dispex_vtbl = { |
| 1132 | 1117 | .traverse = HTMLRectCollection_traverse,
|
| 1133 | 1118 | .unlink = HTMLRectCollection_unlink,
|
| 1134 | 1119 | .get_dispid = HTMLRectCollection_get_dispid,
|
| 1135 | - .get_name = HTMLRectCollection_get_name,
|
|
| 1120 | + .get_prop_desc = dispex_index_prop_desc,
|
|
| 1136 | 1121 | .invoke = HTMLRectCollection_invoke,
|
| 1137 | 1122 | };
|
| 1138 | 1123 | static const tid_t HTMLRectCollection_iface_tids[] = {
|
| ... | ... | @@ -3053,7 +3038,7 @@ static HRESULT WINAPI HTMLElement2_getClientRects(IHTMLElement2 *iface, IHTMLRec |
| 3053 | 3038 | |
| 3054 | 3039 | rects->IHTMLRectCollection_iface.lpVtbl = &HTMLRectCollectionVtbl;
|
| 3055 | 3040 | rects->rect_list = rect_list;
|
| 3056 | - init_dispatch(&rects->dispex, &HTMLRectCollection_dispex, NULL,
|
|
| 3041 | + init_dispatch(&rects->dispex, &HTMLRectCollection_dispex, This->node.doc->script_global,
|
|
| 3057 | 3042 | dispex_compat_mode(&This->node.event_target.dispex));
|
| 3058 | 3043 | |
| 3059 | 3044 | *pRectCol = &rects->IHTMLRectCollection_iface;
|
| ... | ... | @@ -392,6 +392,7 @@ typedef struct { |
| 392 | 392 | HRESULT (*invoke)(DispatchEx*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*);
|
| 393 | 393 | HRESULT (*delete)(DispatchEx*,DISPID);
|
| 394 | 394 | HRESULT (*next_dispid)(DispatchEx*,DISPID,DISPID*);
|
| 395 | + HRESULT (*get_prop_desc)(DispatchEx*,DISPID,struct property_info*);
|
|
| 395 | 396 | |
| 396 | 397 | /* Similar to invoke, but allows overriding all dispids */
|
| 397 | 398 | HRESULT (*disp_invoke)(DispatchEx*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*);
|
| ... | ... | @@ -515,6 +516,7 @@ HRESULT dispex_prop_put(DispatchEx *dispex, DISPID id, LCID lcid, VARIANT *v, EX |
| 515 | 516 | HRESULT dispex_get_id(DispatchEx *dispex, const WCHAR *name, DWORD flags, DISPID *pid);
|
| 516 | 517 | HRESULT dispex_next_id(DispatchEx *dispex, DISPID id, DISPID *ret);
|
| 517 | 518 | HRESULT dispex_prop_name(DispatchEx *dispex, DISPID id, BSTR *ret);
|
| 519 | +HRESULT dispex_index_prop_desc(DispatchEx*,DISPID,struct property_info*);
|
|
| 518 | 520 | |
| 519 | 521 | typedef enum {
|
| 520 | 522 | DISPEXPROP_CUSTOM,
|
| ... | ... | @@ -294,7 +294,7 @@ sync_test("builtin_toString", function() { |
| 294 | 294 | if(false /* todo_wine */) test("attributes", e.attributes, "NamedNodeMap");
|
| 295 | 295 | test("childNodes", document.body.childNodes, "NodeList", null, true);
|
| 296 | 296 | if(clientRects) test("clientRect", clientRects[0], "ClientRect", null, true);
|
| 297 | - if(clientRects) test("clientRects", clientRects, "ClientRectList", null, true);
|
|
| 297 | + if(clientRects) test("clientRects", clientRects, "ClientRectList");
|
|
| 298 | 298 | if(currentStyle) test("currentStyle", currentStyle, "MSCurrentStyleCSSProperties", null, true);
|
| 299 | 299 | if(v >= 11 /* todo_wine */) test("document", document, v < 11 ? "Document" : "HTMLDocument", null, true);
|
| 300 | 300 | test("elements", document.getElementsByTagName("body"), "HTMLCollection", null, true);
|
| ... | ... | @@ -331,6 +331,18 @@ sync_test("rects", function() { |
| 331 | 331 | ok(rects.length === 1, "rect.length = " + rects.length);
|
| 332 | 332 | ok(rects[0].top === rect.top, "rects[0].top = " + rects[0].top + " rect.top = " + rect.top);
|
| 333 | 333 | ok(rects[0].bottom === rect.bottom, "rects[0].bottom = " + rects[0].bottom + " rect.bottom = " + rect.bottom);
|
| 334 | + |
|
| 335 | + ok("" + rects[0] === "[object ClientRect]", "rects[0] = " + rects[0]);
|
|
| 336 | + ok(rects.hasOwnProperty("0"), 'rects.hasOwnProperty("0") = ' + rects.hasOwnProperty("0"));
|
|
| 337 | + todo_wine.
|
|
| 338 | + ok(rects.hasOwnProperty("1"), 'rects.hasOwnProperty("1") = ' + rects.hasOwnProperty("1"));
|
|
| 339 | + var desc = Object.getOwnPropertyDescriptor(rects, "0");
|
|
| 340 | + ok(desc.writable === true, "writable = " + desc.writable);
|
|
| 341 | + todo_wine.
|
|
| 342 | + ok(desc.enumerable === true, "enumerable = " + desc.enumerable);
|
|
| 343 | + ok(desc.configurable === true, "configurable = " + desc.configurable);
|
|
| 344 | + ok("" + desc.value === "[object ClientRect]", "desc.value = " + desc.value);
|
|
| 345 | + |
|
| 334 | 346 | ok(rect.height === rect.bottom - rect.top, "rect.height = " + rect.height + " rect.bottom = " + rect.bottom + " rect.top = " + rect.top);
|
| 335 | 347 | ok(rect.width === rect.right - rect.left, "rect.width = " + rect.width + " rect.right = " + rect.right + " rect.left = " + rect.left);
|
| 336 | 348 |