Jacek Caban : mshtml: Support deleting object properties.

Alexandre Julliard julliard at winehq.org
Mon Mar 29 16:00:04 CDT 2021


Module: wine
Branch: master
Commit: 13050fd9f1d937befca2495be1aa6a9c0f512613
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=13050fd9f1d937befca2495be1aa6a9c0f512613

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Mar 29 12:05:03 2021 +0200

mshtml: Support deleting object properties.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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");
+});




More information about the wine-cvs mailing list