From 45e0dd9d1f1d0ee54ecae91731e79843157540ab Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Mon, 7 Dec 2009 14:51:52 +0100 Subject: [PATCH] mshtml: Added PersistStreamInit_InitNew implementation. --- dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/nsevents.c | 21 ++++---- dlls/mshtml/persist.c | 84 ++++++++++++++++++++++++------- dlls/mshtml/tests/htmldoc.c | 95 ++++++++++++++++++++++++++++++++++-- 4 files changed, 171 insertions(+), 30 deletions(-) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 2a778084eb9..4e02ce61e9a 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -383,6 +383,7 @@ struct HTMLDocumentObj { BOOL has_key_path; BOOL container_locked; BOOL focus; + INT download_state; USERMODE usermode; LPWSTR mime; diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index 7c4c09b0fa7..46f057f079a 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -185,17 +185,19 @@ static void handle_docobj_load(HTMLDocumentObj *doc) hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd); if(SUCCEEDED(hres)) { - VARIANT state, progress; + if(doc->download_state) { + VARIANT state, progress; - V_VT(&progress) = VT_I4; - V_I4(&progress) = 0; - IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSPOS, OLECMDEXECOPT_DONTPROMPTUSER, - &progress, NULL); + V_VT(&progress) = VT_I4; + V_I4(&progress) = 0; + IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSPOS, + OLECMDEXECOPT_DONTPROMPTUSER, &progress, NULL); - V_VT(&state) = VT_I4; - V_I4(&state) = 0; - IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE, OLECMDEXECOPT_DONTPROMPTUSER, - &state, NULL); + V_VT(&state) = VT_I4; + V_I4(&state) = 0; + IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE, + OLECMDEXECOPT_DONTPROMPTUSER, &state, NULL); + } IOleCommandTarget_Exec(olecmd, &CGID_ShellDocView, 103, 0, NULL, NULL); IOleCommandTarget_Exec(olecmd, &CGID_MSHTML, IDM_PARSECOMPLETE, 0, NULL, NULL); @@ -203,6 +205,7 @@ static void handle_docobj_load(HTMLDocumentObj *doc) IOleCommandTarget_Release(olecmd); } + doc->download_state = 0; } static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event) diff --git a/dlls/mshtml/persist.c b/dlls/mshtml/persist.c index 2ea0e5df72f..eaff9ddbd61 100644 --- a/dlls/mshtml/persist.c +++ b/dlls/mshtml/persist.c @@ -40,6 +40,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); +typedef struct { + task_t header; + HTMLDocumentObj *doc; + BOOL set_download; +} download_proc_task_t; + static BOOL use_gecko_script(LPCWSTR url) { static const WCHAR fileW[] = {'f','i','l','e',':'}; @@ -118,7 +124,8 @@ static void set_progress_proc(task_t *_task) static void set_downloading_proc(task_t *_task) { - HTMLDocumentObj *doc = ((docobj_task_t*)_task)->doc; + download_proc_task_t *task = (download_proc_task_t*)_task; + HTMLDocumentObj *doc = task->doc; IOleCommandTarget *olecmd; HRESULT hres; @@ -130,16 +137,20 @@ static void set_downloading_proc(task_t *_task) if(!doc->client) return; - hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd); - if(SUCCEEDED(hres)) { - VARIANT var; + if(task->set_download) { + hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd); + if(SUCCEEDED(hres)) { + VARIANT var; - V_VT(&var) = VT_I4; - V_I4(&var) = 1; + V_VT(&var) = VT_I4; + V_I4(&var) = 1; - IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE, OLECMDEXECOPT_DONTPROMPTUSER, - &var, NULL); - IOleCommandTarget_Release(olecmd); + IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE, + OLECMDEXECOPT_DONTPROMPTUSER, &var, NULL); + IOleCommandTarget_Release(olecmd); + } + + doc->download_state = 1; } if(doc->hostui) { @@ -153,11 +164,12 @@ static void set_downloading_proc(task_t *_task) } } -static HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc) +static HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc, BOOL set_download) { nsChannelBSC *bscallback; LPOLESTR url = NULL; docobj_task_t *task; + download_proc_task_t *download_task; HRESULT hres; nsresult nsres; @@ -248,9 +260,10 @@ static HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc) push_task(&task->header, set_progress_proc, This->doc_obj->basedoc.task_magic); } - task = heap_alloc(sizeof(docobj_task_t)); - task->doc = This->doc_obj; - push_task(&task->header, set_downloading_proc, This->doc_obj->basedoc.task_magic); + download_task = heap_alloc(sizeof(download_proc_task_t)); + download_task->doc = This->doc_obj; + download_task->set_download = set_download; + push_task(&download_task->header, set_downloading_proc, This->doc_obj->basedoc.task_magic); if(This->doc_obj->nscontainer) { This->doc_obj->nscontainer->bscallback = bscallback; @@ -363,7 +376,7 @@ static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAva TRACE("(%p)->(%x %p %p %08x)\n", This, fFullyAvailable, pimkName, pibc, grfMode); - hres = set_moniker(This, pimkName, pibc); + hres = set_moniker(This, pimkName, pibc, TRUE); if(FAILED(hres)) return hres; @@ -624,7 +637,7 @@ static HRESULT WINAPI PersistStreamInit_Load(IPersistStreamInit *iface, LPSTREAM return hres; } - hres = set_moniker(This, mon, NULL); + hres = set_moniker(This, mon, NULL, TRUE); IMoniker_Release(mon); if(FAILED(hres)) return hres; @@ -669,8 +682,45 @@ static HRESULT WINAPI PersistStreamInit_GetSizeMax(IPersistStreamInit *iface, static HRESULT WINAPI PersistStreamInit_InitNew(IPersistStreamInit *iface) { HTMLDocument *This = PERSTRINIT_THIS(iface); - FIXME("(%p)\n", This); - return E_NOTIMPL; + IMoniker *mon; + HGLOBAL body; + LPSTREAM stream; + HRESULT hres; + + static const WCHAR about_blankW[] = {'a','b','o','u','t',':','b','l','a','n','k',0}; + static const WCHAR html_bodyW[] = {'<','H','T','M','L','>','<','/','H','T','M','L','>',0}; + + TRACE("(%p)\n", This); + + body = GlobalAlloc(0, sizeof(html_bodyW)); + if(!body) + return E_OUTOFMEMORY; + memcpy(body, html_bodyW, sizeof(html_bodyW)); + + hres = CreateURLMoniker(NULL, about_blankW, &mon); + if(FAILED(hres)) { + WARN("CreateURLMoniker failed: %08x\n", hres); + GlobalFree(body); + return hres; + } + + hres = set_moniker(This, mon, NULL, FALSE); + IMoniker_Release(mon); + if(FAILED(hres)) { + GlobalFree(body); + return hres; + } + + hres = CreateStreamOnHGlobal(body, TRUE, &stream); + if(FAILED(hres)) { + GlobalFree(body); + return hres; + } + + hres = channelbsc_load_stream(This->window->bscallback, stream); + + IStream_Release(stream); + return hres; } #undef PERSTRINIT_THIS diff --git a/dlls/mshtml/tests/htmldoc.c b/dlls/mshtml/tests/htmldoc.c index ab1a0e000af..751866fc825 100644 --- a/dlls/mshtml/tests/htmldoc.c +++ b/dlls/mshtml/tests/htmldoc.c @@ -2255,6 +2255,8 @@ static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID ok(nCmdexecopt == 0, "nCmdexecopts=%08x\n", nCmdexecopt); ok(pvaOut == NULL, "pvaOut=%p\n", pvaOut); ok(pvaIn == NULL, "pvaIn=%p\n", pvaIn); + readystate_set_loading = FALSE; + readystate_set_interactive = FALSE; load_state = LD_COMPLETE; return S_OK; case OLECMDID_SETDOWNLOADSTATE: @@ -2889,6 +2891,7 @@ static void test_Load(IPersistMoniker *persist, IMoniker *mon) #define DWL_CSS 0x0002 #define DWL_TRYCSS 0x0004 #define DWL_HTTP 0x0008 +#define DWL_EMPTY 0x0010 static void test_download(DWORD flags) { @@ -2905,7 +2908,8 @@ static void test_download(DWORD flags) if((flags & DWL_VERBDONE) && !load_from_stream) SET_EXPECT(GetHostInfo); SET_EXPECT(SetStatusText); - SET_EXPECT(Exec_SETDOWNLOADSTATE_1); + if(!(flags & DWL_EMPTY)) + SET_EXPECT(Exec_SETDOWNLOADSTATE_1); SET_EXPECT(GetDropTarget); if(flags & DWL_TRYCSS) SET_EXPECT(Exec_ShellDocView_84); @@ -2930,7 +2934,8 @@ static void test_download(DWORD flags) SET_EXPECT(OnChanged_1005); SET_EXPECT(OnChanged_READYSTATE); SET_EXPECT(Exec_SETPROGRESSPOS); - SET_EXPECT(Exec_SETDOWNLOADSTATE_0); + if(!(flags & DWL_EMPTY)) + SET_EXPECT(Exec_SETDOWNLOADSTATE_0); SET_EXPECT(Exec_ShellDocView_103); SET_EXPECT(Exec_ShellDocView_105); SET_EXPECT(Exec_ShellDocView_140); @@ -2951,7 +2956,8 @@ static void test_download(DWORD flags) if((flags & DWL_VERBDONE) && !load_from_stream) CHECK_CALLED(GetHostInfo); CHECK_CALLED(SetStatusText); - CHECK_CALLED(Exec_SETDOWNLOADSTATE_1); + if(!(flags & DWL_EMPTY)) + CHECK_CALLED(Exec_SETDOWNLOADSTATE_1); CHECK_CALLED(GetDropTarget); if(flags & DWL_TRYCSS) SET_CALLED(Exec_ShellDocView_84); @@ -2976,7 +2982,8 @@ static void test_download(DWORD flags) CHECK_CALLED(OnChanged_1005); CHECK_CALLED(OnChanged_READYSTATE); CHECK_CALLED(Exec_SETPROGRESSPOS); - CHECK_CALLED(Exec_SETDOWNLOADSTATE_0); + if(!(flags & DWL_EMPTY)) + CHECK_CALLED(Exec_SETDOWNLOADSTATE_0); SET_CALLED(Exec_ShellDocView_103); SET_CALLED(Exec_ShellDocView_105); SET_CALLED(Exec_ShellDocView_140); @@ -3940,6 +3947,36 @@ static void test_StreamLoad(IUnknown *unk) IPersistStreamInit_Release(init); } +static void test_StreamInitNew(IUnknown *unk) +{ + IPersistStreamInit *init; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IPersistStreamInit, (void**)&init); + ok(hres == S_OK, "QueryInterface(IID_IPersistStreamInit) failed: %08x\n", hres); + if(FAILED(hres)) + return; + + SET_EXPECT(Invoke_AMBIENT_SILENT); + SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED); + SET_EXPECT(Exec_ShellDocView_37); + SET_EXPECT(OnChanged_READYSTATE); + readystate_set_loading = TRUE; + + hres = IPersistStreamInit_InitNew(init); + ok(hres == S_OK, "Load failed: %08x\n", hres); + + CHECK_CALLED(Invoke_AMBIENT_SILENT); + CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED); + CHECK_CALLED(Exec_ShellDocView_37); + CHECK_CALLED(OnChanged_READYSTATE); + + test_timer(EXPECT_SETTITLE); + test_GetCurMoniker(unk, NULL, about_blank_url); + + IPersistStreamInit_Release(init); +} + static void test_QueryInterface(IUnknown *unk) { IUnknown *qi; @@ -4298,6 +4335,55 @@ static void test_HTMLDocument_StreamLoad(void) ok(ref == 0, "ref=%d, expected 0\n", ref); } +static void test_HTMLDocument_StreamInitNew(void) +{ + IOleObject *oleobj; + IUnknown *unk; + HRESULT hres; + ULONG ref; + + trace("Testing HTMLDocument (IPersistStreamInit)...\n"); + + init_test(LD_DOLOAD); + load_from_stream = TRUE; + + hres = create_document(&unk); + if(FAILED(hres)) + return; + doc_unk = unk; + + hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj); + ok(hres == S_OK, "Could not get IOleObject: %08x\n", hres); + + test_readyState(unk); + test_IsDirty(unk, S_FALSE); + test_ConnectionPointContainer(unk); + test_ClientSite(oleobj, CLIENTSITE_EXPECTPATH); + test_DoVerb(oleobj); + test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED); + + IOleObject_Release(oleobj); + + test_GetCurMoniker(unk, NULL, NULL); + test_StreamInitNew(unk); + test_download(DWL_VERBDONE|DWL_TRYCSS|DWL_EMPTY); + test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED); + + test_UIDeactivate(); + test_InPlaceDeactivate(unk, TRUE); + test_Close(unk, FALSE); + test_IsDirty(unk, S_FALSE); + + if(view) { + IOleDocumentView_Release(view); + view = NULL; + } + + + ref = IUnknown_Release(unk); + ok(ref == 0, "ref=%d, expected 0\n", ref); +} + static void test_edit_uiactivate(IOleObject *oleobj) { IOleDocumentView *docview; @@ -4479,6 +4565,7 @@ START_TEST(htmldoc) test_HTMLDocument(FALSE); test_HTMLDocument(TRUE); test_HTMLDocument_StreamLoad(); + test_HTMLDocument_StreamInitNew(); test_editing_mode(FALSE); test_editing_mode(TRUE); test_HTMLDocument_http();