From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmldoc.c | 31 +++++++++++++-------- dlls/mshtml/tests/documentmode.js | 46 ++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 13 deletions(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index d86ed07e033..0e35830552c 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -4820,23 +4820,30 @@ static inline HTMLDocument *impl_from_IDispatchEx(IDispatchEx *iface)
static HRESULT has_elem_name(nsIDOMHTMLDocument *nsdoc, const WCHAR *name) { - nsIDOMNodeList *node_list; - nsAString name_str; + static const WCHAR fmt[] = L":-moz-any(applet,embed,form,iframe,img,object)[name=%s]"; + WCHAR buf[128], *selector = buf; + nsAString selector_str; + nsIDOMElement *nselem; nsresult nsres; - UINT32 len; + size_t len;
- nsAString_InitDepend(&name_str, name); - nsres = nsIDOMHTMLDocument_GetElementsByName(nsdoc, &name_str, &node_list); - nsAString_Finish(&name_str); - if(NS_FAILED(nsres)) - return map_nsresult(nsres); + len = wcslen(name) + ARRAY_SIZE(fmt) - 2 /* %s */; + if(len > ARRAY_SIZE(buf) && !(selector = heap_alloc(len * sizeof(WCHAR)))) + return E_OUTOFMEMORY; + swprintf(selector, len, fmt, name);
- nsres = nsIDOMNodeList_GetLength(node_list, &len); - nsIDOMNodeList_Release(node_list); + nsAString_InitDepend(&selector_str, selector); + nsres = nsIDOMHTMLDocument_QuerySelector(nsdoc, &selector_str, &nselem); + nsAString_Finish(&selector_str); + if(selector != buf) + heap_free(selector); if(NS_FAILED(nsres)) return map_nsresult(nsres);
- return len ? S_OK : DISP_E_UNKNOWNNAME; + if(!nselem) + return DISP_E_UNKNOWNNAME; + nsIDOMElement_Release(nselem); + return S_OK; }
static HRESULT dispid_from_elem_name(HTMLDocumentNode *This, const WCHAR *name, DISPID *dispid) @@ -5918,7 +5925,7 @@ static HRESULT HTMLDocumentNode_next_dispid(DispatchEx *dispex, DISPID id, DISPI }
/* Populate possibly missing DISPIDs */ - nsAString_InitDepend(&nsstr, L"[name]"); + nsAString_InitDepend(&nsstr, L":-moz-any(applet,embed,form,iframe,img,object)[name]"); nsres = nsIDOMHTMLDocument_QuerySelectorAll(This->nsdoc, &nsstr, &node_list); nsAString_Finish(&nsstr); if(NS_FAILED(nsres)) diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index ad258b3df2e..9fb17422613 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -669,7 +669,7 @@ sync_test("for..in", function() {
sync_test("elem_by_id", function() { document.body.innerHTML = '<form id="testid" name="testname"></form>'; - var found; + var found, i;
var id_elem = document.getElementById("testid"); ok(id_elem.tagName === "FORM", "id_elem.tagName = " + id_elem.tagName); @@ -704,6 +704,50 @@ sync_test("elem_by_id", function() { found = true; } ok(found, "testname was not enumerated in document"); + + // these tags expose name as props, and id only if they have a name + var tags = [ "embed", "form", "iframe", "img" ]; + for(i = 0; i < tags.length; i++) { + document.body.innerHTML = '<' + tags[i] + ' id="testid" name="testname"></' + tags[i] + '><' + tags[i] + ' id="foobar"></' + tags[i] + '>'; + ok("testname" in document, tags[i] + " did not expose testname"); + todo_wine. + ok("testid" in document, tags[i] + " did not expose testid"); + ok(!("foobar" in document), tags[i] + " exposed foobar"); + } + + // these tags always expose their id as well as name (we don't test applet because it makes Windows pop up a dialog box) + var tags = [ "object" ]; + for(i = 0; i < tags.length; i++) { + document.body.innerHTML = '<' + tags[i] + ' id="testid" name="testname"></' + tags[i] + '><' + tags[i] + ' id="foobar"></' + tags[i] + '>'; + ok("testname" in document, tags[i] + " did not expose testname"); + todo_wine. + ok("testid" in document, tags[i] + " did not expose testid"); + todo_wine. + ok("foobar" in document, tags[i] + " did not expose foobar"); + } + + // all other tags don't expose props for either id or name + tags = [ + "abbr", "acronym", "address", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "big", "blockquote", "body", + "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "data", "datalist", "dd", "del", "details", + "dfn", "dialog", "dir", "div", "dl", "dt", "em", "fieldset", "figcaption", "figure", "font", "footer", "frame", "frameset", + "h1", "h2", "h3", "h4", "h5", "h6", "h7", "head", "header", "hr", "html", "i", "input", "ins", "kbd", "label", "legend", "li", + "link", "main", "map", "mark", "meta", "meter", "nav", "noframes", "noscript", "ol", "optgroup", "option", "output", "p", + "param", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "script", "section", "select", "small", "source", + "span", "strike", "strong", "style", "sub", "summary", "sup", "svg", "table", "tbody", "td", "template", "textarea", "tfoot", + "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "winetest" + ]; + for(i = 0; i < tags.length; i++) { + // IE7 and below throw "Unknown Runtime Error" for some tags, like frameset + try { + document.body.innerHTML = '<' + tags[i] + ' id="testid" name="testname"></' + tags[i] + '><' + tags[i] + ' id="foobar"></' + tags[i] + '>'; + }catch(e) { + continue; + } + ok(!("testname" in document), tags[i] + " exposed testname"); + ok(!("testid" in document), tags[i] + " exposed testid"); + ok(!("foobar" in document), tags[i] + " exposed foobar"); + } });
sync_test("doc_mode", function() {