Andrew Eikum : mshtml: Also search by node name attribute in IHTMLDocument3 ::getElementById.

Alexandre Julliard julliard at winehq.org
Mon Nov 23 08:49:48 CST 2009


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

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Fri Nov 20 17:04:58 2009 -0600

mshtml: Also search by node name attribute in IHTMLDocument3::getElementById.

---

 dlls/mshtml/htmldoc3.c  |   58 +++++++++++++++++++++++++++++++++++++++++++---
 dlls/mshtml/nsiface.idl |   33 ++++++++++++++++++++++++++
 dlls/mshtml/tests/dom.c |    9 ++++++-
 3 files changed, 95 insertions(+), 5 deletions(-)

diff --git a/dlls/mshtml/htmldoc3.c b/dlls/mshtml/htmldoc3.c
index a00fa95..b930d88 100644
--- a/dlls/mshtml/htmldoc3.c
+++ b/dlls/mshtml/htmldoc3.c
@@ -431,6 +431,8 @@ static HRESULT WINAPI HTMLDocument3_getElementById(IHTMLDocument3 *iface, BSTR v
     HTMLDocument *This = HTMLDOC3_THIS(iface);
     nsIDOMElement *nselem;
     HTMLDOMNode *node;
+    nsIDOMNode *nsnode, *nsnode_by_id, *nsnode_by_name;
+    nsIDOMNodeList *nsnode_list;
     nsAString id_str;
     nsresult nsres;
 
@@ -442,16 +444,64 @@ static HRESULT WINAPI HTMLDocument3_getElementById(IHTMLDocument3 *iface, BSTR v
     }
 
     nsAString_Init(&id_str, v);
+    /* get element by id attribute */
     nsres = nsIDOMHTMLDocument_GetElementById(This->doc_node->nsdoc, &id_str, &nselem);
-    nsAString_Finish(&id_str);
     if(FAILED(nsres)) {
         ERR("GetElementById failed: %08x\n", nsres);
+        nsAString_Finish(&id_str);
         return E_FAIL;
     }
+    nsnode_by_id = (nsIDOMNode*)nselem;
 
-    if(nselem) {
-        node = get_node(This->doc_node, (nsIDOMNode*)nselem, TRUE);
-        nsIDOMElement_Release(nselem);
+    /* get first element by name attribute */
+    nsres = nsIDOMHTMLDocument_GetElementsByName(This->doc_node->nsdoc, &id_str, &nsnode_list);
+    if(FAILED(nsres)) {
+        ERR("getElementsByName failed: %08x\n", nsres);
+        nsAString_Finish(&id_str);
+        if(nsnode_by_id)
+            nsIDOMNode_Release(nsnode_by_id);
+        return E_FAIL;
+    }
+    nsIDOMNodeList_Item(nsnode_list, 0, &nsnode_by_name);
+    nsIDOMNodeList_Release(nsnode_list);
+
+    nsAString_Finish(&id_str);
+
+    if(nsnode_by_name && nsnode_by_id) {
+        nsIDOM3Node *node3;
+        PRUint16 pos;
+
+        nsres = nsIDOMNode_QueryInterface(nsnode_by_name, &IID_nsIDOM3Node, (void**)&node3);
+        if(NS_FAILED(nsres)) {
+            FIXME("failed to get nsIDOM3Node interface: 0x%08x\n", nsres);
+            nsIDOMNode_Release(nsnode_by_name);
+            nsIDOMNode_Release(nsnode_by_id);
+            return E_FAIL;
+        }
+
+        nsres = nsIDOM3Node_CompareDocumentPosition(node3, nsnode_by_id, &pos);
+        nsIDOM3Node_Release(node3);
+        if(NS_FAILED(nsres)) {
+            FIXME("nsIDOM3Node_CompareDocumentPosition failed: 0x%08x\n", nsres);
+            nsIDOMNode_Release(nsnode_by_name);
+            nsIDOMNode_Release(nsnode_by_id);
+            return E_FAIL;
+        }
+
+        TRACE("CompareDocumentPosition gave: 0x%x\n", pos);
+        if(pos & PRECEDING || pos & CONTAINS) {
+            nsnode = nsnode_by_id;
+            nsIDOMNode_Release(nsnode_by_name);
+        }else {
+            nsnode = nsnode_by_name;
+            nsIDOMNode_Release(nsnode_by_id);
+        }
+    }else
+        nsnode = nsnode_by_name ? nsnode_by_name : nsnode_by_id;
+
+    if(nsnode) {
+        node = get_node(This->doc_node, nsnode, TRUE);
+        nsIDOMNode_Release(nsnode);
 
         IHTMLDOMNode_QueryInterface(HTMLDOMNODE(node), &IID_IHTMLElement, (void**)pel);
     }else {
diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl
index 19f29b0..9d0bb30 100644
--- a/dlls/mshtml/nsiface.idl
+++ b/dlls/mshtml/nsiface.idl
@@ -140,6 +140,8 @@ typedef nsISupports nsIContent;
 typedef nsISupports nsINode;
 typedef nsISupports nsIStyleSheet;
 typedef nsISupports nsIStyleRule;
+typedef nsISupports nsIVariant;
+typedef nsISupports nsIDOMUserDataHandler;
 
 [
     object,
@@ -603,6 +605,37 @@ interface nsIDOMNodeList : nsISupports
 
 [
     object,
+    uuid(29fb2a18-1dd2-11b2-8dd9-a6fd5d5ad12f),
+    local
+    /* NOT_FROZEN */
+]
+interface nsIDOM3Node : nsISupports
+{
+    enum NSDOCPOSITION {
+        DISCONNECTED = 1,
+        PRECEDING = 2,
+        FOLLOWING = 4,
+        CONTAINS = 8,
+        CONTAINED_BY = 16,
+        IMPLEMENTATION_SPECIFIC = 32
+    };
+
+    nsresult GetBaseURI(nsAString *aBaseURI);
+    nsresult CompareDocumentPosition(nsIDOMNode *other, PRUint16 *_retval);
+    nsresult GetTextContent(nsAString *aTextContent);
+    nsresult SetTextContent(const nsAString *aTextContent);
+    nsresult IsSameNode(nsIDOMNode *other, PRBool *_retval);
+    nsresult LookupPrefix(const nsAString *namespaceURI, PRBool *_retval);
+    nsresult IsDefaultNamespace(const nsAString *namespaceURI, PRBool *_retval);
+    nsresult LookupNamespaceURI(const nsAString *prefix, nsAString _retval);
+    nsresult IsEqualNode(nsIDOMNode *arg, PRBool *_retval);
+    nsresult GetFeature(const nsAString *feature, const nsAString *version, nsISupports **_retval);
+    nsresult SetUserData(const nsAString *key, nsIVariant *data, nsIDOMUserDataHandler *handler, nsIVariant **_retval);
+    nsresult GetUserData(const nsAString *key, nsIVariant **_retval);
+}
+
+[
+    object,
     uuid(a6cf907c-15b3-11d2-932e-00805f8add32),
     local
     /* FROZEN */
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c
index 8681164..bd55c9f 100644
--- a/dlls/mshtml/tests/dom.c
+++ b/dlls/mshtml/tests/dom.c
@@ -65,7 +65,7 @@ static const char cond_comment_str[] =
     "</body></html>";
 static const char frameset_str[] =
     "<html><head><title>frameset test</title></head><frameset rows=\"28, *\">"
-    "<frame src=\"about:blank\" id=\"fr1\"><frame src=\"about:blank\" id=\"fr2\">"
+    "<frame src=\"about:blank\" name=\"nm1\" id=\"fr1\"><frame src=\"about:blank\" name=\"nm2\" id=\"fr2\">"
     "</frameset></html>";
 
 static WCHAR characterW[] = {'c','h','a','r','a','c','t','e','r',0};
@@ -5396,6 +5396,7 @@ static void test_elems(IHTMLDocument2 *doc)
     ok(!node, "node = %p\n", node);
 
     elem2 = get_doc_elem_by_id(doc, "x");
+    test_elem_tag((IUnknown*)elem2, "A");
     node = node_get_next((IUnknown*)elem2);
     IHTMLDOMNode_Release(node);
     IHTMLElement_Release(elem2);
@@ -5682,6 +5683,7 @@ static void test_frameset(IHTMLDocument2 *doc)
 {
     IHTMLWindow2 *window;
     IHTMLFramesCollection2 *frames;
+    IHTMLElement *elem;
     LONG length;
     VARIANT index_var, result_var;
     HRESULT hres;
@@ -5805,6 +5807,11 @@ static void test_frameset(IHTMLDocument2 *doc)
     ok(hres == E_INVALIDARG, "IHTMLWindow2_item should have"
            "failed with E_INVALIDARG, instead: 0x%08x\n", hres);
     VariantClear(&result_var);
+
+    /* getElementById with node name attributes */
+    elem = get_doc_elem_by_id(doc, "nm1");
+    test_elem_id((IUnknown*)elem, "fr1");
+    IHTMLElement_Release(elem);
 }
 
 static IHTMLDocument2 *notif_doc;




More information about the wine-cvs mailing list