Module: wine Branch: master Commit: 73d4d172d5685c6694fa88d512f51eee6061217c URL: http://source.winehq.org/git/wine.git/?a=commit;h=73d4d172d5685c6694fa88d512...
Author: Jacek Caban jacek@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>