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