New version handles tag-specific element props, and uses a blacklist instead (of what's not an attribute), which should avoid regressions if we missed anything (as we used to treat every builtin as an attr before), plus it's shorter lists since most are attributes.
Note that we have to use some element specific lists, because some of them shared DISPIDs and would conflict otherwise, and some of those aren't attributes, while on other elements sharing same DISPID, they are.
Also, here's a diff to apply on top of second patch to test it on IE9 as well but it only works on Windows, as Wine is too broken right now so will have to wait.
```diff diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 1a0a829..56eb87a 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -3941,6 +3941,14 @@ static void test_attr_collection_builtins(IHTMLDocument2 *doc) L"onmsanimationiteration", L"onmsanimationstart", L"onmsmanipulationstatechanged", L"onmstransitionend", L"onmstransitionstart", L"role", L"spellcheck", L"x-ms-acceleratorkey", L"x-ms-aria-flowfrom" }; + static const WCHAR *generic_builtins_ie9[] = { + L"draggable", L"onabort", L"oncanplay", L"oncanplaythrough", L"onchange", L"ondurationchange", L"onemptied", L"onended", L"onerror", L"oninput", L"onload", + L"onloadeddata", L"onloadedmetadata", L"onloadstart", L"onlostpointercapture", L"onmscontentzoom", L"onmsgesturechange", L"onmsgesturedoubletap", + L"onmsgestureend", L"onmsgesturehold", L"onmsgesturestart", L"onmsgesturetap", L"onmsgotpointercapture", L"onmsinertiastart", L"onmspointerdown", + L"onmspointerenter", L"onmspointerhover", L"onmspointerleave", L"onmspointermove", L"onmspointerout", L"onmsregionupdate", L"onpause", L"onplay", L"onplaying", + L"onpointercancel", L"onpointerover", L"onpointerup", L"onprogress", L"onratechange", L"onreset", L"onseeked", L"onseeking", L"onselect", L"onstalled", + L"onsubmit", L"onsuspend", L"ontimeupdate", L"ontouchcancel", L"ontouchend", L"ontouchmove", L"ontouchstart", L"onvolumechange", L"onwaiting" + }; static const WCHAR *tags[] = { L"audio", NULL, L"b", L"cite", L"dateTime", NULL, @@ -4058,10 +4066,36 @@ static void test_attr_collection_builtins(IHTMLDocument2 *doc) L"ul", L"compact", L"type", NULL, NULL }; + static const WCHAR *tags_ie9[] = { + L"audio", L"autobuffer", L"autoplay", L"controls", L"loop", L"muted", L"onmsneedkey", L"preload", L"src", L"x-ms-playtodisabled", L"x-ms-playtopreferredsourceuri", L"x-ms-playtoprimary", NULL, + L"body", L"autofocus", L"onmessage", L"onorientationchange", L"onpagehide", L"onpageshow", L"onpopstate", L"onstorage", L"required", NULL, + L"button", L"autofocus", L"required", NULL, + L"caption", L"autofocus", L"required", NULL, + L"embed", L"autofocus", L"required", L"x-ms-playtodisabled", L"x-ms-playtopreferredsourceuri", L"x-ms-playtoprimary", NULL, + L"fieldset", L"autofocus", L"required", NULL, + L"form", L"novalidate", NULL, + L"frameset", L"autofocus", L"onhashchange", L"onmessage", L"onoffline", L"ononline", L"onorientationchange", L"onpagehide", L"onpageshow", L"onstorage", L"required", NULL, + L"iframe", L"allowfullscreen", NULL, + L"img", L"autofocus", L"crossOrigin", L"required", L"x-ms-playtodisabled", L"x-ms-playtopreferredsourceuri", L"x-ms-playtoprimary", NULL, + L"input", L"autofocus", L"list", L"max", L"min", L"multiple", L"pattern", L"placeholder", L"required", L"step", NULL, + L"legend", L"autofocus", L"required", NULL, + L"object", L"autofocus", L"required", L"x-ms-playtodisabled", L"x-ms-playtopreferredsourceuri", L"x-ms-playtoprimary", NULL, + L"script", L"async", NULL, + L"select", L"autofocus", L"required", NULL, + L"table", L"autofocus", L"required", NULL, + L"td", L"autofocus", L"required", NULL, + L"textarea", L"autofocus", L"maxLength", L"placeholder", L"required", NULL, + L"tr", L"autofocus", L"required", NULL, + L"video", L"autobuffer", L"autoplay", L"controls", L"height", L"loop", L"msStereo3DPackingMode", L"msStereo3DRenderModeatype", L"muted", L"onmsneedkey", L"onMSVideoFormatChange", + L"onMSVideoFrameStepCompleted", L"onMSVideoOptimalLayoutChanged", L"poster", L"preload", L"src", L"width", L"x-ms-playtodisabled", L"x-ms-playtopreferredsourceuri", L"x-ms-playtoprimary", NULL, + NULL + }; BOOLEAN found[ARRAY_SIZE(generic_builtins)]; + BOOLEAN found_ie9[ARRAY_SIZE(generic_builtins_ie9)]; BOOLEAN found_tag_specific[36]; + BOOLEAN found_tag_specific_ie9[20];
- const WCHAR **iter = tags, **iter_todo = tags_todo; + const WCHAR **iter = tags, **iter_todo = tags_todo, **iter_ie9 = tags_ie9; IHTMLAttributeCollection *attr_col; IHTMLDOMAttribute *attr; IHTMLElement *elem; @@ -4073,13 +4107,18 @@ static void test_attr_collection_builtins(IHTMLDocument2 *doc) BSTR bstr;
while(*iter) { - const WCHAR *tag = *iter++, **todos = NULL; + const WCHAR *tag = *iter++, **todos = NULL, **attrs_ie9 = NULL;
if(*iter_todo && !wcscmp(tag, *iter_todo)) { todos = ++iter_todo; while(*iter_todo++) {} }
+ if(compat_mode >= COMPAT_IE9 && *iter_ie9 && !wcscmp(tag, *iter_ie9)) { + attrs_ie9 = ++iter_ie9; + while(*iter_ie9++) {} + } + bstr = SysAllocString(tag); hres = IHTMLDocument2_createElement(doc, bstr, &elem); ok(hres == S_OK, "[%s] createElement failed: %08lx\n", wine_dbgstr_w(tag), hres); @@ -4101,7 +4140,9 @@ static void test_attr_collection_builtins(IHTMLDocument2 *doc) ok(hres == S_OK, "[%s] get_length failed: %08lx\n", wine_dbgstr_w(tag), hres);
memset(found, 0, sizeof(found)); + memset(found_ie9, 0, sizeof(found_ie9)); memset(found_tag_specific, 0, sizeof(found_tag_specific)); + memset(found_tag_specific_ie9, 0, sizeof(found_tag_specific_ie9)); for(i = 0; i < len; i++) { BOOL expected = FALSE;
@@ -4133,6 +4174,24 @@ static void test_attr_collection_builtins(IHTMLDocument2 *doc) break; } } + + if(compat_mode >= COMPAT_IE9) { + for(j = 0; j < ARRAY_SIZE(generic_builtins_ie9); j++) { + if(!wcscmp(bstr, generic_builtins_ie9[j])) { + found_ie9[j] = TRUE; + expected = TRUE; + break; + } + } + + for(j = 0; !expected && attrs_ie9 && attrs_ie9[j]; j++) { + if(!wcsicmp(bstr, attrs_ie9[j])) { + found_tag_specific_ie9[j] = TRUE; + expected = TRUE; + break; + } + } + } } ok(expected, "[%s] %s is in collection but not in expected list\n", wine_dbgstr_w(tag), wine_dbgstr_w(bstr)); SysFreeString(bstr); @@ -4155,6 +4214,13 @@ static void test_attr_collection_builtins(IHTMLDocument2 *doc) ok(found_tag_specific[i], "[%s] %s not in collection\n", wine_dbgstr_w(tag), wine_dbgstr_w(iter[i])); } iter += i + 1; + + if(compat_mode >= COMPAT_IE9) { + for(i = 0; i < ARRAY_SIZE(generic_builtins_ie9); i++) + ok(found_ie9[i], "[%s] %s not in collection\n", wine_dbgstr_w(tag), wine_dbgstr_w(generic_builtins_ie9[i])); + for(i = 0; attrs_ie9 && attrs_ie9[i]; i++) + ok(found_tag_specific_ie9[i], "[%s] %s not in collection\n", wine_dbgstr_w(tag), wine_dbgstr_w(attrs_ie9[i])); + } } }
@@ -12862,6 +12928,7 @@ START_TEST(dom) compat_mode = COMPAT_IE9; run_domtest(doc_blank_ie9, test_dom_elements); run_domtest(doc_blank_ie9, test_about_blank_storage); + run_domtest(doc_blank_ie9, test_attr_collection_builtins); compat_mode = COMPAT_NONE; } run_domtest(noscript_str, test_noscript); ```