From: Gabriel Ivăncescu gabrielopcode@gmail.com
Despite what MSDN says it appears that EmulateIE10 and EmulateIE11 don't care about DOCTYPE validity at all (same as IE=10 and IE=11).
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/mutation.c | 53 +++++++++++++++++++++++++++--------- dlls/mshtml/tests/dom.c | 22 +++++++++++++++ 3 files changed, 63 insertions(+), 13 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index b98671188be..978e4df22db 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -1105,6 +1105,7 @@ struct HTMLDocumentNode {
nsIDOMDocument *dom_document; nsIDOMHTMLDocument *html_document; + unsigned int emulate_mode : 1; unsigned int content_ready : 1; unsigned int unload_sent : 1;
diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index 3c1a25646db..c5ce26b97bb 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -414,19 +414,28 @@ DWORD get_compat_mode_version(compat_mode_t compat_mode) */ compat_mode_t lock_document_mode(HTMLDocumentNode *doc) { - TRACE("%p: %d\n", doc, doc->document_mode); - if(!doc->document_mode_locked) { doc->document_mode_locked = TRUE;
+ if(doc->emulate_mode && doc->document_mode < COMPAT_MODE_IE10) { + nsIDOMDocumentType *nsdoctype; + + if(NS_SUCCEEDED(nsIDOMDocument_GetDoctype(doc->dom_document, &nsdoctype)) && nsdoctype) + nsIDOMDocumentType_Release(nsdoctype); + else + doc->document_mode = COMPAT_MODE_QUIRKS; + } + if(doc->html_document) nsIDOMHTMLDocument_SetIECompatMode(doc->html_document, get_compat_mode_version(doc->document_mode)); }
+ TRACE("%p: %d\n", doc, doc->document_mode); + return doc->document_mode; }
-static void set_document_mode(HTMLDocumentNode *doc, compat_mode_t document_mode, BOOL lock) +static void set_document_mode(HTMLDocumentNode *doc, compat_mode_t document_mode, BOOL emulate_mode, BOOL lock) { compat_mode_t max_compat_mode;
@@ -447,6 +456,7 @@ static void set_document_mode(HTMLDocumentNode *doc, compat_mode_t document_mode }
doc->document_mode = document_mode; + doc->emulate_mode = emulate_mode; if(lock) lock_document_mode(doc); } @@ -491,9 +501,11 @@ const WCHAR *parse_compat_version(const WCHAR *version_string, compat_mode_t *r)
static BOOL parse_ua_compatible(const WCHAR *p, compat_mode_t *r) { + static const WCHAR emulateIEW[] = {'E','m','u','l','a','t','e','I','E'}; static const WCHAR ie_eqW[] = {'I','E','='}; static const WCHAR edgeW[] = {'e','d','g','e'}; compat_mode_t mode = COMPAT_MODE_INVALID; + BOOL emulate_mode = FALSE;
TRACE("%s\n", debugstr_w(p));
@@ -502,21 +514,31 @@ static BOOL parse_ua_compatible(const WCHAR *p, compat_mode_t *r) p += 3;
do { + BOOL is_emulate = FALSE; + while(iswspace(*p)) p++; if(!wcsnicmp(p, edgeW, ARRAY_SIZE(edgeW))) { p += ARRAY_SIZE(edgeW); if(is_ua_compatible_delimiter(*p)) mode = COMPAT_MODE_IE11; break; - }else if(!(p = parse_compat_version(p, r))) - break; - if(mode < *r) + }else { + if(!wcsnicmp(p, emulateIEW, ARRAY_SIZE(emulateIEW))) { + p += ARRAY_SIZE(emulateIEW); + is_emulate = TRUE; + } + if(!(p = parse_compat_version(p, r))) + break; + } + if(mode < *r) { mode = *r; + emulate_mode = is_emulate; + } while(iswspace(*p)) p++; } while(*p++ == ',');
*r = mode; - return mode != COMPAT_MODE_INVALID; + return emulate_mode; }
void process_document_response_headers(HTMLDocumentNode *doc, IBinding *binding) @@ -542,9 +564,13 @@ void process_document_response_headers(HTMLDocumentNode *doc, IBinding *binding) TRACE("size %lu\n", size);
header = strdupAtoW(buf); - if(header && parse_ua_compatible(header, &document_mode)) { - TRACE("setting document mode %d\n", document_mode); - set_document_mode(doc, document_mode, FALSE); + if(header) { + BOOL emulate_mode = parse_ua_compatible(header, &document_mode); + + if(document_mode != COMPAT_MODE_INVALID) { + TRACE("setting document mode %d\n", document_mode); + set_document_mode(doc, document_mode, emulate_mode, FALSE); + } } free(header); } @@ -573,8 +599,9 @@ static void process_meta_element(HTMLDocumentNode *doc, nsIDOMHTMLMetaElement *m
if(!wcsicmp(http_equiv, L"x-ua-compatible")) { compat_mode_t document_mode; - if(parse_ua_compatible(content, &document_mode)) - set_document_mode(doc, document_mode, TRUE); + BOOL emulate_mode = parse_ua_compatible(content, &document_mode); + if(document_mode != COMPAT_MODE_INVALID) + set_document_mode(doc, document_mode, emulate_mode, TRUE); else FIXME("Unsupported document mode %s\n", debugstr_w(content)); } @@ -907,7 +934,7 @@ static void NSAPI nsDocumentObserver_BindToDocument(nsIDocumentObserver *iface, mode = COMPAT_MODE_IE11; }
- set_document_mode(This, mode, FALSE); + set_document_mode(This, mode, FALSE, FALSE); nsIDOMDocumentType_Release(nsdoctype); } } diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 8383f167cdd..0ff11a74d01 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -11836,6 +11836,10 @@ static void test_quirks_mode(void) " <meta http-equiv="x-ua-compatible" content="IE=%s" />" "</head><body></body></html>", tests[i].str); run_domtest(buf, test_document_mode); + sprintf(buf, "<html><head>" + " <meta http-equiv="x-ua-compatible" content="IE=%s" />" + "</head><body></body></html>", tests[i].str); + run_domtest(buf, test_document_mode); }
expected_document_mode = 8; @@ -11848,6 +11852,24 @@ static void test_quirks_mode(void) " <body>" " </body>" "</html>", test_document_mode); + + for(i = 7; i <= 11; i++) { + char buf[128]; + expected_document_mode = i; + sprintf(buf, "<!DOCTYPE html>\n<html><head>" + " <meta http-equiv="x-ua-compatible" content="IE=EmulateIE%u" />" + "</head><body></body></html>", i); + run_domtest(buf, test_document_mode); + expected_document_mode = i < 10 ? 5 : i; + sprintf(buf, "<html><head>" + " <meta http-equiv="x-ua-compatible" content="IE=EmulateIE%u" />" + "</head><body></body></html>", i); + run_domtest(buf, test_document_mode); + sprintf(buf, "<html><head>" + " <meta http-equiv="x-ua-compatible" content="IE=eMulaTeie%u" />" + "</head><body></body></html>", i); + run_domtest(buf, test_document_mode); + } }
static void test_document_mode_lock(void)