Jacek Caban : mshtml: Added IHTMLElement::get_sourceIndex implementation.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Sep 16 14:36:42 CDT 2014


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Sep 16 20:20:02 2014 +0200

mshtml: Added IHTMLElement::get_sourceIndex implementation.

---

 dlls/mshtml/htmlelem.c       |  6 ++--
 dlls/mshtml/htmlelemcol.c    | 70 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/mshtml/mshtml_private.h |  1 +
 dlls/mshtml/tests/dom.c      | 60 ++++++++++++++++++++++++++++---------
 4 files changed, 121 insertions(+), 16 deletions(-)

diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
index 363a89a..3037c10 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -907,8 +907,10 @@ static HRESULT WINAPI HTMLElement_contains(IHTMLElement *iface, IHTMLElement *pC
 static HRESULT WINAPI HTMLElement_get_sourceIndex(IHTMLElement *iface, LONG *p)
 {
     HTMLElement *This = impl_from_IHTMLElement(iface);
-    FIXME("(%p)->(%p)\n", This, p);
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%p)\n", This, p);
+
+    return get_elem_source_index(This, p);
 }
 
 static HRESULT WINAPI HTMLElement_get_recordNumber(IHTMLElement *iface, VARIANT *p)
diff --git a/dlls/mshtml/htmlelemcol.c b/dlls/mshtml/htmlelemcol.c
index 8fd61ed..1542926 100644
--- a/dlls/mshtml/htmlelemcol.c
+++ b/dlls/mshtml/htmlelemcol.c
@@ -17,6 +17,7 @@
  */
 
 #include <stdarg.h>
+#include <assert.h>
 
 #define COBJMACROS
 
@@ -746,6 +747,75 @@ IHTMLElementCollection *create_collection_from_htmlcol(HTMLDocumentNode *doc, ns
     return HTMLElementCollection_Create(buf.buf, buf.len);
 }
 
