Commit a42cffbd authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

mshtml: Added support for accessing document elements by index.

parent 0f8b64a5
......@@ -1557,6 +1557,64 @@ static inline HTMLDocument *impl_from_IDispatchEx(IDispatchEx *iface)
return CONTAINING_RECORD(iface, HTMLDocument, IDispatchEx_iface);
}
static HRESULT dispid_from_elem_name(HTMLDocumentNode *This, BSTR name, DISPID *dispid)
{
nsIDOMNodeList *node_list;
nsAString name_str;
PRUint32 len;
unsigned i;
nsresult nsres;
if(!This->nsdoc)
return DISP_E_UNKNOWNNAME;
nsAString_InitDepend(&name_str, name);
nsres = nsIDOMHTMLDocument_GetElementsByName(This->nsdoc, &name_str, &node_list);
nsAString_Finish(&name_str);
if(NS_FAILED(nsres))
return E_FAIL;
nsres = nsIDOMNodeList_GetLength(node_list, &len);
nsIDOMNodeList_Release(node_list);
if(NS_FAILED(nsres))
return E_FAIL;
if(!len)
return DISP_E_UNKNOWNNAME;
for(i=0; i < This->elem_vars_cnt; i++) {
if(!strcmpW(name, This->elem_vars[i])) {
*dispid = MSHTML_DISPID_CUSTOM_MIN+i;
return S_OK;
}
}
if(This->elem_vars_cnt == This->elem_vars_size) {
WCHAR **new_vars;
if(This->elem_vars_size) {
new_vars = heap_realloc(This->elem_vars, This->elem_vars_size*2*sizeof(WCHAR*));
if(!new_vars)
return E_OUTOFMEMORY;
This->elem_vars_size *= 2;
}else {
new_vars = heap_alloc(16*sizeof(WCHAR*));
if(!new_vars)
return E_OUTOFMEMORY;
This->elem_vars_size = 16;
}
This->elem_vars = new_vars;
}
This->elem_vars[This->elem_vars_cnt] = heap_strdupW(name);
if(!This->elem_vars[This->elem_vars_cnt])
return E_OUTOFMEMORY;
*dispid = MSHTML_DISPID_CUSTOM_MIN+This->elem_vars_cnt++;
return S_OK;
}
static HRESULT WINAPI DocDispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
{
HTMLDocument *This = impl_from_IDispatchEx(iface);
......@@ -1630,8 +1688,13 @@ static HRESULT WINAPI DocDispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMemb
static HRESULT WINAPI DocDispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
{
HTMLDocument *This = impl_from_IDispatchEx(iface);
HRESULT hres;
return IDispatchEx_GetDispID(This->dispex, bstrName, grfdex, pid);
hres = IDispatchEx_GetDispID(This->dispex, bstrName, grfdex, pid);
if(hres != DISP_E_UNKNOWNNAME)
return hres;
return dispid_from_elem_name(This->doc_node, bstrName, pid);
}
static HRESULT WINAPI DocDispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
......@@ -1905,6 +1968,11 @@ static HRESULT HTMLDocumentNode_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
static void HTMLDocumentNode_destructor(HTMLDOMNode *iface)
{
HTMLDocumentNode *This = impl_from_HTMLDOMNode(iface);
unsigned i;
for(i=0; i < This->elem_vars_cnt; i++)
heap_free(This->elem_vars[i]);
heap_free(This->elem_vars);
if(This->body_event_target)
release_event_target(This->body_event_target);
......@@ -1956,6 +2024,61 @@ static HRESULT HTMLDocumentFragment_clone(HTMLDOMNode *iface, nsIDOMNode *nsnode
return S_OK;
}
static inline HTMLDocumentNode *impl_from_DispatchEx(DispatchEx *iface)
{
return CONTAINING_RECORD(iface, HTMLDocumentNode, node.dispex);
}
static HRESULT HTMLDocumentNode_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
{
HTMLDocumentNode *This = impl_from_DispatchEx(dispex);
nsIDOMNodeList *node_list;
nsAString name_str;
nsIDOMNode *nsnode;
HTMLDOMNode *node;
unsigned i;
nsresult nsres;
HRESULT hres;
if(flags != DISPATCH_PROPERTYGET) {
FIXME("unsupported flags %x\n", flags);
return E_NOTIMPL;
}
i = id - MSHTML_DISPID_CUSTOM_MIN;
if(!This->nsdoc || i >= This->elem_vars_cnt)
return DISP_E_UNKNOWNNAME;
nsAString_InitDepend(&name_str, This->elem_vars[i]);
nsres = nsIDOMHTMLDocument_GetElementsByName(This->nsdoc, &name_str, &node_list);
nsAString_Finish(&name_str);
if(NS_FAILED(nsres))
return E_FAIL;
nsres = nsIDOMNodeList_Item(node_list, 0, &nsnode);
nsIDOMNodeList_Release(node_list);
if(NS_FAILED(nsres) || !nsnode)
return DISP_E_UNKNOWNNAME;
hres = get_node(This, nsnode, TRUE, &node);
if(FAILED(hres))
return hres;
IHTMLDOMNode_AddRef(&node->IHTMLDOMNode_iface);
V_VT(res) = VT_DISPATCH;
V_DISPATCH(res) = (IDispatch*)&node->IHTMLDOMNode_iface;
return S_OK;
}
static const dispex_static_data_vtbl_t HTMLDocumentNode_dispex_vtbl = {
NULL,
NULL,
HTMLDocumentNode_invoke
};
static const NodeImplVtbl HTMLDocumentFragmentImplVtbl = {
HTMLDocumentNode_QI,
HTMLDocumentNode_destructor,
......@@ -1973,7 +2096,7 @@ static const tid_t HTMLDocumentNode_iface_tids[] = {
};
static dispex_static_data_t HTMLDocumentNode_dispex = {
NULL,
&HTMLDocumentNode_dispex_vtbl,
DispHTMLDocument_tid,
NULL,
HTMLDocumentNode_iface_tids
......
......@@ -623,6 +623,10 @@ struct HTMLDocumentNode {
nsDocumentEventListener *nsevent_listener;
BOOL *event_vector;
WCHAR **elem_vars;
unsigned elem_vars_size;
unsigned elem_vars_cnt;
BOOL skip_mutation_notif;
struct list bindings;
......
......@@ -43,6 +43,25 @@ function test_createDocumentFragment() {
ok(cloned.nodeName === "#document-fragment", "cloned.nodeName = " + cloned.nodeName);
}
function test_document_name_as_index() {
document.body.innerHTML = '<form name="formname"></form>';
var e = document.getElementById("formname");
ok(!!e, "e is null");
ok(document.formname === e, "document.formname != getElementById('formname')");
ok("formname" in document, "formname' is not in document");
document.body.removeChild(e);
ok(document.formname === undefined, "document.formname is not undefined");
ok(!("formname" in document), "formname' is in document");
document.body.innerHTML = '<form id="formid"></form>';
var e = document.getElementById("formid");
ok(!!e, "e is null");
ok(!("formid" in document), "formid is in document");
}
var globalVar = false;
function runTest() {
......@@ -55,6 +74,7 @@ function runTest() {
test_removeAttribute(document.body);
test_select_index();
test_createDocumentFragment();
test_document_name_as_index();
var r = window.execScript("globalVar = true;");
ok(r === undefined, "execScript returned " + r);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment