[PATCH v4 0/3] MR7360: mshtml: Try to guess the charset on streams with no BOM.
-- 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. https://gitlab.winehq.org/wine/wine/-/merge_requests/7360
From: Gabriel Ivăncescu <gabrielopcode(a)gmail.com> Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)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(a)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(a)boTp@<=$p(a)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(a)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; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7360
From: Gabriel Ivăncescu <gabrielopcode(a)gmail.com> Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)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); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7360
From: Gabriel Ivăncescu <gabrielopcode(a)gmail.com> Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)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) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7360
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. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/7360#note_104968
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.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/7360#note_105020
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`)? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/7360#note_105021
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? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/7360#note_105121
participants (2)
-
Gabriel Ivăncescu -
Jacek Caban (@jacek)