From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmldoc.c | 55 +++++++++++++++++++++---------- dlls/mshtml/tests/documentmode.js | 13 ++++++-- 2 files changed, 47 insertions(+), 21 deletions(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index d86ed07e033..ebc8aadc930 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -4839,6 +4839,28 @@ static HRESULT has_elem_name(nsIDOMHTMLDocument *nsdoc, const WCHAR *name) return len ? S_OK : DISP_E_UNKNOWNNAME; }
+static HRESULT has_elem_id(nsIDOMHTMLDocument *nsdoc, const WCHAR *id) +{ + nsIDOMElement *nselem; + cpp_bool has_name; + nsAString nsstr; + nsresult nsres; + + nsAString_InitDepend(&nsstr, id); + nsres = nsIDOMHTMLDocument_GetElementById(nsdoc, &nsstr, &nselem); + nsAString_Finish(&nsstr); + if(NS_FAILED(nsres)) + return map_nsresult(nsres); + if(!nselem) + return DISP_E_UNKNOWNNAME; + + nsAString_InitDepend(&nsstr, L"name"); + nsIDOMElement_HasAttribute(nselem, &nsstr, &has_name); + nsIDOMElement_Release(nselem); + nsAString_Finish(&nsstr); + return has_name ? S_OK : DISP_E_UNKNOWNNAME; +} + static HRESULT dispid_from_elem_name(HTMLDocumentNode *This, const WCHAR *name, DISPID *dispid) { unsigned i; @@ -4945,6 +4967,8 @@ static HRESULT WINAPI DocDispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName,
if(This->doc_node->nsdoc) { hres = has_elem_name(This->doc_node->nsdoc, bstrName); + if(hres == DISP_E_UNKNOWNNAME) + hres = has_elem_id(This->doc_node->nsdoc, bstrName); if(SUCCEEDED(hres)) hres = dispid_from_elem_name(This->doc_node, bstrName, pid); } @@ -5851,13 +5875,11 @@ static HRESULT HTMLDocumentNode_get_name(DispatchEx *dispex, DISPID id, BSTR *na static HRESULT HTMLDocumentNode_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { + static WCHAR nameW[] = L"name"; HTMLDocumentNode *This = impl_from_DispatchEx(dispex); - nsIDOMNodeList *node_list; - nsAString name_str; - nsIDOMNode *nsnode; - HTMLDOMNode *node; + HTMLElement *elem; + VARIANT_BOOL b; unsigned i; - nsresult nsres; HRESULT hres;
if(flags != DISPATCH_PROPERTYGET && flags != (DISPATCH_METHOD|DISPATCH_PROPERTYGET)) { @@ -5870,23 +5892,20 @@ static HRESULT HTMLDocumentNode_invoke(DispatchEx *dispex, DISPID id, LCID lcid, if(!This->nsdoc || i >= This->elem_vars_cnt) return DISP_E_MEMBERNOTFOUND;
- 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_MEMBERNOTFOUND; - - hres = get_node(nsnode, TRUE, &node); + hres = get_doc_elem_by_id(This, This->elem_vars[i], &elem); if(FAILED(hres)) return hres; + if(!elem) + return DISP_E_MEMBERNOTFOUND; + + hres = IHTMLElement6_hasAttribute(&elem->IHTMLElement6_iface, nameW, &b); + if(FAILED(hres) || !b) { + IHTMLElement6_Release(&elem->IHTMLElement6_iface); + return FAILED(hres) ? hres : DISP_E_MEMBERNOTFOUND; + }
V_VT(res) = VT_DISPATCH; - V_DISPATCH(res) = (IDispatch*)&node->IHTMLDOMNode_iface; + V_DISPATCH(res) = (IDispatch*)&elem->node.IHTMLDOMNode_iface; return S_OK; }
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index ad258b3df2e..32f69789e55 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -668,7 +668,7 @@ sync_test("for..in", function() { });
sync_test("elem_by_id", function() { - document.body.innerHTML = '<form id="testid" name="testname"></form>'; + document.body.innerHTML = '<form id="testid" name="testname"></form><div id="foobar"></div>'; var found;
var id_elem = document.getElementById("testid"); @@ -682,16 +682,23 @@ sync_test("elem_by_id", function() {
id_elem = window.testid; ok(id_elem.tagName === "FORM", "window.testid = " + id_elem); + name_elem = window.testname; + ok(name_elem.tagName === "FORM", "window.testname = " + name_elem); + id_elem = window.foobar; + ok(id_elem.tagName === "DIV", "window.foobar = " + id_elem);
+ id_elem = document.testid; + ok(id_elem.tagName === "FORM", "document.testid = " + id_elem); name_elem = document.testname; ok(name_elem.tagName === "FORM", "document.testname = " + name_elem); + ok(!("foobar" in document), "foobar in document");
for(id_elem in window) - ok(id_elem !== "testid" && id_elem != "testname", id_elem + " was enumerated in window"); + ok(id_elem !== "testid" && id_elem != "testname" && id_elem != "foobar", id_elem + " was enumerated in window"); window.testid = 137; found = false; for(id_elem in window) { - ok(id_elem != "testname", id_elem + " was enumerated in window after set to 137"); + ok(id_elem != "testname" && id_elem != "foobar", id_elem + " was enumerated in window after set to 137"); if(id_elem === "testid") found = true; }