mshtml: Added support for accessing document elements by index.
This commit is contained in:
parent
0f8b64a57b
commit
a42cffbdcc
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue