Module: wine Branch: master Commit: 13050fd9f1d937befca2495be1aa6a9c0f512613 URL: https://source.winehq.org/git/wine.git/?a=commit;h=13050fd9f1d937befca2495be...
Author: Jacek Caban jacek@codeweavers.com Date: Mon Mar 29 12:05:03 2021 +0200
mshtml: Support deleting object properties.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/mshtml/dispex.c | 41 +++++++++++--- dlls/mshtml/tests/documentmode.js | 109 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 6 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 729fac91d43..cb2721ec141 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1675,14 +1675,26 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc } }
-static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex) +static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR name, DWORD grfdex) { DispatchEx *This = impl_from_IDispatchEx(iface); + DISPID id; + HRESULT hres;
- TRACE("(%p)->(%s %x)\n", This, debugstr_w(bstrName), grfdex); + TRACE("(%p)->(%s %x)\n", This, debugstr_w(name), grfdex);
- /* Not implemented by IE */ - return E_NOTIMPL; + if(dispex_compat_mode(This) < COMPAT_MODE_IE8) { + /* Not implemented by IE */ + return E_NOTIMPL; + } + + hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, name, grfdex & ~fdexNameEnsure, &id); + if(FAILED(hres)) { + TRACE("property %s not found\n", debugstr_w(name)); + return dispex_compat_mode(This) < COMPAT_MODE_IE9 ? hres : S_OK; + } + + return IDispatchEx_DeleteMemberByDispID(&This->IDispatchEx_iface, id); }
static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id) @@ -1691,8 +1703,25 @@ static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID
TRACE("(%p)->(%x)\n", This, id);
- /* Not implemented by IE */ - return E_NOTIMPL; + if(dispex_compat_mode(This) < COMPAT_MODE_IE8) { + /* Not implemented by IE */ + return E_NOTIMPL; + } + + if(is_dynamic_dispid(id)) { + DWORD idx = id - DISPID_DYNPROP_0; + dynamic_prop_t *prop; + + if(!get_dynamic_data(This) || idx > This->dynamic_data->prop_cnt) + return S_OK; + + prop = This->dynamic_data->props + idx; + VariantClear(&prop->var); + prop->flags |= DYNPROP_DELETED; + return S_OK; + } + + return S_OK; }
static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex) diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index bc237061939..8755f4ab6ec 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -379,3 +379,112 @@ sync_test("navigator", function() { ok(navigator.toString() === (v < 9 ? "[object]" : "[object Navigator]"), "navigator.toString() = " + navigator.toString()); }); + +sync_test("delete_prop", function() { + var v = document.documentMode; + var obj = document.createElement("div"), r, obj2; + + obj.prop1 = true; + r = false; + try { + delete obj.prop1; + }catch(ex) { + r = true; + } + if(v < 8) { + ok(r, "did not get an expected exception"); + return; + } + ok(!r, "got an unexpected exception"); + ok(!("prop1" in obj), "prop1 is still in obj"); + + /* again, this time prop1 does not exist */ + r = false; + try { + delete obj.prop1; + }catch(ex) { + r = true; + } + if(v < 9) { + ok(r, "did not get an expected exception"); + return; + }else { + ok(!r, "got an unexpected exception"); + ok(!("prop1" in obj), "prop1 is still in obj"); + } + + r = (delete obj.className); + ok(r, "delete returned " + r); + ok("className" in obj, "className deleted from obj"); + ok(obj.className === "", "className = " + obj.className); + + /* builtin propertiles don't throw any exception, but are not really deleted */ + r = (delete obj.tagName); + ok(r, "delete returned " + r); + ok("tagName" in obj, "tagName deleted from obj"); + ok(obj.tagName === "DIV", "tagName = " + obj.tagName); + + obj = document.querySelectorAll("*"); + ok("0" in obj, "0 is not in obj"); + obj2 = obj[0]; + r = (delete obj[0]); + ok("0" in obj, "0 is not in obj"); + ok(obj[0] === obj2, "obj[0] != obj2"); + + /* test window object and its global scope handling */ + obj = window; + + obj.globalprop1 = true; + ok(globalprop1, "globalprop1 = " + globalprop1); + r = false; + try { + delete obj.globalprop1; + }catch(ex) { + r = true; + } + if(v < 9) { + ok(r, "did not get an expected exception"); + }else { + ok(!r, "got an unexpected globalprop1 exception"); + ok(!("globalprop1" in obj), "globalprop1 is still in obj"); + } + + globalprop2 = true; + ok(obj.globalprop2, "globalprop2 = " + globalprop2); + r = false; + try { + delete obj.globalprop2; + }catch(ex) { + r = true; + } + if(v < 9) { + ok(r, "did not get an expected globalprop2 exception"); + }else { + ok(!r, "got an unexpected exception"); + todo_wine. + ok(!("globalprop2" in obj), "globalprop2 is still in obj"); + } + + obj.globalprop3 = true; + ok(globalprop3, "globalprop3 = " + globalprop3); + r = false; + try { + delete globalprop3; + }catch(ex) { + r = true; + } + if(v < 9) { + ok(r, "did not get an expected exception"); + ok("globalprop3" in obj, "globalprop3 is not in obj"); + }else { + ok(!r, "got an unexpected globalprop3 exception"); + ok(!("globalprop3" in obj), "globalprop3 is still in obj"); + } + + globalprop4 = true; + ok(obj.globalprop4, "globalprop4 = " + globalprop4); + r = (delete globalprop4); + ok(r, "delete returned " + r); + todo_wine. + ok(!("globalprop4" in obj), "globalprop4 is still in obj"); +});