mshtml: Added support for accessing select options by index.

This commit is contained in:
Jacek Caban 2010-04-29 18:29:23 +02:00 committed by Alexandre Julliard
parent 21d7f6a7e6
commit 73d4d172d5
4 changed files with 110 additions and 2 deletions

View File

@ -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[] = {

View File

@ -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*);

View File

@ -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;
@ -1319,6 +1318,20 @@ interface nsIDOMHTMLOptionElement : nsIDOMHTMLElement
nsresult SetValue(const nsAString *aValue);
}
[
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),

View File

@ -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>