mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 04:49:47 +00:00
mshtml: Implement document.mimeType.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
parent
8dd8664a51
commit
c25dfb7965
|
@ -1245,8 +1245,27 @@ static HRESULT WINAPI HTMLDocument_get_defaultCharset(IHTMLDocument2 *iface, BST
|
|||
static HRESULT WINAPI HTMLDocument_get_mimeType(IHTMLDocument2 *iface, BSTR *p)
|
||||
{
|
||||
HTMLDocumentNode *This = impl_from_IHTMLDocument2(iface);
|
||||
FIXME("(%p)->(%p)\n", This, p);
|
||||
return E_NOTIMPL;
|
||||
const PRUnichar *content_type;
|
||||
nsAString nsstr;
|
||||
nsresult nsres;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, p);
|
||||
|
||||
*p = NULL;
|
||||
|
||||
if(This->window && This->window->base.outer_window->readystate == READYSTATE_UNINITIALIZED)
|
||||
return (*p = SysAllocString(L"")) ? S_OK : E_FAIL;
|
||||
|
||||
nsAString_InitDepend(&nsstr, NULL);
|
||||
nsres = nsIDOMHTMLDocument_GetContentType(This->nsdoc, &nsstr);
|
||||
if(NS_FAILED(nsres))
|
||||
return map_nsresult(nsres);
|
||||
|
||||
nsAString_GetData(&nsstr, &content_type);
|
||||
hres = get_mime_type_display_name(content_type, p);
|
||||
nsAString_Finish(&nsstr);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HTMLDocument_get_fileSize(IHTMLDocument2 *iface, BSTR *p)
|
||||
|
|
|
@ -126,6 +126,109 @@ BSTR charset_string_from_cp(UINT cp)
|
|||
return SysAllocString(info.wszWebCharset);
|
||||
}
|
||||
|
||||
HRESULT get_mime_type_display_name(const WCHAR *content_type, BSTR *ret)
|
||||
{
|
||||
/* undocumented */
|
||||
extern BOOL WINAPI GetMIMETypeSubKeyW(LPCWSTR,LPWSTR,DWORD);
|
||||
|
||||
WCHAR buffer[128], ext[128], *str, *progid;
|
||||
DWORD type, len;
|
||||
HKEY key = NULL;
|
||||
LSTATUS status;
|
||||
HRESULT hres;
|
||||
CLSID clsid;
|
||||
|
||||
str = buffer;
|
||||
if(!GetMIMETypeSubKeyW(content_type, buffer, ARRAY_SIZE(buffer))) {
|
||||
len = wcslen(content_type) + 32;
|
||||
for(;;) {
|
||||
if(!(str = heap_alloc(len * sizeof(WCHAR))))
|
||||
return E_OUTOFMEMORY;
|
||||
if(GetMIMETypeSubKeyW(content_type, str, len))
|
||||
break;
|
||||
heap_free(str);
|
||||
len *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
status = RegOpenKeyExW(HKEY_CLASSES_ROOT, str, 0, KEY_QUERY_VALUE, &key);
|
||||
if(str != buffer)
|
||||
heap_free(str);
|
||||
if(status != ERROR_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
len = sizeof(ext);
|
||||
status = RegQueryValueExW(key, L"Extension", NULL, &type, (BYTE*)ext, &len);
|
||||
if(status != ERROR_SUCCESS || type != REG_SZ) {
|
||||
len = sizeof(buffer);
|
||||
status = RegQueryValueExW(key, L"CLSID", NULL, &type, (BYTE*)buffer, &len);
|
||||
if(status != ERROR_SUCCESS || type != REG_SZ || CLSIDFromString(buffer, &clsid) != S_OK)
|
||||
goto fail;
|
||||
|
||||
hres = ProgIDFromCLSID(&clsid, &progid);
|
||||
if(hres == E_OUTOFMEMORY) {
|
||||
RegCloseKey(key);
|
||||
return hres;
|
||||
}
|
||||
if(hres != S_OK)
|
||||
goto fail;
|
||||
}else {
|
||||
progid = ext;
|
||||
}
|
||||
|
||||
len = ARRAY_SIZE(buffer);
|
||||
str = buffer;
|
||||
for(;;) {
|
||||
hres = AssocQueryStringW(ASSOCF_NOTRUNCATE, ASSOCSTR_FRIENDLYDOCNAME, progid, NULL, str, &len);
|
||||
if(hres == S_OK && len)
|
||||
break;
|
||||
if(str != buffer)
|
||||
heap_free(str);
|
||||
if(hres != E_POINTER) {
|
||||
if(progid != ext) {
|
||||
CoTaskMemFree(progid);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Try from CLSID */
|
||||
len = sizeof(buffer);
|
||||
status = RegQueryValueExW(key, L"CLSID", NULL, &type, (BYTE*)buffer, &len);
|
||||
if(status != ERROR_SUCCESS || type != REG_SZ || CLSIDFromString(buffer, &clsid) != S_OK)
|
||||
goto fail;
|
||||
|
||||
hres = ProgIDFromCLSID(&clsid, &progid);
|
||||
if(hres == E_OUTOFMEMORY) {
|
||||
RegCloseKey(key);
|
||||
return hres;
|
||||
}
|
||||
if(hres != S_OK)
|
||||
goto fail;
|
||||
|
||||
len = ARRAY_SIZE(buffer);
|
||||
str = buffer;
|
||||
continue;
|
||||
}
|
||||
str = heap_alloc(len * sizeof(WCHAR));
|
||||
}
|
||||
if(progid != ext)
|
||||
CoTaskMemFree(progid);
|
||||
RegCloseKey(key);
|
||||
|
||||
*ret = SysAllocString(str);
|
||||
if(str != buffer)
|
||||
heap_free(str);
|
||||
return *ret ? S_OK : E_OUTOFMEMORY;
|
||||
|
||||
fail:
|
||||
RegCloseKey(key);
|
||||
|
||||
WARN("Did not find MIME in database for %s\n", debugstr_w(content_type));
|
||||
|
||||
/* native seems to return "File" when it doesn't know the content type */
|
||||
*ret = SysAllocString(L"File");
|
||||
return *ret ? S_OK : E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
IInternetSecurityManager *get_security_manager(void)
|
||||
{
|
||||
if(!security_manager) {
|
||||
|
|
|
@ -1455,6 +1455,7 @@ extern void *call_thiscall_func;
|
|||
compat_mode_t get_max_compat_mode(IUri*) DECLSPEC_HIDDEN;
|
||||
UINT cp_from_charset_string(BSTR) DECLSPEC_HIDDEN;
|
||||
BSTR charset_string_from_cp(UINT) DECLSPEC_HIDDEN;
|
||||
HRESULT get_mime_type_display_name(const WCHAR*,BSTR*) DECLSPEC_HIDDEN;
|
||||
HINSTANCE get_shdoclc(void) DECLSPEC_HIDDEN;
|
||||
void set_statustext(HTMLDocumentObj*,INT,LPCWSTR) DECLSPEC_HIDDEN;
|
||||
IInternetSecurityManager *get_security_manager(void) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
TESTDLL = mshtml.dll
|
||||
IMPORTS = ole32 oleaut32 wininet user32 urlmon gdi32 advapi32
|
||||
IMPORTS = ole32 oleaut32 shlwapi wininet user32 urlmon gdi32 advapi32
|
||||
C_SRCS = \
|
||||
activex.c \
|
||||
dom.c \
|
||||
|
|
|
@ -311,6 +311,7 @@ sync_test("doc_props", function() {
|
|||
}
|
||||
|
||||
var v = document.documentMode;
|
||||
ok(document.mimeType === external.getExpectedMimeType("text/html"), "mimeType = " + document.mimeType);
|
||||
|
||||
test_exposed("onstorage", v < 9);
|
||||
test_exposed("textContent", v >= 9);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "winbase.h"
|
||||
#include "initguid.h"
|
||||
#include "ole2.h"
|
||||
#include "shlwapi.h"
|
||||
#include "mshtml.h"
|
||||
#include "docobj.h"
|
||||
#include "docobjectservice.h"
|
||||
|
@ -449,6 +450,84 @@ static void _test_current_url(unsigned line, IUnknown *unk, const WCHAR *exurl)
|
|||
IHTMLDocument2_Release(doc);
|
||||
}
|
||||
|
||||
static BSTR get_mime_type_display_name(const WCHAR *content_type)
|
||||
{
|
||||
WCHAR buffer[128], ext[128], *str, *progid;
|
||||
HKEY key, type_key = NULL;
|
||||
DWORD type, len;
|
||||
LSTATUS status;
|
||||
HRESULT hres;
|
||||
CLSID clsid;
|
||||
BSTR ret;
|
||||
|
||||
status = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"MIME\\Database\\Content Type", 0, KEY_READ, &key);
|
||||
if(status != ERROR_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
status = RegOpenKeyExW(key, content_type, 0, KEY_QUERY_VALUE, &type_key);
|
||||
RegCloseKey(key);
|
||||
if(status != ERROR_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
len = sizeof(ext);
|
||||
status = RegQueryValueExW(type_key, L"Extension", NULL, &type, (BYTE*)ext, &len);
|
||||
if(status != ERROR_SUCCESS || type != REG_SZ) {
|
||||
len = sizeof(buffer);
|
||||
status = RegQueryValueExW(type_key, L"CLSID", NULL, &type, (BYTE*)buffer, &len);
|
||||
|
||||
if(status != ERROR_SUCCESS || type != REG_SZ || CLSIDFromString(buffer, &clsid) != S_OK ||
|
||||
ProgIDFromCLSID(&clsid, &progid) != S_OK)
|
||||
goto fail;
|
||||
}else {
|
||||
/* For some reason w1064v1809 testbot VM uses .htm here, despite .html being set in the database */
|
||||
if(!wcscmp(ext, L".html"))
|
||||
wcscpy(ext, L".htm");
|
||||
progid = ext;
|
||||
}
|
||||
|
||||
len = ARRAY_SIZE(buffer);
|
||||
str = buffer;
|
||||
for(;;) {
|
||||
hres = AssocQueryStringW(ASSOCF_NOTRUNCATE, ASSOCSTR_FRIENDLYDOCNAME, progid, NULL, str, &len);
|
||||
if(hres == S_OK && len)
|
||||
break;
|
||||
if(str != buffer)
|
||||
free(str);
|
||||
if(hres != E_POINTER) {
|
||||
if(progid != ext) {
|
||||
CoTaskMemFree(progid);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Try from CLSID */
|
||||
len = sizeof(buffer);
|
||||
status = RegQueryValueExW(type_key, L"CLSID", NULL, &type, (BYTE*)buffer, &len);
|
||||
|
||||
if(status != ERROR_SUCCESS || type != REG_SZ || CLSIDFromString(buffer, &clsid) != S_OK ||
|
||||
ProgIDFromCLSID(&clsid, &progid) != S_OK)
|
||||
goto fail;
|
||||
|
||||
len = ARRAY_SIZE(buffer);
|
||||
str = buffer;
|
||||
continue;
|
||||
}
|
||||
str = malloc(len * sizeof(WCHAR));
|
||||
}
|
||||
if(progid != ext)
|
||||
CoTaskMemFree(progid);
|
||||
RegCloseKey(type_key);
|
||||
|
||||
ret = SysAllocString(str);
|
||||
if(str != buffer)
|
||||
free(str);
|
||||
return ret;
|
||||
|
||||
fail:
|
||||
RegCloseKey(type_key);
|
||||
trace("Did not find MIME in database for %s\n", debugstr_w(content_type));
|
||||
return SysAllocString(L"File");
|
||||
}
|
||||
|
||||
DEFINE_GUID(IID_External_unk,0x30510406,0x98B5,0x11CF,0xBB,0x82,0x00,0xAA,0x00,0xBD,0xCE,0x0B);
|
||||
|
||||
static HRESULT WINAPI External_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
|
||||
|
@ -7680,6 +7759,25 @@ static void test_QueryInterface(IHTMLDocument2 *htmldoc)
|
|||
IUnknown_Release(qi);
|
||||
}
|
||||
|
||||
static void test_mimeType(IHTMLDocument2 *doc, const WCHAR *content_type)
|
||||
{
|
||||
BSTR mime_type = (BSTR)0xdeadbeef;
|
||||
HRESULT hres;
|
||||
|
||||
hres = IHTMLDocument2_get_mimeType(doc, &mime_type);
|
||||
if(content_type) {
|
||||
BSTR display_name = get_mime_type_display_name(content_type);
|
||||
ok(hres == S_OK, "get_mimeType returned %08lx\n", hres);
|
||||
ok(!wcscmp(mime_type, display_name), "mime type = %s, expected %s\n",
|
||||
debugstr_w(mime_type), debugstr_w(display_name));
|
||||
SysFreeString(display_name);
|
||||
}else {
|
||||
ok(hres == S_OK || broken(hres == E_FAIL), "get_mimeType returned %08lx\n", hres);
|
||||
ok(!mime_type || !mime_type[0], "mime type = %s\n", debugstr_w(mime_type));
|
||||
}
|
||||
SysFreeString(mime_type);
|
||||
}
|
||||
|
||||
static void init_test(enum load_state_t ls) {
|
||||
doc_unk = NULL;
|
||||
doc_hwnd = last_hwnd = NULL;
|
||||
|
@ -7733,6 +7831,7 @@ static void test_HTMLDocument(BOOL do_load, BOOL mime)
|
|||
test_GetCurMoniker((IUnknown*)doc, &Moniker, NULL, FALSE);
|
||||
test_elem_from_point(doc);
|
||||
}
|
||||
test_mimeType(doc, do_load ? L"text/html" : NULL);
|
||||
|
||||
test_MSHTML_QueryStatus(doc, OLECMDF_SUPPORTED);
|
||||
test_OleCommandTarget_fail(doc);
|
||||
|
@ -7844,6 +7943,7 @@ static void test_MHTMLDocument(void)
|
|||
set_custom_uihandler(doc, &CustomDocHostUIHandler);
|
||||
test_GetCurMoniker((IUnknown*)doc, NULL, L"mhtml:winetest:doc", FALSE);
|
||||
test_download(0);
|
||||
test_mimeType(doc, L"text/html");
|
||||
|
||||
test_exec_onunload(doc);
|
||||
test_UIDeactivate();
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "ole2.h"
|
||||
#include "shlwapi.h"
|
||||
#include "wininet.h"
|
||||
#include "docobj.h"
|
||||
#include "dispex.h"
|
||||
|
@ -157,6 +158,7 @@ DEFINE_EXPECT(GetTypeInfo);
|
|||
#define DISPID_EXTERNAL_IS_ENGLISH 0x300009
|
||||
#define DISPID_EXTERNAL_LIST_SEP 0x30000A
|
||||
#define DISPID_EXTERNAL_TEST_VARS 0x30000B
|
||||
#define DISPID_EXTERNAL_GETMIMETYPE 0x30000C
|
||||
|
||||
static const GUID CLSID_TestScript =
|
||||
{0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x07,0x46}};
|
||||
|
@ -200,6 +202,84 @@ static BOOL init_key(const char *key_name, const char *def_value, BOOL init)
|
|||
return res == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static BSTR get_mime_type_display_name(const WCHAR *content_type)
|
||||
{
|
||||
WCHAR buffer[128], ext[128], *str, *progid;
|
||||
HKEY key, type_key = NULL;
|
||||
DWORD type, len;
|
||||
LSTATUS status;
|
||||
HRESULT hres;
|
||||
CLSID clsid;
|
||||
BSTR ret;
|
||||
|
||||
status = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"MIME\\Database\\Content Type", 0, KEY_READ, &key);
|
||||
if(status != ERROR_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
status = RegOpenKeyExW(key, content_type, 0, KEY_QUERY_VALUE, &type_key);
|
||||
RegCloseKey(key);
|
||||
if(status != ERROR_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
len = sizeof(ext);
|
||||
status = RegQueryValueExW(type_key, L"Extension", NULL, &type, (BYTE*)ext, &len);
|
||||
if(status != ERROR_SUCCESS || type != REG_SZ) {
|
||||
len = sizeof(buffer);
|
||||
status = RegQueryValueExW(type_key, L"CLSID", NULL, &type, (BYTE*)buffer, &len);
|
||||
|
||||
if(status != ERROR_SUCCESS || type != REG_SZ || CLSIDFromString(buffer, &clsid) != S_OK ||
|
||||
ProgIDFromCLSID(&clsid, &progid) != S_OK)
|
||||
goto fail;
|
||||
}else {
|
||||
/* For some reason w1064v1809 testbot VM uses .htm here, despite .html being set in the database */
|
||||
if(!wcscmp(ext, L".html"))
|
||||
wcscpy(ext, L".htm");
|
||||
progid = ext;
|
||||
}
|
||||
|
||||
len = ARRAY_SIZE(buffer);
|
||||
str = buffer;
|
||||
for(;;) {
|
||||
hres = AssocQueryStringW(ASSOCF_NOTRUNCATE, ASSOCSTR_FRIENDLYDOCNAME, progid, NULL, str, &len);
|
||||
if(hres == S_OK && len)
|
||||
break;
|
||||
if(str != buffer)
|
||||
free(str);
|
||||
if(hres != E_POINTER) {
|
||||
if(progid != ext) {
|
||||
CoTaskMemFree(progid);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Try from CLSID */
|
||||
len = sizeof(buffer);
|
||||
status = RegQueryValueExW(type_key, L"CLSID", NULL, &type, (BYTE*)buffer, &len);
|
||||
|
||||
if(status != ERROR_SUCCESS || type != REG_SZ || CLSIDFromString(buffer, &clsid) != S_OK ||
|
||||
ProgIDFromCLSID(&clsid, &progid) != S_OK)
|
||||
goto fail;
|
||||
|
||||
len = ARRAY_SIZE(buffer);
|
||||
str = buffer;
|
||||
continue;
|
||||
}
|
||||
str = malloc(len * sizeof(WCHAR));
|
||||
}
|
||||
if(progid != ext)
|
||||
CoTaskMemFree(progid);
|
||||
RegCloseKey(type_key);
|
||||
|
||||
ret = SysAllocString(str);
|
||||
if(str != buffer)
|
||||
free(str);
|
||||
return ret;
|
||||
|
||||
fail:
|
||||
RegCloseKey(type_key);
|
||||
trace("Did not find MIME in database for %s\n", debugstr_w(content_type));
|
||||
return SysAllocString(L"File");
|
||||
}
|
||||
|
||||
static void test_script_vars(unsigned argc, VARIANTARG *argv)
|
||||
{
|
||||
static const WCHAR *const jsobj_names[] = { L"abc", L"foO", L"bar", L"TostRing", L"hasownpropERty" };
|
||||
|
@ -715,6 +795,10 @@ static HRESULT WINAPI externalDisp_GetDispID(IDispatchEx *iface, BSTR bstrName,
|
|||
*pid = DISPID_EXTERNAL_TEST_VARS;
|
||||
return S_OK;
|
||||
}
|
||||
if(!lstrcmpW(bstrName, L"getExpectedMimeType")) {
|
||||
*pid = DISPID_EXTERNAL_GETMIMETYPE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
|
||||
return DISP_E_UNKNOWNNAME;
|
||||
|
@ -948,6 +1032,20 @@ static HRESULT WINAPI externalDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID
|
|||
test_script_vars(pdp->cArgs, pdp->rgvarg);
|
||||
return S_OK;
|
||||
|
||||
case DISPID_EXTERNAL_GETMIMETYPE:
|
||||
ok(pdp != NULL, "pdp == NULL\n");
|
||||
ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
|
||||
ok(V_VT(pdp->rgvarg) == VT_BSTR, "VT(rgvarg) = %d\n", V_VT(pdp->rgvarg));
|
||||
ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
|
||||
ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
|
||||
ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
|
||||
ok(pvarRes != NULL, "pvarRes == NULL\n");
|
||||
ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
|
||||
ok(pei != NULL, "pei == NULL\n");
|
||||
V_BSTR(pvarRes) = get_mime_type_display_name(V_BSTR(pdp->rgvarg));
|
||||
V_VT(pvarRes) = V_BSTR(pvarRes) ? VT_BSTR : VT_NULL;
|
||||
return S_OK;
|
||||
|
||||
default:
|
||||
ok(0, "unexpected call\n");
|
||||
return E_NOTIMPL;
|
||||
|
|
Loading…
Reference in a new issue