-- v4: mshtml: Remove outdated FIXME comment. mshtml: Try to guess the script encoding when there's no BOM. mshtml/tests: Test mixed charset encodings for document and text resources.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/tests/dom.c | 147 ++++++++++++++++++++++++++++++++ dlls/mshtml/tests/rsrc.rc | 24 ++++++ dlls/mshtml/tests/utf16_bom_css | Bin 0 -> 84 bytes dlls/mshtml/tests/utf16_bom_js | Bin 0 -> 56 bytes dlls/mshtml/tests/utf16_css | Bin 0 -> 82 bytes dlls/mshtml/tests/utf16_js | Bin 0 -> 54 bytes dlls/mshtml/tests/utf8_bom_css | 1 + dlls/mshtml/tests/utf8_bom_js | 1 + dlls/mshtml/tests/utf8_css | 1 + dlls/mshtml/tests/utf8_js | 1 + 10 files changed, 175 insertions(+) create mode 100644 dlls/mshtml/tests/utf16_bom_css create mode 100644 dlls/mshtml/tests/utf16_bom_js create mode 100644 dlls/mshtml/tests/utf16_css create mode 100644 dlls/mshtml/tests/utf16_js create mode 100644 dlls/mshtml/tests/utf8_bom_css create mode 100644 dlls/mshtml/tests/utf8_bom_js create mode 100644 dlls/mshtml/tests/utf8_css create mode 100644 dlls/mshtml/tests/utf8_js
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index b1625b619ca..b09c5ef971f 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -12037,6 +12037,152 @@ static void test_quirks_mode(void) } }
+static void test_default_content_charset(void) +{ +#define CHARSETS X(utf8) X(utf16) X(utf8_bom) X(utf16_bom) + enum { +#define X(c) c, + CHARSETS +#undef X + } doc_charset, rsrc_charset; + static const char *charsets[] = { +#define X(c) #c, + CHARSETS +#undef X + }; + static const WCHAR *charsetsW[] = { +#define X(c) L"" #c, + CHARSETS +#undef X + }; +#undef CHARSETS + unsigned module_len, module_lenW; + IHTMLCSSStyleDeclaration *style; + char module_path[MAX_PATH * 3]; + WCHAR module_pathW[MAX_PATH]; + IPersistStreamInit *init; + IHTMLWindow7 *window7; + IHTMLWindow2 *window; + IHTMLDocument2 *doc; + IHTMLElement *body; + IHTMLDOMNode *node; + IStream *stream; + DISPID dispid; + HRESULT hres; + VARIANT var; + HGLOBAL mem; + SIZE_T size; + void *buf; + BSTR bstr; + MSG msg; + + module_lenW = GetModuleFileNameW(NULL, module_pathW, ARRAY_SIZE(module_pathW)); + module_len = WideCharToMultiByte(CP_UTF8, 0, module_pathW, -1, module_path, ARRAY_SIZE(module_path), NULL, NULL); + + for(doc_charset = utf8; doc_charset <= utf16; doc_charset++) { + for(rsrc_charset = utf8; rsrc_charset < ARRAY_SIZE(charsets); rsrc_charset++) { + notif_doc = doc = create_document(); + if(!doc) + return; + doc_complete = FALSE; + + buf = malloc((128 + (doc_charset == utf16 ? module_lenW : module_len)) * (doc_charset == utf16 ? sizeof(WCHAR) : 1)); + if(doc_charset == utf16) + size = wsprintfW(buf, L"<!DOCTYPE html>\n<html><head><link href="res://%s/%s_css" rel="stylesheet"></head><body></body></html>", module_pathW, charsetsW[rsrc_charset]) * sizeof(WCHAR); + else + size = sprintf(buf, "<!DOCTYPE html>\n<html><head><link href="res://%s/%s_css" rel="stylesheet"></head><body></body></html>", module_path, charsets[rsrc_charset]); + mem = GlobalAlloc(0, size); + memcpy(mem, buf, size); + free(buf); + + hres = CreateStreamOnHGlobal(mem, TRUE, &stream); + ok(hres == S_OK, "Failed to create stream: %08lx.\n", hres); + hres = IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init); + ok(hres == S_OK, "Failed to get IPersistStreamInit: %08lx.\n", hres); + IPersistStreamInit_Load(init, stream); + IPersistStreamInit_Release(init); + IStream_Release(stream); + + set_client_site(doc, TRUE); + do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink); + + while(!doc_complete && GetMessageW(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + + hres = IHTMLDocument2_get_parentWindow(doc, &window); + ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres); + + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow7, (void**)&window7); + ok(hres == S_OK, "Could not get IHTMLWindow7: %08lx\n", hres); + IHTMLWindow2_Release(window); + + hres = IHTMLDocument2_get_body(doc, &body); + ok(hres == S_OK, "Could not get body: %08lx\n", hres); + + hres = IHTMLElement_QueryInterface(body, &IID_IHTMLDOMNode, (void**)&node); + ok(hres == S_OK, "Could not get IHTMLDOMNode: %08lx\n", hres); + IHTMLElement_Release(body); + + hres = IHTMLWindow7_getComputedStyle(window7, node, NULL, &style); + ok(hres == S_OK, "getComputedStyle failed: %08lx\n", hres); + IHTMLWindow7_Release(window7); + IHTMLDOMNode_Release(node); + + hres = IHTMLCSSStyleDeclaration_get_backgroundColor(style, &var); + ok(hres == S_OK, "get_backgroundColor failed: %08lx\n", hres); + ok(V_VT(&var) == VT_BSTR, "backgroundColor VT = %d\n", V_VT(&var)); + todo_wine_if((doc_charset == utf8 && rsrc_charset == utf16) || (doc_charset == utf16 && rsrc_charset == utf8)) + ok(!wcscmp(V_BSTR(&var), L"rgb(222, 173, 184)"), "[%s:%s] backgroundColor = %s\n", charsets[doc_charset], charsets[rsrc_charset], wine_dbgstr_w(V_BSTR(&var))); + IHTMLCSSStyleDeclaration_Release(style); + VariantClear(&var); + + set_client_site(doc, FALSE); + IHTMLDocument2_Release(doc); + + notif_doc = doc = create_document(); + if(!doc) + return; + doc_complete = FALSE; + + buf = malloc((128 + (doc_charset == utf16 ? module_lenW : module_len)) * (doc_charset == utf16 ? sizeof(WCHAR) : 1)); + if(doc_charset == utf16) + size = wsprintfW(buf, L"<!DOCTYPE html>\n<html><head><script type="text/javascript" src="res://%s/%s_js"></script></head><body></body></html>", module_pathW, charsetsW[rsrc_charset]) * sizeof(WCHAR); + else + size = sprintf(buf, "<!DOCTYPE html>\n<html><head><script type="text/javascript" src="res://%s/%s_js"></script></head><body></body></html>", module_path, charsets[rsrc_charset]); + mem = GlobalAlloc(0, size); + memcpy(mem, buf, size); + free(buf); + + hres = CreateStreamOnHGlobal(mem, TRUE, &stream); + ok(hres == S_OK, "Failed to create stream: %08lx.\n", hres); + hres = IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init); + ok(hres == S_OK, "Failed to get IPersistStreamInit: %08lx.\n", hres); + IPersistStreamInit_Load(init, stream); + IPersistStreamInit_Release(init); + IStream_Release(stream); + + set_client_site(doc, TRUE); + do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink); + + while(!doc_complete && GetMessageW(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + + bstr = SysAllocString(L"wineTestProp"); + hres = IHTMLDocument2_GetIDsOfNames(doc, &IID_NULL, &bstr, 1, 0, &dispid); + todo_wine_if((doc_charset == utf8 || doc_charset == utf16) && rsrc_charset == utf16) + ok(hres == S_OK, "[%s:%s] GetIDsOfNames(wineTestProp) returned: %08lx\n", charsets[doc_charset], charsets[rsrc_charset], hres); + SysFreeString(bstr); + + set_client_site(doc, FALSE); + IHTMLDocument2_Release(doc); + } + } +} + static void test_document_mode_lock(void) { IHTMLOptionElementFactory *option, *option2; @@ -12414,6 +12560,7 @@ START_TEST(dom) }
test_quirks_mode(); + test_default_content_charset(); test_document_mode_lock(); test_document_mode_after_initnew(); test_threads(); diff --git a/dlls/mshtml/tests/rsrc.rc b/dlls/mshtml/tests/rsrc.rc index 61b53520781..dc586f42c68 100644 --- a/dlls/mshtml/tests/rsrc.rc +++ b/dlls/mshtml/tests/rsrc.rc @@ -91,6 +91,30 @@ iframe.html HTML "iframe.html" /* @makedep: xhr_iframe.html */ xhr_iframe.html HTML "xhr_iframe.html"
+/* @makedep: utf8_css */ +utf8_css HTML "utf8_css" + +/* @makedep: utf16_css */ +utf16_css HTML "utf16_css" + +/* @makedep: utf8_bom_css */ +utf8_bom_css HTML "utf8_bom_css" + +/* @makedep: utf16_bom_css */ +utf16_bom_css HTML "utf16_bom_css" + +/* @makedep: utf8_js */ +utf8_js HTML "utf8_js" + +/* @makedep: utf16_js */ +utf16_js HTML "utf16_js" + +/* @makedep: utf8_bom_js */ +utf8_bom_js HTML "utf8_bom_js" + +/* @makedep: utf16_bom_js */ +utf16_bom_js HTML "utf16_bom_js" + /* For res: protocol test: */
/* @makedep: jstest.html */ diff --git a/dlls/mshtml/tests/utf16_bom_css b/dlls/mshtml/tests/utf16_bom_css new file mode 100644 index 0000000000000000000000000000000000000000..873d27b6544a5d3d373d8e03f090b067f4910636 GIT binary patch literal 84 zcmezWPmiIPA&()2p_-wVL4hHOA)g_Ip^`y?p_(CyA(0`OA)6tcp@<=$p%ko2mm!%U kpCN}KpP`7sia~)vnIVNCl_8NKg&~Q-g29@hmVt`_04ggGr2qf`
literal 0 HcmV?d00001
diff --git a/dlls/mshtml/tests/utf16_bom_js b/dlls/mshtml/tests/utf16_bom_js new file mode 100644 index 0000000000000000000000000000000000000000..4acc12a612bc2ce431bace8c4a23a223b83a50c0 GIT binary patch literal 56 zcmezWFNGnWA(^3+A(tVQA&;SiL64!FA(J7GA(bJ7A(f$+p@boTp@<=$p@2bw!InXR L!H~h4fr|kEmQM?E
literal 0 HcmV?d00001
diff --git a/dlls/mshtml/tests/utf16_css b/dlls/mshtml/tests/utf16_css new file mode 100644 index 0000000000000000000000000000000000000000..fb315b0139f946b4010182b833ee8e229764a8bf GIT binary patch literal 82 zcmdO6C}zlGNMWdEsAW)KNMgumNMWdCP++KLNMcB2NM^`pNM|Tw$Y&@8tI}miX2@sA iVaR7FVz6RRU{GdAVMt|2WJqC1Vz6MaW~gQ0VgLYy6b`5W
literal 0 HcmV?d00001
diff --git a/dlls/mshtml/tests/utf16_js b/dlls/mshtml/tests/utf16_js new file mode 100644 index 0000000000000000000000000000000000000000..649619ba960f339dbab22df3bb64773839e99d25 GIT binary patch literal 54 zcmYdc$Y)4qC}qfHNM*=lC}GfJC}+rI$YV%l2w_NNC}t>O2w*5;$Y&^EP++iSP+%}* Jux8+5001ZR33UJf
literal 0 HcmV?d00001
diff --git a/dlls/mshtml/tests/utf8_bom_css b/dlls/mshtml/tests/utf8_bom_css new file mode 100644 index 00000000000..b44b804ba27 --- /dev/null +++ b/dlls/mshtml/tests/utf8_bom_css @@ -0,0 +1 @@ +.snd{} body {background-color: #deadb8;} diff --git a/dlls/mshtml/tests/utf8_bom_js b/dlls/mshtml/tests/utf8_bom_js new file mode 100644 index 00000000000..4e1d2b52a49 --- /dev/null +++ b/dlls/mshtml/tests/utf8_bom_js @@ -0,0 +1 @@ +document.wineTestProp = 1; diff --git a/dlls/mshtml/tests/utf8_css b/dlls/mshtml/tests/utf8_css new file mode 100644 index 00000000000..8dcd51fc75e --- /dev/null +++ b/dlls/mshtml/tests/utf8_css @@ -0,0 +1 @@ +.snd{} body {background-color: #deadb8;} diff --git a/dlls/mshtml/tests/utf8_js b/dlls/mshtml/tests/utf8_js new file mode 100644 index 00000000000..49a369ce60f --- /dev/null +++ b/dlls/mshtml/tests/utf8_js @@ -0,0 +1 @@ +document.wineTestProp = 1;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/script.c | 25 +++++++++++++++---------- dlls/mshtml/tests/dom.c | 1 - 2 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c index 9d663ee1cf7..945d0d33fc2 100644 --- a/dlls/mshtml/script.c +++ b/dlls/mshtml/script.c @@ -963,6 +963,7 @@ typedef struct {
static HRESULT get_binding_text(ScriptBSC *bsc, WCHAR **ret) { + binding_bom_t bom; UINT cp = CP_UTF8; WCHAR *text;
@@ -975,8 +976,19 @@ static HRESULT get_binding_text(ScriptBSC *bsc, WCHAR **ret) return S_OK; }
- switch(bsc->bsc.bom) { - case BOM_UTF16: + bom = bsc->bsc.bom; + if(bom == BOM_NONE) { + /* FIXME: Try to use charset from HTTP headers first */ + + /* IE guesses the encoding here using heuristics. Since valid JavaScript must start with an + * ASCII character (keyword, comment slash, string literal char, etc) that should be enough. */ + if(bsc->bsc.read > sizeof(WCHAR) && *(WCHAR*)bsc->buf < 128) + bom = BOM_UTF16; + else + cp = get_document_charset(bsc->script_elem->element.node.doc); + } + + if(bom == BOM_UTF16) { if(bsc->bsc.read % sizeof(WCHAR)) { FIXME("The buffer is not a valid utf16 string\n"); return E_FAIL; @@ -988,13 +1000,7 @@ static HRESULT get_binding_text(ScriptBSC *bsc, WCHAR **ret)
memcpy(text, bsc->buf, bsc->bsc.read); text[bsc->bsc.read/sizeof(WCHAR)] = 0; - break; - - default: - /* FIXME: Try to use charset from HTTP headers first */ - cp = get_document_charset(bsc->script_elem->element.node.doc); - /* fall through */ - case BOM_UTF8: { + }else { DWORD len;
len = MultiByteToWideChar(cp, 0, bsc->buf, bsc->bsc.read, NULL, 0); @@ -1005,7 +1011,6 @@ static HRESULT get_binding_text(ScriptBSC *bsc, WCHAR **ret) MultiByteToWideChar(cp, 0, bsc->buf, bsc->bsc.read, text, len); text[len] = 0; } - }
*ret = text; return S_OK; diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index b09c5ef971f..cd03db02df8 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -12173,7 +12173,6 @@ static void test_default_content_charset(void)
bstr = SysAllocString(L"wineTestProp"); hres = IHTMLDocument2_GetIDsOfNames(doc, &IID_NULL, &bstr, 1, 0, &dispid); - todo_wine_if((doc_charset == utf8 || doc_charset == utf16) && rsrc_charset == utf16) ok(hres == S_OK, "[%s:%s] GetIDsOfNames(wineTestProp) returned: %08lx\n", charsets[doc_charset], charsets[rsrc_charset], hres); SysFreeString(bstr);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/navigate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index f05bf0be9c6..b5826a00ea3 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -1144,8 +1144,8 @@ static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream) break; case BOM_UTF16: This->nschannel->charset = strdup("utf-16"); + break; case BOM_NONE: - /* FIXME: Get charset from HTTP headers */; }
if(!This->nschannel->content_type) {
On Fri May 30 16:27:33 2025 +0000, Gabriel Ivăncescu wrote:
changed this line in [version 4 of the diff](/wine/wine/-/merge_requests/7360/diffs?diff_id=181682&start_sha=872bae05a959c70247ed911ff5b4af882a5a7c54#7eb70c323881cba3d64f4e1b8764d8601efa0f61_1149_1148)
I fixed it in gecko, opened [wine-gecko MR !31](https://gitlab.winehq.org/wine/wine-gecko/-/merge_requests/31) and seems to work. But it seems scripts suffered from similar issue. I pushed new version here with todo tests and fixes for scripts since we already handled it in mshtml.
Note that I gave up using IsTextUnicode and instead just check the first WCHAR because it seems good enough, correct me if I'm wrong. Those files must start with ASCII to be valid.
On Fri May 30 16:30:53 2025 +0000, Gabriel Ivăncescu wrote:
I fixed it in gecko, opened [wine-gecko MR !31](https://gitlab.winehq.org/wine/wine-gecko/-/merge_requests/31) and seems to work. But it seems scripts suffered from similar issue. I pushed new version here with todo tests and fixes for scripts since we already handled it in mshtml. Note that I gave up using IsTextUnicode and instead just check the first WCHAR because it seems good enough, correct me if I'm wrong. Those files must start with ASCII to be valid.
We use `iswalnum` for identifier chars, so they may be multi-byte in utf-8. I don't see a way to do that detection fully correctly, through.
It aborts early for some reason, and I can't figure out why. I'm not sure if it's worth considering it's just tests? Maybe you have an idea?
Did you try using `file:` protocol for the main HTML document too (instead of `IPersistStreamInit`)?
On Mon Jun 2 15:13:05 2025 +0000, Jacek Caban wrote:
It aborts early for some reason, and I can't figure out why. I'm not
sure if it's worth considering it's just tests? Maybe you have an idea? Did you try using `file:` protocol for the main HTML document too (instead of `IPersistStreamInit`)?
Sadly it doesn't seem to work either. Here's a diff using it:
```diff diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index b1625b6..663da23 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -12037,6 +12037,144 @@ static void test_quirks_mode(void) } }
+static void test_default_content_charset(void) +{ + static const char *charsets[] = { "utf8", "utf16", "utf8_bom", "utf16_bom" }; + static const char css_utf8[] = "\xef\xbb\xbf""body {background-color: #deadb8;}"; + static const WCHAR css_utf16[] = L"\xfeff""body {background-color: #deadb8;}"; + enum { utf8, utf16, utf8_bom, utf16_bom } doc_charset, css_charset; + WCHAR doc_stringW[128 + MAX_PATH], css_path[MAX_PATH], doc_path[MAX_PATH], docW_path[MAX_PATH]; + IHTMLCSSStyleDeclaration *style; + IHTMLPrivateWindow *priv_window; + HANDLE file, docfile, docWfile; + IHTMLWindow7 *window7; + IHTMLWindow2 *window; + IHTMLDocument2 *doc; + IHTMLElement *body; + IHTMLDOMNode *node; + char *doc_string; + BSTR bstr, bstr2; + DWORD written; + HRESULT hres; + VARIANT var; + VARIANT v; + UINT ret; + MSG msg; + + ret = GetTempPathW(MAX_PATH, doc_stringW); + ok(ret != 0, "GetTempPath failed, error %ld\n", GetLastError()); + ret = GetTempFileNameW(doc_stringW, L"doc", 0, docW_path); + ok(ret != 0, "GetTempFileName failed, error %ld\n", GetLastError()); + wcscpy(docW_path + wcslen(docW_path) - 4, L".htm"); + docWfile = CreateFileW(docW_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, 0); + ok(docWfile != INVALID_HANDLE_VALUE, "CreateFile failed, error %ld\n", GetLastError()); + + ret = GetTempFileNameW(doc_stringW, L"htm", 0, doc_path); + ok(ret != 0, "GetTempFileName failed, error %ld\n", GetLastError()); + wcscpy(doc_path + wcslen(doc_path) - 4, L".htm"); + docfile = CreateFileW(doc_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, 0); + ok(docfile != INVALID_HANDLE_VALUE, "CreateFile failed, error %ld\n", GetLastError()); + + ret = GetTempFileNameW(doc_stringW, L"css", 0, css_path); + ok(ret != 0, "GetTempFileName failed, error %ld\n", GetLastError()); + file = CreateFileW(css_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, 0); + ok(file != INVALID_HANDLE_VALUE, "CreateFile failed, error %ld\n", GetLastError()); + + ret = wsprintfW(doc_stringW, L"<!DOCTYPE html>\n<html><head><link href="file://%s" rel="stylesheet"></head><body></body></html>", css_path); + ret = WriteFile(docWfile, doc_stringW, ret * sizeof(WCHAR), &written, NULL); + ok(ret, "WriteFile failed, error %ld\n", GetLastError()); + + ret = WideCharToMultiByte(CP_UTF8, 0, doc_stringW, -1, NULL, 0, NULL, NULL); + doc_string = malloc(ret); + ret = WideCharToMultiByte(CP_UTF8, 0, doc_stringW, -1, doc_string, ret, NULL, NULL); + ret = WriteFile(docfile, doc_string, ret - 1, &written, NULL); + ok(ret, "WriteFile failed, error %ld\n", GetLastError()); + free(doc_string); + + for(doc_charset = utf8; doc_charset <= utf16; doc_charset++) { + for(css_charset = utf8; css_charset <= utf16_bom; css_charset++) { + notif_doc = doc = create_document(); + if(!doc) + return; + doc_complete = FALSE; + + switch(css_charset) { + case utf8: ret = WriteFile(file, css_utf8 + 3, sizeof(css_utf8) - sizeof(char) - 3, &written, NULL); break; + case utf8_bom: ret = WriteFile(file, css_utf8, sizeof(css_utf8) - sizeof(char), &written, NULL); break; + case utf16: ret = WriteFile(file, css_utf16 + 1, sizeof(css_utf16) - sizeof(WCHAR) - 2, &written, NULL); break; + case utf16_bom: ret = WriteFile(file, css_utf16, sizeof(css_utf16) - sizeof(WCHAR), &written, NULL); break; + } + ok(ret, "WriteFile failed, error %ld\n", GetLastError()); + + set_client_site(doc, TRUE); + do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink); + + hres = IHTMLDocument2_get_parentWindow(doc, &window); + ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres); + + wsprintfW(doc_stringW, L"file://%s", doc_charset == utf8 ? doc_path : docW_path); + + V_VT(&v) = VT_EMPTY; + bstr = SysAllocString(doc_stringW); + bstr2 = SysAllocString(L""); + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLPrivateWindow, (void**)&priv_window); + ok(hres == S_OK, "Could not get IHTMLPrivateWindow) interface: %08lx\n", hres); + hres = IHTMLPrivateWindow_SuperNavigate(priv_window, bstr, bstr2, NULL, NULL, &v, &v, 0); + ok(hres == S_OK, "SuperNavigate failed: %08lx\n", hres); + IHTMLPrivateWindow_Release(priv_window); + IHTMLWindow2_Release(window); + SysFreeString(bstr2); + SysFreeString(bstr); + + while(!doc_complete && GetMessageW(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + + hres = IHTMLDocument2_get_parentWindow(doc, &window); + ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres); + + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow7, (void**)&window7); + ok(hres == S_OK, "Could not get IHTMLWindow7: %08lx\n", hres); + IHTMLWindow2_Release(window); + + hres = IHTMLDocument2_get_body(doc, &body); + ok(hres == S_OK, "Could not get body: %08lx\n", hres); + + hres = IHTMLElement_QueryInterface(body, &IID_IHTMLDOMNode, (void**)&node); + ok(hres == S_OK, "Could not get IHTMLDOMNode: %08lx\n", hres); + IHTMLElement_Release(body); + + hres = IHTMLWindow7_getComputedStyle(window7, node, NULL, &style); + ok(hres == S_OK, "getComputedStyle failed: %08lx\n", hres); + IHTMLWindow7_Release(window7); + IHTMLDOMNode_Release(node); + + hres = IHTMLCSSStyleDeclaration_get_backgroundColor(style, &var); + ok(hres == S_OK, "get_backgroundColor failed: %08lx\n", hres); + ok(V_VT(&var) == VT_BSTR, "backgroundColor VT = %d\n", V_VT(&var)); + ok(!wcscmp(V_BSTR(&var), L"rgb(222, 173, 184)"), "[%s:%s] backgroundColor = %s\n", charsets[doc_charset], charsets[css_charset], wine_dbgstr_w(V_BSTR(&var))); + IHTMLCSSStyleDeclaration_Release(style); + VariantClear(&var); + + set_client_site(doc, FALSE); + IHTMLDocument2_Release(doc); + + ret = SetFilePointer(file, 0, NULL, FILE_BEGIN); + ok(ret == 0, "wrong file offset %u\n", ret); + ret = SetEndOfFile(file); + ok(ret, "SetEndOfFile failed, error %ld\n", GetLastError()); + } + } + + CloseHandle(docWfile); + CloseHandle(docfile); + CloseHandle(file); + DeleteFileW(docW_path); + DeleteFileW(doc_path); + DeleteFileW(css_path); +} + static void test_document_mode_lock(void) { IHTMLOptionElementFactory *option, *option2; @@ -12414,6 +12552,7 @@ START_TEST(dom) }
test_quirks_mode(); + test_default_content_charset(); test_document_mode_lock(); test_document_mode_after_initnew(); test_threads(); ``` This code is pretty crude, I had to use actual htm extension so I didn't bother cleaning up the originals (.tmp) but it's enough to test it. Maybe you can try something else from it and see if it works?