Jacek Caban : mshtml: Use our IDispatchEx-based attributes implementation instead of nsIDOMAttr.

Alexandre Julliard julliard at winehq.org
Wed Mar 2 12:23:49 CST 2011


Module: wine
Branch: master
Commit: 903279eff9ce9c150c9449b9afdb1e2a76912a1c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=903279eff9ce9c150c9449b9afdb1e2a76912a1c

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Mar  2 13:34:24 2011 +0100

mshtml: Use our IDispatchEx-based attributes implementation instead of nsIDOMAttr.

---

 dlls/mshtml/htmlattr.c       |   31 +++++-----------
 dlls/mshtml/htmlelem3.c      |   81 ++++++++++++++++++++++++++++++++---------
 dlls/mshtml/mshtml_private.h |    4 +-
 3 files changed, 75 insertions(+), 41 deletions(-)

diff --git a/dlls/mshtml/htmlattr.c b/dlls/mshtml/htmlattr.c
index bd0f6a2..d5446c6 100644
--- a/dlls/mshtml/htmlattr.c
+++ b/dlls/mshtml/htmlattr.c
@@ -80,7 +80,6 @@ static ULONG WINAPI HTMLDOMAttribute_Release(IHTMLDOMAttribute *iface)
 
     if(!ref) {
         assert(!This->elem);
-        nsIDOMAttr_Release(This->nsattr);
         release_dispex(&This->dispex);
         heap_free(This);
     }
