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();