Jacek Caban : mshtml: Added IHTMLDocument3:: getElementsByName implementation.

Alexandre Julliard julliard at winehq.org
Mon Nov 18 14:51:39 CST 2013


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Sat Nov 16 15:50:15 2013 +0100

mshtml: Added IHTMLDocument3::getElementsByName implementation.

---

 dlls/mshtml/htmldoc3.c  |   39 ++++++++++++++++++++++++++++-
 dlls/mshtml/tests/dom.c |   61 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 98 insertions(+), 2 deletions(-)

diff --git a/dlls/mshtml/htmldoc3.c b/dlls/mshtml/htmldoc3.c
index de5cdab..9637e99 100644
--- a/dlls/mshtml/htmldoc3.c
+++ b/dlls/mshtml/htmldoc3.c
@@ -536,8 +536,43 @@ static HRESULT WINAPI HTMLDocument3_getElementsByName(IHTMLDocument3 *iface, BST
                                                       IHTMLElementCollection **ppelColl)
 {
     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
-    FIXME("(%p)->(%s %p)\n", This, debugstr_w(v), ppelColl);
-    return E_NOTIMPL;
+    nsIDOMNodeList *node_list;
+    nsAString selector_str;
+    WCHAR *selector;
+    nsresult nsres;
+
+    static const WCHAR formatW[] = {'*','[','i','d','=','%','s',']',',','*','[','n','a','m','e','=','%','s',']',0};
+
+    TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), ppelColl);
+
+    if(!This->doc_node || !This->doc_node->nsdoc) {
+        /* We should probably return an empty collection. */
+        FIXME("No nsdoc\n");
+        return E_NOTIMPL;
+    }
+
+    selector = heap_alloc(2*SysStringLen(v)*sizeof(WCHAR) + sizeof(formatW));
+    if(!selector)
+        return E_OUTOFMEMORY;
+    sprintfW(selector, formatW, v, v);
+
+    /*
+     * NOTE: IE getElementsByName implementation differs from Gecko. It searches both name and id attributes.
+     * That's why we use CSS selector instead. We should also use name only when it applies to given element
+     * types and search should be case insensitive. Those are currently not supported properly.
+     */
+    nsAString_InitDepend(&selector_str, selector);
+    nsres = nsIDOMNodeSelector_QuerySelectorAll(This->doc_node->nsnode_selector, &selector_str, &node_list);
+    nsAString_Finish(&selector_str);
+    heap_free(selector);
+    if(NS_FAILED(nsres)) {
+        ERR("QuerySelectorAll failed: %08x\n", nsres);
+        return E_FAIL;
+    }
+
+    *ppelColl = create_collection_from_nodelist(This->doc_node, node_list);
+    nsIDOMNodeList_Release(node_list);
+    return S_OK;
 }
 
 
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c
index cf72873..6e6b01a 100644
--- a/dlls/mshtml/tests/dom.c
+++ b/dlls/mshtml/tests/dom.c
@@ -759,6 +759,18 @@ static IHTMLElement4 *_get_elem4_iface(unsigned line, IUnknown *unk)
     return elem;
 }
 
+#define get_doc3_iface(u) _get_doc3_iface(__LINE__,u)
+static IHTMLDocument3 *_get_doc3_iface(unsigned line, IHTMLDocument2 *doc)
+{
+    IHTMLDocument3 *doc3;
+    HRESULT hres;
+
+    hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
+    ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3 interface: %08x\n", hres);
+
+    return doc3;
+}
+
 #define get_node_iface(u) _get_node_iface(__LINE__,u)
 static IHTMLDOMNode *_get_node_iface(unsigned line, IUnknown *unk)
 {
@@ -6737,6 +6749,54 @@ static void test_blocked(IHTMLDocument2 *doc, IHTMLElement *outer_elem)
     }
 }
 
+#define doc_get_elems_by_name(a,b) _doc_get_elems_by_name(__LINE__,a,b)
+static IHTMLElementCollection *_doc_get_elems_by_name(unsigned line, IHTMLDocument2 *doc, const char *name)
+{
+    IHTMLDocument3 *doc3 = _get_doc3_iface(line, doc);
+    IHTMLElementCollection *col;
+    BSTR str = a2bstr(name);
+    HRESULT hres;
+
+    hres = IHTMLDocument3_getElementsByName(doc3, str, &col);
+    ok_(__FILE__,line)(hres == S_OK, "getElementsByName failed: %08x\n", hres);
+    ok_(__FILE__,line)(col != NULL, "col = NULL\n");
+
+    IHTMLDocument3_Release(doc3);
+    SysFreeString(str);
+    return col;
+}
+
+static void test_elem_names(IHTMLDocument2 *doc)
+{
+    IHTMLElementCollection *col;
+    IHTMLElement *body;
+    LONG len;
+    HRESULT hres;
+
+    static const elem_type_t test1_types[] = {ET_INPUT, ET_A, ET_DIV};
+
+    body = doc_get_body(doc);
+
+    test_elem_set_innerhtml((IUnknown*)body,
+            "<input name=\"test\"><a name=\"test\"></a><a name=\"xxx\"></a><div id=\"test\"></div>");
+    col = doc_get_elems_by_name(doc, "test");
+    test_elem_collection((IUnknown*)col, test1_types, sizeof(test1_types)/sizeof(*test1_types));
+    IHTMLElementCollection_Release(col);
+
+    col = doc_get_elems_by_name(doc, "yyy");
+    test_elem_collection((IUnknown*)col, NULL, 0);
+    IHTMLElementCollection_Release(col);
+
+    /* case insensivity test */
+    col = doc_get_elems_by_name(doc, "Xxx");
+    hres = IHTMLElementCollection_get_length(col, &len);
+    ok(hres == S_OK, "get_length failed: %08x\n", hres);
+    todo_wine ok(len == 1, "len = %d\n", len);
+    IHTMLElementCollection_Release(col);
+
+    IHTMLElement_Release(body);
+}
+
 static void test_elems2(IHTMLDocument2 *doc)
 {
     IHTMLElement *elem, *elem2, *div;
@@ -6825,6 +6885,7 @@ static void test_elems2(IHTMLDocument2 *doc)
 
     test_attr(div);
     test_blocked(doc, div);
+    test_elem_names(doc);
 
     IHTMLElement_Release(div);
 }




More information about the wine-cvs mailing list