@@ -136,27 +135,19 @@ static HRESULT WINAPI HTMLDOMAttribute_put_nodeName(IHTMLDOMAttribute *iface, VA
 static HRESULT WINAPI HTMLDOMAttribute_get_nodeValue(IHTMLDOMAttribute *iface, VARIANT *p)
 {
     HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface);
-    const PRUnichar *val;
-    nsAString val_str;
-    HRESULT hres = S_OK;
+    DISPPARAMS dp = {NULL, NULL, 0, 0};
+    EXCEPINFO ei;
 
     TRACE("(%p)->(%p)\n", This, p);
 
-    nsAString_Init(&val_str, NULL);
-    nsIDOMAttr_GetNodeValue(This->nsattr, &val_str);
-    nsAString_GetData(&val_str, &val);
-
-    V_VT(p) = VT_BSTR;
-    if(*val) {
-        V_BSTR(p) = SysAllocString(val);
-        if(!V_BSTR(p))
-            hres = E_OUTOFMEMORY;
-    }else {
-        V_BSTR(p) = NULL;
+    if(!This->elem) {
+        FIXME("NULL This->elem\n");
+        return E_UNEXPECTED;
     }
 
-    nsAString_Finish(&val_str);
-    return hres;
+    memset(&ei, 0, sizeof(ei));
+    return IDispatchEx_InvokeEx(&This->elem->node.dispex.IDispatchEx_iface, This->dispid, LOCALE_SYSTEM_DEFAULT,
+            DISPATCH_PROPERTYGET, &dp, p, &ei, NULL);
 }
 
 static HRESULT WINAPI HTMLDOMAttribute_get_specified(IHTMLDOMAttribute *iface, VARIANT_BOOL *p)
@@ -191,7 +182,7 @@ static dispex_static_data_t HTMLDOMAttribute_dispex = {
     HTMLDOMAttribute_iface_tids
 };
 
-HRESULT HTMLDOMAttribute_Create(HTMLElement *elem, nsIDOMAttr *nsattr, HTMLDOMAttribute **attr)
+HRESULT HTMLDOMAttribute_Create(HTMLElement *elem, DISPID dispid, HTMLDOMAttribute **attr)
 {
     HTMLDOMAttribute *ret;
 
@@ -202,9 +193,7 @@ HRESULT HTMLDOMAttribute_Create(HTMLElement *elem, nsIDOMAttr *nsattr, HTMLDOMAt
     ret->IHTMLDOMAttribute_iface.lpVtbl = &HTMLDOMAttributeVtbl;
     ret->ref = 1;
 
-    nsIDOMAttr_AddRef(nsattr);
-    ret->nsattr = nsattr;
-
+    ret->dispid = dispid;
     ret->elem = elem;
     list_add_tail(&elem->attrs, &ret->entry);
 
diff --git a/dlls/mshtml/htmlelem3.c b/dlls/mshtml/htmlelem3.c
index 02015e5..b23c5ad 100644
--- a/dlls/mshtml/htmlelem3.c
+++ b/dlls/mshtml/htmlelem3.c
@@ -557,43 +557,88 @@ static HRESULT WINAPI HTMLElement4_normalize(IHTMLElement4 *iface)
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI HTMLElement4_getAttributeNode(IHTMLElement4 *iface, BSTR bstrname, IHTMLDOMAttribute **ppAttribute)
+/* FIXME: This should be done in IDispatchEx implementation layer */
+static BOOL get_attr_from_nselem(HTMLElement *This, BSTR name, DISPID *dispid)
 {
-    HTMLElement *This = impl_from_IHTMLElement4(iface);
-    HTMLDOMAttribute *attr = NULL, *iter;
-    nsAString name_str;
+    const PRUnichar *v;
     nsIDOMAttr *nsattr;
+    nsAString nsstr;
+    BSTR val = NULL;
     nsresult nsres;
     HRESULT hres;
 
-    TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrname), ppAttribute);
+    nsAString_InitDepend(&nsstr, name);
+    nsres = nsIDOMHTMLElement_GetAttributeNode(This->nselem, &nsstr, &nsattr);
+    nsAString_Finish(&nsstr);
+    if(NS_FAILED(nsres) || !nsattr)
+        return FALSE;
+
+    FIXME("HACK\n");
 
-    nsAString_InitDepend(&name_str, bstrname);
-    nsres = nsIDOMHTMLElement_GetAttributeNode(This->nselem, &name_str, &nsattr);
-    nsAString_Finish(&name_str);
+    nsAString_Init(&nsstr, NULL);
+    nsres = nsIDOMAttr_GetNodeValue(nsattr, &nsstr);
     if(NS_FAILED(nsres)) {
-        ERR("GetAttributeNode failed: %08x\n", nsres);
-        return E_FAIL;
+        nsAString_Finish(&nsstr);
+        return FALSE;
     }
 
-    if(!nsattr) {
-        *ppAttribute = NULL;
-        return S_OK;
+    nsAString_GetData(&nsstr, &v);
+    if(*v) {
+        val = SysAllocString(v);
+        if(!val) {
+            nsAString_Finish(&nsstr);
+            return FALSE;
+        }
+    }
+    nsAString_Finish(&nsstr);
+
+    hres = IDispatchEx_GetDispID(&This->node.dispex.IDispatchEx_iface, name, fdexNameEnsure, dispid);
+    if(SUCCEEDED(hres)) {
+        VARIANT arg;
+        DISPPARAMS dp = {&arg, NULL, 1, 0};
+        EXCEPINFO ei;
+
+        V_VT(&arg) = VT_BSTR;
+        V_BSTR(&arg) = val;
+        memset(&ei, 0, sizeof(ei));
+        hres = IDispatchEx_InvokeEx(&This->node.dispex.IDispatchEx_iface, *dispid,
+                LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
+    }
+
+    SysFreeString(val);
+    return SUCCEEDED(hres);
+}
+
+static HRESULT WINAPI HTMLElement4_getAttributeNode(IHTMLElement4 *iface, BSTR bstrname, IHTMLDOMAttribute **ppAttribute)
+{
+    HTMLElement *This = impl_from_IHTMLElement4(iface);
+    HTMLDOMAttribute *attr = NULL, *iter;
+    DISPID dispid;
+    HRESULT hres;
+
+    TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrname), ppAttribute);
+
+    hres = IDispatchEx_GetDispID(&This->node.dispex.IDispatchEx_iface, bstrname, fdexNameCaseInsensitive, &dispid);
+    if(hres == DISP_E_UNKNOWNNAME) {
+        if(!get_attr_from_nselem(This, bstrname, &dispid)) {
+            *ppAttribute = NULL;
+            return S_OK;
+        }
+    }else if(FAILED(hres)) {
+        return hres;
     }
 
     LIST_FOR_EACH_ENTRY(iter, &This->attrs, HTMLDOMAttribute, entry) {
-        if(iter->nsattr == nsattr) {
+        if(iter->dispid == dispid) {
             attr = iter;
             break;
         }
     }
 
     if(!attr) {
-        hres = HTMLDOMAttribute_Create(This, nsattr, &attr);
-        if(FAILED(hres)) {
-            nsIDOMAttr_Release(nsattr);
+        hres = HTMLDOMAttribute_Create(This, dispid, &attr);
+        if(FAILED(hres))
             return hres;
-        }
     }
 
     IHTMLDOMAttribute_AddRef(&attr->IHTMLDOMAttribute_iface);
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index b39ad75..11ab878 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -749,13 +749,13 @@ typedef struct {
     IHTMLDOMAttribute IHTMLDOMAttribute_iface;
 
     LONG ref;
-    nsIDOMAttr *nsattr;
 
+    DISPID dispid;
     HTMLElement *elem;
     struct list entry;
 } HTMLDOMAttribute;
 
-HRESULT HTMLDOMAttribute_Create(HTMLElement*,nsIDOMAttr*,HTMLDOMAttribute**);
+HRESULT HTMLDOMAttribute_Create(HTMLElement*,DISPID,HTMLDOMAttribute**);
 
 HRESULT HTMLElement_Create(HTMLDocumentNode*,nsIDOMNode*,BOOL,HTMLElement**);
 HRESULT HTMLCommentElement_Create(HTMLDocumentNode*,nsIDOMNode*,HTMLElement**);




More information about the wine-cvs mailing list