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);
|
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)
|
static HRESULT WINAPI DocDispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
|
||||||
{
|
{
|
||||||
HTMLDocument *This = impl_from_IDispatchEx(iface);
|
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)
|
static HRESULT WINAPI DocDispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
|
||||||
{
|
{
|
||||||
HTMLDocument *This = impl_from_IDispatchEx(iface);
|
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,
|
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)
|
static void HTMLDocumentNode_destructor(HTMLDOMNode *iface)
|
||||||
{
|
{
|
||||||
HTMLDocumentNode *This = impl_from_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)
|
if(This->body_event_target)
|
||||||
release_event_target(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;
|
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 = {
|
static const NodeImplVtbl HTMLDocumentFragmentImplVtbl = {
|
||||||
HTMLDocumentNode_QI,
|
HTMLDocumentNode_QI,
|
||||||
HTMLDocumentNode_destructor,
|
HTMLDocumentNode_destructor,
|
||||||
@ -1973,7 +2096,7 @@ static const tid_t HTMLDocumentNode_iface_tids[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static dispex_static_data_t HTMLDocumentNode_dispex = {
|
static dispex_static_data_t HTMLDocumentNode_dispex = {
|
||||||
NULL,
|
&HTMLDocumentNode_dispex_vtbl,
|
||||||
DispHTMLDocument_tid,
|
DispHTMLDocument_tid,
|
||||||
NULL,
|
NULL,
|
||||||
HTMLDocumentNode_iface_tids
|
HTMLDocumentNode_iface_tids
|
||||||
|
@ -623,6 +623,10 @@ struct HTMLDocumentNode {
|
|||||||
nsDocumentEventListener *nsevent_listener;
|
nsDocumentEventListener *nsevent_listener;
|
||||||
BOOL *event_vector;
|
BOOL *event_vector;
|
||||||
|
|
||||||
|
WCHAR **elem_vars;
|
||||||
|
unsigned elem_vars_size;
|
||||||
|
unsigned elem_vars_cnt;
|
||||||
|
|
||||||
BOOL skip_mutation_notif;
|
BOOL skip_mutation_notif;
|
||||||
|
|
||||||
struct list bindings;
|
struct list bindings;
|
||||||
|
@ -43,6 +43,25 @@ function test_createDocumentFragment() {
|
|||||||
ok(cloned.nodeName === "#document-fragment", "cloned.nodeName = " + cloned.nodeName);
|
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;
|
var globalVar = false;
|
||||||
|
|
||||||
function runTest() {
|
function runTest() {
|
||||||
@ -55,6 +74,7 @@ function runTest() {
|
|||||||
test_removeAttribute(document.body);
|
test_removeAttribute(document.body);
|
||||||
test_select_index();
|
test_select_index();
|
||||||
test_createDocumentFragment();
|
test_createDocumentFragment();
|
||||||
|
test_document_name_as_index();
|
||||||
|
|
||||||
var r = window.execScript("globalVar = true;");
|
var r = window.execScript("globalVar = true;");
|
||||||
ok(r === undefined, "execScript returned " + r);
|
ok(r === undefined, "execScript returned " + r);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user