Jacek Caban : mshtml: Added support for accessing select options by index.

Alexandre Julliard julliard at winehq.org
Thu Apr 29 14:45:07 CDT 2010


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Apr 29 18:29:23 2010 +0200

mshtml: Added support for accessing select options by index.

---

 dlls/mshtml/htmlselect.c      |   80 ++++++++++++++++++++++++++++++++++++++++-
 dlls/mshtml/mshtml_private.h  |    1 +
 dlls/mshtml/nsiface.idl       |   15 +++++++-
 dlls/mshtml/tests/jstest.html |   16 ++++++++
 4 files changed, 110 insertions(+), 2 deletions(-)

diff --git a/dlls/mshtml/htmlselect.c b/dlls/mshtml/htmlselect.c
index 20f11ee..ee5d214 100644
--- a/dlls/mshtml/htmlselect.c
+++ b/dlls/mshtml/htmlselect.c
@@ -504,6 +504,80 @@ static HRESULT HTMLSelectElementImpl_get_disabled(HTMLDOMNode *iface, VARIANT_BO
     return IHTMLSelectElement_get_disabled(HTMLSELECT(This), p);
 }
 
+#define DISPID_OPTIONCOL_0 MSHTML_DISPID_CUSTOM_MIN
+
+static HRESULT HTMLSelectElement_get_dispid(HTMLDOMNode *iface, BSTR name, DWORD flags, DISPID *dispid)
+{
+    const WCHAR *ptr;
+    DWORD idx = 0;
+
+    for(ptr = name; *ptr && isdigitW(*ptr); ptr++) {
+        idx = idx*10 + (*ptr-'0');
+        if(idx > MSHTML_CUSTOM_DISPID_CNT) {
+            WARN("too big idx\n");
+            return DISP_E_UNKNOWNNAME;
+        }
+    }
+    if(*ptr)
+        return DISP_E_UNKNOWNNAME;
+
+    *dispid = DISPID_OPTIONCOL_0 + idx;
+    return S_OK;
+}
+
+static HRESULT HTMLSelectElement_invoke(HTMLDOMNode *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
+        VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
+{
+    HTMLSelectElement *This = HTMLSELECT_NODE_THIS(iface);
+
+    TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, flags, params, res, ei, caller);
+
+    switch(flags) {
+    case DISPATCH_PROPERTYGET: {
+        nsIDOMHTMLOptionsCollection *nscol;
+        nsIDOMNode *nsnode;
+        nsresult nsres;
+
+        nsres = nsIDOMHTMLSelectElement_GetOptions(This->nsselect, &nscol);
+        if(NS_FAILED(nsres)) {
+            ERR("GetOptions failed: %08x\n", nsres);
+            return E_FAIL;
+        }
+
+        nsres = nsIDOMHTMLOptionsCollection_Item(nscol, id-DISPID_OPTIONCOL_0, &nsnode);
+        nsIDOMHTMLOptionsCollection_Release(nscol);
+        if(NS_FAILED(nsres)) {
+            ERR("Item failed: %08x\n", nsres);
+            return E_FAIL;
+        }
+
+        if(nsnode) {
+            HTMLDOMNode *node;
+
+            node = get_node(This->element.node.doc, nsnode, TRUE);
+            nsIDOMNode_Release(nsnode);
+            if(!node) {
+                ERR("Could not find node\n");
+                return E_FAIL;
+            }
+
+            IHTMLDOMNode_AddRef(HTMLDOMNODE(node));
+            V_VT(res) = VT_DISPATCH;
+            V_DISPATCH(res) = (IDispatch*)HTMLDOMNODE(node);
+        }else {
+            V_VT(res) = VT_NULL;
+        }
+        break;
+    }
+
+    default:
+        FIXME("unimplemented flags %x\n", flags);
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
+}
+
 #undef HTMLSELECT_NODE_THIS
 
 static const NodeImplVtbl HTMLSelectElementImplVtbl = {
@@ -512,7 +586,11 @@ static const NodeImplVtbl HTMLSelectElementImplVtbl = {
     NULL,
     NULL,
     HTMLSelectElementImpl_put_disabled,
-    HTMLSelectElementImpl_get_disabled
+    HTMLSelectElementImpl_get_disabled,
+    NULL,
+    NULL,
+    HTMLSelectElement_get_dispid,
+    HTMLSelectElement_invoke
 };
 
 static const tid_t HTMLSelectElement_tids[] = {
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index c88b3e5..4deb4d6 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -144,6 +144,7 @@ typedef struct dispex_dynamic_data_t dispex_dynamic_data_t;
 
 #define MSHTML_DISPID_CUSTOM_MIN 0x60000000
 #define MSHTML_DISPID_CUSTOM_MAX 0x6fffffff
+#define MSHTML_CUSTOM_DISPID_CNT (MSHTML_DISPID_CUSTOM_MAX-MSHTML_DISPID_CUSTOM_MIN)
 
 typedef struct {
     HRESULT (*value)(IUnknown*,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*);
diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl
index 66ab8e6..4ccc64a 100644
--- a/dlls/mshtml/nsiface.idl
+++ b/dlls/mshtml/nsiface.idl
@@ -119,7 +119,6 @@ typedef nsISupports nsIDOMDOMImplementation;
 typedef nsISupports nsIDOMCDATASection;
 typedef nsISupports nsIDOMProcessingInstruction;
 typedef nsISupports nsIDOMEntityReference;
-typedef nsISupports nsIDOMHTMLOptionsCollection;
 typedef nsISupports nsIWebProgressListener;
 typedef nsISupports nsIDOMCSSValue;
 typedef nsISupports nsIPrintSession;
@@ -1321,6 +1320,20 @@ interface nsIDOMHTMLOptionElement : nsIDOMHTMLElement
 
 [
     object,
+    uuid(bce0213c-f70f-488f-b93f-688acca55d63),
+    local
+    /* FROZEN */
+]
+interface nsIDOMHTMLOptionsCollection : nsISupports
+{
+    nsresult GetLength(PRUint32 *aLength);
+    nsresult SetLength(PRUint32 aLength);
+    nsresult Item(PRUint32 index, nsIDOMNode **_retval);
+    nsresult NamedItem(const nsAString *name, nsIDOMNode **_retval);
+}
+
+[
+    object,
     uuid(a6cf9090-15b3-11d2-932e-00805f8add32),
     local
     /* FROZEN */
diff --git a/dlls/mshtml/tests/jstest.html b/dlls/mshtml/tests/jstest.html
index 6192f81..3363c5a 100644
--- a/dlls/mshtml/tests/jstest.html
+++ b/dlls/mshtml/tests/jstest.html
@@ -20,6 +20,17 @@ function test_removeAttribute(e) {
 
 }
 
+function test_select_index() {
+    var s = document.getElementById("sel");
+
+    ok("0" in s, "'0' is not in s");
+    ok(s[0].text === "opt1", "s[0].text = " + s[0].text);
+    ok("1" in s, "'1 is not in s");
+    ok(s[1].text === "opt2", "s[1].text = " + s[1].text);
+    ok("2" in s, "'2' is in s");
+    ok(s[2] === null, "s[2] = " + s[2]);
+}
+
 function runTest() {
     obj = new Object();
     ok(obj === window.obj, "obj !== window.obj");
@@ -28,11 +39,16 @@ function runTest() {
 
     test_removeAttribute(document.getElementById("divid"));
     test_removeAttribute(document.body);
+    test_select_index();
 
     external.reportSuccess();
 }
 </script>
 <body onload="runTest();">
 <div id="divid"></div>
+<select id="sel">
+<option>opt1</option>
+<option>opt2</option>
+</select>
 </body>
 </html>




More information about the wine-cvs mailing list