+HRESULT get_elem_source_index(HTMLElement *elem, LONG *ret)
+{
+    elem_vector_t buf = {NULL, 0, 8};
+    nsIDOMNode *parent_node, *iter;
+    UINT16 parent_type;
+    HTMLDOMNode *node;
+    int i;
+    nsresult nsres;
+    HRESULT hres;
+
+    iter = elem->node.nsnode;
+    nsIDOMNode_AddRef(iter);
+
+    /* Find document or document fragment parent. */
+    while(1) {
+        nsres = nsIDOMNode_GetParentNode(iter, &parent_node);
+        nsIDOMNode_Release(iter);
+        assert(nsres == NS_OK);
+        if(!parent_node)
+            break;
+
+        nsres = nsIDOMNode_GetNodeType(parent_node, &parent_type);
+        assert(nsres == NS_OK);
+
+        if(parent_type != ELEMENT_NODE) {
+            if(parent_type != DOCUMENT_NODE && parent_type != DOCUMENT_FRAGMENT_NODE)
+                FIXME("Unexpected parent_type %d\n", parent_type);
+            break;
+        }
+
+        iter = parent_node;
+    }
+
+    if(!parent_node) {
+        *ret = -1;
+        return S_OK;
+    }
+
+    hres = get_node(elem->node.doc, parent_node, TRUE, &node);
+    nsIDOMNode_Release(parent_node);
+    if(FAILED(hres))
+        return hres;
+
+
+    /* Create all children collection and find the element in it.
+     * This could be optimized if we ever find the reason. */
+    buf.buf = heap_alloc(buf.size*sizeof(*buf.buf));
+    if(!buf.buf) {
+        IHTMLDOMNode_Release(&node->IHTMLDOMNode_iface);
+        return E_OUTOFMEMORY;
+    }
+
+    create_all_list(elem->node.doc, node, &buf);
+
+    for(i=0; i < buf.len; i++) {
+        if(buf.buf[i] == elem)
+            break;
+    }
+    IHTMLDOMNode_Release(&node->IHTMLDOMNode_iface);
+    heap_free(buf.buf);
+    if(i == buf.len) {
+        FIXME("The element is not in parent's child list?\n");
+        return E_UNEXPECTED;
+    }
+
+    *ret = i;
+    return S_OK;
+}
+
 static IHTMLElementCollection *HTMLElementCollection_Create(HTMLElement **elems, DWORD len)
 {
     HTMLElementCollection *ret = heap_alloc_zero(sizeof(HTMLElementCollection));
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 19e424f..78d61f0 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -961,6 +961,7 @@ HRESULT wrap_iface(IUnknown*,IUnknown*,IUnknown**) DECLSPEC_HIDDEN;
 IHTMLElementCollection *create_all_collection(HTMLDOMNode*,BOOL) DECLSPEC_HIDDEN;
 IHTMLElementCollection *create_collection_from_nodelist(HTMLDocumentNode*,nsIDOMNodeList*) DECLSPEC_HIDDEN;
 IHTMLElementCollection *create_collection_from_htmlcol(HTMLDocumentNode*,nsIDOMHTMLCollection*) DECLSPEC_HIDDEN;
+HRESULT get_elem_source_index(HTMLElement*,LONG*) DECLSPEC_HIDDEN;
 
 nsresult get_elem_attr_value(nsIDOMHTMLElement*,const WCHAR*,nsAString*,const PRUnichar**) DECLSPEC_HIDDEN;
 HRESULT elem_string_attr_getter(HTMLElement*,const WCHAR*,BOOL,BSTR*) DECLSPEC_HIDDEN;
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c
index 17f39ce..9f352f6 100644
--- a/dlls/mshtml/tests/dom.c
+++ b/dlls/mshtml/tests/dom.c
@@ -1142,6 +1142,17 @@ static void _test_elem_offset(unsigned line, IUnknown *unk, const char *parent_t
     IHTMLElement_Release(elem);
 }
 
+#define test_elem_source_index(a,b) _test_elem_source_index(__LINE__,a,b)
+static void _test_elem_source_index(unsigned line, IHTMLElement *elem, int index)
+{
+    LONG l = 0xdeadbeef;
+    HRESULT hres;
+
+    hres = IHTMLElement_get_sourceIndex(elem, &l);
+    ok_(__FILE__,line)(hres == S_OK, "get_sourceIndex failed: %08x\n", hres);
+    ok_(__FILE__,line)(l == index, "sourceIndex = %d, expected %d\n", l, index);
+}
+
 #define get_doc_node(d) _get_doc_node(__LINE__,d)
 static IHTMLDocument2 *_get_doc_node(unsigned line, IHTMLDocument2 *doc)
 {
@@ -2105,6 +2116,26 @@ static void _test_range_parent(unsigned line, IHTMLTxtRange *range, elem_type_t
     IHTMLElement_Release(elem);
 }
 
+#define get_elem_col_item_idx(a,b) _get_elem_col_item_idx(__LINE__,a,b)
+static IHTMLElement *_get_elem_col_item_idx(unsigned line, IHTMLElementCollection *col, int i)
+{
+    VARIANT name, index;
+    IHTMLElement *elem;
+    IDispatch *disp;
+    HRESULT hres;
+
+    V_VT(&index) = VT_EMPTY;
+    V_VT(&name) = VT_I4;
+    V_I4(&name) = i;
+    hres = IHTMLElementCollection_item(col, name, index, &disp);
+    ok_(__FILE__,line)(hres == S_OK, "item failed: %08x\n", hres);
+    ok_(__FILE__,line)(disp != NULL, "disp == NULL\n");
+
+    elem = _get_elem_iface(line, (IUnknown*)disp);
+    IDispatch_Release(disp);
+    return elem;
+}
+
 #define test_elem_collection(c,t,l) _test_elem_collection(__LINE__,c,t,l)
 static void _test_elem_collection(unsigned line, IUnknown *unk,
         const elem_type_t *elem_types, LONG exlen)
@@ -2290,20 +2321,8 @@ static void _test_elem_getelembytag(unsigned line, IUnknown *unk, elem_type_t ty
 
     HeapFree(GetProcessHeap(), 0, types);
 
-    if(ret) {
-        IDispatch *disp;
-        VARIANT v;
-
-        V_VT(&v) = VT_I4;
-        V_I4(&v) = 0;
-        disp = NULL;
-        hres = IHTMLElementCollection_item(col, v, v, &disp);
-        ok(hres == S_OK, "item failed: %08x\n", hres);
-        ok(disp != NULL, "disp == NULL\n");
-        *ret = _get_elem_iface(line, (IUnknown*)disp);
-        IDispatch_Release(disp);
-    }
-
+    if(ret)
+        *ret = get_elem_col_item_idx(col, 0);
     IHTMLElementCollection_Release(col);
 }
 
@@ -6909,6 +6928,15 @@ static void test_elems(IHTMLDocument2 *doc)
     ok(hres == S_OK, "get_all failed: %08x\n", hres);
     test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
     test_elem_col_item(col, "x", item_types, sizeof(item_types)/sizeof(item_types[0]));
+
+    elem = get_elem_col_item_idx(col, 0);
+    test_elem_source_index(elem, 0);
+    IHTMLElement_Release(elem);
+
+    elem = get_elem_col_item_idx(col, 3);
+    test_elem_source_index(elem, 3);
+    IHTMLElement_Release(elem);
+
     IHTMLElementCollection_Release(col);
 
     hres = IHTMLDocument2_get_images(doc, &collection);
@@ -7012,6 +7040,7 @@ static void test_elems(IHTMLDocument2 *doc)
 
         elem2 = test_elem_get_parent((IUnknown*)elem3);
         ok(elem2 == NULL, "elem2 != NULL\n");
+        test_elem_source_index(elem3, 0);
         IHTMLElement_Release(elem3);
 
         test_elem_getelembytag((IUnknown*)elem, ET_OPTION, 2, NULL);
@@ -7737,6 +7766,7 @@ static void test_create_elems(IHTMLDocument2 *doc)
     ok(type == 1, "type=%d\n", type);
     test_ifaces((IUnknown*)elem, elem_iids);
     test_disp((IUnknown*)elem, &DIID_DispHTMLGenericElement, "[object]");
+    test_elem_source_index(elem, -1);
 
     body = doc_get_body(doc);
     test_node_has_child((IUnknown*)body, VARIANT_FALSE);
@@ -8333,7 +8363,9 @@ static void test_docfrag(IHTMLDocument2 *doc)
     ok(location == (void*)0xdeadbeef, "location changed\n");
 
     br = test_create_elem(doc, "BR");
+    test_elem_source_index(br, -1);
     test_node_append_child((IUnknown*)frag, (IUnknown*)br);
+    test_elem_source_index(br, 0);
     IHTMLElement_Release(br);
 
     div = get_elem_by_id(doc, "divid", TRUE);




More information about the wine-cvs mailing list